diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2010-11-26 13:24:00 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2010-11-26 13:24:00 +0200 |
commit | 51a71bc5cfe38ab7d4789f90725f8a24f49bd057 (patch) | |
tree | 066cf64fb40528c1147bb9426b3794e187bea4b9 | |
parent | e412109818a7e1b77c3cc955cadf56b34dde44a5 (diff) |
Add support for recursive object loading
If an object of a type needs to be loaded recursively, then it is addded to
the delayed loading list which is processed once the statements are unlocked.
-rw-r--r-- | odb/cache-traits.hxx | 36 | ||||
-rw-r--r-- | odb/result.hxx | 4 | ||||
-rw-r--r-- | odb/result.txx | 36 |
3 files changed, 44 insertions, 32 deletions
diff --git a/odb/cache-traits.hxx b/odb/cache-traits.hxx index 5d32624..a475d35 100644 --- a/odb/cache-traits.hxx +++ b/odb/cache-traits.hxx @@ -27,12 +27,10 @@ namespace odb struct insert_guard { insert_guard (const position_type& pos): pos_ (pos) {} + ~insert_guard () {erase (pos_);} - ~insert_guard () - { - if (pos_.map_ != 0) - session::current ().erase<element_type> (pos_); - } + position_type + position () const {return pos_;} void release () {pos_.map_ = 0;} @@ -65,6 +63,13 @@ namespace odb if (session::has_current ()) session::current ().erase<element_type> (db, id); } + + static void + erase (const position_type& p) + { + if (p.map_ != 0) + session::current ().erase<element_type> (p); + } }; // Unique pointers don't work with the object cache. @@ -80,7 +85,12 @@ namespace odb struct insert_guard { insert_guard (const position_type&) {} - void release () {} + + position_type + position () const {return position_type ();} + + void + release () {} }; static position_type @@ -94,6 +104,9 @@ namespace odb static void erase (database&, const id_type&) {} + + static void + erase (const position_type&) {} }; // Caching traits for objects passed by reference. Only if the object @@ -108,12 +121,19 @@ namespace odb typedef typename object_traits<element_type>::pointer_type pointer_type; typedef typename object_traits<element_type>::id_type id_type; - struct position_type {}; + typedef + typename pointer_cache_traits<pointer_type>::position_type + position_type; struct insert_guard { insert_guard (const position_type&) {} - void release () {} + + position_type + position () const {return position_type ();} + + void + release () {} }; static position_type diff --git a/odb/result.hxx b/odb/result.hxx index e87374e..cc7495f 100644 --- a/odb/result.hxx +++ b/odb/result.hxx @@ -77,10 +77,10 @@ namespace odb protected: virtual void - current (object_type&) = 0; + load (object_type&) = 0; virtual id_type - current_id () = 0; + load_id () = 0; virtual void next () = 0; diff --git a/odb/result.txx b/odb/result.txx index 603ee54..1cbf6f7 100644 --- a/odb/result.txx +++ b/odb/result.txx @@ -25,20 +25,17 @@ namespace odb { if (!session::has_current ()) { - // Non-const pointer. - // - unrestricted_pointer_type p (object_traits::create ()); - object_type& r (unrestricted_pointer_traits::get_ref (p)); - - current (pointer_type (p)); - current (r); + unrestricted_pointer_type up (object_traits::create ()); + object_type& obj (unrestricted_pointer_traits::get_ref (up)); + current (pointer_type (up)); + load (obj); } else { - const id_type& id (current_id ()); - // First check the session. // + const id_type& id (load_id ()); + pointer_type p ( pointer_cache_traits<pointer_type>::find (database (), id)); @@ -50,14 +47,12 @@ namespace odb typename pointer_cache_traits<unrestricted_pointer_type>::insert_guard ig ( - pointer_cache_traits<unrestricted_pointer_type>::insert ( - database (), id, up)); - - object_type& r (unrestricted_pointer_traits::get_ref (up)); + pointer_cache_traits<unrestricted_pointer_type>::insert ( + database (), id, up)); + object_type& obj (unrestricted_pointer_traits::get_ref (up)); current (pointer_type (up)); - current (r); - + load (obj); ig.release (); } } @@ -72,22 +67,19 @@ namespace odb template <typename T> void result_iterator<T>:: - load (object_type& x) + load (object_type& obj) { if (res_->end ()) return; if (!session::has_current ()) - res_->current (x); + res_->load (obj); else { - const id_type& id (res_->current_id ()); - typename reference_cache_traits<object_type>::insert_guard ig ( reference_cache_traits<object_type>::insert ( - res_->database (), id, x)); - - res_->current (x); + res_->database (), res_->load_id (), obj)); + res_->load (obj); ig.release (); } } |