aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-07-04 17:53:47 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-07-04 17:53:47 +0200
commit3c549ec489afe54037bd2d486502f10971a75cb5 (patch)
tree5c0428f3383a605d0d31b6d28680c2c9c02a90b9
parent47584aa7e59d5bd273970551a26c4b8f8c1cba3d (diff)
Implement support for database operations callbacks
New object pragma: callback. New test: common/callback. New manual section: 10.1.4, "callback".
-rw-r--r--odb/mysql/object-statements.hxx22
-rw-r--r--odb/mysql/object-statements.txx25
-rw-r--r--odb/mysql/result.txx9
3 files changed, 48 insertions, 8 deletions
diff --git a/odb/mysql/object-statements.hxx b/odb/mysql/object-statements.hxx
index e5f6489..c341352 100644
--- a/odb/mysql/object-statements.hxx
+++ b/odb/mysql/object-statements.hxx
@@ -362,6 +362,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/mysql/object-statements.txx b/odb/mysql/object-statements.txx
index 46c8ab0..f98f11d 100644
--- a/odb/mysql/object-statements.txx
+++ b/odb/mysql/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/mysql/connection.hxx>
@@ -43,22 +44,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/mysql/result.txx b/odb/mysql/result.txx
index f6d0a79..84eb723 100644
--- a/odb/mysql/result.txx
+++ b/odb/mysql/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
@@ -39,8 +40,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).
@@ -57,8 +61,9 @@ namespace odb
}
object_traits::load_ (statements_, obj);
-
statements_.load_delayed ();
+ object_traits::callback (db, obj, callback_event::post_load);
+
l.unlock ();
}