[odb-users] Prepared statement feature
Boris Kolpackov
boris at codesynthesis.com
Mon Oct 1 05:58:41 EDT 2012
Hi Paul,
Thanks for the suggestions. While I don't like your interface any better
than mine ;-) and there are some implementation issues with it, it
highlighted some of the aspects that I didn't think about (e.g., the
desire to define age_pquery in the same header as the persistent class,
which would not be possible if it contains references to the odb::query
template -- it can only be used after the -odb.hxx header has been
included).
So based on your suggestions and some more thinking, I came up with
the following alternative design:
Simple Scenario
The query is prepared, executed within a transaction several times,
and then discarded (i.e., no caching in the connection). This approach
can also work for a single-threaded application which uses a single
connection.
typedef odb::query<person> query;
typedef odb::result<person> result;
transaction t (db->begin ());
unsigned short age;
prepared_query<person> pq (
db->prepare_query<person> (
"age-query", query::age < query::_ref (age)));
age = 20;
result r1 (pq->execute ());
age = 30;
result r2 (pq->execute ());
age = 40;
result r3 (pq->execute ());
...
t.commit ();
Complex Scenario
Here we want to cache the prepared query so that it can be executed
later in other transactions.
struct query_params
{
unsigned short age;
};
typedef odb::query<person> query;
typedef odb::result<person> result;
transaction t (db->begin ());
query_params* params;
prepared_query<person>* pq (db->lookup<person> ("age-query", params));
if (pq == 0)
{
auto_ptr<query_params> p (new query_params); // Or unique_ptr.
prepared_query<person> q (
db->prepare_query<person> (
"age-query", query::age < query::_ref (p->age)));
params = p.get ();
pq = db->cache (q, p); // Assumes ownership of p.
}
params->age = 20;
result r (pq->execute ());
...
t.commit ();
Now if we don't have any by-reference parameters, then this can be
simplified to:
typedef odb::query<person> query;
typedef odb::result<person> result;
transaction t (db->begin ());
prepared_query<person>* pq (db->lookup<person> ("age18-query"));
if (pq == 0)
{
prepared_query<person> q (
db->prepare_query<person> (
"age18-query", query::age < 18));
pq = db->cache (q);
}
result r (pq->execute ());
...
t.commit ();
What do you think?
Boris
More information about the odb-users
mailing list