diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2014-11-13 13:54:29 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2014-11-13 13:54:29 +0200 |
commit | 3afd0ae312029464ccea86f112d2d65fb858029d (patch) | |
tree | 696e08de5e706987b48d1f829a61a39741fcb11c | |
parent | 1586cc2c76b2ce7845fd3f60d789a772c4958e4a (diff) |
Bulk update implementation
-rw-r--r-- | odb/database.hxx | 17 | ||||
-rw-r--r-- | odb/database.ixx | 7 | ||||
-rw-r--r-- | odb/database.txx | 55 |
3 files changed, 78 insertions, 1 deletions
diff --git a/odb/database.hxx b/odb/database.hxx index f4a3d36..0304d3c 100644 --- a/odb/database.hxx +++ b/odb/database.hxx @@ -78,7 +78,8 @@ namespace odb typename object_traits<T>::id_type persist (const typename object_traits<T>::pointer_type& obj_ptr); - // Bulk persist. + // Bulk persist. Can be a range of references or pointers (including + // smart pointers) to objects. // template <typename I> void @@ -170,6 +171,13 @@ namespace odb void update (const typename object_traits<T>::pointer_type& obj_ptr); + // Bulk update. Can be a range of references or pointers (including + // smart pointers) to objects. + // + template <typename I> + void + update (I begin, I end); + // Update a section of an object. Throws section_not_loaded exception // if section is not loaded. Note also that this function does not // clear the changed flag if it is set. @@ -219,6 +227,9 @@ namespace odb void erase (I id_begin, I id_end); + // Can be a range of references or pointers (including smart pointers) + // to objects. + // template <typename I> void erase (I obj_begin, I obj_end); @@ -550,6 +561,10 @@ namespace odb void update_ (const typename object_traits<T>::pointer_type&); + template <typename I, database_id DB> + void + update_ (I, I); + template <typename T, database_id DB> void update_ (const T&, const section&); diff --git a/odb/database.ixx b/odb/database.ixx index a17e90a..57828a4 100644 --- a/odb/database.ixx +++ b/odb/database.ixx @@ -396,6 +396,13 @@ namespace odb update_<T, id_common> (pobj); } + template <typename I> + inline void database:: + update (I b, I e) + { + update_<I, id_common> (b, e); + } + template <typename T> inline void database:: update (const T& obj, const section& s) diff --git a/odb/database.txx b/odb/database.txx index 943f31c..7683d50 100644 --- a/odb/database.txx +++ b/odb/database.txx @@ -259,6 +259,61 @@ namespace odb throw object_not_persistent (); } + template <typename I, database_id DB> + void database:: + update_ (I b, I e) + { + // Sun CC with non-standard STL does not have iterator_traits. + // +#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC + typedef typename std::iterator_traits<I>::value_type value_type; +#else + // Assume iterator is just a pointer. + // + typedef typename object_pointer_traits<I>::object_type value_type; +#endif + + // object_pointer_traits<T>::object_type can be const. + // + typedef object_pointer_traits<value_type> opt; + + typedef + typename object_traits<typename opt::object_type>::object_type + object_type; + + typedef object_traits_impl<object_type, DB> object_traits; + + multiple_exceptions mex (typeid (object_not_persistent)); + try + { + while (b != e) + { + std::size_t n (0); + const object_type* a[object_traits::batch]; + + for (; b != e && n < object_traits::batch; ++n) + a[n] = &opt::get_ref (*b++); + + object_traits::update (*this, a, n, &mex); + + if (mex.fatal ()) + break; + + mex.delta (n); + } + } + catch (const odb::exception& ex) + { + mex.insert (ex, true); + } + + if (!mex.empty ()) + { + mex.prepare (); + throw mex; + } + } + template <typename T, database_id DB> void database:: update_ (const T& obj, const section& s) |