From ee570de4bd013fd2a4351d33d11539621f00bf57 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/pgsql/connection-factory.cxx | 6 +++--- odb/pgsql/connection-factory.hxx | 6 +++--- odb/pgsql/connection.cxx | 46 ++++++++++++++++++++++++++++++++++++++-- odb/pgsql/connection.hxx | 23 +++++++++++++++++++- odb/pgsql/database.cxx | 45 +++++---------------------------------- odb/pgsql/database.hxx | 21 +++++++++--------- odb/pgsql/database.ixx | 14 ++++++++++-- odb/pgsql/forward.hxx | 12 +++++++++++ odb/pgsql/transaction-impl.cxx | 4 ++-- odb/pgsql/transaction-impl.hxx | 6 +++--- 10 files changed, 116 insertions(+), 67 deletions(-) (limited to 'odb/pgsql') diff --git a/odb/pgsql/connection-factory.cxx b/odb/pgsql/connection-factory.cxx index 45d86cd..c9e758d 100644 --- a/odb/pgsql/connection-factory.cxx +++ b/odb/pgsql/connection-factory.cxx @@ -29,10 +29,10 @@ namespace odb // new_connection_factory // - shared_ptr new_connection_factory:: + connection_ptr new_connection_factory:: connect () { - return shared_ptr (new (shared) connection (*db_)); + return connection_ptr (new (shared) connection (*db_)); } void new_connection_factory:: @@ -60,7 +60,7 @@ namespace odb } } - shared_ptr connection_pool_factory:: + connection_ptr connection_pool_factory:: connect () { lock l (mutex_); diff --git a/odb/pgsql/connection-factory.hxx b/odb/pgsql/connection-factory.hxx index d90b7cb..8a7b9c8 100644 --- a/odb/pgsql/connection-factory.hxx +++ b/odb/pgsql/connection-factory.hxx @@ -28,7 +28,7 @@ namespace odb class LIBODB_PGSQL_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 @@ -92,7 +92,7 @@ namespace odb // @@ check min_ <= max_ } - virtual details::shared_ptr + virtual connection_ptr connect (); virtual void diff --git a/odb/pgsql/connection.cxx b/odb/pgsql/connection.cxx index 36a5713..808cdbb 100644 --- a/odb/pgsql/connection.cxx +++ b/odb/pgsql/connection.cxx @@ -4,16 +4,19 @@ // license : GNU GPL v2; see accompanying LICENSE file #include // std::bad_alloc -#include // std::strcmp #include +#include // std::strcmp +#include // std::atol #include #include #include +#include #include #include #include +#include using namespace std; @@ -28,7 +31,8 @@ namespace odb { connection:: connection (database_type& db) - : db_ (db), + : odb::connection (db), + db_ (db), handle_ (0), statement_cache_ (new statement_cache_type (*this)) { @@ -65,5 +69,43 @@ namespace odb PQfinish (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) + { + // The string may not be '\0'-terminated. + // + string str (s, n); + + result_ptr r (PQexec (handle_, str.c_str ())); + PGresult* h (r.get ()); + + unsigned long long count (0); + + if (!is_good_result (h)) + translate_error (*this, h); + else if (PGRES_TUPLES_OK == PQresultStatus (h)) + count = static_cast (PQntuples (h)); + else + { + const char* s (PQcmdTuples (h)); + + if (s[0] != '\0' && s[1] == '\0') + count = static_cast (s[0] - '0'); + else + count = static_cast (atol (s)); + } + + return count; + } } } diff --git a/odb/pgsql/connection.hxx b/odb/pgsql/connection.hxx index 6914d5b..2e7679c 100644 --- a/odb/pgsql/connection.hxx +++ b/odb/pgsql/connection.hxx @@ -12,11 +12,13 @@ #include // std::auto_ptr #include +#include #include #include #include +#include #include // PGconn #include @@ -28,7 +30,10 @@ namespace odb class statement; class statement_cache; - class LIBODB_PGSQL_EXPORT connection: public details::shared_base + class connection; + typedef details::shared_ptr connection_ptr; + + class LIBODB_PGSQL_EXPORT connection: public odb::connection { public: typedef pgsql::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: PGconn* handle () { diff --git a/odb/pgsql/database.cxx b/odb/pgsql/database.cxx index 721e600..050961f 100644 --- a/odb/pgsql/database.cxx +++ b/odb/pgsql/database.cxx @@ -4,14 +4,11 @@ // license : GNU GPL v2; see accompanying LICENSE file #include -#include // std::atol #include -#include #include +#include #include -#include -#include #include @@ -211,43 +208,11 @@ namespace odb { } - unsigned long long database:: - execute (const char* s, std::size_t) + odb::connection* database:: + connection_ () { - if (!transaction::has_current ()) - throw not_in_transaction (); - - connection_type& c (transaction::current ().connection ()); - - result_ptr r (PQexec (c.handle (), s)); - PGresult* h (r.get ()); - - unsigned long long count (0); - - if (!is_good_result (h)) - translate_error (c, h); - else if (PGRES_TUPLES_OK == PQresultStatus (h)) - count = static_cast (PQntuples (h)); - else - { - const char* s (PQcmdTuples (h)); - - if (s[0] != '\0' && s[1] == '\0') - count = static_cast (s[0] - '0'); - else - count = static_cast (atol (s)); - } - - return count; - } - - 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/pgsql/database.hxx b/odb/pgsql/database.hxx index b4917cc..d3d8f7d 100644 --- a/odb/pgsql/database.hxx +++ b/odb/pgsql/database.hxx @@ -20,7 +20,6 @@ #include #include #include -#include #include @@ -28,12 +27,11 @@ namespace odb { namespace pgsql { + class transaction_impl; + class LIBODB_PGSQL_EXPORT database: public odb::database { public: - typedef pgsql::connection connection_type; - - public: database (const std::string& user, const std::string& password, const std::string& db, @@ -82,23 +80,24 @@ namespace odb static void print_usage (std::ostream&); + // Transactions. + // 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_ (); + public: const std::string& user () const diff --git a/odb/pgsql/database.ixx b/odb/pgsql/database.ixx index a4f5040..467f765 100644 --- a/odb/pgsql/database.ixx +++ b/odb/pgsql/database.ixx @@ -7,10 +7,20 @@ namespace odb { namespace pgsql { - 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/pgsql/forward.hxx b/odb/pgsql/forward.hxx index 8b8ac90..046942d 100644 --- a/odb/pgsql/forward.hxx +++ b/odb/pgsql/forward.hxx @@ -8,12 +8,15 @@ #include +#include + namespace odb { namespace pgsql { 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/pgsql/transaction-impl.cxx b/odb/pgsql/transaction-impl.cxx index eb93361..81aaf08 100644 --- a/odb/pgsql/transaction-impl.cxx +++ b/odb/pgsql/transaction-impl.cxx @@ -19,8 +19,8 @@ namespace odb namespace pgsql { 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) { result_ptr r (PQexec (connection_->handle (), "begin")); PGresult* h (r.get ()); diff --git a/odb/pgsql/transaction-impl.hxx b/odb/pgsql/transaction-impl.hxx index 9b4ec56..d3a76ce 100644 --- a/odb/pgsql/transaction-impl.hxx +++ b/odb/pgsql/transaction-impl.hxx @@ -24,13 +24,13 @@ namespace odb class LIBODB_PGSQL_EXPORT transaction_impl: public odb::transaction_impl { protected: - friend class database; + friend class connection; friend class transaction; typedef pgsql::database database_type; typedef pgsql::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