Mapping a Table to a User Defined Object in Four Easy Steps:


1. Define an object to hold the rows from your query.

2. Define an association between fields in your query and fields in your object. This is what we call a 'BCA', which is short for Bind Column Addresses. In the example below, this is done via the functor "BCAExample". The job of the BCA is to equate SQL fields with object fields via the '==' operator which will then establish ODBC bindings to move data to or from a user query.

3. Create a view to select records from. This view is built from the template DBView and establishes which table(s) you want to access, what fields you want to look at (via the BCA), and an optional where clause to further limit the set of records that you are working with. The DBView template forms a semi-Container in the STL sense.1.

4. Use the DBView container to obtain an iterator to SELECT, INSERT, UPDATE or DELETE records from your view. These iterators may be used to either populate STL containers or apply algorithms from the Standard Template library.


In all the examples that follow we will assume that our database contains a table called DB_EXAMPLE of the form

SQL> desc db_example;
Name                            Type
------------------------------- --------
INT_VALUE                       INTEGER
STRING_VALUE                    VARCHAR
DOUBLE_VALUE                    FLOAT
EXAMPLE_LONG                    INTEGER
EXAMPLE_DATE                    DATE

// STEP 1 ////
// "Example" class to hold rows from our database table
class Example
{
  public:                                // tablename.columnname:
	int exampleInt;                 // DB_EXAMPLE.INT_VALUE
	string exampleStr;              // DB_EXAMPLE.STRING_VALUE
	double exampleDouble;           // DB_EXAMPLE.DOUBLE_VALUE
	long exampleLong;               // DB_EXAMPLE.EXAMPLE_LONG
	TIMESTAMP_STRUCT exampleDate;   // DB_EXAMPLE.EXAMPLE_DATE

	Example(int exInt, const string &exStr, double exDouble, long exLong,
		const TIMESTAMP_STRUCT &exDate) :
	   exampleInt(exInt), exampleStr(exStr), exampleDouble(exDouble), exampleLong(exLong),
	   exampleDate(exDate)
	{ }

};

// STEP 2 ////
// Create an association between table columns and fields in our object
template<> class dtl::DefaultBCA<Example>
{
public:
	void operator()(BoundIOs &cols, Example &rowbuf)
    	{
	   cols["INT_VALUE"] == rowbuf.exampleInt;
	   cols["STRING_VALUE"] == rowbuf.exampleStr;
	   cols["DOUBLE_VALUE"] == rowbuf.exampleDouble;
	   cols["EXAMPLE_LONG"] == rowbuf.exampleLong;
	   cols["EXAMPLE_DATE"] == rowbuf.exampleDate;
	}
}

// STEP 3 & 4
// Read the contents of the DB_EXAMPLE table and return a vector of the
// resulting rows
vector<Example> ReadData() {
	// Read the data
	vector<Example> results;
	DBView<Example> view("DB_EXAMPLE");

	DBView<Example>::select_iterator read_it = view.begin();
	for ( ; read_it != view.end();  read_it++)
	{
		results.push_back(*read_it);
	}
	return results;
}

1 See http://www.sgi.com/tech/stl/Container.html for the definition of an STL container, we call DBView a semi container because it supports all standard container methods except size(), max_size() and empty(). We explain why these were left out by design in the documentation for the DBView template.

1