aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2014-11-13 13:54:29 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2014-11-13 13:54:29 +0200
commit3afd0ae312029464ccea86f112d2d65fb858029d (patch)
tree696e08de5e706987b48d1f829a61a39741fcb11c
parent1586cc2c76b2ce7845fd3f60d789a772c4958e4a (diff)
Bulk update implementation
-rw-r--r--odb/database.hxx17
-rw-r--r--odb/database.ixx7
-rw-r--r--odb/database.txx55
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)