diff options
-rw-r--r-- | odb/pgsql/makefile | 4 | ||||
-rw-r--r-- | odb/pgsql/transaction-impl.cxx | 80 | ||||
-rw-r--r-- | odb/pgsql/transaction-impl.hxx | 57 | ||||
-rw-r--r-- | odb/pgsql/transaction-impl.ixx | 16 | ||||
-rw-r--r-- | odb/pgsql/transaction.cxx | 26 | ||||
-rw-r--r-- | odb/pgsql/transaction.hxx | 60 | ||||
-rw-r--r-- | odb/pgsql/transaction.ixx | 41 |
7 files changed, 283 insertions, 1 deletions
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 <constantin@codesynthesis.com> +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include <cassert> + +#include <libpq-fe.h> + +#include <odb/pgsql/database.hxx> +#include <odb/pgsql/connection.hxx> +#include <odb/pgsql/error.hxx> +#include <odb/pgsql/exceptions.hxx> +#include <odb/pgsql/transaction-impl.hxx> + +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 <constantin@codesynthesis.com> +// 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 <odb/pre.hxx> + +#include <odb/transaction.hxx> + +#include <odb/pgsql/version.hxx> +#include <odb/pgsql/forward.hxx> + +#include <odb/details/shared-ptr.hxx> + +#include <odb/pgsql/details/export.hxx> + +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_type> connection_; + }; + } +} + +#include <odb/pgsql/transaction-impl.ixx> + +#include <odb/post.hxx> + +#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 <constantin@codesynthesis.com> +// 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 <constantin@codesynthesis.com> +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include <odb/pgsql/transaction.hxx> + +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<transaction_impl&> (b.implementation ()); + return reinterpret_cast<transaction&> (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 <constantin@codesynthesis.com> +// 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 <odb/pre.hxx> + +#include <odb/transaction.hxx> + +#include <odb/pgsql/version.hxx> +#include <odb/pgsql/forward.hxx> + +#include <odb/pgsql/details/export.hxx> + +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 <odb/pgsql/transaction.ixx> + +#include <odb/post.hxx> + +#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 <constantin@codesynthesis.com> +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include <odb/pgsql/database.hxx> +#include <odb/pgsql/transaction-impl.hxx> + +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<transaction_impl&> ( + odb::transaction::implementation ()); + } + + inline transaction::database_type& transaction:: + database () + { + return static_cast<database_type&> (odb::transaction::database ()); + } + + inline transaction::connection_type& transaction:: + connection () + { + return implementation ().connection (); + } + } +} |