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

OOFTST 35 - relative access patterns

This sample tests the database backend relative access patterns similarly to a GUI listbox being scrolled by a user. Also shows how you override saveRecord; 


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

First we declare the class we will be using.

class	dbNumbers : public dbTable {
	OOFILE_METHODS(dbNumbers)
	dbLong	Integer;
	dbLong	UnindexedInt;
	dbChar	IntName;
	  
	dbNumbers() :
		Integer("Integer", kIndexed),
		UnindexedInt("UnindexedInt"),
		IntName(9, "Integer Name", kIndexCompressPadding)
	{};

We have a number of methods, for this class, that will be defined later.

	virtual void saveRecord();
	void DisplayTest();
	void AddTestData();
	void Display(unsigned int recsToDisplay);
};

The first method is a descendant of saveRecord(). We are going to initialise everything from the field Integer, so to add a record, we just assign a value to integer, then use saveRecord() and this function will do the rest before calling the original version of saveRecord().

void
dbNumbers::saveRecord()
{
	char str[10];
	sprintf(str, "%4d", Integer.value());
	IntName = str;
	UnindexedInt = Integer;  
	dbTable::saveRecord();
}

Now we have a method for adding the test data. Note that we create a new record, then assign a value just to Integer, then call saveRecord() which does the rest.

void
dbNumbers::AddTestData()
{
	cout << "\nAdding test data...\n\n";
	  
	for (long i=0; i<1000; i++) {
		newRecord();
		Integer = i;
		saveRecord();
	}
}

Now we have a method that mimics a listbox class. These would typically put an array-like layer on top of the database. Refreshing each cell in order becomes a succession of gotoRecords that know nothing of the wider context of the database. We pass in the number of records we would like to display and it starts where we currently are and keeps displaying until that many have been displayed. We must access the current record number, however, to know where to start. This is done by using the recordNumber() function (alternate useage).

Testing: function recordNumber()

void 
dbNumbers::Display(unsigned int recsToDisplay)
{
	unsigned long rec = recordNumber();
	for (unsigned int i=0; i<recsToDisplay; i++)  {
		gotoRecord(rec);
		cout << Integer << "   '" <<  IntName << "'" << endl;
		rec++;
	}
}

This last method is the one that will do the testing.

void
dbNumbers::DisplayTest()
{

We start by testing our display function. We are going to start at the first record (by iitialising with the start() function). So this will display the first 25 records. This is very much how a listbox would appear when we first see it.

	start();
	Display(25);

Now we pretend that we scrolled down a chunk of records to record number 400. The listbox would still diplay 25 records, but now it would start at number 400. All we do to get this is to use gotoRecord(400) then do our display  () function -> remember that the display function doesn't care where it starts, it just displays the number it was asked to, starting from the current record selected.

	cout << "\nPretend we scrolled down a chunk to record 400 (in order)\n" ;
	gotoRecord(400);
	Display(25);	  

Now we've scrolled back three lines. In a real situation, we'd have a scrollbar or up/down keys organised to actually implement these functions, but this will show how you actually do the code for moving about the database. We're only going to display 5 records this time, just to see if we can do different amounts.

	cout << "\nPretend we scrolled back three lines to 397th record\n" ;
	gotoRecord(397);
	Display(5);	  

Now we try going to the previous record using the prev() function. This is much like if the user hit up or the prev button. We then display another 5 records.

	cout << "\nNow try going to the previous record (from 401)\n" ;
	prev();
	Display(5);	
}	// DisplayTest  
	
  
int main()
{
	cout << "OOFILE Validation Suite - Test 35\n"
		 << "Simple test to store some regular ascending data and retrieve it\n"
		 << "in pattern like a user scrolling a listbox around\n" << endl;  
	TEST_CONNECT    theDB;
	dbNumbers    Numbers;  
	#ifdef TESTING_DBASE
		#ifdef _Macintosh
			const char* kExistsName =  ":ooftst35:Numbers.dbf";
			const char* kDatabaseName = ":ooftst35:";
		#else
			const char* kExistsName =   "Numbers.dbf"
			const char* kDatabaseName = "";
		#endif	  
	#else
		const char* kDatabaseName = "ooftst35.db";
		const char* kExistsName = kDatabaseName;
	#endif
	  
	if (dbConnect::fileExists(kExistsName)) {
		dbConnect::raise("Must delete databases before this test for unsorted test to be valid");
	}
	else {
		theDB.newConnection(kDatabaseName);
		Numbers.AddTestData();
	}  
	cout << "First few records unsorted - results may vary\n" ;
	Numbers.DisplayTest();
	  
	Numbers.setSortOrder(Numbers.Integer);
	cout << "\n\nNow sorted by integer\n" ;
	Numbers.DisplayTest();
	  
	Numbers.setSortOrder(Numbers.UnindexedInt);
	cout << "\n\nNow sorted by Unindexed integer (only makes difference on c-tree)\n" ;
	Numbers.DisplayTest();
	  
	Numbers.setSortOrder(Numbers.IntName);
	Numbers.selectAll();	//*** work around bug, if have all records selected and sort by non-indexed field
							// fails to correctly change state when sorting by indexed field later
	cout << "\n\nNow sorted by integer name\n" ;
	Numbers.DisplayTest();
	  
	cout << "Test Completed" << endl;
	  
	return EXIT_SUCCESS;

 

Feature index

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