From 33c8b712edde86572443a0200169262240d2d974 Mon Sep 17 00:00:00 2001
From: Boris Kolpackov <boris@codesynthesis.com>
Date: Thu, 26 Apr 2012 16:45:23 +0200
Subject: Add database::reset()

---
 odb/transaction.cxx | 35 ++++++++++++++++-------------------
 odb/transaction.hxx | 15 ++++++++++++---
 odb/transaction.ixx |  7 +++++++
 3 files changed, 35 insertions(+), 22 deletions(-)

diff --git a/odb/transaction.cxx b/odb/transaction.cxx
index 9099b57..6f92c41 100644
--- a/odb/transaction.cxx
+++ b/odb/transaction.cxx
@@ -18,35 +18,32 @@ namespace odb
   static ODB_TLS_POINTER (transaction) current_transaction;
 
   transaction::
-  transaction (transaction_impl* impl, bool make_current)
-      : finalized_ (false), impl_ (impl)
+  ~transaction ()
+  {
+    if (!finalized_)
+      try {rollback ();} catch (...) {}
+  }
+
+  void transaction::
+  reset (transaction_impl* impl, bool make_current)
   {
+    details::unique_ptr<transaction_impl> i (impl);
+
+    if (!finalized_)
+      rollback ();
+
+    impl_.reset (i.release ());
+
     if (make_current && tls_get (current_transaction) != 0)
       throw already_in_transaction ();
 
     impl_->start ();
+    finalized_ = false;
 
     if (make_current)
       tls_set (current_transaction, this);
   }
 
-  transaction::
-  ~transaction ()
-  {
-    if (!finalized_)
-    {
-      try
-      {
-        rollback ();
-      }
-      catch (...)
-      {
-      }
-    }
-
-    delete impl_;
-  }
-
   bool transaction::
   has_current ()
   {
diff --git a/odb/transaction.hxx b/odb/transaction.hxx
index 8c00508..e75cddd 100644
--- a/odb/transaction.hxx
+++ b/odb/transaction.hxx
@@ -10,6 +10,7 @@
 #include <odb/forward.hxx>
 
 #include <odb/details/export.hxx>
+#include <odb/details/unique-ptr.hxx>
 
 namespace odb
 {
@@ -21,8 +22,8 @@ namespace odb
     typedef odb::database database_type;
     typedef odb::connection connection_type;
 
-    // If the second argument is false, then this transaction is not
-    // made the current transaction of the thread.
+    // If the second argument is false, then this transaction is not made
+    // the current transaction of the thread.
     //
     explicit
     transaction (transaction_impl*, bool make_current = true);
@@ -32,6 +33,14 @@ namespace odb
     //
     ~transaction ();
 
+    // Unless the current transaction has already been finalized (explicitly
+    // committed or rolled back), reset will roll it back. If the second
+    // argument is false, then this transaction is not made the current
+    // transaction of the thread.
+    //
+    void
+    reset (transaction_impl*, bool make_current = true);
+
     void
     commit ();
 
@@ -96,7 +105,7 @@ namespace odb
 
   protected:
     bool finalized_;
-    transaction_impl* impl_;
+    details::unique_ptr<transaction_impl> impl_;
   };
 
   class LIBODB_EXPORT transaction_impl
diff --git a/odb/transaction.ixx b/odb/transaction.ixx
index ad614af..6c6c3c1 100644
--- a/odb/transaction.ixx
+++ b/odb/transaction.ixx
@@ -6,6 +6,13 @@
 
 namespace odb
 {
+  inline transaction::
+  transaction (transaction_impl* impl, bool make_current)
+      : finalized_ (true), impl_ (0)
+  {
+    reset (impl, make_current);
+  }
+
   inline transaction::database_type& transaction::
   database ()
   {
-- 
cgit v1.1