aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-10-12 17:24:44 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-10-19 11:40:30 +0200
commitd94948b8bccfd8748245726487d54c41bb199baf (patch)
treec83176902ed8cb3c49532078e0705e2fc6621555
parent1c8dc77a0feae8b33e8c06f7ba076bd26d278054 (diff)
Completion of prepared query support
-rw-r--r--odb/sqlite/connection.cxx4
-rw-r--r--odb/sqlite/connection.hxx18
-rw-r--r--odb/sqlite/connection.ixx30
-rw-r--r--odb/sqlite/database.hxx14
-rw-r--r--odb/sqlite/database.ixx26
-rw-r--r--odb/sqlite/makefile1
-rw-r--r--odb/sqlite/no-id-object-result.hxx2
-rw-r--r--odb/sqlite/no-id-object-result.txx10
-rw-r--r--odb/sqlite/polymorphic-object-result.hxx7
-rw-r--r--odb/sqlite/polymorphic-object-result.txx7
-rw-r--r--odb/sqlite/prepared-query.cxx16
-rw-r--r--odb/sqlite/prepared-query.hxx6
-rw-r--r--odb/sqlite/query.cxx3
-rw-r--r--odb/sqlite/query.hxx2
-rw-r--r--odb/sqlite/query.ixx2
-rw-r--r--odb/sqlite/result.cxx2
-rw-r--r--odb/sqlite/result.hxx2
-rw-r--r--odb/sqlite/simple-object-result.hxx2
-rw-r--r--odb/sqlite/simple-object-result.txx2
-rw-r--r--odb/sqlite/statement.cxx16
-rw-r--r--odb/sqlite/statement.hxx26
-rw-r--r--odb/sqlite/view-result.hxx2
-rw-r--r--odb/sqlite/view-result.txx4
23 files changed, 154 insertions, 50 deletions
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 <odb/sqlite/transaction.hxx>
#include <odb/sqlite/statement.hxx>
#include <odb/sqlite/statement-cache.hxx>
+#include <odb/sqlite/prepared-query.hxx>
#include <odb/sqlite/error.hxx>
#include <odb/sqlite/exceptions.hxx> // 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 <odb/sqlite/version.hxx>
#include <odb/sqlite/forward.hxx>
+#include <odb/sqlite/query.hxx>
#include <odb/sqlite/tracer.hxx>
#include <odb/sqlite/transaction-impl.hxx>
#include <odb/sqlite/auto-handle.hxx>
@@ -68,6 +69,21 @@ namespace odb
virtual unsigned long long
execute (const char* statement, std::size_t length);
+ // Query preparation.
+ //
+ public:
+ template <typename T>
+ prepared_query<T>
+ prepare_query (const char* name, const char*);
+
+ template <typename T>
+ prepared_query<T>
+ prepare_query (const char* name, const std::string&);
+
+ template <typename T>
+ prepared_query<T>
+ prepare_query (const char* name, const query<T>&);
+
// SQL statement tracing.
//
public:
@@ -153,6 +169,8 @@ namespace odb
}
}
+#include <odb/sqlite/connection.ixx>
+
#include <odb/post.hxx>
#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 <typename T>
+ inline prepared_query<T> connection::
+ prepare_query (const char* n, const char* q)
+ {
+ return prepare_query<T> (n, query<T> (q));
+ }
+
+ template <typename T>
+ inline prepared_query<T> connection::
+ prepare_query (const char* n, const std::string& q)
+ {
+ return prepare_query<T> (n, query<T> (q));
+ }
+
+ template <typename T>
+ inline prepared_query<T> connection::
+ prepare_query (const char* n, const query<T>& q)
+ {
+ return query_<T, id_sqlite>::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<T>
query (const sqlite::query<T>&);
+ // Query preparation.
+ //
+ template <typename T>
+ prepared_query<T>
+ prepare_query (const char* name, const char*);
+
+ template <typename T>
+ prepared_query<T>
+ prepare_query (const char* name, const std::string&);
+
+ template <typename T>
+ prepared_query<T>
+ prepare_query (const char* name, const sqlite::query<T>&);
+
// 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 <odb/sqlite/transaction.hxx>
+
namespace odb
{
namespace sqlite
@@ -393,5 +395,29 @@ namespace odb
//
return query_<T, id_sqlite>::call (*this, q);
}
+
+ template <typename T>
+ inline prepared_query<T> database::
+ prepare_query (const char* n, const char* q)
+ {
+ return prepare_query<T> (n, sqlite::query<T> (q));
+ }
+
+ template <typename T>
+ inline prepared_query<T> database::
+ prepare_query (const char* n, const std::string& q)
+ {
+ return prepare_query<T> (n, sqlite::query<T> (q));
+ }
+
+ template <typename T>
+ inline prepared_query<T> database::
+ prepare_query (const char* n, const sqlite::query<T>& 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<select_statement>,
+ const details::shared_ptr<select_statement>&,
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 <typename T>
no_id_object_result_impl<T>::
no_id_object_result_impl (const query_base& q,
- details::shared_ptr<select_statement> statement,
- statements_type& statements)
- : base_type (statements.connection ().database ()),
- result_impl_base (q, statement),
- statements_ (statements)
+ const details::shared_ptr<select_statement>& 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<select_statement>,
- statements_type&);
+ polymorphic_object_result_impl (
+ const query_base&,
+ const details::shared_ptr<select_statement>&,
+ 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 <typename T>
polymorphic_object_result_impl<T>::
- polymorphic_object_result_impl (const query_base& q,
- details::shared_ptr<select_statement> st,
- statements_type& sts)
+ polymorphic_object_result_impl (
+ const query_base& q,
+ const details::shared_ptr<select_statement>& 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 <odb/sqlite/prepared-query.hxx>
+
+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 <odb/pre.hxx>
#include <odb/prepared-query.hxx>
-#include <odb/details/shared-ptr.hxx>
#include <odb/sqlite/version.hxx>
#include <odb/sqlite/query.hxx>
-#include <odb/sqlite/statement.hxx>
#include <odb/sqlite/details/export.hxx>
@@ -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<select_statement> 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<query_params>
+ const details::shared_ptr<query_params>&
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_params> query_base::
+ inline const details::shared_ptr<query_params>& 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<select_statement> s)
+ const details::shared_ptr<select_statement>& 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<select_statement>);
+ const details::shared_ptr<select_statement>&);
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<select_statement>,
+ const details::shared_ptr<select_statement>&,
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 <typename T>
object_result_impl<T>::
object_result_impl (const query_base& q,
- details::shared_ptr<select_statement> statement,
+ const details::shared_ptr<select_statement>& 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<sqlite3_stmt> 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<select_statement>,
+ const details::shared_ptr<select_statement>&,
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 <typename T>
view_result_impl<T>::
view_result_impl (const query_base& q,
- details::shared_ptr<select_statement> statement,
- statements_type& statements)
+ const details::shared_ptr<select_statement>& statement,
+ statements_type& statements)
: base_type (statements.connection ().database ()),
result_impl_base (q, statement),
statements_ (statements)