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
commitbcf5fce175953bec0fd2725968828850a74d8539 (patch)
tree74388e8f50f893d53cf748a34b601c96557d0228
parent02e8d8116c01594716323fc6e03ede7094699d5c (diff)
Add support for SQL statement tracing
-rw-r--r--odb/connection.hxx31
-rw-r--r--odb/connection.ixx26
-rw-r--r--odb/database.hxx23
-rw-r--r--odb/database.ixx19
-rw-r--r--odb/forward.hxx13
-rw-r--r--odb/makefile2
-rw-r--r--odb/statement.cxx14
-rw-r--r--odb/statement.hxx38
-rw-r--r--odb/tracer.cxx58
-rw-r--r--odb/tracer.hxx38
-rw-r--r--odb/transaction.cxx4
-rw-r--r--odb/transaction.hxx15
-rw-r--r--odb/transaction.ixx23
13 files changed, 298 insertions, 6 deletions
diff --git a/odb/connection.hxx b/odb/connection.hxx
index db8635c..fdf5036 100644
--- a/odb/connection.hxx
+++ b/odb/connection.hxx
@@ -51,6 +51,30 @@ namespace odb
virtual unsigned long long
execute (const char* statement, std::size_t length) = 0;
+ // SQL statement tracing.
+ //
+ public:
+ typedef odb::tracer tracer_type;
+
+ void
+ tracer (tracer_type&);
+
+ void
+ tracer (tracer_type*);
+
+ tracer_type*
+ tracer () const;
+
+ public:
+ // Store the transaction-spacific tracer in the connection. If we
+ // were to store it in the transaction, then in order to check if
+ // it was set, we would need to get the transaction instance using
+ // the current() API. But that requires a TLS lookup, which can be
+ // slow.
+ //
+ tracer_type*
+ transaction_tracer () const;
+
public:
virtual
~connection ();
@@ -62,8 +86,13 @@ namespace odb
connection (const connection&);
connection& operator= (const connection&);
- private:
+ protected:
database_type& database_;
+ tracer_type* tracer_;
+
+ protected:
+ friend class transaction;
+ tracer_type* transaction_tracer_;
};
}
diff --git a/odb/connection.ixx b/odb/connection.ixx
index 0e6d24c..8e9f26a 100644
--- a/odb/connection.ixx
+++ b/odb/connection.ixx
@@ -9,7 +9,7 @@ namespace odb
{
inline connection::
connection (database_type& database)
- : database_ (database)
+ : database_ (database), tracer_ (0), transaction_tracer_ (0)
{
}
@@ -30,4 +30,28 @@ namespace odb
{
return execute (st.c_str (), st.size ());
}
+
+ inline void connection::
+ tracer (tracer_type& t)
+ {
+ tracer_ = &t;
+ }
+
+ inline void connection::
+ tracer (tracer_type* t)
+ {
+ tracer_ = t;
+ }
+
+ inline connection::tracer_type* connection::
+ tracer () const
+ {
+ return tracer_;
+ }
+
+ inline connection::tracer_type* connection::
+ transaction_tracer () const
+ {
+ return transaction_tracer_;
+ }
}
diff --git a/odb/database.hxx b/odb/database.hxx
index c7816f6..e9c44f2 100644
--- a/odb/database.hxx
+++ b/odb/database.hxx
@@ -205,9 +205,27 @@ namespace odb
connection_ptr
connection ();
+ // SQL statement tracing.
+ //
+ public:
+ typedef odb::tracer tracer_type;
+
+ void
+ tracer (tracer_type&);
+
+ void
+ tracer (tracer_type*);
+
+ tracer_type*
+ tracer () const;
+
protected:
database ();
+ private:
+ database (const database&);
+ database& operator= (const database&);
+
protected:
typedef odb::connection connection_type;
@@ -230,9 +248,8 @@ namespace odb
template <typename T, class_kind kind>
struct query_;
- private:
- database (const database&);
- database& operator= (const database&);
+ protected:
+ tracer_type* tracer_;
};
}
diff --git a/odb/database.ixx b/odb/database.ixx
index 11b59ca..7df0d79 100644
--- a/odb/database.ixx
+++ b/odb/database.ixx
@@ -9,6 +9,7 @@ namespace odb
{
inline database::
database ()
+ : tracer_ (0)
{
}
@@ -18,6 +19,24 @@ namespace odb
return connection_ptr (connection_ ());
}
+ inline void database::
+ tracer (tracer_type& t)
+ {
+ tracer_ = &t;
+ }
+
+ inline void database::
+ tracer (tracer_type* t)
+ {
+ tracer_ = t;
+ }
+
+ inline database::tracer_type* database::
+ tracer () const
+ {
+ return tracer_;
+ }
+
template <typename T>
inline typename object_traits<T>::id_type database::
persist (T* p)
diff --git a/odb/forward.hxx b/odb/forward.hxx
index b253118..41ed70f 100644
--- a/odb/forward.hxx
+++ b/odb/forward.hxx
@@ -8,6 +8,7 @@
#include <odb/pre.hxx>
+#include <odb/details/export.hxx>
#include <odb/details/shared-ptr-fwd.hxx>
namespace odb
@@ -16,6 +17,7 @@ namespace odb
class connection;
typedef details::shared_ptr<connection> connection_ptr;
class transaction;
+ class statement;
class session;
namespace core
@@ -24,9 +26,20 @@ namespace odb
using odb::connection;
using odb::connection_ptr;
using odb::transaction;
+ using odb::statement;
using odb::session;
}
+ // Tracing.
+ //
+ class tracer; // Not in core.
+ extern LIBODB_EXPORT tracer& stderr_tracer;
+
+ namespace core
+ {
+ using odb::stderr_tracer;
+ }
+
// Implementation details.
//
diff --git a/odb/makefile b/odb/makefile
index 9937509..54499a0 100644
--- a/odb/makefile
+++ b/odb/makefile
@@ -12,6 +12,8 @@ connection.cxx \
lazy-ptr-impl.cxx \
schema-catalog.cxx \
session.cxx \
+statement.cxx \
+tracer.cxx \
transaction.cxx
diff --git a/odb/statement.cxx b/odb/statement.cxx
new file mode 100644
index 0000000..d5666ca
--- /dev/null
+++ b/odb/statement.cxx
@@ -0,0 +1,14 @@
+// file : odb/statement.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/statement.hxx>
+
+namespace odb
+{
+ statement::
+ ~statement ()
+ {
+ }
+}
diff --git a/odb/statement.hxx b/odb/statement.hxx
new file mode 100644
index 0000000..ca6df5a
--- /dev/null
+++ b/odb/statement.hxx
@@ -0,0 +1,38 @@
+// file : odb/statement.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_STATEMENT_HXX
+#define ODB_STATEMENT_HXX
+
+#include <odb/pre.hxx>
+
+#include <odb/forward.hxx>
+
+#include <odb/details/export.hxx>
+#include <odb/details/shared-ptr.hxx>
+
+namespace odb
+{
+ class LIBODB_EXPORT statement: public details::shared_base
+ {
+ public:
+ virtual
+ ~statement () = 0;
+
+ statement () {}
+
+ private:
+ statement (const statement&);
+ statement& operator= (const statement&);
+
+ public:
+ virtual const char*
+ text () const = 0;
+ };
+}
+
+#include <odb/post.hxx>
+
+#endif // ODB_MYSQL_STATEMENT_HXX
diff --git a/odb/tracer.cxx b/odb/tracer.cxx
new file mode 100644
index 0000000..aa33822
--- /dev/null
+++ b/odb/tracer.cxx
@@ -0,0 +1,58 @@
+// file : odb/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 <iostream>
+
+#include <odb/tracer.hxx>
+#include <odb/statement.hxx>
+
+using namespace std;
+
+namespace odb
+{
+ //
+ // tracer
+ //
+
+ 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&)
+ {
+ }
+
+ //
+ // stderr_tracer
+ //
+
+ class stderr_tracer_type: public tracer
+ {
+ virtual void
+ execute (connection&, const char* statement);
+ };
+
+ void stderr_tracer_type::
+ execute (connection&, const char* s)
+ {
+ cerr << s << endl;
+ }
+
+ static stderr_tracer_type stderr_tracer_;
+ tracer& stderr_tracer = stderr_tracer_;
+}
diff --git a/odb/tracer.hxx b/odb/tracer.hxx
new file mode 100644
index 0000000..9a8ec88
--- /dev/null
+++ b/odb/tracer.hxx
@@ -0,0 +1,38 @@
+// file : odb/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_TRACER_HXX
+#define ODB_TRACER_HXX
+
+#include <odb/pre.hxx>
+
+#include <odb/forward.hxx>
+#include <odb/details/export.hxx>
+
+namespace odb
+{
+ class LIBODB_EXPORT 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&);
+ };
+}
+
+#include <odb/post.hxx>
+
+#endif // ODB_TRACER_HXX
diff --git a/odb/transaction.cxx b/odb/transaction.cxx
index 70abd0c..b96a1bf 100644
--- a/odb/transaction.cxx
+++ b/odb/transaction.cxx
@@ -3,8 +3,8 @@
// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
// license : GNU GPL v2; see accompanying LICENSE file
-#include <odb/exceptions.hxx>
#include <odb/transaction.hxx>
+#include <odb/exceptions.hxx>
#include <odb/details/tls.hxx>
@@ -85,6 +85,7 @@ namespace odb
throw transaction_already_finalized ();
finalized_ = true;
+ impl_->connection ().transaction_tracer_ = 0;
if (tls_get (current_transaction) == this)
{
@@ -102,6 +103,7 @@ namespace odb
throw transaction_already_finalized ();
finalized_ = true;
+ impl_->connection ().transaction_tracer_ = 0;
if (tls_get (current_transaction) == this)
{
diff --git a/odb/transaction.hxx b/odb/transaction.hxx
index 0d4f518..e8488a4 100644
--- a/odb/transaction.hxx
+++ b/odb/transaction.hxx
@@ -49,6 +49,7 @@ namespace odb
connection_type&
connection ();
+ public:
// Return true if there is a transaction in effect.
//
static bool
@@ -70,6 +71,20 @@ namespace odb
static void
reset_current ();
+ // SQL statement tracing.
+ //
+ public:
+ typedef odb::tracer tracer_type;
+
+ void
+ tracer (tracer_type&);
+
+ void
+ tracer (tracer_type*);
+
+ tracer_type*
+ tracer () const;
+
public:
transaction_impl&
implementation ();
diff --git a/odb/transaction.ixx b/odb/transaction.ixx
index d838a9f..13bf141 100644
--- a/odb/transaction.ixx
+++ b/odb/transaction.ixx
@@ -3,6 +3,8 @@
// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
// license : GNU GPL v2; see accompanying LICENSE file
+#include <odb/connection.hxx>
+
namespace odb
{
inline transaction::database_type& transaction::
@@ -22,4 +24,25 @@ namespace odb
{
return *impl_;
}
+
+ // The transaction-specific tracer is stored in the connection. See
+ // the connection class for the reason.
+ //
+ inline void transaction::
+ tracer (tracer_type& t)
+ {
+ impl_->connection ().transaction_tracer_ = &t;
+ }
+
+ inline void transaction::
+ tracer (tracer_type* t)
+ {
+ impl_->connection ().transaction_tracer_ = t;
+ }
+
+ inline transaction::tracer_type* transaction::
+ tracer () const
+ {
+ return impl_->connection ().transaction_tracer_;
+ }
}