From d94948b8bccfd8748245726487d54c41bb199baf 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/sqlite/connection.cxx | 4 ++++ odb/sqlite/connection.hxx | 18 ++++++++++++++++++ odb/sqlite/connection.ixx | 30 ++++++++++++++++++++++++++++++ odb/sqlite/database.hxx | 14 ++++++++++++++ odb/sqlite/database.ixx | 26 ++++++++++++++++++++++++++ odb/sqlite/makefile | 1 + odb/sqlite/no-id-object-result.hxx | 2 +- odb/sqlite/no-id-object-result.txx | 10 +++++----- odb/sqlite/polymorphic-object-result.hxx | 7 ++++--- odb/sqlite/polymorphic-object-result.txx | 7 ++++--- odb/sqlite/prepared-query.cxx | 16 ++++++++++++++++ odb/sqlite/prepared-query.hxx | 6 +++--- odb/sqlite/query.cxx | 3 +-- odb/sqlite/query.hxx | 2 +- odb/sqlite/query.ixx | 2 +- odb/sqlite/result.cxx | 2 +- odb/sqlite/result.hxx | 2 +- odb/sqlite/simple-object-result.hxx | 2 +- odb/sqlite/simple-object-result.txx | 2 +- odb/sqlite/statement.cxx | 16 ++++++++++++++-- odb/sqlite/statement.hxx | 26 ++++---------------------- odb/sqlite/view-result.hxx | 2 +- odb/sqlite/view-result.txx | 4 ++-- 23 files changed, 154 insertions(+), 50 deletions(-) create mode 100644 odb/sqlite/connection.ixx create mode 100644 odb/sqlite/prepared-query.cxx diff --git a/odb/sqlite/connection.cxx b/odb/sqlite/connection.cxx index a477e28..bcf28a2 100644 --- a/odb/sqlite/connection.cxx +++ b/odb/sqlite/connection.cxx @@ -13,6 +13,7 @@ #include #include #include +#include #include #include // deadlock @@ -101,6 +102,9 @@ namespace odb connection:: ~connection () { + // Destroy prepared query statements before freeing the connections. + // + prepared_map_.clear (); } transaction_impl* connection:: diff --git a/odb/sqlite/connection.hxx b/odb/sqlite/connection.hxx index 5eb1995..3524a48 100644 --- a/odb/sqlite/connection.hxx +++ b/odb/sqlite/connection.hxx @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -68,6 +69,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: @@ -153,6 +169,8 @@ namespace odb } } +#include + #include #endif // ODB_SQLITE_CONNECTION_HXX diff --git a/odb/sqlite/connection.ixx b/odb/sqlite/connection.ixx new file mode 100644 index 0000000..9117bd4 --- /dev/null +++ b/odb/sqlite/connection.ixx @@ -0,0 +1,30 @@ +// file : odb/sqlite/connection.ixx +// copyright : Copyright (c) 2005-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +namespace odb +{ + namespace sqlite + { + 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/sqlite/database.hxx b/odb/sqlite/database.hxx index aa15a9b..318cb57 100644 --- a/odb/sqlite/database.hxx +++ b/odb/sqlite/database.hxx @@ -288,6 +288,20 @@ namespace odb result query (const sqlite::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 sqlite::query&); + // Transactions. // public: diff --git a/odb/sqlite/database.ixx b/odb/sqlite/database.ixx index c8b2a30..2b57912 100644 --- a/odb/sqlite/database.ixx +++ b/odb/sqlite/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 sqlite @@ -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, sqlite::query (q)); + } + + template + inline prepared_query database:: + prepare_query (const char* n, const std::string& q) + { + return prepare_query (n, sqlite::query (q)); + } + + template + inline prepared_query database:: + prepare_query (const char* n, const sqlite::query& q) + { + // Throws if not in transaction. + // + sqlite::connection& c (transaction::current ().connection ()); + return c.prepare_query (n, q); + } } } diff --git a/odb/sqlite/makefile b/odb/sqlite/makefile index 28cb2fe..1f9e0ae 100644 --- a/odb/sqlite/makefile +++ b/odb/sqlite/makefile @@ -10,6 +10,7 @@ connection-factory.cxx \ database.cxx \ error.cxx \ exceptions.cxx \ +prepared-query.cxx \ query.cxx \ query-const-expr.cxx \ result.cxx \ diff --git a/odb/sqlite/no-id-object-result.hxx b/odb/sqlite/no-id-object-result.hxx index 7079678..60e69e3 100644 --- a/odb/sqlite/no-id-object-result.hxx +++ b/odb/sqlite/no-id-object-result.hxx @@ -41,7 +41,7 @@ namespace odb ~no_id_object_result_impl (); no_id_object_result_impl (const query_base&, - details::shared_ptr, + const details::shared_ptr&, statements_type&); virtual void diff --git a/odb/sqlite/no-id-object-result.txx b/odb/sqlite/no-id-object-result.txx index 5dad5b2..3fe9fc2 100644 --- a/odb/sqlite/no-id-object-result.txx +++ b/odb/sqlite/no-id-object-result.txx @@ -22,11 +22,11 @@ namespace odb template no_id_object_result_impl:: no_id_object_result_impl (const query_base& q, - details::shared_ptr statement, - statements_type& statements) - : base_type (statements.connection ().database ()), - result_impl_base (q, statement), - statements_ (statements) + const details::shared_ptr& s, + statements_type& sts) + : base_type (sts.connection ().database ()), + result_impl_base (q, s), + statements_ (sts) { } diff --git a/odb/sqlite/polymorphic-object-result.hxx b/odb/sqlite/polymorphic-object-result.hxx index 6023248..9cf9c6c 100644 --- a/odb/sqlite/polymorphic-object-result.hxx +++ b/odb/sqlite/polymorphic-object-result.hxx @@ -47,9 +47,10 @@ namespace odb virtual ~polymorphic_object_result_impl (); - polymorphic_object_result_impl (const query_base&, - details::shared_ptr, - statements_type&); + polymorphic_object_result_impl ( + const query_base&, + const details::shared_ptr&, + statements_type&); virtual void load (object_type*, bool fetch); diff --git a/odb/sqlite/polymorphic-object-result.txx b/odb/sqlite/polymorphic-object-result.txx index 7e751b3..0dd68cf 100644 --- a/odb/sqlite/polymorphic-object-result.txx +++ b/odb/sqlite/polymorphic-object-result.txx @@ -23,9 +23,10 @@ namespace odb template polymorphic_object_result_impl:: - polymorphic_object_result_impl (const query_base& q, - details::shared_ptr st, - statements_type& sts) + polymorphic_object_result_impl ( + const query_base& q, + const details::shared_ptr& st, + statements_type& sts) : base_type (sts.connection ().database ()), result_impl_base (q, st), statements_ (sts) diff --git a/odb/sqlite/prepared-query.cxx b/odb/sqlite/prepared-query.cxx new file mode 100644 index 0000000..1eb875d --- /dev/null +++ b/odb/sqlite/prepared-query.cxx @@ -0,0 +1,16 @@ +// file : odb/sqlite/prepared-query.cxx +// copyright : Copyright (c) 2005-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include + +namespace odb +{ + namespace sqlite + { + prepared_query_impl:: + ~prepared_query_impl () + { + } + } +} diff --git a/odb/sqlite/prepared-query.hxx b/odb/sqlite/prepared-query.hxx index aee1d95..ddc2c9c 100644 --- a/odb/sqlite/prepared-query.hxx +++ b/odb/sqlite/prepared-query.hxx @@ -8,11 +8,9 @@ #include #include -#include #include #include -#include #include @@ -22,8 +20,10 @@ namespace odb { struct LIBODB_SQLITE_EXPORT prepared_query_impl: odb::prepared_query_impl { + virtual + ~prepared_query_impl (); + sqlite::query_base query; - details::shared_ptr stmt; }; } } diff --git a/odb/sqlite/query.cxx b/odb/sqlite/query.cxx index f6a4dc1..2a1c203 100644 --- a/odb/sqlite/query.cxx +++ b/odb/sqlite/query.cxx @@ -96,7 +96,6 @@ namespace odb init () { bool inc_ver (false); - sqlite::bind* b (&bind_[0]); for (size_t i (0); i < params_.size (); ++i) { @@ -106,7 +105,7 @@ namespace odb { if (p.init ()) { - p.bind (b + i); + p.bind (&bind_[i]); inc_ver = true; } } diff --git a/odb/sqlite/query.hxx b/odb/sqlite/query.hxx index eebc7c3..7264bf4 100644 --- a/odb/sqlite/query.hxx +++ b/odb/sqlite/query.hxx @@ -213,7 +213,7 @@ namespace odb binding& parameters_binding () const; - details::shared_ptr + const details::shared_ptr& parameters () const; public: diff --git a/odb/sqlite/query.ixx b/odb/sqlite/query.ixx index 627ebb7..c3a5f14 100644 --- a/odb/sqlite/query.ixx +++ b/odb/sqlite/query.ixx @@ -18,7 +18,7 @@ namespace odb return parameters_->binding (); } - inline details::shared_ptr query_base:: + inline const details::shared_ptr& query_base:: parameters () const { return parameters_; diff --git a/odb/sqlite/result.cxx b/odb/sqlite/result.cxx index f8b1073..ccd6c05 100644 --- a/odb/sqlite/result.cxx +++ b/odb/sqlite/result.cxx @@ -11,7 +11,7 @@ namespace odb { result_impl_base:: result_impl_base (const query_base& q, - details::shared_ptr s) + const details::shared_ptr& s) : params_ (q.parameters ()), statement_ (s) { } diff --git a/odb/sqlite/result.hxx b/odb/sqlite/result.hxx index cd2d376..6e915d4 100644 --- a/odb/sqlite/result.hxx +++ b/odb/sqlite/result.hxx @@ -23,7 +23,7 @@ namespace odb { public: result_impl_base (const query_base&, - details::shared_ptr); + const details::shared_ptr&); protected: // We need to hold on to the query parameters because SQLite uses diff --git a/odb/sqlite/simple-object-result.hxx b/odb/sqlite/simple-object-result.hxx index 08132b1..3e2a17b 100644 --- a/odb/sqlite/simple-object-result.hxx +++ b/odb/sqlite/simple-object-result.hxx @@ -42,7 +42,7 @@ namespace odb ~object_result_impl (); object_result_impl (const query_base&, - details::shared_ptr, + const details::shared_ptr&, statements_type&); virtual void diff --git a/odb/sqlite/simple-object-result.txx b/odb/sqlite/simple-object-result.txx index 34eaab5..6763850 100644 --- a/odb/sqlite/simple-object-result.txx +++ b/odb/sqlite/simple-object-result.txx @@ -24,7 +24,7 @@ namespace odb template object_result_impl:: object_result_impl (const query_base& q, - details::shared_ptr statement, + const details::shared_ptr& statement, statements_type& statements) : base_type (statements.connection ().database ()), result_impl_base (q, statement), diff --git a/odb/sqlite/statement.cxx b/odb/sqlite/statement.cxx index 5955b33..ce194ed 100644 --- a/odb/sqlite/statement.cxx +++ b/odb/sqlite/statement.cxx @@ -29,6 +29,20 @@ namespace odb } void statement:: + cached (bool cached) + { + assert (cached); + + if (!cached_) + { + if (!active_) + list_remove (); + + cached_ = true; + } + } + + void statement:: init (const char* text, std::size_t text_size) { int e; @@ -46,9 +60,7 @@ namespace odb translate_error (e, conn_); stmt_.reset (stmt); - active_ = false; - cached_ = false; prev_ = 0; next_ = this; diff --git a/odb/sqlite/statement.hxx b/odb/sqlite/statement.hxx index 3c57c74..92b9c7c 100644 --- a/odb/sqlite/statement.hxx +++ b/odb/sqlite/statement.hxx @@ -53,28 +53,11 @@ namespace odb return conn_; } - // Cached state (public part). - // public: - bool - cached () const - { - return cached_; - } - - void - cached (bool cached) - { - assert (cached); - - if (!cached_) - { - if (!active_) - list_remove (); + using odb::statement::cached; - cached_ = true; - } - } + virtual void + cached (bool); protected: statement (connection_type& conn, const std::string& text) @@ -154,11 +137,10 @@ namespace odb protected: friend class sqlite::connection; - connection_type& conn_; // Cached static type. + connection_type& conn_; auto_handle stmt_; bool active_; - bool cached_; private: void diff --git a/odb/sqlite/view-result.hxx b/odb/sqlite/view-result.hxx index 846504f..7d552b7 100644 --- a/odb/sqlite/view-result.hxx +++ b/odb/sqlite/view-result.hxx @@ -40,7 +40,7 @@ namespace odb ~view_result_impl (); view_result_impl (const query_base&, - details::shared_ptr, + const details::shared_ptr&, statements_type&); virtual void diff --git a/odb/sqlite/view-result.txx b/odb/sqlite/view-result.txx index 7d8ac5f..5256467 100644 --- a/odb/sqlite/view-result.txx +++ b/odb/sqlite/view-result.txx @@ -22,8 +22,8 @@ namespace odb template view_result_impl:: view_result_impl (const query_base& q, - details::shared_ptr statement, - statements_type& statements) + const details::shared_ptr& statement, + statements_type& statements) : base_type (statements.connection ().database ()), result_impl_base (q, statement), statements_ (statements) -- cgit v1.1