aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-11-07 15:00:06 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-11-07 15:00:06 +0200
commit0a71eaad620be004e7e28e7d3265a373dcd92395 (patch)
tree66adb95b0a79c376a3380182cd28601901dd741f
parent3c150763bc946bebe2eb5a2e487a28cf25f2e449 (diff)
Add support for SQL statement tracing
-rw-r--r--odb/sqlite/auto-handle.hxx2
-rw-r--r--odb/sqlite/connection.cxx4
-rw-r--r--odb/sqlite/connection.hxx20
-rw-r--r--odb/sqlite/database.hxx20
-rw-r--r--odb/sqlite/forward.hxx2
-rw-r--r--odb/sqlite/makefile1
-rw-r--r--odb/sqlite/statement-cache.cxx10
-rw-r--r--odb/sqlite/statement-cache.hxx20
-rw-r--r--odb/sqlite/statement.cxx86
-rw-r--r--odb/sqlite/statement.hxx25
-rw-r--r--odb/sqlite/tracer.cxx62
-rw-r--r--odb/sqlite/tracer.hxx62
-rw-r--r--odb/sqlite/transaction.hxx20
13 files changed, 296 insertions, 38 deletions
diff --git a/odb/sqlite/auto-handle.hxx b/odb/sqlite/auto-handle.hxx
index 60b1ea9..f0f0806 100644
--- a/odb/sqlite/auto-handle.hxx
+++ b/odb/sqlite/auto-handle.hxx
@@ -83,7 +83,7 @@ namespace odb
return h;
}
- operator H* ()
+ operator H* () const
{
return h_;
}
diff --git a/odb/sqlite/connection.cxx b/odb/sqlite/connection.cxx
index 7b16547..f9753be 100644
--- a/odb/sqlite/connection.cxx
+++ b/odb/sqlite/connection.cxx
@@ -80,7 +80,7 @@ namespace odb
{
// Enable/disable foreign key constraints.
//
- simple_statement st (
+ generic_statement st (
*this,
db_.foreign_keys ()
? "PRAGMA foreign_keys=ON"
@@ -122,7 +122,7 @@ namespace odb
unsigned long long connection::
execute (const char* s, std::size_t n)
{
- simple_statement st (*this, s, n);
+ generic_statement st (*this, s, n);
return st.execute ();
}
diff --git a/odb/sqlite/connection.hxx b/odb/sqlite/connection.hxx
index 4ad4f42..0986866 100644
--- a/odb/sqlite/connection.hxx
+++ b/odb/sqlite/connection.hxx
@@ -20,6 +20,7 @@
#include <odb/sqlite/version.hxx>
#include <odb/sqlite/forward.hxx>
+#include <odb/sqlite/tracer.hxx>
#include <odb/sqlite/transaction-impl.hxx>
#include <odb/sqlite/auto-handle.hxx>
@@ -69,6 +70,25 @@ namespace odb
virtual unsigned long long
execute (const char* statement, std::size_t length);
+ // SQL statement tracing.
+ //
+ public:
+ typedef sqlite::tracer tracer_type;
+
+ void
+ tracer (tracer_type& t)
+ {
+ odb::connection::tracer (t);
+ }
+
+ void
+ tracer (tracer_type* t)
+ {
+ odb::connection::tracer (t);
+ }
+
+ using odb::connection::tracer;
+
public:
sqlite3*
handle ()
diff --git a/odb/sqlite/database.hxx b/odb/sqlite/database.hxx
index 348f236..aeaca22 100644
--- a/odb/sqlite/database.hxx
+++ b/odb/sqlite/database.hxx
@@ -19,6 +19,7 @@
#include <odb/sqlite/version.hxx>
#include <odb/sqlite/forward.hxx>
+#include <odb/sqlite/tracer.hxx>
#include <odb/sqlite/connection.hxx>
#include <odb/sqlite/connection-factory.hxx>
#include <odb/sqlite/transaction-impl.hxx>
@@ -100,6 +101,25 @@ namespace odb
connection_ptr
connection ();
+ // SQL statement tracing.
+ //
+ public:
+ typedef sqlite::tracer tracer_type;
+
+ void
+ tracer (tracer_type& t)
+ {
+ odb::database::tracer (t);
+ }
+
+ void
+ tracer (tracer_type* t)
+ {
+ odb::database::tracer (t);
+ }
+
+ using odb::database::tracer;
+
public:
virtual
~database ();
diff --git a/odb/sqlite/forward.hxx b/odb/sqlite/forward.hxx
index cc1fbfc..5ad3a0f 100644
--- a/odb/sqlite/forward.hxx
+++ b/odb/sqlite/forward.hxx
@@ -18,7 +18,9 @@ namespace odb
class connection;
typedef details::shared_ptr<connection> connection_ptr;
class connection_factory;
+ class statement;
class transaction;
+ class tracer;
class query;
// Implementation details.
diff --git a/odb/sqlite/makefile b/odb/sqlite/makefile
index 50ef959..69ae8de 100644
--- a/odb/sqlite/makefile
+++ b/odb/sqlite/makefile
@@ -18,6 +18,7 @@ result.cxx \
statement-cache.cxx \
statement.cxx \
statements-base.cxx \
+tracer.cxx \
traits.cxx \
transaction.cxx \
transaction-impl.cxx
diff --git a/odb/sqlite/statement-cache.cxx b/odb/sqlite/statement-cache.cxx
index ba7b56c..48a4220 100644
--- a/odb/sqlite/statement-cache.cxx
+++ b/odb/sqlite/statement-cache.cxx
@@ -17,9 +17,9 @@ namespace odb
// String lengths below include '\0', as per SQLite manual
// suggestions.
//
- begin_ (new (shared) simple_statement (conn_, "BEGIN", 6)),
- commit_ (new (shared) simple_statement (conn_, "COMMIT", 7)),
- rollback_ (new (shared) simple_statement (conn_, "ROLLBACK", 9))
+ begin_ (new (shared) generic_statement (conn_, "BEGIN", 6)),
+ commit_ (new (shared) generic_statement (conn_, "COMMIT", 7)),
+ rollback_ (new (shared) generic_statement (conn_, "ROLLBACK", 9))
{
rollback_->cached (true);
commit_->cached (true);
@@ -30,7 +30,7 @@ namespace odb
begin_immediate_statement_ () const
{
begin_immediate_.reset (
- new (shared) simple_statement (conn_, "BEGIN IMMEDIATE", 16));
+ new (shared) generic_statement (conn_, "BEGIN IMMEDIATE", 16));
begin_immediate_->cached (true);
}
@@ -38,7 +38,7 @@ namespace odb
begin_exclusive_statement_ () const
{
begin_exclusive_.reset (
- new (shared) simple_statement (conn_, "BEGIN EXCLUSIVE", 16));
+ new (shared) generic_statement (conn_, "BEGIN EXCLUSIVE", 16));
begin_exclusive_->cached (true);
}
}
diff --git a/odb/sqlite/statement-cache.hxx b/odb/sqlite/statement-cache.hxx
index 1bdefb6..4f717e7 100644
--- a/odb/sqlite/statement-cache.hxx
+++ b/odb/sqlite/statement-cache.hxx
@@ -35,13 +35,13 @@ namespace odb
public:
statement_cache (connection&);
- simple_statement&
+ generic_statement&
begin_statement () const
{
return *begin_;
}
- simple_statement&
+ generic_statement&
begin_immediate_statement () const
{
if (!begin_immediate_)
@@ -50,7 +50,7 @@ namespace odb
return *begin_immediate_;
}
- simple_statement&
+ generic_statement&
begin_exclusive_statement () const
{
if (!begin_exclusive_)
@@ -59,13 +59,13 @@ namespace odb
return *begin_exclusive_;
}
- simple_statement&
+ generic_statement&
commit_statement () const
{
return *commit_;
}
- simple_statement&
+ generic_statement&
rollback_statement () const
{
return *rollback_;
@@ -119,11 +119,11 @@ namespace odb
connection& conn_;
- details::shared_ptr<simple_statement> begin_;
- mutable details::shared_ptr<simple_statement> begin_immediate_;
- mutable details::shared_ptr<simple_statement> begin_exclusive_;
- details::shared_ptr<simple_statement> commit_;
- details::shared_ptr<simple_statement> rollback_;
+ details::shared_ptr<generic_statement> begin_;
+ mutable details::shared_ptr<generic_statement> begin_immediate_;
+ mutable details::shared_ptr<generic_statement> begin_exclusive_;
+ details::shared_ptr<generic_statement> commit_;
+ details::shared_ptr<generic_statement> rollback_;
map map_;
};
diff --git a/odb/sqlite/statement.cxx b/odb/sqlite/statement.cxx
index a33ebcb..e1f4fb6 100644
--- a/odb/sqlite/statement.cxx
+++ b/odb/sqlite/statement.cxx
@@ -6,8 +6,10 @@
#include <cstring> // std::memcpy
#include <cassert>
+#include <odb/tracer.hxx>
#include <odb/exceptions.hxx> // object_not_persistent
+#include <odb/sqlite/database.hxx>
#include <odb/sqlite/statement.hxx>
#include <odb/sqlite/connection.hxx>
#include <odb/sqlite/error.hxx>
@@ -24,7 +26,8 @@ namespace odb
statement::
~statement ()
{
- finilize ();
+ if (stmt_ != 0)
+ finilize ();
}
void statement::
@@ -53,6 +56,35 @@ namespace odb
next_ = this;
list_add (); // Add to the list because we are uncached.
+
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->prepare (conn_, *this);
+ }
+ }
+
+ void statement::
+ finilize ()
+ {
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->deallocate (conn_, *this);
+ }
+
+ list_remove ();
+ stmt_.reset ();
+ }
+
+ const char* statement::
+ text () const
+ {
+ return sqlite3_sql (stmt_);
}
void statement::
@@ -187,29 +219,37 @@ namespace odb
return r;
}
- // simple_statement
+ // generic_statement
//
- simple_statement::
- simple_statement (connection& conn, const string& s)
+ generic_statement::
+ generic_statement (connection& conn, const string& s)
: statement (conn, s),
result_set_ (stmt_ ? sqlite3_column_count (stmt_) != 0: false)
{
}
- simple_statement::
- simple_statement (connection& conn, const char* s, std::size_t n)
+ generic_statement::
+ generic_statement (connection& conn, const char* s, std::size_t n)
: statement (conn, s, n),
result_set_ (stmt_ ? sqlite3_column_count (stmt_) != 0: false)
{
}
- unsigned long long simple_statement::
+ unsigned long long generic_statement::
execute ()
{
if (stmt_ == 0) // Empty statement or comment.
return 0;
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->execute (conn_, *this);
+ }
+
unsigned long long r (0);
// Only the first call to sqlite3_step() can return SQLITE_LOCKED.
@@ -266,6 +306,14 @@ namespace odb
if (active ())
reset ();
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->execute (conn_, *this);
+ }
+
done_ = false;
if (param_ != 0)
@@ -340,6 +388,14 @@ namespace odb
bool insert_statement::
execute ()
{
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->execute (conn_, *this);
+ }
+
bind_param (param_.bind, param_.count);
int e;
@@ -392,6 +448,14 @@ namespace odb
unsigned long long update_statement::
execute ()
{
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->execute (conn_, *this);
+ }
+
bind_param (param_.bind, param_.count);
int e;
@@ -426,6 +490,14 @@ namespace odb
unsigned long long delete_statement::
execute ()
{
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->execute (conn_, *this);
+ }
+
bind_param (param_.bind, param_.count);
int e;
diff --git a/odb/sqlite/statement.hxx b/odb/sqlite/statement.hxx
index 4fad1a3..4f1e3fd 100644
--- a/odb/sqlite/statement.hxx
+++ b/odb/sqlite/statement.hxx
@@ -15,7 +15,7 @@
#include <cassert>
#include <odb/forward.hxx>
-#include <odb/details/shared-ptr.hxx>
+#include <odb/statement.hxx>
#include <odb/sqlite/version.hxx>
#include <odb/sqlite/binding.hxx>
@@ -30,18 +30,21 @@ namespace odb
{
class connection;
- class LIBODB_SQLITE_EXPORT statement: public details::shared_base
+ class LIBODB_SQLITE_EXPORT statement: public odb::statement
{
public:
virtual
~statement () = 0;
sqlite3_stmt*
- handle ()
+ handle () const
{
return stmt_;
}
+ virtual const char*
+ text () const;
+
// Cached state (public part).
//
public:
@@ -130,11 +133,7 @@ namespace odb
//
protected:
void
- finilize ()
- {
- list_remove ();
- stmt_.reset ();
- }
+ finilize ();
protected:
friend class connection;
@@ -191,18 +190,18 @@ namespace odb
statement* next_;
};
- class LIBODB_SQLITE_EXPORT simple_statement: public statement
+ class LIBODB_SQLITE_EXPORT generic_statement: public statement
{
public:
- simple_statement (connection&, const std::string& statement);
- simple_statement (connection&, const char* statement, std::size_t n);
+ generic_statement (connection&, const std::string& statement);
+ generic_statement (connection&, const char* statement, std::size_t n);
unsigned long long
execute ();
private:
- simple_statement (const simple_statement&);
- simple_statement& operator= (const simple_statement&);
+ generic_statement (const generic_statement&);
+ generic_statement& operator= (const generic_statement&);
private:
bool result_set_;
diff --git a/odb/sqlite/tracer.cxx b/odb/sqlite/tracer.cxx
new file mode 100644
index 0000000..45f1a3d
--- /dev/null
+++ b/odb/sqlite/tracer.cxx
@@ -0,0 +1,62 @@
+// file : odb/sqlite/tracer.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#include <odb/sqlite/tracer.hxx>
+#include <odb/sqlite/connection.hxx>
+#include <odb/sqlite/statement.hxx>
+
+namespace odb
+{
+ namespace sqlite
+ {
+ tracer::
+ ~tracer ()
+ {
+ }
+
+ void tracer::
+ prepare (connection&, const statement&)
+ {
+ }
+
+ void tracer::
+ execute (connection& c, const statement& s)
+ {
+ execute (c, s.text ());
+ }
+
+ void tracer::
+ deallocate (connection&, const statement&)
+ {
+ }
+
+ void tracer::
+ prepare (odb::connection& c, const odb::statement& s)
+ {
+ prepare (static_cast<connection&> (c),
+ static_cast<const statement&> (s));
+ }
+
+ void tracer::
+ execute (odb::connection& c, const odb::statement& s)
+ {
+ execute (static_cast<connection&> (c),
+ static_cast<const statement&> (s));
+ }
+
+ void tracer::
+ execute (odb::connection& c, const char* s)
+ {
+ execute (static_cast<connection&> (c), s);
+ }
+
+ void tracer::
+ deallocate (odb::connection& c, const odb::statement& s)
+ {
+ deallocate (static_cast<connection&> (c),
+ static_cast<const statement&> (s));
+ }
+ }
+}
diff --git a/odb/sqlite/tracer.hxx b/odb/sqlite/tracer.hxx
new file mode 100644
index 0000000..f5466dc
--- /dev/null
+++ b/odb/sqlite/tracer.hxx
@@ -0,0 +1,62 @@
+// file : odb/sqlite/tracer.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_SQLITE_TRACER_HXX
+#define ODB_SQLITE_TRACER_HXX
+
+#include <odb/pre.hxx>
+
+#include <odb/tracer.hxx>
+
+#include <odb/sqlite/forward.hxx>
+#include <odb/sqlite/details/export.hxx>
+
+namespace odb
+{
+ namespace sqlite
+ {
+ class LIBODB_EXPORT tracer: private odb::tracer
+ {
+ public:
+ virtual
+ ~tracer ();
+
+ virtual void
+ prepare (connection&, const statement&);
+
+ virtual void
+ execute (connection&, const statement&);
+
+ virtual void
+ execute (connection&, const char* statement) = 0;
+
+ virtual void
+ deallocate (connection&, const statement&);
+
+ private:
+ // Allow these classes to convert sqlite::tracer to odb::tracer.
+ //
+ friend class database;
+ friend class connection;
+ friend class transaction;
+
+ virtual void
+ prepare (odb::connection&, const odb::statement&);
+
+ virtual void
+ execute (odb::connection&, const odb::statement&);
+
+ virtual void
+ execute (odb::connection&, const char* statement);
+
+ virtual void
+ deallocate (odb::connection&, const odb::statement&);
+ };
+ }
+}
+
+#include <odb/post.hxx>
+
+#endif // ODB_SQLITE_TRACER_HXX
diff --git a/odb/sqlite/transaction.hxx b/odb/sqlite/transaction.hxx
index b30a818..dbf73ab 100644
--- a/odb/sqlite/transaction.hxx
+++ b/odb/sqlite/transaction.hxx
@@ -12,6 +12,7 @@
#include <odb/sqlite/version.hxx>
#include <odb/sqlite/forward.hxx>
+#include <odb/sqlite/tracer.hxx>
#include <odb/sqlite/details/export.hxx>
namespace odb
@@ -50,6 +51,25 @@ namespace odb
static void
current (transaction&);
+ // SQL statement tracing.
+ //
+ public:
+ typedef sqlite::tracer tracer_type;
+
+ void
+ tracer (tracer_type& t)
+ {
+ odb::transaction::tracer (t);
+ }
+
+ void
+ tracer (tracer_type* t)
+ {
+ odb::transaction::tracer (t);
+ }
+
+ using odb::transaction::tracer;
+
public:
transaction_impl&
implementation ();