From 78e81069aadc609aee1e4b8137516d9cfce47b0a Mon Sep 17 00:00:00 2001 From: Constantin Michael Date: Wed, 11 May 2011 10:58:27 +0200 Subject: Add transaction implementation --- odb/pgsql/makefile | 4 ++- odb/pgsql/transaction-impl.cxx | 80 ++++++++++++++++++++++++++++++++++++++++++ odb/pgsql/transaction-impl.hxx | 57 ++++++++++++++++++++++++++++++ odb/pgsql/transaction-impl.ixx | 16 +++++++++ odb/pgsql/transaction.cxx | 26 ++++++++++++++ odb/pgsql/transaction.hxx | 60 +++++++++++++++++++++++++++++++ odb/pgsql/transaction.ixx | 41 ++++++++++++++++++++++ 7 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 odb/pgsql/transaction-impl.cxx create mode 100644 odb/pgsql/transaction-impl.hxx create mode 100644 odb/pgsql/transaction-impl.ixx create mode 100644 odb/pgsql/transaction.cxx create mode 100644 odb/pgsql/transaction.hxx create mode 100644 odb/pgsql/transaction.ixx (limited to 'odb') diff --git a/odb/pgsql/makefile b/odb/pgsql/makefile index 722a34d..8b4b316 100644 --- a/odb/pgsql/makefile +++ b/odb/pgsql/makefile @@ -11,7 +11,9 @@ connection.cxx \ connection-factory.cxx \ database.cxx \ error.cxx \ -exceptions.cxx +exceptions.cxx \ +transaction.cxx \ +transaction-impl.cxx cli_tun := details/options.cli cxx_tun := $(cxx) diff --git a/odb/pgsql/transaction-impl.cxx b/odb/pgsql/transaction-impl.cxx new file mode 100644 index 0000000..2d2a988 --- /dev/null +++ b/odb/pgsql/transaction-impl.cxx @@ -0,0 +1,80 @@ +// file : odb/pgsql/transaction-impl.cxx +// author : Constantin Michael +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include + +#include + +#include +#include +#include +#include +#include + +namespace odb +{ + namespace pgsql + { + transaction_impl:: + transaction_impl (database_type& db) + : odb::transaction_impl (db), connection_ (db.connection ()) + { + PGresult* r (PQexec (connection_->handle (), "begin")); + + if (!r) + translate_result_error (*connection_); + + ExecStatusType s (PQresultStatus (r)); + + if (PGRES_COMMAND_OK != s) + translate_result_error (*connection_, r, s); + } + + transaction_impl:: + ~transaction_impl () + { + } + + void transaction_impl:: + commit () + { + // connection_->clear (); + + PGresult* r (PQexec (connection_->handle (), "commit")); + + if (!r) + translate_result_error (*connection_); + + ExecStatusType s (PQresultStatus (r)); + + if (PGRES_COMMAND_OK != s) + translate_result_error (*connection_, r, s); + + // Release the connection. + // + // connection_.reset (); + } + + void transaction_impl:: + rollback () + { + // connection_->clear (); + + PGresult* r (PQexec (connection_->handle (), "rollback")); + + if (!r) + translate_result_error (*connection_); + + ExecStatusType s (PQresultStatus (r)); + + if (PGRES_COMMAND_OK != s) + translate_result_error (*connection_, r, s); + + // Release the connection. + // + //connection_.reset (); + } + } +} diff --git a/odb/pgsql/transaction-impl.hxx b/odb/pgsql/transaction-impl.hxx new file mode 100644 index 0000000..9b4ec56 --- /dev/null +++ b/odb/pgsql/transaction-impl.hxx @@ -0,0 +1,57 @@ +// file : odb/pgsql/transaction-impl.hxx +// author : Constantin Michael +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_PGSQL_TRANSACTION_IMPL_HXX +#define ODB_PGSQL_TRANSACTION_IMPL_HXX + +#include + +#include + +#include +#include + +#include + +#include + +namespace odb +{ + namespace pgsql + { + class LIBODB_PGSQL_EXPORT transaction_impl: public odb::transaction_impl + { + protected: + friend class database; + friend class transaction; + + typedef pgsql::database database_type; + typedef pgsql::connection connection_type; + + transaction_impl (database_type&); + + virtual + ~transaction_impl (); + + virtual void + commit (); + + virtual void + rollback (); + + connection_type& + connection (); + + private: + details::shared_ptr connection_; + }; + } +} + +#include + +#include + +#endif // ODB_PGSQL_TRANSACTION_IMPL_HXX diff --git a/odb/pgsql/transaction-impl.ixx b/odb/pgsql/transaction-impl.ixx new file mode 100644 index 0000000..cd7e0ac --- /dev/null +++ b/odb/pgsql/transaction-impl.ixx @@ -0,0 +1,16 @@ +// file : odb/pgsql/transaction-impl.ixx +// author : Constantin Michael +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +namespace odb +{ + namespace pgsql + { + inline transaction_impl::connection_type& transaction_impl:: + connection () + { + return *connection_; + } + } +} diff --git a/odb/pgsql/transaction.cxx b/odb/pgsql/transaction.cxx new file mode 100644 index 0000000..2632318 --- /dev/null +++ b/odb/pgsql/transaction.cxx @@ -0,0 +1,26 @@ +// file : odb/pgsql/transaction.cxx +// author : Constantin Michael +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include + +namespace odb +{ + namespace pgsql + { + transaction& transaction:: + current () + { + // While the impl type can be of the concrete type, the transaction + // object can be created as either odb:: or odb::pgsql:: type. To + // work around that we are going to hard-cast one to the other + // relying on the fact that they have the same representation and + // no virtual functions. The former is checked in the tests. + // + odb::transaction& b (odb::transaction::current ()); + dynamic_cast (b.implementation ()); + return reinterpret_cast (b); + } + } +} diff --git a/odb/pgsql/transaction.hxx b/odb/pgsql/transaction.hxx new file mode 100644 index 0000000..450842d --- /dev/null +++ b/odb/pgsql/transaction.hxx @@ -0,0 +1,60 @@ +// file : odb/pgsql/transaction.hxx +// author : Constantin Michael +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_PGSQL_TRANSACTION_HXX +#define ODB_PGSQL_TRANSACTION_HXX + +#include + +#include + +#include +#include + +#include + +namespace odb +{ + namespace pgsql + { + class transaction_impl; + + class LIBODB_PGSQL_EXPORT transaction: public odb::transaction + { + public: + typedef pgsql::database database_type; + typedef pgsql::connection connection_type; + + explicit + transaction (transaction_impl*); + + // Return the database this transaction is on. + // + database_type& + database (); + + // Return the underlying database connection for this transaction. + // + connection_type& + connection (); + + // Return current transaction or throw if there is no transaction + // in effect. + // + static transaction& + current (); + + public: + transaction_impl& + implementation (); + }; + } +} + +#include + +#include + +#endif // ODB_PGSQL_TRANSACTION_HXX diff --git a/odb/pgsql/transaction.ixx b/odb/pgsql/transaction.ixx new file mode 100644 index 0000000..d109e97 --- /dev/null +++ b/odb/pgsql/transaction.ixx @@ -0,0 +1,41 @@ +// file : odb/pgsql/transaction.ixx +// author : Constantin Michael +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include +#include + +namespace odb +{ + namespace pgsql + { + inline transaction:: + transaction (transaction_impl* impl) + : odb::transaction (impl) + { + } + + inline transaction_impl& transaction:: + implementation () + { + // We can use static_cast here since we have an instance of + // pgsql::transaction. + // + return static_cast ( + odb::transaction::implementation ()); + } + + inline transaction::database_type& transaction:: + database () + { + return static_cast (odb::transaction::database ()); + } + + inline transaction::connection_type& transaction:: + connection () + { + return implementation ().connection (); + } + } +} -- cgit v1.1