From 5b6649e6f7dd256147b48197a007c23001cef647 Mon Sep 17 00:00:00 2001
From: Boris Kolpackov <boris@codesynthesis.com>
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/connection.cxx  | 14 ++++++++++
 odb/connection.hxx  | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 odb/connection.ixx  | 33 ++++++++++++++++++++++++
 odb/database.cxx    | 10 ++++++++
 odb/database.hxx    | 23 +++++++++++++----
 odb/database.ixx    | 12 +++++++++
 odb/forward.hxx     | 13 ++++++++++
 odb/makefile        |  1 +
 odb/transaction.hxx | 18 +++++++++++--
 odb/transaction.ixx |  6 +++++
 10 files changed, 197 insertions(+), 7 deletions(-)
 create mode 100644 odb/connection.cxx
 create mode 100644 odb/connection.hxx
 create mode 100644 odb/connection.ixx

diff --git a/odb/connection.cxx b/odb/connection.cxx
new file mode 100644
index 0000000..3779981
--- /dev/null
+++ b/odb/connection.cxx
@@ -0,0 +1,14 @@
+// file      : odb/connection.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/connection.hxx>
+
+namespace odb
+{
+  connection::
+  ~connection ()
+  {
+  }
+}
diff --git a/odb/connection.hxx b/odb/connection.hxx
new file mode 100644
index 0000000..db8635c
--- /dev/null
+++ b/odb/connection.hxx
@@ -0,0 +1,74 @@
+// file      : odb/connection.hxx
+// author    : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
+// license   : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_CONNECTION_HXX
+#define ODB_CONNECTION_HXX
+
+#include <odb/pre.hxx>
+
+#include <string>
+#include <cstddef> // std::size_t
+
+#include <odb/forward.hxx>
+
+#include <odb/details/export.hxx>
+#include <odb/details/shared-ptr.hxx>
+
+namespace odb
+{
+  class transaction_impl;
+
+  class connection;
+  typedef details::shared_ptr<connection> connection_ptr;
+
+  class LIBODB_EXPORT connection: public details::shared_base
+  {
+  public:
+    typedef odb::database database_type;
+
+    database_type&
+    database ();
+
+    // Transactions.
+    //
+  public:
+    virtual transaction_impl*
+    begin () = 0;
+
+    // Native database statement execution. Note that unlike the
+    // versions in the database class, these can be executed
+    // without a transaction.
+    //
+  public:
+    unsigned long long
+    execute (const char* statement);
+
+    unsigned long long
+    execute (const std::string& statement);
+
+    virtual unsigned long long
+    execute (const char* statement, std::size_t length) = 0;
+
+  public:
+    virtual
+    ~connection ();
+
+  protected:
+    connection (database_type&);
+
+  private:
+    connection (const connection&);
+    connection& operator= (const connection&);
+
+  private:
+    database_type& database_;
+  };
+}
+
+#include <odb/connection.ixx>
+
+#include <odb/post.hxx>
+
+#endif // ODB_MYSQL_CONNECTION_HXX
diff --git a/odb/connection.ixx b/odb/connection.ixx
new file mode 100644
index 0000000..0e6d24c
--- /dev/null
+++ b/odb/connection.ixx
@@ -0,0 +1,33 @@
+// file      : odb/connection.ixx
+// author    : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license   : GNU GPL v2; see accompanying LICENSE file
+
+#include <cstring> // std::string
+
+namespace odb
+{
+  inline connection::
+  connection (database_type& database)
+      : database_ (database)
+  {
+  }
+
+  inline connection::database_type& connection::
+  database ()
+  {
+    return database_;
+  }
+
+  inline unsigned long long connection::
+  execute (const char* st)
+  {
+    return execute (st, std::strlen (st));
+  }
+
+  inline unsigned long long connection::
+  execute (const std::string& st)
+  {
+    return execute (st.c_str (), st.size ());
+  }
+}
diff --git a/odb/database.cxx b/odb/database.cxx
index 89f0260..ca6c7cc 100644
--- a/odb/database.cxx
+++ b/odb/database.cxx
@@ -11,4 +11,14 @@ namespace odb
   ~database ()
   {
   }
+
+  unsigned long long database::
+  execute (const char* st, std::size_t n)
+  {
+    if (!transaction::has_current ())
+      throw not_in_transaction ();
+
+    connection_type& c (transaction::current ().connection ());
+    return c.execute (st, n);
+  }
 }
diff --git a/odb/database.hxx b/odb/database.hxx
index bc7a10b..c4458d9 100644
--- a/odb/database.hxx
+++ b/odb/database.hxx
@@ -15,6 +15,7 @@
 #include <odb/forward.hxx>
 #include <odb/query.hxx>
 #include <odb/result.hxx>
+#include <odb/connection.hxx>
 #include <odb/exceptions.hxx>
 
 #include <odb/details/export.hxx>
@@ -152,19 +153,31 @@ namespace odb
     unsigned long long
     execute (const std::string& statement);
 
-    virtual unsigned long long
-    execute (const char* statement, std::size_t length) = 0;
+    unsigned long long
+    execute (const char* statement, std::size_t length);
+
+    // Transactions.
+    //
+  public:
+    transaction_impl*
+    begin ();
 
-    // Transaction API.
+    // Connections.
     //
   public:
-    virtual transaction_impl*
-    begin () = 0;
+    connection_ptr
+    connection ();
 
   protected:
     database ();
 
   protected:
+    typedef odb::connection connection_type;
+
+    virtual connection_type*
+    connection_ () = 0;
+
+  protected:
     template <typename T>
     typename object_traits<T>::id_type
     persist_ (const typename object_traits<T>::pointer_type&);
diff --git a/odb/database.ixx b/odb/database.ixx
index bd3fb44..a308bfe 100644
--- a/odb/database.ixx
+++ b/odb/database.ixx
@@ -12,6 +12,18 @@ namespace odb
   {
   }
 
+  inline transaction_impl* database::
+  begin ()
+  {
+    return connection ()->begin ();
+  }
+
+  inline connection_ptr database::
+  connection ()
+  {
+    return connection_ptr (connection_ ());
+  }
+
   template <typename T>
   inline typename object_traits<T>::id_type database::
   persist (T* p)
diff --git a/odb/forward.hxx b/odb/forward.hxx
index d51240a..830193c 100644
--- a/odb/forward.hxx
+++ b/odb/forward.hxx
@@ -13,6 +13,8 @@
 namespace odb
 {
   class database;
+  class connection;
+  typedef details::shared_ptr<connection> connection_ptr;
   class transaction;
   class session;
 
@@ -22,6 +24,8 @@ namespace odb
   namespace core
   {
     using odb::database;
+    using odb::connection;
+    using odb::connection_ptr;
     using odb::transaction;
     using odb::session;
     using odb::result;
@@ -51,6 +55,15 @@ namespace odb
 
   template <typename T>
   struct object_traits;
+
+  namespace details
+  {
+    template <>
+    struct counter_type<connection>
+    {
+      typedef shared_base counter;
+    };
+  }
 }
 
 #include <odb/post.hxx>
diff --git a/odb/makefile b/odb/makefile
index 3790bbc..e5c9a0e 100644
--- a/odb/makefile
+++ b/odb/makefile
@@ -8,6 +8,7 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make
 cxx :=             \
 exceptions.cxx     \
 database.cxx       \
+connection.cxx     \
 lazy-ptr-impl.cxx  \
 schema-catalog.cxx \
 session.cxx        \
diff --git a/odb/transaction.hxx b/odb/transaction.hxx
index 17487b2..c2b1f77 100644
--- a/odb/transaction.hxx
+++ b/odb/transaction.hxx
@@ -20,6 +20,7 @@ namespace odb
   {
   public:
     typedef odb::database database_type;
+    typedef odb::connection connection_type;
 
     explicit
     transaction (transaction_impl*);
@@ -40,6 +41,11 @@ namespace odb
     database_type&
     database ();
 
+    // Return the connection this transaction is on.
+    //
+    connection_type&
+    connection ();
+
     // Return current transaction or throw if there is no transaction
     // in effect.
     //
@@ -72,9 +78,10 @@ namespace odb
     friend class transaction;
 
     typedef odb::database database_type;
+    typedef odb::connection connection_type;
 
-    transaction_impl (database_type& db)
-        : database_ (db)
+    transaction_impl (database_type& db, connection_type& c)
+      : database_ (db), connection_ (c)
     {
     }
 
@@ -93,8 +100,15 @@ namespace odb
       return database_;
     }
 
+    connection_type&
+    connection ()
+    {
+      return connection_;
+    }
+
   protected:
     database_type& database_;
+    connection_type& connection_;
   };
 }
 
diff --git a/odb/transaction.ixx b/odb/transaction.ixx
index 4f2ff46..d838a9f 100644
--- a/odb/transaction.ixx
+++ b/odb/transaction.ixx
@@ -11,6 +11,12 @@ namespace odb
     return impl_->database ();
   }
 
+  inline transaction::connection_type& transaction::
+  connection ()
+  {
+    return impl_->connection ();
+  }
+
   inline transaction_impl& transaction::
   implementation ()
   {
-- 
cgit v1.1