From bcf5fce175953bec0fd2725968828850a74d8539 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 7 Nov 2011 15:00:06 +0200 Subject: Add support for SQL statement tracing --- odb/connection.hxx | 31 +++++++++++++++++++++++++++- odb/connection.ixx | 26 +++++++++++++++++++++++- odb/database.hxx | 23 ++++++++++++++++++--- odb/database.ixx | 19 ++++++++++++++++++ odb/forward.hxx | 13 ++++++++++++ odb/makefile | 2 ++ odb/statement.cxx | 14 +++++++++++++ odb/statement.hxx | 38 +++++++++++++++++++++++++++++++++++ odb/tracer.cxx | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++ odb/tracer.hxx | 38 +++++++++++++++++++++++++++++++++++ odb/transaction.cxx | 4 +++- odb/transaction.hxx | 15 ++++++++++++++ odb/transaction.ixx | 23 +++++++++++++++++++++ 13 files changed, 298 insertions(+), 6 deletions(-) create mode 100644 odb/statement.cxx create mode 100644 odb/statement.hxx create mode 100644 odb/tracer.cxx create mode 100644 odb/tracer.hxx 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 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 inline typename object_traits::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 +#include #include namespace odb @@ -16,6 +17,7 @@ namespace odb class connection; typedef details::shared_ptr 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 +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include + +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 +// 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 + +#include + +#include +#include + +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 + +#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 +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include + +#include +#include + +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 +// 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 + +#include +#include + +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 + +#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 #include +#include #include @@ -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 + 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_; + } } -- cgit v1.1