aboutsummaryrefslogtreecommitdiff
path: root/odb/session.txx
diff options
context:
space:
mode:
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);
+ }
+}