aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-01-16 16:31:29 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-01-16 16:31:29 +0200
commite3dafcdf8b43880c6a1e0451c8ee621f7c3cb954 (patch)
treeab90ae868337a1c286ab9334c83e890cd0614686
parentd2c1f5f1a3063553483d09dec261efa44c6bc9bf (diff)
Make session cache management functions static, add notifications
-rw-r--r--odb/cache-traits.hxx78
-rw-r--r--odb/database.txx4
-rw-r--r--odb/no-op-cache-traits.hxx35
-rw-r--r--odb/polymorphic-object-result.txx2
-rw-r--r--odb/session.cxx29
-rw-r--r--odb/session.hxx46
-rw-r--r--odb/session.ixx3
-rw-r--r--odb/session.txx26
-rw-r--r--odb/simple-object-result.txx4
9 files changed, 138 insertions, 89 deletions
diff --git a/odb/cache-traits.hxx b/odb/cache-traits.hxx
index 5732cfc..5ab5022 100644
--- a/odb/cache-traits.hxx
+++ b/odb/cache-traits.hxx
@@ -28,29 +28,19 @@ namespace odb
typedef odb::pointer_traits<pointer_type> pointer_traits;
typedef typename pointer_traits::element_type object_type;
typedef typename object_traits<object_type>::id_type id_type;
-
- struct position_type
- {
- typedef typename session_type::template position<object_type> base_type;
-
- position_type (): empty_ (true) {}
- position_type (const base_type& pos): empty_ (false), pos_ (pos) {}
-
- bool empty_;
- base_type pos_;
- };
+ typedef typename session_type::template position<object_type> position_type;
struct insert_guard
{
insert_guard () {}
insert_guard (const position_type& pos): pos_ (pos) {}
- ~insert_guard () {erase (pos_);}
+ ~insert_guard () {session_type::erase (pos_);}
const position_type&
position () const {return pos_;}
void
- release () {pos_.empty_ = true;}
+ release () {pos_ = position_type ();}
// Note: doesn't call erase() on the old position (assumes empty).
//
@@ -61,6 +51,8 @@ namespace odb
position_type pos_;
};
+ // Cache management.
+ //
// We need the insert() overload with explicit id to handle self-
// references. In such cases the object is not yet loaded and the
// id member does not contain the correct id.
@@ -70,18 +62,7 @@ namespace odb
static position_type
insert (odb::database& db, const id_type& id, const pointer_type& p)
{
- if (session_type::has_current ())
- return session_type::current ().template insert<object_type> (
- db, id, p);
- else
- return position_type ();
- }
-
- static void
- initialize (const position_type& p)
- {
- if (!p.empty_)
- session_type::template initialize<object_type> (p.pos_);
+ return session_type::template insert<object_type> (db, id, p);
}
static position_type
@@ -91,30 +72,45 @@ namespace odb
object_traits<object_type>::id (
pointer_traits::get_ref (p)));
- return insert (db, id, p);
+ return session_type::template insert<object_type> (db, id, p);
}
static pointer_type
find (odb::database& db, const id_type& id)
{
- if (session_type::has_current ())
- return session_type::current ().template find<object_type> (db, id);
- else
- return pointer_type ();
+ return session_type::template find<object_type> (db, id);
}
static void
- erase (odb::database& db, const id_type& id)
+ erase (const position_type& p)
{
- if (session_type::has_current ())
- session_type::current ().template erase<object_type> (db, id);
+ session_type::template erase<object_type> (p);
}
+ // Notifications.
+ //
static void
- erase (const position_type& p)
+ persist (const position_type& p)
{
- if (!p.empty_)
- session_type::template erase<object_type> (p.pos_);
+ session_type::template persist<object_type> (p);
+ }
+
+ static void
+ load (const position_type& p)
+ {
+ session_type::template load<object_type> (p);
+ }
+
+ static void
+ update (odb::database& db, const object_type& obj)
+ {
+ session_type::template update<object_type> (db, obj);
+ }
+
+ static void
+ erase (odb::database& db, const id_type& id)
+ {
+ session_type::template erase<object_type> (db, id);
}
};
@@ -163,9 +159,15 @@ namespace odb
}
static void
- initialize (const position_type& p)
+ persist (const position_type& p)
+ {
+ pointer_traits::persist (p);
+ }
+
+ static void
+ load (const position_type& p)
{
- pointer_traits::initialize (p);
+ pointer_traits::load (p);
}
};
diff --git a/odb/database.txx b/odb/database.txx
index b5f9640..d96fd14 100644
--- a/odb/database.txx
+++ b/odb/database.txx
@@ -40,7 +40,7 @@ namespace odb
object_traits::reference_cache_traits::insert (
*this, reference_cache_type<T>::convert (obj)));
- object_traits::reference_cache_traits::initialize (p);
+ object_traits::reference_cache_traits::persist (p);
return object_traits::id (obj);
}
@@ -65,7 +65,7 @@ namespace odb
object_traits::pointer_cache_traits::insert (
*this, pointer_cache_type<pointer_type>::convert (pobj)));
- object_traits::pointer_cache_traits::initialize (p);
+ object_traits::pointer_cache_traits::persist (p);
return object_traits::id (obj);
}
diff --git a/odb/no-op-cache-traits.hxx b/odb/no-op-cache-traits.hxx
index 5600a81..f1bf718 100644
--- a/odb/no-op-cache-traits.hxx
+++ b/odb/no-op-cache-traits.hxx
@@ -114,6 +114,8 @@ namespace odb
reset (const position_type&) {}
};
+ // Cache management.
+ //
static position_type
insert (odb::database&, const id_type&, const pointer_type&)
{
@@ -128,17 +130,25 @@ namespace odb
static position_type
insert (odb::database&, void*) {return position_type ();}
- static void
- initialize (const position_type&) {}
-
static pointer_type
find (odb::database&, const id_type&) {return pointer_type ();}
static void
- erase (odb::database&, const id_type&) {}
+ erase (const position_type&) {}
+ // Notifications.
+ //
static void
- erase (const position_type&) {}
+ persist (const position_type&) {}
+
+ static void
+ load (const position_type&) {}
+
+ static void
+ update (odb::database&, const object_type&) {}
+
+ static void
+ erase (odb::database&, const id_type&) {}
};
template <typename P>
@@ -156,7 +166,10 @@ namespace odb
insert (odb::database&, void*) {return position_type ();}
static void
- initialize (const position_type&) {}
+ persist (const position_type&) {}
+
+ static void
+ load (const position_type&) {}
};
// reference_cache_traits
@@ -196,7 +209,10 @@ namespace odb
insert (odb::database&, object_type&) {return position_type ();}
static void
- initialize (const position_type&) {}
+ persist (const position_type&) {}
+
+ static void
+ load (const position_type&) {}
};
template <typename T>
@@ -209,7 +225,10 @@ namespace odb
insert (odb::database&, object_type&) {return position_type ();}
static void
- initialize (const position_type&) {}
+ persist (const position_type&) {}
+
+ static void
+ load (const position_type&) {}
};
}
diff --git a/odb/polymorphic-object-result.txx b/odb/polymorphic-object-result.txx
index 69d365d..7ee2b82 100644
--- a/odb/polymorphic-object-result.txx
+++ b/odb/polymorphic-object-result.txx
@@ -65,7 +65,7 @@ namespace odb
res_->db_, res_->load_id (), obj));
typename object_traits::reference_cache_traits::insert_guard ig (p);
res_->load (&obj, false);
- object_traits::reference_cache_traits::initialize (p);
+ object_traits::reference_cache_traits::load (p);
ig.release ();
}
}
diff --git a/odb/session.cxx b/odb/session.cxx
index 3ca6af4..0f18684 100644
--- a/odb/session.cxx
+++ b/odb/session.cxx
@@ -21,7 +21,7 @@ namespace odb
if (has_current ())
throw already_in_session ();
- current (*this);
+ current_pointer (this);
}
}
@@ -30,14 +30,20 @@ namespace odb
{
// If we are the current thread's session, reset it.
//
- if (has_current () && &current () == this)
+ if (current_pointer () == this)
reset_current ();
}
- bool session::
- has_current ()
+ session* session::
+ current_pointer ()
{
- return tls_get (current_session) != 0;
+ return tls_get (current_session);
+ }
+
+ void session::
+ current_pointer (session* s)
+ {
+ tls_set (current_session, s);
}
session& session::
@@ -51,19 +57,6 @@ namespace odb
return *cur;
}
- void session::
- current (session& s)
- {
- tls_set (current_session, &s);
- }
-
- void session::
- reset_current ()
- {
- session* s (0);
- tls_set (current_session, s);
- }
-
//
// object_map_base
//
diff --git a/odb/session.hxx b/odb/session.hxx
index 3f58a80..6c9359c 100644
--- a/odb/session.hxx
+++ b/odb/session.hxx
@@ -42,7 +42,7 @@ namespace odb
// thread.
//
static bool
- has_current ();
+ has_current () {return current_pointer () != 0;}
// Get current thread's session. Throw if no session is in effect.
//
@@ -52,12 +52,18 @@ namespace odb
// Set current thread's session.
//
static void
- current (session&);
+ current (session& s) {current_pointer (&s);}
// Revert to the no session in effect state for the current thread.
//
static void
- reset_current ();
+ reset_current () {current_pointer (0);}
+
+ static session*
+ current_pointer ();
+
+ static void
+ current_pointer (session*);
// Copying or assignment of sessions is not supported.
//
@@ -84,7 +90,8 @@ namespace odb
public:
// Position in the cache of an inserted element. The requirements
// for this class template are: default and copy-constructible as
- // well as copy-assignable.
+ // well as copy-assignable. The default constructor creates an
+ // empty/NULL position.
//
template <typename T>
struct position
@@ -92,35 +99,50 @@ namespace odb
typedef object_map<T> map;
typedef typename map::iterator iterator;
- position () {}
+ position (): map_ (0) {}
position (map& m, const iterator& p): map_ (&m), pos_ (p) {}
map* map_;
iterator pos_;
};
+ // The following cache management functions are all static to
+ // allow for a custom notion of a current session. The erase()
+ // function is called to remove the object if the operation
+ // that caused it to be inserted (e.g., load) failed.
+ //
template <typename T>
- position<T>
+ static position<T>
insert (database_type&,
const typename object_traits<T>::id_type&,
const typename object_traits<T>::pointer_type&);
template <typename T>
+ static typename object_traits<T>::pointer_type
+ find (database_type&, const typename object_traits<T>::id_type&);
+
+ template <typename T>
static void
- initialize (const position<T>&) {}
+ erase (const position<T>&);
+ // Notifications. These are called after per-object callbacks for
+ // post_{persist, load, update, erase} events.
+ //
template <typename T>
- typename object_traits<T>::pointer_type
- find (database_type&, const typename object_traits<T>::id_type&) const;
+ static void
+ persist (const position<T>&) {}
template <typename T>
- void
- erase (database_type&, const typename object_traits<T>::id_type&);
+ static void
+ load (const position<T>&) {}
template <typename T>
static void
- erase (const position<T>&);
+ update (database_type&, const T&) {}
+ template <typename T>
+ static void
+ erase (database_type&, const typename object_traits<T>::id_type&);
// Low-level object cache access (iteration, etc).
//
diff --git a/odb/session.ixx b/odb/session.ixx
index 50a2ca1..4748cae 100644
--- a/odb/session.ixx
+++ b/odb/session.ixx
@@ -12,6 +12,7 @@ namespace odb
{
// @@ Empty maps are not cleaned up by this version of erase.
//
- p.map_->erase (p.pos_);
+ if (p.map_ != 0)
+ p.map_->erase (p.pos_);
}
}
diff --git a/odb/session.txx b/odb/session.txx
index 941f059..e89e439 100644
--- a/odb/session.txx
+++ b/odb/session.txx
@@ -12,7 +12,11 @@ namespace odb
{
typedef odb::object_traits<T> object_traits;
- type_map& tm (db_map_[&db]);
+ session* s (current_pointer ());
+ if (s == 0)
+ return position<T> ();
+
+ type_map& tm (s->db_map_[&db]);
details::shared_ptr<object_map_base>& pom (tm[&typeid (T)]);
if (!pom)
@@ -36,13 +40,17 @@ namespace odb
template <typename T>
typename object_traits<T>::pointer_type session::
- find (database_type& db, const typename object_traits<T>::id_type& id) const
+ find (database_type& db, const typename object_traits<T>::id_type& id)
{
typedef typename object_traits<T>::pointer_type pointer_type;
- database_map::const_iterator di (db_map_.find (&db));
+ const session* s (current_pointer ());
+ if (s == 0)
+ return pointer_type ();
+
+ database_map::const_iterator di (s->db_map_.find (&db));
- if (di == db_map_.end ())
+ if (di == s->db_map_.end ())
return pointer_type ();
const type_map& tm (di->second);
@@ -64,9 +72,13 @@ namespace odb
void session::
erase (database_type& db, const typename object_traits<T>::id_type& id)
{
- database_map::iterator di (db_map_.find (&db));
+ session* s (current_pointer ());
+ if (s == 0)
+ return;
+
+ database_map::iterator di (s->db_map_.find (&db));
- if (di == db_map_.end ())
+ if (di == s->db_map_.end ())
return;
type_map& tm (di->second);
@@ -87,6 +99,6 @@ namespace odb
tm.erase (ti);
if (tm.empty ())
- db_map_.erase (di);
+ s->db_map_.erase (di);
}
}
diff --git a/odb/simple-object-result.txx b/odb/simple-object-result.txx
index f14caac..1a6332c 100644
--- a/odb/simple-object-result.txx
+++ b/odb/simple-object-result.txx
@@ -30,7 +30,7 @@ namespace odb
object_type& obj (pointer_traits::get_ref (p));
current (p);
load (obj, false);
- object_traits::pointer_cache_traits::initialize (ig.position ());
+ object_traits::pointer_cache_traits::load (ig.position ());
ig.release ();
}
}
@@ -53,7 +53,7 @@ namespace odb
res_->db_, res_->load_id (), obj));
typename object_traits::reference_cache_traits::insert_guard ig (p);
res_->load (obj, false);
- object_traits::reference_cache_traits::initialize (p);
+ object_traits::reference_cache_traits::load (p);
ig.release ();
}
}