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
commit0e37272b9ab8f37ad2f3d37bf6a09c68e5117d02 (patch)
tree823c0bc76f6c03e9ecedaaad6db719a7b0367299
parent26f53799c911e44da5d229e8f6bf2c40f79c31b1 (diff)
Add support for SQL statement tracing
-rw-r--r--odb/pgsql/auto-handle.hxx2
-rw-r--r--odb/pgsql/connection.cxx8
-rw-r--r--odb/pgsql/connection.hxx20
-rw-r--r--odb/pgsql/database.hxx20
-rw-r--r--odb/pgsql/forward.hxx2
-rw-r--r--odb/pgsql/makefile1
-rw-r--r--odb/pgsql/statement.cxx61
-rw-r--r--odb/pgsql/statement.hxx17
-rw-r--r--odb/pgsql/tracer.cxx62
-rw-r--r--odb/pgsql/tracer.hxx62
-rw-r--r--odb/pgsql/transaction-impl.cxx20
-rw-r--r--odb/pgsql/transaction.hxx20
12 files changed, 289 insertions, 6 deletions
diff --git a/odb/pgsql/auto-handle.hxx b/odb/pgsql/auto-handle.hxx
index 2ed58e5..be565e5 100644
--- a/odb/pgsql/auto-handle.hxx
+++ b/odb/pgsql/auto-handle.hxx
@@ -72,7 +72,7 @@ namespace odb
return h;
}
- operator H* ()
+ operator H* () const
{
return h_;
}
diff --git a/odb/pgsql/connection.cxx b/odb/pgsql/connection.cxx
index 6f0feaf..b173136 100644
--- a/odb/pgsql/connection.cxx
+++ b/odb/pgsql/connection.cxx
@@ -86,6 +86,14 @@ namespace odb
//
string str (s, n);
+ {
+ odb::tracer* t;
+ if ((t = transaction_tracer ()) ||
+ (t = tracer ()) ||
+ (t = database ().tracer ()))
+ t->execute (*this, str.c_str ());
+ }
+
auto_handle<PGresult> h (PQexec (handle_, str.c_str ()));
unsigned long long count (0);
diff --git a/odb/pgsql/connection.hxx b/odb/pgsql/connection.hxx
index e8a1f17..737551d 100644
--- a/odb/pgsql/connection.hxx
+++ b/odb/pgsql/connection.hxx
@@ -18,6 +18,7 @@
#include <odb/pgsql/version.hxx>
#include <odb/pgsql/forward.hxx>
+#include <odb/pgsql/tracer.hxx>
#include <odb/pgsql/transaction-impl.hxx>
#include <odb/pgsql/auto-handle.hxx>
#include <odb/pgsql/pgsql-fwd.hxx> // PGconn
@@ -62,6 +63,25 @@ namespace odb
virtual unsigned long long
execute (const char* statement, std::size_t length);
+ // SQL statement tracing.
+ //
+ public:
+ typedef pgsql::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:
PGconn*
handle ()
diff --git a/odb/pgsql/database.hxx b/odb/pgsql/database.hxx
index 1b688fc..52e48c3 100644
--- a/odb/pgsql/database.hxx
+++ b/odb/pgsql/database.hxx
@@ -18,6 +18,7 @@
#include <odb/pgsql/version.hxx>
#include <odb/pgsql/forward.hxx>
+#include <odb/pgsql/tracer.hxx>
#include <odb/pgsql/connection.hxx>
#include <odb/pgsql/connection-factory.hxx>
@@ -98,6 +99,25 @@ namespace odb
virtual odb::connection*
connection_ ();
+ // SQL statement tracing.
+ //
+ public:
+ typedef pgsql::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:
const std::string&
user () const
diff --git a/odb/pgsql/forward.hxx b/odb/pgsql/forward.hxx
index 640d379..dd6f5ad 100644
--- a/odb/pgsql/forward.hxx
+++ b/odb/pgsql/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/pgsql/makefile b/odb/pgsql/makefile
index e447f8e..410650a 100644
--- a/odb/pgsql/makefile
+++ b/odb/pgsql/makefile
@@ -16,6 +16,7 @@ exceptions.cxx \
object-statements.cxx \
statement.cxx \
statements-base.cxx \
+tracer.cxx \
traits.cxx \
transaction.cxx \
transaction-impl.cxx \
diff --git a/odb/pgsql/statement.cxx b/odb/pgsql/statement.cxx
index 049a00d..8a20456 100644
--- a/odb/pgsql/statement.cxx
+++ b/odb/pgsql/statement.cxx
@@ -9,6 +9,8 @@
#include <libpq-fe.h>
+#include <odb/tracer.hxx>
+
#include <odb/pgsql/pgsql-oid.hxx>
#include <odb/pgsql/statement.hxx>
#include <odb/pgsql/connection.hxx>
@@ -68,6 +70,14 @@ namespace odb
if (deallocated_)
return;
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->deallocate (conn_, *this);
+ }
+
string s ("deallocate \"");
s += name_;
s += "\"";
@@ -79,17 +89,26 @@ namespace odb
statement::
statement (connection& conn,
const string& name,
- const string& stmt,
+ const string& text,
const Oid* types,
size_t types_count)
: conn_ (conn),
name_ (name),
+ text_ (text),
deallocated_ (false)
{
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->prepare (conn_, *this);
+ }
+
auto_handle<PGresult> h (
PQprepare (conn_.handle (),
name_.c_str (),
- stmt.c_str (),
+ text_.c_str (),
static_cast<int> (types_count),
types));
@@ -102,6 +121,12 @@ namespace odb
//
}
+ const char* statement::
+ text () const
+ {
+ return text_.c_str ();
+ }
+
void statement::
bind_param (native_binding& n, const binding& b)
{
@@ -384,6 +409,14 @@ namespace odb
if (param_ != 0)
bind_param (*native_param_, *param_);
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->execute (conn_, *this);
+ }
+
bool in (native_param_ != 0);
handle_.reset (
@@ -478,6 +511,14 @@ namespace odb
{
bind_param (native_param_, param_);
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->execute (conn_, *this);
+ }
+
auto_handle<PGresult> h (
PQexecPrepared (conn_.handle (),
name_.c_str (),
@@ -570,6 +611,14 @@ namespace odb
{
bind_param (native_param_, param_);
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->execute (conn_, *this);
+ }
+
auto_handle<PGresult> h (
PQexecPrepared (conn_.handle (),
name_.c_str (),
@@ -627,6 +676,14 @@ namespace odb
if (param_ != 0)
bind_param (native_param_, *param_);
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->execute (conn_, *this);
+ }
+
auto_handle<PGresult> h (
PQexecPrepared (conn_.handle (),
name_.c_str (),
diff --git a/odb/pgsql/statement.hxx b/odb/pgsql/statement.hxx
index 8beb01f..3230bb2 100644
--- a/odb/pgsql/statement.hxx
+++ b/odb/pgsql/statement.hxx
@@ -11,7 +11,8 @@
#include <string>
#include <cstddef> // std::size_t
-#include <odb/details/shared-ptr.hxx>
+#include <odb/forward.hxx>
+#include <odb/statement.hxx>
#include <odb/pgsql/version.hxx>
#include <odb/pgsql/binding.hxx>
@@ -26,12 +27,21 @@ namespace odb
{
class connection;
- class LIBODB_PGSQL_EXPORT statement: public details::shared_base
+ class LIBODB_PGSQL_EXPORT statement: public odb::statement
{
public:
virtual
~statement () = 0;
+ const char*
+ name () const
+ {
+ return name_.c_str ();
+ }
+
+ virtual const char*
+ text () const;
+
void
deallocate ();
@@ -55,13 +65,14 @@ namespace odb
protected:
statement (connection&,
const std::string& name,
- const std::string& stmt,
+ const std::string& text,
const Oid* types,
std::size_t types_count);
protected:
connection& conn_;
std::string name_;
+ std::string text_;
private:
bool deallocated_;
diff --git a/odb/pgsql/tracer.cxx b/odb/pgsql/tracer.cxx
new file mode 100644
index 0000000..b0cf4d2
--- /dev/null
+++ b/odb/pgsql/tracer.cxx
@@ -0,0 +1,62 @@
+// file : odb/pgsql/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/pgsql/tracer.hxx>
+#include <odb/pgsql/connection.hxx>
+#include <odb/pgsql/statement.hxx>
+
+namespace odb
+{
+ namespace pgsql
+ {
+ 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/pgsql/tracer.hxx b/odb/pgsql/tracer.hxx
new file mode 100644
index 0000000..9af7df8
--- /dev/null
+++ b/odb/pgsql/tracer.hxx
@@ -0,0 +1,62 @@
+// file : odb/pgsql/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_PGSQL_TRACER_HXX
+#define ODB_PGSQL_TRACER_HXX
+
+#include <odb/pre.hxx>
+
+#include <odb/tracer.hxx>
+
+#include <odb/pgsql/forward.hxx>
+#include <odb/pgsql/details/export.hxx>
+
+namespace odb
+{
+ namespace pgsql
+ {
+ 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 pgsql::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_PGSQL_TRACER_HXX
diff --git a/odb/pgsql/transaction-impl.cxx b/odb/pgsql/transaction-impl.cxx
index e4604e3..ac90e93 100644
--- a/odb/pgsql/transaction-impl.cxx
+++ b/odb/pgsql/transaction-impl.cxx
@@ -7,6 +7,8 @@
#include <libpq-fe.h>
+#include <odb/tracer.hxx>
+
#include <odb/pgsql/database.hxx>
#include <odb/pgsql/connection.hxx>
#include <odb/pgsql/error.hxx>
@@ -46,6 +48,12 @@ namespace odb
odb::transaction_impl::connection_ = connection_.get ();
}
+ {
+ odb::tracer* t;
+ if ((t = connection_->tracer ()) || (t = database_.tracer ()))
+ t->execute (*connection_, "BEGIN");
+ }
+
auto_handle<PGresult> h (PQexec (connection_->handle (), "begin"));
if (!h || PGRES_COMMAND_OK != PQresultStatus (h))
@@ -55,6 +63,12 @@ namespace odb
void transaction_impl::
commit ()
{
+ {
+ odb::tracer* t;
+ if ((t = connection_->tracer ()) || (t = database_.tracer ()))
+ t->execute (*connection_, "COMMIT");
+ }
+
auto_handle<PGresult> h (PQexec (connection_->handle (), "commit"));
if (!h || PGRES_COMMAND_OK != PQresultStatus (h))
@@ -64,6 +78,12 @@ namespace odb
void transaction_impl::
rollback ()
{
+ {
+ odb::tracer* t;
+ if ((t = connection_->tracer ()) || (t = database_.tracer ()))
+ t->execute (*connection_, "ROLLBACK");
+ }
+
auto_handle<PGresult> h (PQexec (connection_->handle (), "rollback"));
if (!h || PGRES_COMMAND_OK != PQresultStatus (h))
diff --git a/odb/pgsql/transaction.hxx b/odb/pgsql/transaction.hxx
index 39675d8..d56a08b 100644
--- a/odb/pgsql/transaction.hxx
+++ b/odb/pgsql/transaction.hxx
@@ -12,6 +12,7 @@
#include <odb/pgsql/version.hxx>
#include <odb/pgsql/forward.hxx>
+#include <odb/pgsql/tracer.hxx>
#include <odb/pgsql/details/export.hxx>
@@ -51,6 +52,25 @@ namespace odb
static void
current (transaction&);
+ // SQL statement tracing.
+ //
+ public:
+ typedef pgsql::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 ();