Category: functors Component type: concept


A BPA is a function object (this can be a wrapped function pointer if you use cb_ptr_fun()) that is called to create an association between the parameters in a SQL statement and the fields in a user defined parameter object that is used to hold individual values to pass to the query.

Each possible form of information flow between boundIO and DataObj/ParamObj corresponds to whether the parameter passed in to the query is an input, output, or input/output parameter. The user must be able to define the direction of information flow for parameters in cases such as stored procedure calls. The new binding syntax DTL provides shows the flow of information very clearly:

Expressions Parameter Type Description

boundIOs[colName] << dataObj.member

boundIOs[paramNum] << paramObj.member

INPUT The DataObj/ParamObj member supplies data needed by the SQL query.

boundIOs[colName] >> dataObj.member

boundIOs[paramNum] >> paramObj.member

OUTPUT The DataObj/ParamObj member receives data back from the SQL query.

boundIOs[colName] == dataObj.member

boundIOs[paramNum] == paramObj.member

INPUT/OUTPUT The DataObj/ParamObj member both supplies data to and receives back data from the SQL query.

You should always use this new syntax with any BCA's and BPA's you define. To maintain backwards compatibility with BCA's and BPA's for select_iterator's, insert_iterator's, delete_iterator's, and update_iterator's, the use of "boundIOs[colName] == dataObj.member" and "boundIOs[paramNum] == paramObj.member" is still legal. The direction of information flow can be inferred from the type of iterator used in those cases. However, the directional syntax is mandatory for sql_iterators as no information flow semantics can be inferred from a general SQL query. Examples in this documentation may use both forms of syntax where legal.

Refinement of


Associated types


Example 1:

//BPA Functor to bind SQL parameters to a data object

// "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


	Example(int exInt, const string &exStr, double exDouble, long exLong,

		const TIMESTAMP_STRUCT &exDate) :

	   exampleInt(exInt), exampleStr(exStr), exampleDouble(exDouble), exampleLong(exLong),


	{ }


// Create an association between table columns and fields in our object

class BCAExampleObj



	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;



class ExampleParamObj



       	int lowIntValue;

	int highIntValue;

	string strValue;



class BPAParamObj



	void operator()(BoundIOs &boundIOs, ExampleParamObj &paramObj)


	  boundIOs[0] << paramObj.lowIntValue;

	  boundIOs[1] << paramObj.highIntValue;

	  boundIOs[2] << paramObj.strValue;

	  boundIOs[3] << paramObj.dateValue;



// read some Example objects from the database and return a vector of

// the results, use BPA to set join parameters

vector<Example> ReadData()


	vector<Example> results;

	// construct view


	DBView<Example, ExampleParamObj>

		view("DB_EXAMPLE", BCAExampleObj(),




	// loop through query results and add them to our vector

	// in this loop, read_it.GetLastCount() records read from DB

	DBView<Example, ExampleParamObj>::select_iterator read_it = view.begin();

	// set parameter values for the WHERE clause in our SQL query

	read_it.Params().lowIntValue = 2;

	read_it.Params().highIntValue = 8;

	read_it.Params().strValue = "Example";


	TIMESTAMP_STRUCT paramDate = {2000, 1, 1, 0, 0, 0, 0};

	read_it.Params().dateValue = paramDate;

	for ( ; read_it != view.end();  read_it++)


		cout << "Reading element #" << read_it.GetLastCount() << endl;


		cout << "read_it->exampleInt = " << read_it->exampleInt << endl;

		cout << "read_it->exampleStr = " << read_it->exampleStr << endl;




	return results;



Example 2:

//Function object to bind SQL parameters to a data object

class BPAExampleObj



	void operator()(BoundIOs &boundIOs, ParamObjExample &paramObj)


	  boundIOs[0] << paramObj.lowIntValue;

	  boundIOs[1] << paramObj.highIntValue;

	  boundIOs[2] << paramObj.strValue;

	  boundIOs[3] << paramObj.dateValue;




X A type that is a model of BPA
a Object of type X

Expression semantics

Name Expression Precondition Semantics Postcondition
Default constructor
X a()
  Construct the function object.  
Copy constructor
X a(constX &b)
  Copy construct the BPA.  
Assignment operator
X& operator=(const X&b)
  Assignment copy  
Bind columns operator
void operator()(BoundIOs &boundIOs, ParamObj &parambuf)
  This operator takes a BoundIOs object and a reference to a parambuf holding a user defined parameter object. The job of the bind parameters operator is to create an association between parameters in a SQL view as designated by a "(?)" and fields in a user defined parameter object. This association is usually created by invoking the following cantrip:

boundIOs[SQL Parameter Number] == parambuf.FieldName

for each parameter in the SQL query. For details on this syntax see BoundIOs. The parameters to be bound must be statically allocated members of the ParamObj (there are some exceptions - see BoundIOs for details). At the end of the operation, all parameters to be bound in the SQL query must be in the BoundIOs container. When operator() is called, the BoundIOs container will not be empty, but will typically contain any previously bound fields from the BCA.

BoundIOs contains a complete list of parameter in the SQL query which are bound to the ParamObj.




See also

BCA, BoundIOs, DBView, IndexedDBView

[DTL Home]

Copyright 2002, Michael Gradman and Corwin Joy.

Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Corwin Joy and Michael Gradman make no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.

SourceForge Logo

This site written using the ORB. [The ORB]