aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-11-17 11:31:00 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-11-17 11:31:00 +0200
commit61e6f0fded93f1e2105d7f4734b280712afe0c59 (patch)
treeb462d0b4e27456300c6c21afad21a6d0afa4341e
parent00d972abb9dcbe7c99cd9b94cefc725024cfb4bc (diff)
Add connection, connection-factory implementations
-rw-r--r--odb/mssql/connection-factory.cxx174
-rw-r--r--odb/mssql/connection-factory.hxx164
-rw-r--r--odb/mssql/connection.cxx110
-rw-r--r--odb/mssql/connection.hxx137
-rw-r--r--odb/mssql/database.cxx2
-rw-r--r--odb/mssql/database.hxx16
-rw-r--r--odb/mssql/database.ixx4
-rw-r--r--odb/mssql/makefile13
-rw-r--r--odb/mssql/mssql-fwd.hxx15
-rw-r--r--odb/mssql/odbc.hxx6
-rw-r--r--odb/mssql/transaction-impl.cxx99
-rw-r--r--odb/mssql/transaction-impl.hxx56
-rw-r--r--odb/mssql/transaction-impl.ixx16
13 files changed, 793 insertions, 19 deletions
diff --git a/odb/mssql/connection-factory.cxx b/odb/mssql/connection-factory.cxx
new file mode 100644
index 0000000..5c91fad
--- /dev/null
+++ b/odb/mssql/connection-factory.cxx
@@ -0,0 +1,174 @@
+// file : odb/mssql/connection-factory.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/mssql/connection-factory.hxx>
+#include <odb/mssql/exceptions.hxx>
+
+#include <odb/details/lock.hxx>
+
+using namespace std;
+
+namespace odb
+{
+ using namespace details;
+
+ namespace mssql
+ {
+ //
+ // connection_factory
+ //
+
+ connection_factory::
+ ~connection_factory ()
+ {
+ }
+
+ //
+ // new_connection_factory
+ //
+
+ connection_ptr new_connection_factory::
+ connect ()
+ {
+ return connection_ptr (new (shared) connection (*db_));
+ }
+
+ void new_connection_factory::
+ database (database_type& db)
+ {
+ db_ = &db;
+ }
+
+ //
+ // connection_pool_factory
+ //
+
+ connection_pool_factory::pooled_connection_ptr connection_pool_factory::
+ create ()
+ {
+ return pooled_connection_ptr (new (shared) pooled_connection (*db_));
+ }
+
+ connection_pool_factory::
+ ~connection_pool_factory ()
+ {
+ // Wait for all the connections currently in use to return to
+ // the pool.
+ //
+ lock l (mutex_);
+ while (in_use_ != 0)
+ {
+ waiters_++;
+ cond_.wait ();
+ waiters_--;
+ }
+ }
+
+ connection_ptr connection_pool_factory::
+ connect ()
+ {
+ lock l (mutex_);
+
+ while (true)
+ {
+ // See if we have a spare connection.
+ //
+ if (connections_.size () != 0)
+ {
+ shared_ptr<pooled_connection> c (connections_.back ());
+ connections_.pop_back ();
+
+ c->pool_ = this;
+ in_use_++;
+ return c;
+ }
+
+ // See if we can create a new one.
+ //
+ if (max_ == 0 || in_use_ < max_)
+ {
+ shared_ptr<pooled_connection> c (create ());
+ c->pool_ = this;
+ in_use_++;
+ return c;
+ }
+
+ // Wait until someone releases a connection.
+ //
+ waiters_++;
+ cond_.wait ();
+ waiters_--;
+ }
+ }
+
+ void connection_pool_factory::
+ database (database_type& db)
+ {
+ db_ = &db;
+
+ if (min_ > 0)
+ {
+ connections_.reserve (min_);
+
+ for(size_t i (0); i < min_; ++i)
+ connections_.push_back (create ());
+ }
+ }
+
+ bool connection_pool_factory::
+ release (pooled_connection* c)
+ {
+ c->pool_ = 0;
+
+ lock l (mutex_);
+
+ // Determine if we need to keep or free this connection.
+ //
+ bool keep (!c->failed () &&
+ (waiters_ != 0 ||
+ min_ == 0 ||
+ (connections_.size () + in_use_ <= min_)));
+
+ in_use_--;
+
+ if (keep)
+ connections_.push_back (pooled_connection_ptr (inc_ref (c)));
+
+ if (waiters_ != 0)
+ cond_.signal ();
+
+ return !keep;
+ }
+
+ //
+ // connection_pool_factory::pooled_connection
+ //
+
+ connection_pool_factory::pooled_connection::
+ pooled_connection (database_type& db)
+ : connection (db), pool_ (0)
+ {
+ callback_.arg = this;
+ callback_.zero_counter = &zero_counter;
+ shared_base::callback_ = &callback_;
+ }
+
+ connection_pool_factory::pooled_connection::
+ pooled_connection (database_type& db, SQLHDBC handle)
+ : connection (db, handle), pool_ (0)
+ {
+ callback_.arg = this;
+ callback_.zero_counter = &zero_counter;
+ shared_base::callback_ = &callback_;
+ }
+
+ bool connection_pool_factory::pooled_connection::
+ zero_counter (void* arg)
+ {
+ pooled_connection* c (static_cast<pooled_connection*> (arg));
+ return c->pool_ ? c->pool_->release (c) : true;
+ }
+ }
+}
diff --git a/odb/mssql/connection-factory.hxx b/odb/mssql/connection-factory.hxx
new file mode 100644
index 0000000..d74fef9
--- /dev/null
+++ b/odb/mssql/connection-factory.hxx
@@ -0,0 +1,164 @@
+// file : odb/mssql/connection-factory.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_MSSQL_CONNECTION_FACTORY_HXX
+#define ODB_MSSQL_CONNECTION_FACTORY_HXX
+
+#include <odb/pre.hxx>
+
+#include <vector>
+#include <cstddef> // std::size_t
+
+#include <odb/mssql/version.hxx>
+#include <odb/mssql/forward.hxx>
+#include <odb/mssql/connection.hxx>
+
+#include <odb/details/mutex.hxx>
+#include <odb/details/condition.hxx>
+#include <odb/details/shared-ptr.hxx>
+
+#include <odb/mssql/details/export.hxx>
+
+namespace odb
+{
+ namespace mssql
+ {
+ class LIBODB_MSSQL_EXPORT connection_factory
+ {
+ public:
+ virtual connection_ptr
+ connect () = 0;
+
+ public:
+ typedef mssql::database database_type;
+
+ virtual void
+ database (database_type&) = 0;
+
+ virtual
+ ~connection_factory ();
+ };
+
+ class LIBODB_MSSQL_EXPORT new_connection_factory: public connection_factory
+ {
+ public:
+ new_connection_factory ()
+ : db_ (0)
+ {
+ }
+
+ virtual connection_ptr
+ connect ();
+
+ virtual void
+ database (database_type&);
+
+ private:
+ new_connection_factory (const new_connection_factory&);
+ new_connection_factory& operator= (const new_connection_factory&);
+
+ private:
+ database_type* db_;
+ };
+
+ class LIBODB_MSSQL_EXPORT connection_pool_factory:
+ public connection_factory
+ {
+ public:
+ // The max_connections argument specifies the maximum number of
+ // concurrent connections this pool will maintain. If this value
+ // is 0 then the pool will create a new connection every time all
+ // of the existing connections are in use.
+ //
+ // The min_connections argument specifies the minimum number of
+ // connections that should be maintained by the pool. If the
+ // number of connections maintained by the pool exceeds this
+ // number and there are no active waiters for a new connection,
+ // then the pool will release the excess connections. If this
+ // value is 0 then the pool will maintain all the connections
+ // that were ever created.
+ //
+ connection_pool_factory (std::size_t max_connections = 0,
+ std::size_t min_connections = 0)
+ : max_ (max_connections),
+ min_ (min_connections),
+ in_use_ (0),
+ waiters_ (0),
+ db_ (0),
+ cond_ (mutex_)
+ {
+ // @@ check min_ <= max_
+ }
+
+ virtual connection_ptr
+ connect ();
+
+ virtual void
+ database (database_type&);
+
+ virtual
+ ~connection_pool_factory ();
+
+ private:
+ connection_pool_factory (const connection_pool_factory&);
+ connection_pool_factory& operator= (const connection_pool_factory&);
+
+ protected:
+ class pooled_connection: public connection
+ {
+ public:
+ pooled_connection (database_type&);
+ pooled_connection (database_type&, SQLHDBC);
+
+ private:
+ static bool
+ zero_counter (void*);
+
+ private:
+ friend class connection_pool_factory;
+
+ shared_base::refcount_callback callback_;
+
+ // NULL pool value indicates that the connection is not in use.
+ //
+ connection_pool_factory* pool_;
+ };
+
+ friend class pooled_connection;
+
+ typedef details::shared_ptr<pooled_connection> pooled_connection_ptr;
+ typedef std::vector<pooled_connection_ptr> connections;
+
+ // This function is called whenever the pool needs to create a new
+ // connection.
+ //
+ virtual pooled_connection_ptr
+ create ();
+
+ protected:
+ // Return true if the connection should be deleted, false otherwise.
+ //
+ bool
+ release (pooled_connection*);
+
+ protected:
+ const std::size_t max_;
+ const std::size_t min_;
+
+ std::size_t in_use_; // Number of connections currently in use.
+ std::size_t waiters_; // Number of threads waiting for a connection.
+
+ database_type* db_;
+ connections connections_;
+
+ details::mutex mutex_;
+ details::condition cond_;
+ };
+ }
+}
+
+#include <odb/post.hxx>
+
+#endif // ODB_MSSQL_CONNECTION_FACTORY_HXX
diff --git a/odb/mssql/connection.cxx b/odb/mssql/connection.cxx
new file mode 100644
index 0000000..ff62c49
--- /dev/null
+++ b/odb/mssql/connection.cxx
@@ -0,0 +1,110 @@
+// file : odb/mssql/connection.cxx
+// author : Constantin Michael <constantin@codesynthesis.com>
+// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
+// license : ODB NCUEL; see accompanying LICENSE file
+
+//@@ disabled functionality
+
+//#include <string>
+
+#include <odb/mssql/odbc.hxx>
+#include <odb/mssql/database.hxx>
+#include <odb/mssql/connection.hxx>
+//#include <odb/mssql/transaction.hxx>
+//#include <odb/mssql/statement.hxx>
+//#include <odb/mssql/statement-cache.hxx>
+#include <odb/mssql/error.hxx>
+
+using namespace std;
+
+namespace odb
+{
+ namespace mssql
+ {
+ connection::
+ connection (database_type& db)
+ : odb::connection (db),
+ db_ (db),
+ state_ (state_disconnected)
+ // statement_cache_ (new statement_cache_type (*this))
+ {
+ SQLRETURN r;
+
+ // Allocate the connection handle.
+ //
+ {
+ SQLHANDLE h;
+ r = SQLAllocHandle (SQL_HANDLE_DBC, db_.environment (), &h);
+
+ if (!SQL_SUCCEEDED (r))
+ translate_error (db_.environment (), SQL_HANDLE_ENV);
+
+ handle_.reset (h);
+ }
+
+ // Connect.
+ //
+ {
+ SQLSMALLINT out_conn_str_size;
+ r = SQLDriverConnect (handle_,
+ 0, // Parent windows handle.
+ (SQLCHAR*) db_.connect_string ().c_str (),
+ SQL_NTS,
+ 0, // Output connection string buffer.
+ 0, // Size of output connection string buffer.
+ &out_conn_str_size,
+ SQL_DRIVER_NOPROMPT);
+
+ if (!SQL_SUCCEEDED (r))
+ // Still use the handle version of translate_error since there
+ // is no connection.
+ //
+ translate_error (handle_, SQL_HANDLE_DBC);
+
+ state_ = state_connected;
+ }
+
+ // If an exception is thrown after this line, we will not disconnect
+ // the connection.
+ //
+ }
+
+ connection::
+ connection (database_type& db, SQLHDBC handle)
+ : odb::connection (db),
+ db_ (db),
+ handle_ (handle),
+ state_ (state_connected)
+ // statement_cache_ (new statement_cache_type (*this))
+ {
+ }
+
+ connection::
+ ~connection ()
+ {
+ // Deallocate prepared statements before we close the connection.
+ //
+ //statement_cache_.reset ();
+
+ if (state_ != state_disconnected)
+ SQLDisconnect (handle_); // Ignore any errors.
+ }
+
+ transaction_impl* connection::
+ begin ()
+ {
+ //@@
+ //return new transaction_impl (connection_ptr (inc_ref (this)));
+ return 0;
+ }
+
+ unsigned long long connection::
+ execute (const char* /*s*/, std::size_t /*n*/)
+ {
+ //@@
+ //generic_statement st (*this, string (s, n));
+ //return st.execute ();
+ return 0;
+ }
+ }
+}
diff --git a/odb/mssql/connection.hxx b/odb/mssql/connection.hxx
new file mode 100644
index 0000000..fea9035
--- /dev/null
+++ b/odb/mssql/connection.hxx
@@ -0,0 +1,137 @@
+// file : odb/mssql/connection.hxx
+// author : Constantin Michael <constantin@codesynthesis.com>
+// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
+// license : ODB NCUEL; see accompanying LICENSE file
+
+//@@ disabled functionality
+
+#ifndef ODB_MSSQL_CONNECTION_HXX
+#define ODB_MSSQL_CONNECTION_HXX
+
+#include <odb/pre.hxx>
+
+#include <memory> // std::auto_ptr
+
+#include <odb/forward.hxx>
+#include <odb/connection.hxx>
+
+#include <odb/details/shared-ptr.hxx>
+
+#include <odb/mssql/version.hxx>
+#include <odb/mssql/forward.hxx>
+//#include <odb/mssql/tracer.hxx>
+#include <odb/mssql/transaction-impl.hxx>
+#include <odb/mssql/auto-handle.hxx>
+#include <odb/mssql/mssql-fwd.hxx>
+
+#include <odb/mssql/details/export.hxx>
+
+namespace odb
+{
+ namespace mssql
+ {
+ class statement_cache;
+
+ class connection;
+ typedef details::shared_ptr<connection> connection_ptr;
+
+ class LIBODB_MSSQL_EXPORT connection: public odb::connection
+ {
+ public:
+ typedef mssql::statement_cache statement_cache_type;
+ typedef mssql::database database_type;
+
+ virtual
+ ~connection ();
+
+ connection (database_type&);
+ connection (database_type&, SQLHDBC handle);
+
+ database_type&
+ database ()
+ {
+ return db_;
+ }
+
+ public:
+ virtual transaction_impl*
+ begin ();
+
+ public:
+ using odb::connection::execute;
+
+ virtual unsigned long long
+ execute (const char* statement, std::size_t length);
+
+ // SQL statement tracing.
+ //
+ public:
+ /*
+ typedef mssql::tracer tracer_type;
+
+ void
+ tracer (tracer_type& t)
+ {
+ odb::connection::tracer (t);
+ }
+
+ void
+ tracer (tracer_type* t)
+ {
+ odb::connection::tracer (t);
+ }
+
+ using odb::connection::tracer;
+ */
+
+ public:
+ bool
+ failed () const
+ {
+ return state_ == state_failed;
+ }
+
+ void
+ mark_failed ()
+ {
+ state_ = state_failed;
+ }
+
+ public:
+ SQLHDBC
+ handle ()
+ {
+ return handle_;
+ }
+
+ /*
+ statement_cache_type&
+ statement_cache ()
+ {
+ return *statement_cache_;
+ }
+ */
+
+ private:
+ connection (const connection&);
+ connection& operator= (const connection&);
+
+ private:
+ database_type& db_;
+ auto_handle<SQL_HANDLE_DBC> handle_;
+
+ enum
+ {
+ state_disconnected,
+ state_connected,
+ state_failed
+ } state_;
+
+ //std::auto_ptr<statement_cache_type> statement_cache_;
+ };
+ }
+}
+
+#include <odb/post.hxx>
+
+#endif // ODB_MSSQL_CONNECTION_HXX
diff --git a/odb/mssql/database.cxx b/odb/mssql/database.cxx
index b6ef146..51010ac 100644
--- a/odb/mssql/database.cxx
+++ b/odb/mssql/database.cxx
@@ -228,7 +228,6 @@ namespace odb
{
}
- /*
transaction_impl* database::
begin ()
{
@@ -241,6 +240,5 @@ namespace odb
connection_ptr c (factory_->connect ());
return c.release ();
}
- */
}
}
diff --git a/odb/mssql/database.hxx b/odb/mssql/database.hxx
index d5d5597..f82d7c9 100644
--- a/odb/mssql/database.hxx
+++ b/odb/mssql/database.hxx
@@ -19,8 +19,8 @@
#include <odb/mssql/version.hxx>
#include <odb/mssql/forward.hxx>
//#include <odb/mssql/tracer.hxx>
-//#include <odb/mssql/connection.hxx>
-//#include <odb/mssql/connection-factory.hxx>
+#include <odb/mssql/connection.hxx>
+#include <odb/mssql/connection-factory.hxx>
#include <odb/mssql/auto-handle.hxx>
#include <odb/mssql/mssql-fwd.hxx>
@@ -84,12 +84,12 @@ namespace odb
public:
- //virtual transaction_impl*
- //begin ();
+ virtual transaction_impl*
+ begin ();
public:
- //connection_ptr
- //connection ();
+ connection_ptr
+ connection ();
public:
/*
@@ -168,8 +168,8 @@ namespace odb
~database ();
protected:
- //virtual odb::connection*
- //connection_ ();
+ virtual odb::connection*
+ connection_ ();
private:
/*
diff --git a/odb/mssql/database.ixx b/odb/mssql/database.ixx
index 3c8bf8e..bd84527 100644
--- a/odb/mssql/database.ixx
+++ b/odb/mssql/database.ixx
@@ -3,13 +3,10 @@
// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
// license : ODB NCUEL; see accompanying LICENSE file
-//@@ disabled functionality
-
namespace odb
{
namespace mssql
{
- /*
inline connection_ptr database::
connection ()
{
@@ -19,6 +16,5 @@ namespace odb
return connection_ptr (
static_cast<mssql::connection*> (connection_ ()));
}
- */
}
}
diff --git a/odb/mssql/makefile b/odb/mssql/makefile
index 70fc9c6..10e9e28 100644
--- a/odb/mssql/makefile
+++ b/odb/mssql/makefile
@@ -6,11 +6,14 @@
include $(dir $(lastword $(MAKEFILE_LIST)))../../build/bootstrap.make
-cxx := \
-auto-handle.cxx \
-database.cxx \
-error.cxx \
-exceptions.cxx
+cxx := \
+auto-handle.cxx \
+connection.cxx \
+connection-factory.cxx \
+database.cxx \
+error.cxx \
+exceptions.cxx \
+transaction-impl.cxx
cli_tun := details/options.cli
diff --git a/odb/mssql/mssql-fwd.hxx b/odb/mssql/mssql-fwd.hxx
index c837cd5..bee639b 100644
--- a/odb/mssql/mssql-fwd.hxx
+++ b/odb/mssql/mssql-fwd.hxx
@@ -22,6 +22,21 @@ typedef unsigned short SQLUSMALLINT;
typedef void* SQLHANDLE;
typedef SQLHANDLE SQLHENV;
+typedef SQLHANDLE SQLHDBC;
+typedef SQLHANDLE SQLHSTMT;
+typedef SQLHANDLE SQLHDESC;
+
+// If you get a redefinition error or warning for one of these macros,
+// then that means you included this header (or one that includes it),
+// before <sql.h> or <sqlext.h>. As a general rule, include <sql.h> or
+// <sqlext.h> before any of the ODB headers.
+//
+#ifndef SQL_HANDLE_ENV
+# define SQL_HANDLE_ENV 1
+# define SQL_HANDLE_DBC 2
+# define SQL_HANDLE_STMT 3
+# define SQL_HANDLE_DESC 4
+#endif
#include <odb/post.hxx>
diff --git a/odb/mssql/odbc.hxx b/odb/mssql/odbc.hxx
index 91023b3..7276a40 100644
--- a/odb/mssql/odbc.hxx
+++ b/odb/mssql/odbc.hxx
@@ -8,6 +8,12 @@
#include <odb/pre.hxx>
+// This file should always be included before mssql-fwd.hxx.
+//
+#ifdef ODB_MSSQL_MSSQL_FWD_HXX
+# error odb/mssql/mssql-fwd.hxx included before odb/mssql/odbc.hxx
+#endif
+
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
diff --git a/odb/mssql/transaction-impl.cxx b/odb/mssql/transaction-impl.cxx
new file mode 100644
index 0000000..4d0d77f
--- /dev/null
+++ b/odb/mssql/transaction-impl.cxx
@@ -0,0 +1,99 @@
+// file : odb/mssql/transaction-impl.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/tracer.hxx>
+
+#include <odb/mssql/database.hxx>
+#include <odb/mssql/connection.hxx>
+#include <odb/mssql/transaction-impl.hxx>
+#include <odb/mssql/error.hxx>
+
+namespace odb
+{
+ namespace mssql
+ {
+ transaction_impl::
+ transaction_impl (database_type& db)
+ : odb::transaction_impl (db)
+ {
+ }
+
+ transaction_impl::
+ transaction_impl (connection_ptr c)
+ : odb::transaction_impl (c->database (), *c), connection_ (c)
+ {
+ }
+
+ transaction_impl::
+ ~transaction_impl ()
+ {
+ }
+
+ void transaction_impl::
+ start ()
+ {
+ /*
+ // Grab a connection if we don't already have one.
+ //
+ if (connection_ == 0)
+ {
+ connection_ = static_cast<database_type&> (database_).connection ();
+ odb::transaction_impl::connection_ = connection_.get ();
+ }
+
+ {
+ odb::tracer* t;
+ if ((t = connection_->tracer ()) || (t = database_.tracer ()))
+ t->execute (*connection_, "BEGIN");
+ }
+
+ if (mssql_real_query (connection_->handle (), "begin", 5) != 0)
+ translate_error (*connection_);
+ */
+ }
+
+ void transaction_impl::
+ commit ()
+ {
+ /*
+ connection_->clear ();
+
+ {
+ odb::tracer* t;
+ if ((t = connection_->tracer ()) || (t = database_.tracer ()))
+ t->execute (*connection_, "COMMIT");
+ }
+
+ if (mssql_real_query (connection_->handle (), "commit", 6) != 0)
+ translate_error (*connection_);
+
+ // Release the connection.
+ //
+ //connection_.reset ();
+ */
+ }
+
+ void transaction_impl::
+ rollback ()
+ {
+ /*
+ connection_->clear ();
+
+ {
+ odb::tracer* t;
+ if ((t = connection_->tracer ()) || (t = database_.tracer ()))
+ t->execute (*connection_, "ROLLBACK");
+ }
+
+ if (mssql_real_query (connection_->handle (), "rollback", 8) != 0)
+ translate_error (*connection_);
+
+ // Release the connection.
+ //
+ //connection_.reset ();
+ */
+ }
+ }
+}
diff --git a/odb/mssql/transaction-impl.hxx b/odb/mssql/transaction-impl.hxx
new file mode 100644
index 0000000..57d9d5b
--- /dev/null
+++ b/odb/mssql/transaction-impl.hxx
@@ -0,0 +1,56 @@
+// file : odb/mssql/transaction-impl.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_MSSQL_TRANSACTION_IMPL_HXX
+#define ODB_MSSQL_TRANSACTION_IMPL_HXX
+
+#include <odb/pre.hxx>
+
+#include <odb/transaction.hxx>
+
+#include <odb/mssql/version.hxx>
+#include <odb/mssql/forward.hxx>
+
+#include <odb/mssql/details/export.hxx>
+
+namespace odb
+{
+ namespace mssql
+ {
+ class LIBODB_MSSQL_EXPORT transaction_impl: public odb::transaction_impl
+ {
+ public:
+ typedef mssql::database database_type;
+ typedef mssql::connection connection_type;
+
+ transaction_impl (database_type&);
+ transaction_impl (connection_ptr);
+
+ virtual
+ ~transaction_impl ();
+
+ virtual void
+ start ();
+
+ virtual void
+ commit ();
+
+ virtual void
+ rollback ();
+
+ connection_type&
+ connection ();
+
+ private:
+ connection_ptr connection_;
+ };
+ }
+}
+
+#include <odb/mssql/transaction-impl.ixx>
+
+#include <odb/post.hxx>
+
+#endif // ODB_MSSQL_TRANSACTION_IMPL_HXX
diff --git a/odb/mssql/transaction-impl.ixx b/odb/mssql/transaction-impl.ixx
new file mode 100644
index 0000000..d675224
--- /dev/null
+++ b/odb/mssql/transaction-impl.ixx
@@ -0,0 +1,16 @@
+// file : odb/mssql/transaction-impl.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+namespace odb
+{
+ namespace mssql
+ {
+ inline transaction_impl::connection_type& transaction_impl::
+ connection ()
+ {
+ return *connection_;
+ }
+ }
+}