From f1d06b7994d8b0aa31f86288183f46509bb78c19 Mon Sep 17 00:00:00 2001
From: Boris Kolpackov <boris@codesynthesis.com>
Date: Fri, 30 Apr 2021 10:03:56 +0200
Subject: Add transaction::connection(database&) overload

---
 odb/connection.hxx  |  9 +++++----
 odb/connection.ixx  |  4 ++--
 odb/database.cxx    |  2 +-
 odb/database.hxx    |  4 ++--
 odb/database.ixx    | 16 ++++++++--------
 odb/database.txx    |  4 ++--
 odb/transaction.cxx | 26 ++++++++++++++++++++++++--
 odb/transaction.hxx | 22 +++++++++++++++++-----
 odb/transaction.ixx | 17 ++++++++++-------
 9 files changed, 71 insertions(+), 33 deletions(-)

diff --git a/odb/connection.hxx b/odb/connection.hxx
index 57d9dc3..8ce4544 100644
--- a/odb/connection.hxx
+++ b/odb/connection.hxx
@@ -89,11 +89,11 @@ namespace odb
 
     template <typename T>
     prepared_query<T>
-    lookup_query (const char* name) const;
+    lookup_query (const char* name);
 
     template <typename T, typename P>
     prepared_query<T>
-    lookup_query (const char* name, P*& params) const;
+    lookup_query (const char* name, P*& params);
 
     // SQL statement tracing.
     //
@@ -199,8 +199,9 @@ namespace odb
     friend class prepared_query_impl;
     prepared_query_impl* prepared_queries_;
 
-  protected:
-    friend class transaction;
+    // Implementation details.
+    //
+  public:
     tracer_type* transaction_tracer_;
   };
 
diff --git a/odb/connection.ixx b/odb/connection.ixx
index ba1353e..d19390a 100644
--- a/odb/connection.ixx
+++ b/odb/connection.ixx
@@ -89,14 +89,14 @@ namespace odb
 
   template <typename T>
   inline prepared_query<T> connection::
-  lookup_query (const char* name) const
+  lookup_query (const char* name)
   {
     return prepared_query<T> (lookup_query_ (name, typeid (T), 0, 0));
   }
 
   template <typename T, typename P>
   inline prepared_query<T> connection::
-  lookup_query (const char* name, P*& params) const
+  lookup_query (const char* name, P*& params)
   {
     return prepared_query<T> (
       lookup_query_ (name,
diff --git a/odb/database.cxx b/odb/database.cxx
index 3ad3716..9e098c7 100644
--- a/odb/database.cxx
+++ b/odb/database.cxx
@@ -19,7 +19,7 @@ namespace odb
   unsigned long long database::
   execute (const char* st, std::size_t n)
   {
-    connection_type& c (transaction::current ().connection ());
+    connection_type& c (transaction::current ().connection (*this));
     return c.execute (st, n);
   }
 
diff --git a/odb/database.hxx b/odb/database.hxx
index dba56c6..485cf52 100644
--- a/odb/database.hxx
+++ b/odb/database.hxx
@@ -377,11 +377,11 @@ namespace odb
 
     template <typename T>
     prepared_query<T>
-    lookup_query (const char* name) const;
+    lookup_query (const char* name);
 
     template <typename T, typename P>
     prepared_query<T>
-    lookup_query (const char* name, P*& params) const;
+    lookup_query (const char* name, P*& params);
 
     // Prepared query factory.
     //
diff --git a/odb/database.ixx b/odb/database.ixx
index 5f874bc..c3cf2e2 100644
--- a/odb/database.ixx
+++ b/odb/database.ixx
@@ -674,7 +674,7 @@ namespace odb
   inline prepared_query<T> database::
   prepare_query (const char* n, const odb::query<T>& q)
   {
-    connection_type& c (transaction::current ().connection ());
+    connection_type& c (transaction::current ().connection (*this));
     return c.prepare_query (n, q);
   }
 
@@ -682,7 +682,7 @@ namespace odb
   inline void database::
   cache_query (const prepared_query<T>& pq)
   {
-    connection_type& c (transaction::current ().connection ());
+    connection_type& c (transaction::current ().connection (*this));
     c.cache_query (pq);
   }
 
@@ -691,7 +691,7 @@ namespace odb
   inline void database::
   cache_query (const prepared_query<T>& pq, std::unique_ptr<P> params)
   {
-    connection_type& c (transaction::current ().connection ());
+    connection_type& c (transaction::current ().connection (*this));
     c.cache_query (pq, std::move (params));
   }
 #else
@@ -699,24 +699,24 @@ namespace odb
   inline void database::
   cache_query (const prepared_query<T>& pq, std::auto_ptr<P> params)
   {
-    connection_type& c (transaction::current ().connection ());
+    connection_type& c (transaction::current ().connection (*this));
     c.cache_query (pq, params);
   }
 #endif
 
   template <typename T>
   inline prepared_query<T> database::
-  lookup_query (const char* name) const
+  lookup_query (const char* name)
   {
-    connection_type& c (transaction::current ().connection ());
+    connection_type& c (transaction::current ().connection (*this));
     return c.lookup_query<T> (name);
   }
 
   template <typename T, typename P>
   inline prepared_query<T> database::
-  lookup_query (const char* name, P*& params) const
+  lookup_query (const char* name, P*& params)
   {
-    connection_type& c (transaction::current ().connection ());
+    connection_type& c (transaction::current ().connection (*this));
     return c.lookup_query<T, P> (name, params);
   }
 
diff --git a/odb/database.txx b/odb/database.txx
index 8e69e6a..5659b6f 100644
--- a/odb/database.txx
+++ b/odb/database.txx
@@ -255,7 +255,7 @@ namespace odb
   void database::
   load_ (T& obj, section& s)
   {
-    connection_type& c (transaction::current ().connection ());
+    connection_type& c (transaction::current ().connection (*this));
 
     // T is always object_type.
     //
@@ -349,7 +349,7 @@ namespace odb
 
     // T is always object_type.
     //
-    if (object_traits_impl<T, DB>::update (t.connection (), obj, s))
+    if (object_traits_impl<T, DB>::update (t.connection (*this), obj, s))
     {
       if (s.changed ())
         s.reset (true, false, &t); // Clear the change flag.
diff --git a/odb/transaction.cxx b/odb/transaction.cxx
index 1dc68e5..f75cf32 100644
--- a/odb/transaction.cxx
+++ b/odb/transaction.cxx
@@ -94,7 +94,7 @@ namespace odb
     finalized_ = true;
     rollback_guard rg (*this);
 
-    impl_->connection ().transaction_tracer_ = 0;
+    impl_->tracer (0);
 
     if (tls_get (current_transaction) == this)
     {
@@ -118,7 +118,7 @@ namespace odb
     finalized_ = true;
     rollback_guard rg (*this);
 
-    impl_->connection ().transaction_tracer_ = 0;
+    impl_->tracer (0);
 
     if (tls_get (current_transaction) == this)
     {
@@ -331,4 +331,26 @@ namespace odb
   ~transaction_impl ()
   {
   }
+
+  connection& transaction_impl::
+  connection (database_type* db)
+  {
+    assert (db == 0 || db == &database_);
+    return *connection_;
+  }
+
+  // The transaction-specific tracer is stored in the connection. See the
+  // connection class for the reason.
+  //
+  void transaction_impl::
+  tracer (tracer_type* t)
+  {
+    connection_->transaction_tracer_ = t;
+  }
+
+  tracer* transaction_impl::
+  tracer () const
+  {
+    return connection_->transaction_tracer_;
+  }
 }
diff --git a/odb/transaction.hxx b/odb/transaction.hxx
index 1298760..1958df3 100644
--- a/odb/transaction.hxx
+++ b/odb/transaction.hxx
@@ -61,9 +61,17 @@ namespace odb
 
     // Return the connection this transaction is on.
     //
+    // The second version verifies the connection is to the specified
+    // database. For database implementations that support attaching multiple
+    // databases it may also select the connection corresponding to the
+    // specified database.
+    //
     connection_type&
     connection ();
 
+    connection_type&
+    connection (database_type&);
+
     bool
     finalized () const {return finalized_;}
 
@@ -215,6 +223,7 @@ namespace odb
   class LIBODB_EXPORT transaction_impl
   {
   public:
+    typedef odb::tracer tracer_type;
     typedef odb::database database_type;
     typedef odb::connection connection_type;
 
@@ -236,11 +245,14 @@ namespace odb
       return database_;
     }
 
-    connection_type&
-    connection ()
-    {
-      return *connection_;
-    }
+    virtual connection_type&
+    connection (database_type*);
+
+    virtual void
+    tracer (tracer_type*);
+
+    virtual tracer_type*
+    tracer () const;
 
   protected:
     transaction_impl (database_type& db)
diff --git a/odb/transaction.ixx b/odb/transaction.ixx
index 16a0633..cc1ce5e 100644
--- a/odb/transaction.ixx
+++ b/odb/transaction.ixx
@@ -33,7 +33,13 @@ namespace odb
   inline transaction::connection_type& transaction::
   connection ()
   {
-    return impl_->connection ();
+    return impl_->connection (0);
+  }
+
+  inline transaction::connection_type& transaction::
+  connection (database_type& db)
+  {
+    return impl_->connection (&db);
   }
 
   inline transaction_impl& transaction::
@@ -42,24 +48,21 @@ namespace odb
     return *impl_;
   }
 
-  // The transaction-specific tracer is stored in the connection. See
-  // the connection class for the reason.
-  //
   inline void transaction::
   tracer (tracer_type& t)
   {
-    impl_->connection ().transaction_tracer_ = &t;
+    impl_->tracer (&t);
   }
 
   inline void transaction::
   tracer (tracer_type* t)
   {
-    impl_->connection ().transaction_tracer_ = t;
+    impl_->tracer (t);
   }
 
   inline transaction::tracer_type* transaction::
   tracer () const
   {
-    return impl_->connection ().transaction_tracer_;
+    return impl_->tracer ();
   }
 }
-- 
cgit v1.1