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

OOFTST 16 - modifying related data (inc caching)

This sample modifies related data including demonstrating the caching of related records as would typically be used in a GUI environment


#include "oofile.h"	// the general oofile library
#include "ooftst16.h"	// the declarations for the database classes we will be using in this test.

These are global variables that define the database using the ooftst16.h classes. 

	TEST_CONNECT    theDB;
	dbPatients     Patients;
	dbVisits	Visits;
	dbRelationship PatientVisits(Patients.Visits, Visits.Patient);
	  
int main()
{
	cout << "OOFILE Validation Suite - Test 16\n"
		 << "Simple test to demonstrate updating related fields" << endl
		 << "using a similar database to ooftst06 but with direct OID relationships" << endl;  

This code determines what platform we are running under and assigns a name for the database file accordingly.

	#ifdef TESTING_DBASE
		#ifdef _Macintosh
			const char* kExistsName =  ":ooftst16:Patients.dbf";
			const char* kDatabaseName = ":ooftst16:";
		#else
			const char* kExistsName =   "Patients.dbf"
			const char* kDatabaseName = "";
		#endif	  
	#else
		const char* kDatabaseName = "ooftst16.db";
		const char* kExistsName = kDatabaseName;
	#endif  

Now we open the old file and clear its contents or create a new one.

	if (dbConnect::fileExists(kExistsName)) {
		theDB.openConnection(kDatabaseName);
		Patients.deleteAll();
	}
	else {
		theDB.newConnection(kDatabaseName);
	}

Then we add the test data.

	Patients.AddTestData();

Now we run our tests and print out the database at the end of each one, to see what has been selected and what changes have occured.

This first one demonstrates a search where the items selected have a certain value in their related records. The patients sleected must have a related visit whose field named "why" has a value of "flu".

Testing: search through related field

	cout << "Now finding the Flu sufferers: " << endl;
	Patients.search(Patients.Visits->Why=="Flu");
	cout << Patients << endl << endl;  

We now do a combinatorial search not only for the people whose related field "why" has a value of flu, they must also have a salary of value less than 60000. Another way to do this would be to take the previous search and do a 'searchSelection' on it, refining the search to include those whose salary was less than 60000. This is demonstrated in ooftst13.

	cout << "Now finding the poorly-paid Flu sufferers: " << endl;
	Patients.search(Patients.Salary < 60000 && Patients.Visits->Why=="Flu");
	cout << Patients << endl << endl;  

We now reset our selection by using the function selectAll(), then define a dbView for easier printing of the database.

	Patients.selectAll();
	dbView smithVisits(Patients.Visits); 

Note that we can pass in fields from our related records if we wish, just as if they were fields in the actual table. It will print them as a list if there are more than one for each record.

	smithVisits << Patients.Visits->VisitDate << Patients.Visits->Why;   

Now you can see how useful this dbView is. Here we search for all records with the name Smith. We can print out the records from the patients database then easily print out the related visits.

	Patients.search(Patients.LastName=="Smith");
	cout << "Dumping Smith and his visits: " << endl 
	     << Patients << endl 
		 << smithVisits << endl;

Now we'll try modifying some of the information.

	cout << "changing the first reason to 'Computer-Induced Sanity' " << endl;

First we choose our record. We go to the first related record (ie, the first visit recorded for Smith). by using goToRecord() throguh the relationship.

Testing: function gotoRecord() through relationship

	Patients.Visits->gotoRecord(0);

Modifying the data is then a simple assignment, except that you are referring to a field in the related record's structure.

Testing: modification of character field through pointer relationship.

	Patients.Visits->Why = "Computer-Induced Sanity";

We will now test navigation via the view. Ie, we take the view that we have. Remember, these are visit fields. They are records whose related patient's lastName is Smith. We refer to them by using the function source(). We can then jump to the first in the list using goToRecord() as before.

Testing: Navigation via dbView using source()
Testing: goToRecord() in list of related records

	cout << "changing the second reason to 'Funny Views' " << endl;
	smithVisits.source()->gotoRecord(1);  

We can then change the value of why as previously, assigning it a string value through the relationship.

	Patients.Visits->Why = "Funny Views";  

We now save both changes and print the database as well as the revised visits (by passing in the dbView once more).

	Patients.saveRecord();   
	cout << "Dumping Smith and changed visits: " << endl 
	     << Patients << endl 
		 << smithVisits << endl;  

Now we add a new record to cache.

	Patients.AddVisit("14/2/1995", "Anxiety Attacks");

We now change to another related record - our new one should be cached

	smithVisits.source()->gotoRecord(1);

Then try changing the field for the first record again.

 	Patients.Visits->Why = "Changed Again";  

We'll now return to the new record (in the cache) and update it

	smithVisits.source()->gotoRecord(2);  
	Patients.Visits->VisitDate = "15/2/1994";

Then save the changes once more and print to see the changes.

	Patients.saveRecord(); 
	cout << "Dumping Smith and visits with added visit: " << endl 
	     << Patients << endl 
		 << smithVisits << endl;

Now we print out the entire database.

	cout << "Now dumping the entire database: " << endl << theDB;

Now we print out the schema so we can see the structure of the two tables and how they interrelate. 

	cout << "Description of database schema: " << endl;
	theDB.describe(cout);
	  
	cout << "done" << endl;  
	return EXIT_SUCCESS;
}        

 

Feature index

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