From fef380f6c9a5fb9904d551478fe180a9c5d24b37 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 12 Oct 2012 17:24:44 +0200 Subject: Completion of prepared query support --- odb/pgsql/connection.cxx | 3 +++ odb/pgsql/connection.hxx | 18 ++++++++++++++++++ odb/pgsql/connection.ixx | 30 ++++++++++++++++++++++++++++++ odb/pgsql/database.hxx | 14 ++++++++++++++ odb/pgsql/database.ixx | 26 ++++++++++++++++++++++++++ odb/pgsql/makefile | 1 + odb/pgsql/prepared-query.cxx | 16 ++++++++++++++++ odb/pgsql/prepared-query.hxx | 33 +++++++++++++++++++++++++++++++++ odb/pgsql/query.cxx | 19 +++++-------------- odb/pgsql/query.hxx | 5 +++++ odb/pgsql/query.ixx | 6 ++++++ odb/pgsql/statement.cxx | 28 ++++++++++++++-------------- odb/pgsql/statement.hxx | 39 ++++++++++++++++++++++++--------------- 13 files changed, 195 insertions(+), 43 deletions(-) create mode 100644 odb/pgsql/connection.ixx create mode 100644 odb/pgsql/prepared-query.cxx create mode 100644 odb/pgsql/prepared-query.hxx diff --git a/odb/pgsql/connection.cxx b/odb/pgsql/connection.cxx index 40a65ef..7921723 100644 --- a/odb/pgsql/connection.cxx +++ b/odb/pgsql/connection.cxx @@ -70,6 +70,9 @@ namespace odb connection:: ~connection () { + // Destroy prepared query statements before freeing the connections. + // + prepared_map_.clear (); } transaction_impl* connection:: diff --git a/odb/pgsql/connection.hxx b/odb/pgsql/connection.hxx index 8ac0f50..3cc1f63 100644 --- a/odb/pgsql/connection.hxx +++ b/odb/pgsql/connection.hxx @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -59,6 +60,21 @@ namespace odb virtual unsigned long long execute (const char* statement, std::size_t length); + // Query preparation. + // + public: + template + prepared_query + prepare_query (const char* name, const char*); + + template + prepared_query + prepare_query (const char* name, const std::string&); + + template + prepared_query + prepare_query (const char* name, const query&); + // SQL statement tracing. // public: @@ -129,6 +145,8 @@ namespace odb } } +#include + #include #endif // ODB_PGSQL_CONNECTION_HXX diff --git a/odb/pgsql/connection.ixx b/odb/pgsql/connection.ixx new file mode 100644 index 0000000..70501e1 --- /dev/null +++ b/odb/pgsql/connection.ixx @@ -0,0 +1,30 @@ +// file : odb/pgsql/connection.ixx +// copyright : Copyright (c) 2005-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +namespace odb +{ + namespace pgsql + { + template + inline prepared_query connection:: + prepare_query (const char* n, const char* q) + { + return prepare_query (n, query (q)); + } + + template + inline prepared_query connection:: + prepare_query (const char* n, const std::string& q) + { + return prepare_query (n, query (q)); + } + + template + inline prepared_query connection:: + prepare_query (const char* n, const query& q) + { + return query_::call (*this, n, q); + } + } +} diff --git a/odb/pgsql/database.hxx b/odb/pgsql/database.hxx index 6f40486..02aa240 100644 --- a/odb/pgsql/database.hxx +++ b/odb/pgsql/database.hxx @@ -266,6 +266,20 @@ namespace odb result query (const pgsql::query&); + // Query preparation. + // + template + prepared_query + prepare_query (const char* name, const char*); + + template + prepared_query + prepare_query (const char* name, const std::string&); + + template + prepared_query + prepare_query (const char* name, const pgsql::query&); + // Transactions. // public: diff --git a/odb/pgsql/database.ixx b/odb/pgsql/database.ixx index bdd4390..7ad92be 100644 --- a/odb/pgsql/database.ixx +++ b/odb/pgsql/database.ixx @@ -2,6 +2,8 @@ // copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file +#include + namespace odb { namespace pgsql @@ -393,5 +395,29 @@ namespace odb // return query_::call (*this, q); } + + template + inline prepared_query database:: + prepare_query (const char* n, const char* q) + { + return prepare_query (n, pgsql::query (q)); + } + + template + inline prepared_query database:: + prepare_query (const char* n, const std::string& q) + { + return prepare_query (n, pgsql::query (q)); + } + + template + inline prepared_query database:: + prepare_query (const char* n, const pgsql::query& q) + { + // Throws if not in transaction. + // + pgsql::connection& c (transaction::current ().connection ()); + return c.prepare_query (n, q); + } } } diff --git a/odb/pgsql/makefile b/odb/pgsql/makefile index b343fce..c18a8de 100644 --- a/odb/pgsql/makefile +++ b/odb/pgsql/makefile @@ -11,6 +11,7 @@ connection-factory.cxx \ database.cxx \ error.cxx \ exceptions.cxx \ +prepared-query.cxx \ query.cxx \ query-const-expr.cxx \ simple-object-statements.cxx \ diff --git a/odb/pgsql/prepared-query.cxx b/odb/pgsql/prepared-query.cxx new file mode 100644 index 0000000..80f42ac --- /dev/null +++ b/odb/pgsql/prepared-query.cxx @@ -0,0 +1,16 @@ +// file : odb/pgsql/prepared-query.cxx +// copyright : Copyright (c) 2005-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include + +namespace odb +{ + namespace pgsql + { + prepared_query_impl:: + ~prepared_query_impl () + { + } + } +} diff --git a/odb/pgsql/prepared-query.hxx b/odb/pgsql/prepared-query.hxx new file mode 100644 index 0000000..9b90688 --- /dev/null +++ b/odb/pgsql/prepared-query.hxx @@ -0,0 +1,33 @@ +// file : odb/pgsql/prepared-query.hxx +// copyright : Copyright (c) 2005-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_PGSQL_PREPARED_QUERY_HXX +#define ODB_PGSQL_PREPARED_QUERY_HXX + +#include + +#include + +#include +#include + +#include + +namespace odb +{ + namespace pgsql + { + struct LIBODB_PGSQL_EXPORT prepared_query_impl: odb::prepared_query_impl + { + virtual + ~prepared_query_impl (); + + pgsql::query_base query; + }; + } +} + +#include + +#endif // ODB_PGSQL_PREPARED_QUERY_HXX diff --git a/odb/pgsql/query.cxx b/odb/pgsql/query.cxx index 2233110..966df92 100644 --- a/odb/pgsql/query.cxx +++ b/odb/pgsql/query.cxx @@ -222,19 +222,12 @@ namespace odb statement::bind_param (native_binding_, binding_); } - native_binding& query_base:: - parameters_binding () const + void query_base:: + init_parameters () const { - size_t n (parameters_.size ()); - - if (n == 0) - return native_binding_; - bool ref (false), inc_ver (false); - binding& r (binding_); - bind* b (&bind_[0]); - for (size_t i (0); i < n; ++i) + for (size_t i (0); i < parameters_.size (); ++i) { query_param& p (*parameters_[i]); @@ -244,7 +237,7 @@ namespace odb if (p.init ()) { - p.bind (b + i); + p.bind (&bind_[i]); inc_ver = true; } } @@ -255,10 +248,8 @@ namespace odb statement::bind_param (native_binding_, binding_); if (inc_ver) - r.version++; + binding_.version++; } - - return native_binding_; } static bool diff --git a/odb/pgsql/query.hxx b/odb/pgsql/query.hxx index 0c5e8f4..2a1c6b8 100644 --- a/odb/pgsql/query.hxx +++ b/odb/pgsql/query.hxx @@ -175,6 +175,11 @@ namespace odb const char* clause_prefix () const; + // Initialize the by-reference parameters from bound variables. + // + void + init_parameters () const; + native_binding& parameters_binding () const; diff --git a/odb/pgsql/query.ixx b/odb/pgsql/query.ixx index ef8ea77..178a6eb 100644 --- a/odb/pgsql/query.ixx +++ b/odb/pgsql/query.ixx @@ -6,6 +6,12 @@ namespace odb { namespace pgsql { + inline native_binding& query_base:: + parameters_binding () const + { + return native_binding_; + } + template inline void query_base:: append (val_bind v, const char* conv) diff --git a/odb/pgsql/statement.cxx b/odb/pgsql/statement.cxx index 453307d..d522dfa 100644 --- a/odb/pgsql/statement.cxx +++ b/odb/pgsql/statement.cxx @@ -86,7 +86,7 @@ namespace odb } statement:: - statement (connection& conn, + statement (connection_type& conn, const string& name, const string& text, const Oid* types, @@ -105,7 +105,7 @@ namespace odb } statement:: - statement (connection& conn, + statement (connection_type& conn, const char* name, const char* text, bool copy, @@ -393,7 +393,7 @@ namespace odb } select_statement:: - select_statement (connection& conn, + select_statement (connection_type& conn, const std::string& name, const std::string& text, const Oid* types, @@ -411,7 +411,7 @@ namespace odb } select_statement:: - select_statement (connection& conn, + select_statement (connection_type& conn, const char* name, const char* text, const Oid* types, @@ -430,7 +430,7 @@ namespace odb } select_statement:: - select_statement (connection& conn, + select_statement (connection_type& conn, const std::string& name, const std::string& text, binding& result) @@ -444,7 +444,7 @@ namespace odb } select_statement:: - select_statement (connection& conn, + select_statement (connection_type& conn, const char* name, const char* text, binding& result, @@ -459,7 +459,7 @@ namespace odb } select_statement:: - select_statement (connection& conn, + select_statement (connection_type& conn, const std::string& name, const std::string& text, const Oid* types, @@ -565,7 +565,7 @@ namespace odb } insert_statement:: - insert_statement (connection& conn, + insert_statement (connection_type& conn, const string& name, const string& text, const Oid* types, @@ -581,7 +581,7 @@ namespace odb } insert_statement:: - insert_statement (connection& conn, + insert_statement (connection_type& conn, const char* name, const char* text, const Oid* types, @@ -684,7 +684,7 @@ namespace odb } update_statement:: - update_statement (connection& conn, + update_statement (connection_type& conn, const string& name, const string& text, const Oid* types, @@ -698,7 +698,7 @@ namespace odb } update_statement:: - update_statement (connection& conn, + update_statement (connection_type& conn, const char* name, const char* text, const Oid* types, @@ -750,7 +750,7 @@ namespace odb } delete_statement:: - delete_statement (connection& conn, + delete_statement (connection_type& conn, const string& name, const string& text, const Oid* types, @@ -764,7 +764,7 @@ namespace odb } delete_statement:: - delete_statement (connection& conn, + delete_statement (connection_type& conn, const char* name, const char* text, const Oid* types, @@ -779,7 +779,7 @@ namespace odb } delete_statement:: - delete_statement (connection& conn, + delete_statement (connection_type& conn, const string& name, const string& text, const Oid* types, diff --git a/odb/pgsql/statement.hxx b/odb/pgsql/statement.hxx index 94fceb6..c062fea 100644 --- a/odb/pgsql/statement.hxx +++ b/odb/pgsql/statement.hxx @@ -16,6 +16,7 @@ #include #include #include // PGresult +#include #include #include @@ -29,6 +30,8 @@ namespace odb class LIBODB_PGSQL_EXPORT statement: public odb::statement { public: + typedef pgsql::connection connection_type; + virtual ~statement () = 0; @@ -41,6 +44,12 @@ namespace odb virtual const char* text () const; + virtual connection_type& + connection () + { + return conn_; + } + void deallocate (); @@ -62,13 +71,13 @@ namespace odb bool truncated = false); protected: - statement (connection&, + statement (connection_type&, const std::string& name, const std::string& text, const Oid* types, std::size_t types_count); - statement (connection&, + statement (connection_type&, const char* name, const char* text, bool copy_name_text, @@ -80,7 +89,7 @@ namespace odb init (const Oid* types, std::size_t types_count); protected: - connection& conn_; + connection_type& conn_; std::string name_copy_; const char* name_; @@ -98,7 +107,7 @@ namespace odb virtual ~select_statement (); - select_statement (connection& conn, + select_statement (connection_type& conn, const std::string& name, const std::string& text, const Oid* types, @@ -107,7 +116,7 @@ namespace odb native_binding& native_param, binding& result); - select_statement (connection& conn, + select_statement (connection_type& conn, const char* name, const char* stmt, const Oid* types, @@ -117,18 +126,18 @@ namespace odb binding& result, bool copy_name_text = true); - select_statement (connection& conn, + select_statement (connection_type& conn, const std::string& name, const std::string& text, binding& result); - select_statement (connection& conn, + select_statement (connection_type& conn, const char* name, const char* text, binding& result, bool copy_name_text = true); - select_statement (connection& conn, + select_statement (connection_type& conn, const std::string& name, const std::string& text, const Oid* types, @@ -228,7 +237,7 @@ namespace odb virtual ~insert_statement (); - insert_statement (connection& conn, + insert_statement (connection_type& conn, const std::string& name, const std::string& text, const Oid* types, @@ -237,7 +246,7 @@ namespace odb native_binding& native_param, bool returning); - insert_statement (connection& conn, + insert_statement (connection_type& conn, const char* name, const char* text, const Oid* types, @@ -277,7 +286,7 @@ namespace odb virtual ~update_statement (); - update_statement (connection& conn, + update_statement (connection_type& conn, const std::string& name, const std::string& text, const Oid* types, @@ -285,7 +294,7 @@ namespace odb binding& param, native_binding& native_param); - update_statement (connection& conn, + update_statement (connection_type& conn, const char* name, const char* text, const Oid* types, @@ -312,7 +321,7 @@ namespace odb virtual ~delete_statement (); - delete_statement (connection& conn, + delete_statement (connection_type& conn, const std::string& name, const std::string& text, const Oid* types, @@ -320,7 +329,7 @@ namespace odb binding& param, native_binding& native_param); - delete_statement (connection& conn, + delete_statement (connection_type& conn, const char* name, const char* text, const Oid* types, @@ -329,7 +338,7 @@ namespace odb native_binding& native_param, bool copy_name_text = true); - delete_statement (connection& conn, + delete_statement (connection_type& conn, const std::string& name, const std::string& text, const Oid* types, -- cgit v1.1