aboutsummaryrefslogtreecommitdiff
path: root/odb/session.txx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-11-22 12:03:11 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-11-22 12:03:11 +0200
commit531c792dd4eecd246cc1ccebac812d6888464a78 (patch)
tree9bed050c98a2c407c68e808ae1f1d296a65c5fee /odb/session.txx
parent1cddfd09a7007f77fc243f178b1ca88ea4d0f4f6 (diff)
Add session, database operations on pointers and const objects
Currently, session is just an object cache. The persist, update, and erase database operations are overloaded to also work on object pointers. All the database operations and the query facility now support const objects. New session-related exceptions: not_in_session, already_in_session, const_object.
Diffstat (limited to 'odb/session.txx')
-rw-r--r--odb/session.txx116
1 files changed, 116 insertions, 0 deletions
diff --git a/odb/session.txx b/odb/session.txx
new file mode 100644
index 0000000..1e3ba96
--- /dev/null
+++ b/odb/session.txx
@@ -0,0 +1,116 @@
+// file : odb/session.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#include <odb/pointer-traits.hxx>
+
+namespace odb
+{
+ template <typename T>
+ typename session::object_position<T> session::
+ insert (database_type& db,
+ const typename object_traits<T>::id_type& id,
+ const typename object_traits<T>::pointer_type& obj)
+ {
+ // T can be const T while object_type will always be T.
+ //
+ typedef typename object_traits<T>::object_type object_type;
+ typedef odb::object_traits<object_type> object_traits;
+
+ typedef typename odb::object_traits<T>::pointer_type pointer_type;
+ typedef odb::pointer_traits<pointer_type> pointer_traits;
+
+ type_map& tm (db_map_[&db]);
+ details::shared_ptr<object_map_base>& pom (tm[&typeid (object_type)]);
+
+ if (!pom)
+ pom.reset (new (details::shared) object_map<object_type>);
+
+ object_map<object_type>& om (
+ static_cast<object_map<object_type>&> (*pom));
+
+ typename object_map<object_type>::value_type vt (
+ id, object_pointers<object_type> ());
+ vt.second.set (obj);
+ std::pair<typename object_map<object_type>::iterator, bool> r (
+ om.insert (vt));
+
+ // In what situation may we possibly attempt to reinsert the object?
+ // For example, when the user loads the same object in to different
+ // instances (i.e., load into a pre-allocated object). In this case
+ // we should probably update our entries accordingly.
+ //
+ if (!r.second)
+ r.first->second.set (obj);
+
+ return object_position<T> (om, r.first);
+ }
+
+ template <typename T>
+ typename object_traits<T>::pointer_type session::
+ find (database_type& db, const typename object_traits<T>::id_type& id) const
+ {
+ // T can be const T while object_type will always be T.
+ //
+ typedef typename object_traits<T>::object_type object_type;
+ typedef typename object_traits<T>::pointer_type pointer_type;
+
+ database_map::const_iterator di (db_map_.find (&db));
+
+ if (di == db_map_.end ())
+ return pointer_type ();
+
+ const type_map& tm (di->second);
+ type_map::const_iterator ti (tm.find (&typeid (object_type)));
+
+ if (ti == tm.end ())
+ return pointer_type ();
+
+ const object_map<object_type>& om (
+ static_cast<const object_map<object_type>&> (*ti->second));
+ typename object_map<object_type>::const_iterator oi (om.find (id));
+
+ if (oi == om.end ())
+ return pointer_type ();
+
+ pointer_type r;
+ oi->second.get (r);
+ return r;
+ }
+
+ template <typename T>
+ void session::
+ erase (database_type& db, const typename object_traits<T>::id_type& id)
+ {
+ // T can be const T while object_type will always be T.
+ //
+ typedef typename object_traits<T>::object_type object_type;
+
+ database_map::iterator di (db_map_.find (&db));
+
+ if (di == db_map_.end ())
+ return;
+
+ type_map& tm (di->second);
+ type_map::iterator ti (tm.find (&typeid (object_type)));
+
+ if (ti == tm.end ())
+ return;
+
+ object_map<object_type>& om (
+ static_cast<object_map<object_type>&> (*ti->second));
+ typename object_map<object_type>::iterator oi (om.find (id));
+
+ if (oi == om.end ())
+ return;
+
+ om.erase (oi);
+
+ if (om.empty ())
+ tm.erase (ti);
+
+ if (tm.empty ())
+ db_map_.erase (di);
+ }
+}