aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--odb/pgsql/object-statements.hxx16
-rw-r--r--odb/pgsql/object-statements.ixx16
-rw-r--r--odb/pgsql/object-statements.txx13
-rw-r--r--odb/pgsql/result.txx3
4 files changed, 45 insertions, 3 deletions
diff --git a/odb/pgsql/object-statements.hxx b/odb/pgsql/object-statements.hxx
index 32ea24b..ca5aecd 100644
--- a/odb/pgsql/object-statements.hxx
+++ b/odb/pgsql/object-statements.hxx
@@ -74,6 +74,22 @@ namespace odb
{
}
+ struct auto_unlock
+ {
+ // Unlocks the statement on construction and re-locks it on
+ // destruction.
+ //
+ auto_unlock (object_statements_base&);
+ ~auto_unlock ();
+
+ private:
+ auto_unlock (const auto_unlock&);
+ auto_unlock& operator= (const auto_unlock&);
+
+ private:
+ object_statements_base& s_;
+ };
+
protected:
connection_type& conn_;
bool locked_;
diff --git a/odb/pgsql/object-statements.ixx b/odb/pgsql/object-statements.ixx
index ea19baa..3955bf6 100644
--- a/odb/pgsql/object-statements.ixx
+++ b/odb/pgsql/object-statements.ixx
@@ -8,6 +8,22 @@ namespace odb
namespace pgsql
{
//
+ // auto_unlock
+ //
+ inline object_statements_base::auto_unlock::
+ auto_unlock (object_statements_base& s)
+ : s_ (s)
+ {
+ s_.unlock ();
+ }
+
+ inline object_statements_base::auto_unlock::
+ ~auto_unlock ()
+ {
+ s_.lock ();
+ }
+
+ //
// auto_lock
//
template <typename T>
diff --git a/odb/pgsql/object-statements.txx b/odb/pgsql/object-statements.txx
index b64d5b8..c568ca7 100644
--- a/odb/pgsql/object-statements.txx
+++ b/odb/pgsql/object-statements.txx
@@ -80,7 +80,18 @@ namespace odb
if (!delayed_.empty ())
load_delayed_ ();
- object_traits::callback (db, *l.obj, callback_event::post_load);
+ // Temporarily unlock the statement for the post_load call so that
+ // it can load objects of this type recursively. This is safe to do
+ // because we have completely loaded the current object. Also the
+ // delayed_ list is clear before the unlock and should be clear on
+ // re-lock (since a callback can only call public API functions
+ // which will make sure all the delayed loads are processed before
+ // returning).
+ //
+ {
+ auto_unlock u (*this);
+ object_traits::callback (db, *l.obj, callback_event::post_load);
+ }
g.release ();
}
diff --git a/odb/pgsql/result.txx b/odb/pgsql/result.txx
index edea595..a0dc2f8 100644
--- a/odb/pgsql/result.txx
+++ b/odb/pgsql/result.txx
@@ -60,9 +60,8 @@ namespace odb
object_traits::load_ (statements_, obj);
statements_.load_delayed ();
- object_traits::callback (db, obj, callback_event::post_load);
-
l.unlock ();
+ object_traits::callback (db, obj, callback_event::post_load);
}
template <typename T>