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
commit57d5d8fe9dc4c0d6b4ef21754c5a3539e4c01cf9 (patch)
tree4daef878ce8276b663a2bc5470e3d9dc37ee2086
parent2077828442e58677a2af1d15c6d5266455e50cad (diff)
Add support for SQL statement tracing
-rw-r--r--odb/mysql/auto-handle.hxx2
-rw-r--r--odb/mysql/connection.cxx11
-rw-r--r--odb/mysql/connection.hxx20
-rw-r--r--odb/mysql/database.hxx20
-rw-r--r--odb/mysql/forward.hxx2
-rw-r--r--odb/mysql/makefile1
-rw-r--r--odb/mysql/statement.cxx96
-rw-r--r--odb/mysql/statement.hxx16
-rw-r--r--odb/mysql/tracer.cxx62
-rw-r--r--odb/mysql/tracer.hxx62
-rw-r--r--odb/mysql/transaction-impl.cxx20
-rw-r--r--odb/mysql/transaction.hxx20
12 files changed, 300 insertions, 32 deletions
diff --git a/odb/mysql/auto-handle.hxx b/odb/mysql/auto-handle.hxx
index 6950551..42e06e4 100644
--- a/odb/mysql/auto-handle.hxx
+++ b/odb/mysql/auto-handle.hxx
@@ -76,7 +76,7 @@ namespace odb
return h;
}
- operator H* ()
+ operator H* () const
{
return h_;
}
diff --git a/odb/mysql/connection.cxx b/odb/mysql/connection.cxx
index 114ea38..473079d 100644
--- a/odb/mysql/connection.cxx
+++ b/odb/mysql/connection.cxx
@@ -97,6 +97,17 @@ namespace odb
{
clear ();
+ {
+ odb::tracer* t;
+ if ((t = transaction_tracer ()) ||
+ (t = tracer ()) ||
+ (t = database ().tracer ()))
+ {
+ string str (s, n);
+ t->execute (*this, str.c_str ());
+ }
+ }
+
if (mysql_real_query (handle_, s, static_cast<unsigned long> (n)))
translate_error (*this);
diff --git a/odb/mysql/connection.hxx b/odb/mysql/connection.hxx
index a54194e..81e5019 100644
--- a/odb/mysql/connection.hxx
+++ b/odb/mysql/connection.hxx
@@ -17,6 +17,7 @@
#include <odb/mysql/mysql.hxx>
#include <odb/mysql/version.hxx>
#include <odb/mysql/forward.hxx>
+#include <odb/mysql/tracer.hxx>
#include <odb/mysql/transaction-impl.hxx>
#include <odb/mysql/auto-handle.hxx>
@@ -62,6 +63,25 @@ namespace odb
virtual unsigned long long
execute (const char* statement, std::size_t length);
+ // SQL statement tracing.
+ //
+ public:
+ typedef mysql::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:
bool
failed () const
diff --git a/odb/mysql/database.hxx b/odb/mysql/database.hxx
index be9bb58..a245a37 100644
--- a/odb/mysql/database.hxx
+++ b/odb/mysql/database.hxx
@@ -17,6 +17,7 @@
#include <odb/mysql/mysql.hxx>
#include <odb/mysql/version.hxx>
#include <odb/mysql/forward.hxx>
+#include <odb/mysql/tracer.hxx>
#include <odb/mysql/connection.hxx>
#include <odb/mysql/connection-factory.hxx>
@@ -176,6 +177,25 @@ namespace odb
connection_ptr
connection ();
+ // SQL statement tracing.
+ //
+ public:
+ typedef mysql::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/mysql/forward.hxx b/odb/mysql/forward.hxx
index 8ed934c..2252098 100644
--- a/odb/mysql/forward.hxx
+++ b/odb/mysql/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/mysql/makefile b/odb/mysql/makefile
index 2e6d5ad..069df5f 100644
--- a/odb/mysql/makefile
+++ b/odb/mysql/makefile
@@ -17,6 +17,7 @@ query.cxx \
query-const-expr.cxx \
statement.cxx \
statements-base.cxx \
+tracer.cxx \
transaction.cxx \
transaction-impl.cxx \
traits.cxx
diff --git a/odb/mysql/statement.cxx b/odb/mysql/statement.cxx
index d4e4943..04f59f6 100644
--- a/odb/mysql/statement.cxx
+++ b/odb/mysql/statement.cxx
@@ -5,9 +5,12 @@
#include <cassert>
+#include <odb/tracer.hxx>
+
#include <odb/mysql/mysql.hxx>
-#include <odb/mysql/statement.hxx>
+#include <odb/mysql/database.hxx>
#include <odb/mysql/connection.hxx>
+#include <odb/mysql/statement.hxx>
#include <odb/mysql/error.hxx>
using namespace std;
@@ -20,15 +23,34 @@ namespace odb
//
statement::
- statement (connection& conn)
- : conn_ (conn), stmt_ (conn_.alloc_stmt_handle ())
+ statement (connection& conn, const string& text)
+ : conn_ (conn), text_ (text), stmt_ (conn_.alloc_stmt_handle ())
{
+ conn_.clear ();
+
+ if (mysql_stmt_prepare (stmt_, text_.c_str (), text_.size ()) != 0)
+ translate_error (conn_, stmt_);
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->prepare (conn_, *this);
+ }
}
statement::
~statement ()
{
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->deallocate (conn_, *this);
+ }
+
// Let the connection handle the release of the statement (it
// may delay the actual freeing if it will mess up the currently
// active statement).
@@ -36,6 +58,12 @@ namespace odb
conn_.free_stmt_handle (stmt_);
}
+ const char* statement::
+ text () const
+ {
+ return text_.c_str ();
+ }
+
void statement::
cancel ()
{
@@ -64,7 +92,7 @@ namespace odb
const string& s,
binding& param,
binding& result)
- : statement (conn),
+ : statement (conn, s),
end_ (false),
cached_ (false),
rows_ (0),
@@ -73,15 +101,11 @@ namespace odb
result_ (result),
result_version_ (0)
{
- conn_.clear ();
-
- if (mysql_stmt_prepare (stmt_, s.c_str (), s.size ()) != 0)
- translate_error (conn_, stmt_);
}
select_statement::
select_statement (connection& conn, const string& s, binding& result)
- : statement (conn),
+ : statement (conn, s),
end_ (false),
cached_ (false),
rows_ (0),
@@ -89,10 +113,6 @@ namespace odb
result_ (result),
result_version_ (0)
{
- conn_.clear ();
-
- if (mysql_stmt_prepare (stmt_, s.c_str (), s.size ()) != 0)
- translate_error (conn_, stmt_);
}
void select_statement::
@@ -117,6 +137,14 @@ namespace odb
param_version_ = param_->version;
}
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->execute (conn_, *this);
+ }
+
if (mysql_stmt_execute (stmt_))
translate_error (conn_, stmt_);
@@ -249,12 +277,8 @@ namespace odb
insert_statement::
insert_statement (connection& conn, const string& s, binding& param)
- : statement (conn), param_ (param), param_version_ (0)
+ : statement (conn, s), param_ (param), param_version_ (0)
{
- conn_.clear ();
-
- if (mysql_stmt_prepare (stmt_, s.c_str (), s.size ()) != 0)
- translate_error (conn_, stmt_);
}
bool insert_statement::
@@ -273,6 +297,14 @@ namespace odb
param_version_ = param_.version;
}
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->execute (conn_, *this);
+ }
+
if (mysql_stmt_execute (stmt_))
{
if (mysql_stmt_errno (stmt_) == ER_DUP_ENTRY)
@@ -300,12 +332,8 @@ namespace odb
update_statement::
update_statement (connection& conn, const string& s, binding& param)
- : statement (conn), param_ (param), param_version_ (0)
+ : statement (conn, s), param_ (param), param_version_ (0)
{
- conn_.clear ();
-
- if (mysql_stmt_prepare (stmt_, s.c_str (), s.size ()) != 0)
- translate_error (conn_, stmt_);
}
unsigned long long update_statement::
@@ -324,6 +352,14 @@ namespace odb
param_version_ = param_.version;
}
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->execute (conn_, *this);
+ }
+
if (mysql_stmt_execute (stmt_))
translate_error (conn_, stmt_);
@@ -345,12 +381,8 @@ namespace odb
delete_statement::
delete_statement (connection& conn, const string& s, binding& param)
- : statement (conn), param_ (param), param_version_ (0)
+ : statement (conn, s), param_ (param), param_version_ (0)
{
- conn_.clear ();
-
- if (mysql_stmt_prepare (stmt_, s.c_str (), s.size ()) != 0)
- translate_error (conn_, stmt_);
}
unsigned long long delete_statement::
@@ -369,6 +401,14 @@ namespace odb
param_version_ = param_.version;
}
+ {
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->execute (conn_, *this);
+ }
+
if (mysql_stmt_execute (stmt_))
translate_error (conn_, stmt_);
diff --git a/odb/mysql/statement.hxx b/odb/mysql/statement.hxx
index 93adea4..ee1284b 100644
--- a/odb/mysql/statement.hxx
+++ b/odb/mysql/statement.hxx
@@ -12,7 +12,7 @@
#include <cstddef> // std::size_t
#include <odb/forward.hxx>
-#include <odb/details/shared-ptr.hxx>
+#include <odb/statement.hxx>
#include <odb/mysql/mysql.hxx>
#include <odb/mysql/version.hxx>
@@ -27,12 +27,21 @@ namespace odb
{
class connection;
- class LIBODB_MYSQL_EXPORT statement: public details::shared_base
+ class LIBODB_MYSQL_EXPORT statement: public odb::statement
{
public:
virtual
~statement () = 0;
+ MYSQL_STMT*
+ handle () const
+ {
+ return stmt_;
+ }
+
+ virtual const char*
+ text () const;
+
// Cancel the statement execution (e.g., result fetching) so
// that another statement can be executed on the connection.
//
@@ -40,10 +49,11 @@ namespace odb
cancel ();
protected:
- statement (connection&);
+ statement (connection&, const std::string& text);
protected:
connection& conn_;
+ const std::string text_;
auto_handle<MYSQL_STMT> stmt_;
};
diff --git a/odb/mysql/tracer.cxx b/odb/mysql/tracer.cxx
new file mode 100644
index 0000000..7b5a03d
--- /dev/null
+++ b/odb/mysql/tracer.cxx
@@ -0,0 +1,62 @@
+// file : odb/mysql/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/mysql/tracer.hxx>
+#include <odb/mysql/connection.hxx>
+#include <odb/mysql/statement.hxx>
+
+namespace odb
+{
+ namespace mysql
+ {
+ 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/mysql/tracer.hxx b/odb/mysql/tracer.hxx
new file mode 100644
index 0000000..87116d5
--- /dev/null
+++ b/odb/mysql/tracer.hxx
@@ -0,0 +1,62 @@
+// file : odb/mysql/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_MYSQL_TRACER_HXX
+#define ODB_MYSQL_TRACER_HXX
+
+#include <odb/pre.hxx>
+
+#include <odb/tracer.hxx>
+
+#include <odb/mysql/forward.hxx>
+#include <odb/mysql/details/export.hxx>
+
+namespace odb
+{
+ namespace mysql
+ {
+ 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 mysql::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_MYSQL_TRACER_HXX
diff --git a/odb/mysql/transaction-impl.cxx b/odb/mysql/transaction-impl.cxx
index 24c511f..7aa86a5 100644
--- a/odb/mysql/transaction-impl.cxx
+++ b/odb/mysql/transaction-impl.cxx
@@ -3,6 +3,8 @@
// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
// license : GNU GPL v2; see accompanying LICENSE file
+#include <odb/tracer.hxx>
+
#include <odb/mysql/mysql.hxx>
#include <odb/mysql/database.hxx>
#include <odb/mysql/connection.hxx>
@@ -41,6 +43,12 @@ namespace odb
odb::transaction_impl::connection_ = connection_.get ();
}
+ {
+ odb::tracer* t;
+ if ((t = connection_->tracer ()) || (t = database_.tracer ()))
+ t->execute (*connection_, "BEGIN");
+ }
+
if (mysql_real_query (connection_->handle (), "begin", 5) != 0)
translate_error (*connection_);
}
@@ -50,6 +58,12 @@ namespace odb
{
connection_->clear ();
+ {
+ odb::tracer* t;
+ if ((t = connection_->tracer ()) || (t = database_.tracer ()))
+ t->execute (*connection_, "COMMIT");
+ }
+
if (mysql_real_query (connection_->handle (), "commit", 6) != 0)
translate_error (*connection_);
@@ -63,6 +77,12 @@ namespace odb
{
connection_->clear ();
+ {
+ odb::tracer* t;
+ if ((t = connection_->tracer ()) || (t = database_.tracer ()))
+ t->execute (*connection_, "ROLLBACK");
+ }
+
if (mysql_real_query (connection_->handle (), "rollback", 8) != 0)
translate_error (*connection_);
diff --git a/odb/mysql/transaction.hxx b/odb/mysql/transaction.hxx
index 90182e1..7ef1e17 100644
--- a/odb/mysql/transaction.hxx
+++ b/odb/mysql/transaction.hxx
@@ -12,6 +12,7 @@
#include <odb/mysql/version.hxx>
#include <odb/mysql/forward.hxx>
+#include <odb/mysql/tracer.hxx>
#include <odb/mysql/details/export.hxx>
@@ -51,6 +52,25 @@ namespace odb
static void
current (transaction&);
+ // SQL statement tracing.
+ //
+ public:
+ typedef mysql::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 ();