dtl


BPA

Category: functors Component type: concept

Description

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

None.

Associated types

BoundIOs.

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
	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)
	{ }

};

// Create an association between table columns and fields in our object
class BCAExampleObj
{
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;
	}
}

class ExampleParamObj
{
    public:
       	int lowIntValue;
	int highIntValue;
	string strValue;
	TIMESTAMP_STRUCT dateValue;
};

class BPAParamObj
{
public:
	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(),
		"WHERE INT_VALUE BETWEEN (?) AND (?) AND "
		"STRING_VALUE = (?) OR EXAMPLE_DATE < (?) ORDER BY EXAMPLE_LONG",
		BPAParamObj());

	// 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;
		results.push_back(*read_it);

		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
{
public:
	void operator()(BoundIOs &boundIOs, ParamObjExample &paramObj)
	{
	  boundIOs[0] << paramObj.lowIntValue;
	  boundIOs[1] << paramObj.highIntValue;
	  boundIOs[2] << paramObj.strValue;
	  boundIOs[3] << paramObj.dateValue;
	}

};

Notation

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.

 

Notes

None.

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.

This site written using the ORB. [The ORB]

1