From e84fa8e3b8defe24a00e14ba046e8e71b438ce0b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 21 Aug 2011 16:27:34 +0200 Subject: Add odb::connection class This abstract class represents a connection to the database. One can use it to start a transaction or to execute a native statement out of a transaction. Before we had concrete connection classes in the database runtime libraries (e.g., odb::mysql::connection). Now these classes derive from odb::connection. --- odb/mysql/connection-factory.cxx | 6 ++--- odb/mysql/connection-factory.hxx | 6 ++--- odb/mysql/connection.cxx | 42 ++++++++++++++++++++++++++++++++++- odb/mysql/connection.hxx | 23 ++++++++++++++++++- odb/mysql/database.cxx | 48 ++++------------------------------------ odb/mysql/database.hxx | 20 +++++++---------- odb/mysql/database.ixx | 14 ++++++++++-- odb/mysql/forward.hxx | 12 ++++++++++ odb/mysql/transaction-impl.cxx | 4 ++-- odb/mysql/transaction-impl.hxx | 6 ++--- 10 files changed, 110 insertions(+), 71 deletions(-) diff --git a/odb/mysql/connection-factory.cxx b/odb/mysql/connection-factory.cxx index 225ef9a..2da8235 100644 --- a/odb/mysql/connection-factory.cxx +++ b/odb/mysql/connection-factory.cxx @@ -131,12 +131,12 @@ namespace odb // new_connection_factory // - shared_ptr new_connection_factory:: + connection_ptr new_connection_factory:: connect () { tls_get (mysql_thread_init_); - return shared_ptr (new (shared) connection (*db_)); + return connection_ptr (new (shared) connection (*db_)); } void new_connection_factory:: @@ -164,7 +164,7 @@ namespace odb } } - shared_ptr connection_pool_factory:: + connection_ptr connection_pool_factory:: connect () { tls_get (mysql_thread_init_); diff --git a/odb/mysql/connection-factory.hxx b/odb/mysql/connection-factory.hxx index eb7380c..399fdae 100644 --- a/odb/mysql/connection-factory.hxx +++ b/odb/mysql/connection-factory.hxx @@ -28,7 +28,7 @@ namespace odb class LIBODB_MYSQL_EXPORT connection_factory { public: - virtual details::shared_ptr + virtual connection_ptr connect () = 0; public: @@ -49,7 +49,7 @@ namespace odb { } - virtual details::shared_ptr + virtual connection_ptr connect (); virtual void @@ -97,7 +97,7 @@ namespace odb // @@ check min_ <= max_ } - virtual details::shared_ptr + virtual connection_ptr connect (); virtual void diff --git a/odb/mysql/connection.cxx b/odb/mysql/connection.cxx index 3f4a664..fe4996f 100644 --- a/odb/mysql/connection.cxx +++ b/odb/mysql/connection.cxx @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -21,7 +22,8 @@ namespace odb { connection:: connection (database_type& db) - : db_ (db), + : odb::connection (db), + db_ (db), failed_ (false), handle_ (&mysql_), active_ (0), @@ -72,6 +74,44 @@ namespace odb mysql_close (handle_); } + transaction_impl* connection:: + begin () + { + if (transaction::has_current ()) + throw already_in_transaction (); + + return new transaction_impl (connection_ptr (inc_ref (this))); + } + + unsigned long long connection:: + execute (const char* s, std::size_t n) + { + clear (); + + if (mysql_real_query (handle_, s, static_cast (n))) + translate_error (*this); + + // Get the affected row count, if any. If the statement has a result + // set (e.g., SELECT), we first need to call mysql_store_result(). + // + unsigned long long r (0); + + if (mysql_field_count (handle_) == 0) + r = static_cast (mysql_affected_rows (handle_)); + else + { + if (MYSQL_RES* rs = mysql_store_result (handle_)) + { + r = static_cast (mysql_num_rows (rs)); + mysql_free_result (rs); + } + else + translate_error (*this); + } + + return r; + } + bool connection:: ping () { diff --git a/odb/mysql/connection.hxx b/odb/mysql/connection.hxx index 89103c7..7db9230 100644 --- a/odb/mysql/connection.hxx +++ b/odb/mysql/connection.hxx @@ -12,10 +12,12 @@ #include // std::auto_ptr #include +#include #include #include #include +#include #include @@ -28,7 +30,10 @@ namespace odb class statement; class statement_cache; - class LIBODB_MYSQL_EXPORT connection: public details::shared_base + class connection; + typedef details::shared_ptr connection_ptr; + + class LIBODB_MYSQL_EXPORT connection: public odb::connection { public: typedef mysql::statement_cache statement_cache_type; @@ -46,6 +51,22 @@ namespace odb } public: + virtual transaction_impl* + begin (); + + transaction_impl* + begin_immediate (); + + transaction_impl* + begin_exclusive (); + + public: + using odb::connection::execute; + + virtual unsigned long long + execute (const char* statement, std::size_t length); + + public: bool failed () const { diff --git a/odb/mysql/database.cxx b/odb/mysql/database.cxx index 31d6c7b..dc78bce 100644 --- a/odb/mysql/database.cxx +++ b/odb/mysql/database.cxx @@ -5,12 +5,9 @@ #include -#include #include -#include #include #include -#include #include #include @@ -211,48 +208,11 @@ namespace odb details::options::print_usage (os); } - unsigned long long database:: - execute (const char* s, std::size_t n) + odb::connection* database:: + connection_ () { - if (!transaction::has_current ()) - throw not_in_transaction (); - - connection_type& c (transaction::current ().connection ()); - c.clear (); - - MYSQL* h (c.handle ()); - - if (mysql_real_query (h, s, static_cast (n))) - translate_error (c); - - // Get the affected row count, if any. If the statement has a result - // set (e.g., SELECT), we first need to call mysql_store_result(). - // - unsigned long long r (0); - - if (mysql_field_count (h) == 0) - r = static_cast (mysql_affected_rows (h)); - else - { - if (MYSQL_RES* rs = mysql_store_result (h)) - { - r = static_cast (mysql_num_rows (rs)); - mysql_free_result (rs); - } - else - translate_error (c); - } - - return r; - } - - transaction_impl* database:: - begin () - { - if (transaction::has_current ()) - throw already_in_transaction (); - - return new transaction_impl (*this); + connection_ptr c (factory_->connect ()); + return c.release (); } } } diff --git a/odb/mysql/database.hxx b/odb/mysql/database.hxx index 5e2ebc6..37b966f 100644 --- a/odb/mysql/database.hxx +++ b/odb/mysql/database.hxx @@ -19,7 +19,6 @@ #include #include #include -#include #include @@ -29,12 +28,11 @@ namespace odb { namespace mysql { + class transaction_impl; + class LIBODB_MYSQL_EXPORT database: public odb::database { public: - typedef mysql::connection connection_type; - - public: // In MySQL, NULL and empty string are treated as the same value // for all the arguments except passwd and socket. // @@ -159,23 +157,21 @@ namespace odb } public: - using odb::database::execute; - - virtual unsigned long long - execute (const char* statement, std::size_t length); - - public: - virtual transaction_impl* + transaction_impl* begin (); public: - details::shared_ptr + connection_ptr connection (); public: virtual ~database (); + protected: + virtual odb::connection* + connection_ (); + private: std::string user_; std::string passwd_str_; diff --git a/odb/mysql/database.ixx b/odb/mysql/database.ixx index 5791222..399fbdc 100644 --- a/odb/mysql/database.ixx +++ b/odb/mysql/database.ixx @@ -7,10 +7,20 @@ namespace odb { namespace mysql { - inline details::shared_ptr database:: + inline connection_ptr database:: connection () { - return factory_->connect (); + // Go through the virtual connection_() function instead of + // directly to allow overriding. + // + return connection_ptr ( + static_cast (connection_ ())); + } + + inline transaction_impl* database:: + begin () + { + return connection ()->begin (); } } } diff --git a/odb/mysql/forward.hxx b/odb/mysql/forward.hxx index 75aeff0..94b175b 100644 --- a/odb/mysql/forward.hxx +++ b/odb/mysql/forward.hxx @@ -8,12 +8,15 @@ #include +#include + namespace odb { namespace mysql { class database; class connection; + typedef details::shared_ptr connection_ptr; class connection_factory; class transaction; class query; @@ -29,6 +32,15 @@ namespace odb template class container_statements; } + + namespace details + { + template <> + struct counter_type + { + typedef shared_base counter; + }; + } } #include diff --git a/odb/mysql/transaction-impl.cxx b/odb/mysql/transaction-impl.cxx index 659dc56..86cccbe 100644 --- a/odb/mysql/transaction-impl.cxx +++ b/odb/mysql/transaction-impl.cxx @@ -14,8 +14,8 @@ namespace odb namespace mysql { transaction_impl:: - transaction_impl (database_type& db) - : odb::transaction_impl (db), connection_ (db.connection ()) + transaction_impl (connection_ptr c) + : odb::transaction_impl (c->database (), *c), connection_ (c) { if (mysql_real_query (connection_->handle (), "begin", 5) != 0) translate_error (*connection_); diff --git a/odb/mysql/transaction-impl.hxx b/odb/mysql/transaction-impl.hxx index a15ac8b..a8aa491 100644 --- a/odb/mysql/transaction-impl.hxx +++ b/odb/mysql/transaction-impl.hxx @@ -24,13 +24,13 @@ namespace odb class LIBODB_MYSQL_EXPORT transaction_impl: public odb::transaction_impl { protected: - friend class database; + friend class connection; friend class transaction; typedef mysql::database database_type; typedef mysql::connection connection_type; - transaction_impl (database_type&); + transaction_impl (connection_ptr); virtual ~transaction_impl (); @@ -45,7 +45,7 @@ namespace odb connection (); private: - details::shared_ptr connection_; + connection_ptr connection_; }; } } -- cgit v1.1