diff options
Diffstat (limited to 'odb/session.txx')
-rw-r--r-- | odb/session.txx | 116 |
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); + } +} |