diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2012-10-12 17:24:45 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2012-10-19 11:41:11 +0200 |
commit | f2e4c2c70344dd1a98593cfbe9256d1b3ed54f27 (patch) | |
tree | 713e2b8625aa9db41f2c18194baf68b830df39a3 /common/prepared/driver.cxx | |
parent | 3fd1098c70a36cdffa256b6d9fd721cf95c6f482 (diff) |
Completion of prepared query support
Diffstat (limited to 'common/prepared/driver.cxx')
-rw-r--r-- | common/prepared/driver.cxx | 276 |
1 files changed, 273 insertions, 3 deletions
diff --git a/common/prepared/driver.cxx b/common/prepared/driver.cxx index 24a3788..6738e6b 100644 --- a/common/prepared/driver.cxx +++ b/common/prepared/driver.cxx @@ -5,7 +5,8 @@ // Test prepared query functionality. // -#include <memory> // std::auto_ptr +#include <memory> // std::auto_ptr, std::unique_ptr +#include <utility> // std::move #include <cassert> #include <iostream> @@ -13,6 +14,7 @@ #include <odb/transaction.hxx> #include <common/common.hxx> +#include <common/config.hxx> // HAVE_CXX11 #include "test.hxx" #include "test-odb.hxx" @@ -20,6 +22,26 @@ using namespace std; using namespace odb::core; +struct params +{ + unsigned short age; + std::string name; +}; + +static void +query_factory (const char* name, connection& c) +{ + typedef odb::query<person> query; + + auto_ptr<params> p (new params); + prepared_query<person> pq ( + c.prepare_query<person> ( + name, + query::age > query::_ref (p->age) && + query::name != query::_ref (p->name))); + c.cache_query (pq, p); +} + int main (int argc, char* argv[]) { @@ -47,14 +69,14 @@ main (int argc, char* argv[]) typedef odb::prepared_query<person> prep_query; typedef odb::result<person> result; - // Simple case: uncached query. + // Uncached query. // { transaction t (db->begin ()); unsigned short age (90); prep_query pq ( - t.connection ().prepare_query<person> ( + db->prepare_query<person> ( "person-age-query", query::age > query::_ref (age))); @@ -64,6 +86,254 @@ main (int argc, char* argv[]) assert (size (r) == i); } + age = 90; + result r (pq.execute ()); + result::iterator i (r.begin ()); + assert (i != r.end () && i->name_ == "John First" && i->age_ == 91); + assert (++i == r.end ()); + + t.commit (); + } + + // Cached query without parameters. + // + { + for (unsigned short i (1); i < 6; ++i) + { + transaction t (db->begin ()); + + prep_query pq (db->lookup_query<person> ("person-val-age-query")); + + if (!pq) + { + assert (i == 1); + pq = db->prepare_query<person> ( + "person-val-age-query", + query::age > 90); + db->cache_query (pq); + prep_query pq1 (db->lookup_query<person> ("person-val-age-query")); + } + else if (i == 2) + { + try + { + db->cache_query (pq); + assert (false); + } + catch (const odb::prepared_already_cached&) + { + } + } + + result r (pq.execute ()); + assert (size (r) == 1); + + t.commit (); + } + } + + // Cached query with parameters. + // + { + for (unsigned short i (1); i < 6; ++i) + { + transaction t (db->begin ()); + + unsigned short* age; + prep_query pq (db->lookup_query<person> ("person-ref-age-query", age)); + + if (!pq) + { + assert (i == 1); + +#ifdef HAVE_CXX11 + unique_ptr<unsigned short> p (new unsigned short); +#else + auto_ptr<unsigned short> p (new unsigned short); +#endif + age = p.get (); + pq = db->prepare_query<person> ( + "person-ref-age-query", + query::age > query::_ref (*age)); + +#ifdef HAVE_CXX11 + db->cache_query (pq, move (p)); +#else + db->cache_query (pq, p); +#endif + } + else if (i == 2) + { + // Object type mismatch. + // + try + { + db->lookup_query<int> ("person-ref-age-query", age); + assert (false); + } + catch (const odb::prepared_type_mismatch&) + { + } + + // Parameters type mismatch. + // + try + { + int* age; + db->lookup_query<person> ("person-ref-age-query", age); + assert (false); + } + catch (const odb::prepared_type_mismatch&) + { + } + } + + *age = 100 - i * 10; + result r (pq.execute ()); + assert (size (r) == i); + + t.commit (); + } + } + + // Cached query with factory. + // + { + db->query_factory ("person-params-query", &query_factory); + + for (unsigned int i (1); i < 6; ++i) + { + transaction t (db->begin ()); + + params* p; + prep_query pq (db->lookup_query<person> ("person-params-query", p)); + assert (pq); + + p->age = 100 - i * 10; + p->name = "John First"; + result r (pq.execute ()); + assert (size (r) == i - 1); + + t.commit (); + } + + db->query_factory ("person-params-query", 0); + } + + // Cached query with wildcard factory. + // + { + db->query_factory ("", &query_factory); + + for (unsigned int i (1); i < 6; ++i) + { + transaction t (db->begin ()); + + params* p; + prep_query pq (db->lookup_query<person> ("person-params-query-1", p)); + assert (pq); + + p->age = 100 - i * 10; + p->name = "John First"; + result r (pq.execute ()); + assert (size (r) == i - 1); + + t.commit (); + } + + db->query_factory ("", 0); + } + + // Cached query with lambda factory. + // +#ifdef HAVE_CXX11 + { + db->query_factory ( + "person-params-query-2", + [] (const char* name, connection& c) + { + auto_ptr<params> p (new params); + prepared_query<person> pq ( + c.prepare_query<person> ( + name, + query::age > query::_ref (p->age) && + query::name != query::_ref (p->name))); + c.cache_query (pq, p); + }); + + for (unsigned int i (1); i < 6; ++i) + { + transaction t (db->begin ()); + + params* p; + prep_query pq (db->lookup_query<person> ("person-params-query-2", p)); + assert (pq); + + p->age = 100 - i * 10; + p->name = "John First"; + result r (pq.execute ()); + assert (size (r) == i - 1); + + t.commit (); + } + + db->query_factory ("person-params-query-2", 0); + } +#endif + + // View prepared query. + // + { + typedef odb::query<person_view> query; + typedef odb::prepared_query<person_view> prep_query; + typedef odb::result<person_view> result; + + transaction t (db->begin ()); + + unsigned short age (90); + prep_query pq ( + db->prepare_query<person_view> ( + "person-view-age-query", + query::age > query::_ref (age))); + + for (unsigned short i (1); i < 6; ++i, age -= 10) + { + result r (pq.execute ()); + assert (size (r) == i); + } + + age = 90; + result r (pq.execute ()); + result::iterator i (r.begin ()); + assert (i != r.end () && i->name == "John First" && i->age == 91); + assert (++i == r.end ()); + + t.commit (); + } + + // By-ref parameter image growth. + // + { + transaction t (db->begin ()); + + string name; + prep_query pq ( + db->prepare_query<person> ( + "person-name-query", + query::name != query::_ref (name))); + + { + name = "John First"; + result r (pq.execute ()); + assert (size (r) == 4); + } + + { + name.assign (2048, 'x'); + result r (pq.execute ()); + assert (size (r) == 5); + } + t.commit (); } } |