From f2e4c2c70344dd1a98593cfbe9256d1b3ed54f27 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 12 Oct 2012 17:24:45 +0200 Subject: Completion of prepared query support --- common/inheritance/polymorphism/makefile | 2 +- common/prepared/driver.cxx | 276 ++++++++++++++++++++++++++++++- common/prepared/makefile | 2 +- common/prepared/test.hxx | 7 + common/query/makefile | 2 +- common/threads/driver.cxx | 20 ++- common/threads/makefile | 2 +- common/view/makefile | 2 +- 8 files changed, 304 insertions(+), 9 deletions(-) diff --git a/common/inheritance/polymorphism/makefile b/common/inheritance/polymorphism/makefile index 5796d49..10e0a01 100644 --- a/common/inheritance/polymorphism/makefile +++ b/common/inheritance/polymorphism/makefile @@ -36,7 +36,7 @@ gen := $(addprefix $(out_base)/,$(genf)) $(gen): $(odb) $(gen): odb := $(odb) $(gen) $(dist): export odb_options += --database $(db_id) --generate-schema \ ---generate-query --table-prefix inherit_p_ +--generate-query --generate-prepared --table-prefix inherit_p_ $(gen): cpp_options := -I$(src_base) $(gen): $(common.l.cpp-options) 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 // std::auto_ptr +#include // std::auto_ptr, std::unique_ptr +#include // std::move #include #include @@ -13,6 +14,7 @@ #include #include +#include // 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 query; + + auto_ptr p (new params); + prepared_query pq ( + c.prepare_query ( + 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 prep_query; typedef odb::result result; - // Simple case: uncached query. + // Uncached query. // { transaction t (db->begin ()); unsigned short age (90); prep_query pq ( - t.connection ().prepare_query ( + db->prepare_query ( "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-val-age-query")); + + if (!pq) + { + assert (i == 1); + pq = db->prepare_query ( + "person-val-age-query", + query::age > 90); + db->cache_query (pq); + prep_query pq1 (db->lookup_query ("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-ref-age-query", age)); + + if (!pq) + { + assert (i == 1); + +#ifdef HAVE_CXX11 + unique_ptr p (new unsigned short); +#else + auto_ptr p (new unsigned short); +#endif + age = p.get (); + pq = db->prepare_query ( + "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 ("person-ref-age-query", age); + assert (false); + } + catch (const odb::prepared_type_mismatch&) + { + } + + // Parameters type mismatch. + // + try + { + int* age; + db->lookup_query ("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-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-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 p (new params); + prepared_query pq ( + c.prepare_query ( + 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-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 query; + typedef odb::prepared_query prep_query; + typedef odb::result result; + + transaction t (db->begin ()); + + unsigned short age (90); + prep_query pq ( + db->prepare_query ( + "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-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 (); } } diff --git a/common/prepared/makefile b/common/prepared/makefile index 6da88d3..4126b54 100644 --- a/common/prepared/makefile +++ b/common/prepared/makefile @@ -35,7 +35,7 @@ gen := $(addprefix $(out_base)/,$(genf)) $(gen): $(odb) $(gen): odb := $(odb) $(gen) $(dist): export odb_options += --database $(db_id) --generate-schema \ ---generate-query --omit-unprepared --table-prefix prepared_ +--generate-query --generate-prepared --omit-unprepared --table-prefix prepared_ $(gen): cpp_options := -I$(src_base) $(gen): $(common.l.cpp-options) diff --git a/common/prepared/test.hxx b/common/prepared/test.hxx index 734b138..7ea0ce8 100644 --- a/common/prepared/test.hxx +++ b/common/prepared/test.hxx @@ -23,4 +23,11 @@ struct person unsigned short age_; }; +#pragma db view object(person) +struct person_view +{ + std::string name; + unsigned short age; +}; + #endif // TEST_HXX diff --git a/common/query/makefile b/common/query/makefile index 8cfbb95..6f25ba4 100644 --- a/common/query/makefile +++ b/common/query/makefile @@ -35,7 +35,7 @@ gen := $(addprefix $(out_base)/,$(genf)) $(gen): $(odb) $(gen): odb := $(odb) $(gen) $(dist): export odb_options += --database $(db_id) --generate-schema \ ---generate-query --table-prefix t_query_ +--generate-query --generate-prepared --table-prefix t_query_ $(gen): cpp_options := -I$(src_base) $(gen): $(common.l.cpp-options) diff --git a/common/threads/driver.cxx b/common/threads/driver.cxx index dc4de0d..b8a66f1 100644 --- a/common/threads/driver.cxx +++ b/common/threads/driver.cxx @@ -96,10 +96,25 @@ struct task for (unsigned long j (0); j < sub_iteration_count; ++j) { typedef odb::query query; + typedef odb::prepared_query prep_query; typedef odb::result result; transaction t (db_.begin ()); - result r (db_.query (query::str == "another value", false)); + + { // @@ TMP + + //result r (db_.query (query::str == "another value", false)); + + prep_query pq (db_.lookup_query ("object-query")); + + if (!pq) + { + pq = db_.prepare_query ( + "object-query", query::str == "another value"); + db_.cache_query (pq); + } + + result r (pq.execute (false)); bool found (false); for (result::iterator i (r.begin ()); i != r.end (); ++i) @@ -111,6 +126,9 @@ struct task } } assert (found); + + } // @@ TMP + t.commit (); } diff --git a/common/threads/makefile b/common/threads/makefile index 3c0a041..a9f2a66 100644 --- a/common/threads/makefile +++ b/common/threads/makefile @@ -35,7 +35,7 @@ gen := $(addprefix $(out_base)/,$(genf)) $(gen): $(odb) $(gen): odb := $(odb) $(gen) $(dist): export odb_options += --database $(db_id) --generate-schema \ ---generate-query --table-prefix threads_ +--generate-query --generate-prepared --table-prefix threads_ $(gen): cpp_options := -I$(src_base) $(gen): $(common.l.cpp-options) diff --git a/common/view/makefile b/common/view/makefile index cf389cc..bb78891 100644 --- a/common/view/makefile +++ b/common/view/makefile @@ -35,7 +35,7 @@ gen := $(addprefix $(out_base)/,$(genf)) $(gen): $(odb) $(gen): odb := $(odb) $(gen) $(dist): export odb_options += --database $(db_id) --generate-schema \ ---generate-query --table-prefix t_view_ +--generate-query --generate-prepared --table-prefix t_view_ $(gen): cpp_options := -I$(src_base) $(gen): $(common.l.cpp-options) -- cgit v1.1