OOFILE | Downloads | Purchasing | Press | Services | Company Information | Soapbox | References | F.A.Q. | HOME

OOFTST 29 - calculated fields

This sample tests a calculated fieldcalled Total Price to show how a calculated field is defined and can be used for searches and sorting (via method).


#include "oofile.h"	// the general oofile library

Our first thing to do is to define a calculater class. This class is derived from the dbRealCalculater class and must define it's own version of the clone() function and well as the calc() function (this is the function actually does the required calculation).

class OrderPriceCalculater : public dbRealCalculater{
public:
   virtual dbCalculater* clone() const {return new OrderPriceCalculater(*this);};
   virtual double	calc(const dbReal*);
};

Now we declare a class that has a calculated field in it. Note that we must provide a method calculateWith() that must have an instance of the above class passed to it.

class dbOrderItem : public dbTable {
   OOFILE_METHODS(dbOrderItem)
   dbReal   ItemPrice;
   dbUshort UnitsOrdered;

This is the actual calculated field. Note that due to having to be calculated, this field is virtual.

   dbReal   TotalOrderPrice; 
   dbOrderItem() :
      ItemPrice("Item Price"),
      UnitsOrdered("Units Ordered"),

Now we declare that we must use the specified calculater on this field.

      TotalOrderPrice("Total Price")
   {
      TotalOrderPrice.calculateWith( new OrderPriceCalculater );
   };     

   void addTestData();
};

Now we define the calc() method. Note that we must refer to the calling table by use of the function fieldTable(). In this way, the calc() procedure does not need to be tied specifically with one table and field, but the required field can just call the function and calc() will work it out from there. 

Testing: function fieldTable()
Testing: calculated field - method for actual calculation

double   OrderPriceCalculater::calc(const dbReal* theField)
{
   dbOrderItem* theTable = (dbOrderItem*) (theField->fieldTable());
   double ret = theTable->UnitsOrdered * theTable->ItemPrice;  
   return ret;
}

This procedure adds some test data to the table.

void   dbOrderItem::addTestData()
{
	newRecord();
	ItemPrice = 0.5;
	UnitsOrdered = 1000;
	saveRecord();  
	newRecord();
	ItemPrice = 0.05;
	UnitsOrdered = 1000;
	saveRecord();  
	newRecord();
	ItemPrice = 0.25;
	UnitsOrdered = 2000;
	saveRecord();  
	newRecord();
	ItemPrice = 12.79;
	UnitsOrdered = 100;
	saveRecord();
}
  
int main()
{
	cout << "OOFILE Validation Suite - Test 29\n"
		 << "Use of methods in queries and sorting" << endl << endl;

First, we must declare the global variables for our table and create the connection.

	dbConnect_ram  theDB;
	dbOrderItem  testItems;
	theDB.newConnection();

Now we add the test data.

	testItems.addTestData();

We print the database so we can see its initial state.

	cout << "Price, Qty & calculated Total Price:\n" 
		 << testItems << endl << endl;

Now we will attempt to sort the database by the calculated field, and print the results.

Testing: sort on calculated field

	testItems.setSortOrder(testItems.TotalOrderPrice);
	cout << "Now list again, sorted by the calculated Total Price:\n" 
		 << testItems << endl << endl;  

Now we will try and search for records who have a particular value in their calculated field.

Note: each time the computer tries to read the calculated field, it will be recalculated.

Testing: search on calculated field

	testItems.search(testItems.TotalOrderPrice==500);
	cout << "Now list searching by the calculated Total Price = $500:\n" 
		 << testItems << endl << endl;  

Now we will test if our calculaters clone correctly. Our calculater above must point to the new table. First we declare a new calculater and intitialise it with the one from above.

Testing: initialisation of calculated field from another calculated field

	dbOrderItem anotherIterator = testItems;

We undo our search selection.

	anotherIterator.selectAll();

Then set our sort order by our cloned object.

Testing: setting sort order to cloned calculated field

	anotherIterator.setSortOrder(anotherIterator.UnitsOrdered);

Now we print it out to see if it cloned correctly.

	cout << "Now list a cloned iterator, to check calculaters clone correctly:\n" 
		 << anotherIterator << endl << endl;
	  
	cout << "Test Completed" << endl;
	  
	return EXIT_SUCCESS;
}        

 

Feature index

(c) Copyright A.D. Software 1994-2000 (All Rights Reserved).
Last Updated: 9th September 2001