diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2011-07-05 14:56:58 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2011-07-05 14:56:58 +0200 |
commit | 0eb2f9a50cd70599757bde6056d8981d7f892c0d (patch) | |
tree | c0fd7705b5754abcde9ae5cf6e06a53d830cad17 | |
parent | 1d3edf0de34c311014fd222a737e96c9f1d5b83a (diff) |
Support for callbacks in PG runtime
-rw-r--r-- | odb/pgsql/object-statements.hxx | 22 | ||||
-rw-r--r-- | odb/pgsql/object-statements.txx | 25 | ||||
-rw-r--r-- | odb/pgsql/result.txx | 9 |
3 files changed, 48 insertions, 8 deletions
diff --git a/odb/pgsql/object-statements.hxx b/odb/pgsql/object-statements.hxx index ff86bcf..32ea24b 100644 --- a/odb/pgsql/object-statements.hxx +++ b/odb/pgsql/object-statements.hxx @@ -395,6 +395,28 @@ namespace odb typedef std::vector<delayed_load> delayed_loads; delayed_loads delayed_; + + // Delayed vectors swap guard. See the load_delayed_() function for + // details. + // + struct swap_guard + { + swap_guard (object_statements& os, delayed_loads& dl) + : os_ (os), dl_ (dl) + { + dl_.swap (os_.delayed_); + } + + ~swap_guard () + { + os_.clear_delayed (); + dl_.swap (os_.delayed_); + } + + private: + object_statements& os_; + delayed_loads& dl_; + }; }; } } diff --git a/odb/pgsql/object-statements.txx b/odb/pgsql/object-statements.txx index f355b13..b64d5b8 100644 --- a/odb/pgsql/object-statements.txx +++ b/odb/pgsql/object-statements.txx @@ -7,6 +7,7 @@ #include <cstring> // std::memset #include <odb/session.hxx> +#include <odb/callback.hxx> #include <odb/exceptions.hxx> #include <odb/pgsql/connection.hxx> @@ -53,22 +54,34 @@ namespace odb void object_statements<T>:: load_delayed_ () { - // We should be careful here: the delayed vector can change - // from under us as a result of a recursive load. - // database& db (connection ().database ()); - while (!delayed_.empty ()) + delayed_loads dls; + swap_guard sg (*this, dls); + + while (!dls.empty ()) { - delayed_load l (delayed_.back ()); + delayed_load l (dls.back ()); typename object_cache_traits::insert_guard g (l.pos); - delayed_.pop_back (); + dls.pop_back (); if (!object_traits::find_ (*this, l.id)) throw object_not_persistent (); + object_traits::callback (db, *l.obj, callback_event::pre_load); + + // Our calls to init/load below can result in additional delayed + // loads being added to the delayed_ vector. We need to process + // those before we call the post callback. + // object_traits::init (*l.obj, image (), db); object_traits::load_ (*this, *l.obj); // Load containers, etc. + + if (!delayed_.empty ()) + load_delayed_ (); + + 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 d0afe1c..edea595 100644 --- a/odb/pgsql/result.txx +++ b/odb/pgsql/result.txx @@ -3,6 +3,7 @@ // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file +#include <odb/callback.hxx> #include <odb/exceptions.hxx> namespace odb @@ -37,8 +38,11 @@ namespace odb assert (!statements_.locked ()); typename object_statements<object_type>::auto_lock l (statements_); + odb::database& db (this->database ()); + object_traits::callback (db, obj, callback_event::pre_load); + typename object_traits::image_type& i (statements_.image ()); - object_traits::init (obj, i, this->database ()); + object_traits::init (obj, i, db); // Initialize the id image and binding and load the rest of the object // (containers, etc). @@ -55,8 +59,9 @@ namespace odb } object_traits::load_ (statements_, obj); - statements_.load_delayed (); + object_traits::callback (db, obj, callback_event::post_load); + l.unlock (); } |