diff options
-rw-r--r-- | odb/pgsql/object-statements.hxx | 16 | ||||
-rw-r--r-- | odb/pgsql/object-statements.ixx | 16 | ||||
-rw-r--r-- | odb/pgsql/object-statements.txx | 13 | ||||
-rw-r--r-- | odb/pgsql/result.txx | 3 |
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> |