[odb-users] Prepared statement feature

Stath, Paul pstath at axxcelera.com
Mon Oct 1 15:48:01 EDT 2012


Boris --

One of the goals I was trying to satisfy was that management of the prepared query statement
in the database session would be defined by the life-cycle of the prepared_query<> object.
This would eliminate the need to expose any database lookup/cache methods to the user.

Any time one can make it simpler for a developer to use a library/framework, the better.

Since the prepared query would exist for the lifetime of the prepared_query<> object,
the query could be prepared in the database session when the object is constructed.

When the destructor of the prepared_query<> is called, the prepared query statement
would be cleared from the database session.

In your simple scenario, the prepared query would be compiled when the pq() object is constructed,
and would be cleaned up when the pq object goes out of scope.
While it can be done, why not use the current obd::query<> with query::_ref(age) in the simple scenario?

To make a prepared query operate over multiple transactions, the programmer would simply need to
construct the prepared_query<> in such a way that it has an extended life-cycle.
(i.e. member variable of a long-lived class, or as part of a shared_ptr.)

For processing a prepared query that contains by-reference arguments, the execute() method
should accept the parameter structure (POD) constructed as an auto_ptr (or unique_ptr).

I believe that the above is simpler from a developer point of view, as well as a
multi-threaded point of view.
By providing the parameters via a "transfer_ptr" in the execute() method, the parameter POD
only needs to be protected from concurrent use when actually binding the parameters to the
prepared query.  Doesn't your approach require the developer to provide their own thread
safety to protect the data elements of the parameter POD?

-- Paul

struct query_params
{
  unsigned short age;
};

typedef odb::query<person> query;
typedef odb::result<person> result;

auto_ptr<query_params> p (new query_params); // Or unique_ptr.
shared_ptr<prepared_query<person> pq (query::age < query::_ref(p->age, p);


Then, later on, possibly in multiple worker threads:

transaction t (db->begin ());

auto_ptr<query_params> params;
params->age = 20;
result r (pq->execute (params));  // pq assumes ownership of params.

...

t.commit ();



More information about the odb-users mailing list