aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-08-21 16:27:34 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-08-21 16:27:34 +0200
commitee570de4bd013fd2a4351d33d11539621f00bf57 (patch)
tree48a7857b2e5fcf799ae4773cbd61252b76ec7512
parent6e3ac760696d4ec43138b1aba82426582c767072 (diff)
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.
-rw-r--r--odb/pgsql/connection-factory.cxx6
-rw-r--r--odb/pgsql/connection-factory.hxx6
-rw-r--r--odb/pgsql/connection.cxx46
-rw-r--r--odb/pgsql/connection.hxx23
-rw-r--r--odb/pgsql/database.cxx45
-rw-r--r--odb/pgsql/database.hxx21
-rw-r--r--odb/pgsql/database.ixx14
-rw-r--r--odb/pgsql/forward.hxx12
-rw-r--r--odb/pgsql/transaction-impl.cxx4
-rw-r--r--odb/pgsql/transaction-impl.hxx6
10 files changed, 116 insertions, 67 deletions
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<connection> new_connection_factory::
+ connection_ptr new_connection_factory::
connect ()
{
- return shared_ptr<connection> (new (shared) connection (*db_));
+ return connection_ptr (new (shared) connection (*db_));
}
void new_connection_factory::
@@ -60,7 +60,7 @@ namespace odb
}
}
- shared_ptr<connection> 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<connection>
+ virtual connection_ptr
connect () = 0;
public:
@@ -49,7 +49,7 @@ namespace odb
{
}
- virtual details::shared_ptr<connection>
+ virtual connection_ptr
connect ();
virtual void
@@ -92,7 +92,7 @@ namespace odb
// @@ check min_ <= max_
}
- virtual details::shared_ptr<connection>
+ 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 <new> // std::bad_alloc
-#include <cstring> // std::strcmp
#include <string>
+#include <cstring> // std::strcmp
+#include <cstdlib> // std::atol
#include <libpq-fe.h>
#include <odb/pgsql/database.hxx>
#include <odb/pgsql/connection.hxx>
+#include <odb/pgsql/transaction.hxx>
#include <odb/pgsql/error.hxx>
#include <odb/pgsql/exceptions.hxx>
#include <odb/pgsql/statement-cache.hxx>
+#include <odb/pgsql/result-ptr.hxx>
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<unsigned long long> (PQntuples (h));
+ else
+ {
+ const char* s (PQcmdTuples (h));
+
+ if (s[0] != '\0' && s[1] == '\0')
+ count = static_cast<unsigned long long> (s[0] - '0');
+ else
+ count = static_cast<unsigned long long> (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 <memory> // std::auto_ptr
#include <odb/forward.hxx>
+#include <odb/connection.hxx>
#include <odb/details/shared-ptr.hxx>
#include <odb/pgsql/version.hxx>
#include <odb/pgsql/forward.hxx>
+#include <odb/pgsql/transaction-impl.hxx>
#include <odb/pgsql/pgsql-fwd.hxx> // PGconn
#include <odb/pgsql/details/export.hxx>
@@ -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> 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 <sstream>
-#include <cstdlib> // std::atol
#include <odb/pgsql/database.hxx>
-#include <odb/pgsql/error.hxx>
#include <odb/pgsql/exceptions.hxx>
+#include <odb/pgsql/connection.hxx>
#include <odb/pgsql/connection-factory.hxx>
-#include <odb/pgsql/transaction.hxx>
-#include <odb/pgsql/result-ptr.hxx>
#include <odb/pgsql/details/options.hxx>
@@ -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<unsigned long long> (PQntuples (h));
- else
- {
- const char* s (PQcmdTuples (h));
-
- if (s[0] != '\0' && s[1] == '\0')
- count = static_cast<unsigned long long> (s[0] - '0');
- else
- count = static_cast<unsigned long long> (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 <odb/pgsql/forward.hxx>
#include <odb/pgsql/connection.hxx>
#include <odb/pgsql/connection-factory.hxx>
-#include <odb/pgsql/transaction-impl.hxx>
#include <odb/pgsql/details/export.hxx>
@@ -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_type>
+ 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::connection_type> 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<pgsql::connection*> (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 <odb/pre.hxx>
+#include <odb/forward.hxx>
+
namespace odb
{
namespace pgsql
{
class database;
class connection;
+ typedef details::shared_ptr<connection> connection_ptr;
class connection_factory;
class transaction;
class query;
@@ -29,6 +32,15 @@ namespace odb
template <typename T>
class container_statements;
}
+
+ namespace details
+ {
+ template <>
+ struct counter_type<pgsql::connection>
+ {
+ typedef shared_base counter;
+ };
+ }
}
#include <odb/post.hxx>
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_type> connection_;
+ connection_ptr connection_;
};
}
}