aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-07-20 11:02:07 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-07-20 11:02:07 +0200
commit6400b736456af65176c9c1959022f1eb49fcde32 (patch)
treecdf457de88eda70b89d4cd98e83334e690c96ef1
parent8b416ee938662901e1d75cf631c198cde17bb8c8 (diff)
Get rid of the session mechanism for now
Add low-level API instead.
-rw-r--r--makefile2
-rw-r--r--odb/database.hxx58
-rw-r--r--odb/database.txx84
-rw-r--r--odb/exceptions.hxx8
-rw-r--r--odb/forward.hxx3
-rw-r--r--odb/makefile3
-rw-r--r--odb/pointer-traits.hxx (renamed from odb/shared-ptr-traits.hxx)75
-rw-r--r--odb/session.cxx120
-rw-r--r--odb/session.hxx190
-rw-r--r--odb/session.txx320
-rw-r--r--odb/traits.hxx42
-rw-r--r--odb/transaction.cxx7
-rw-r--r--odb/transaction.hxx42
-rw-r--r--odb/transaction.ixx6
14 files changed, 174 insertions, 786 deletions
diff --git a/makefile b/makefile
index 32b7548..811738c 100644
--- a/makefile
+++ b/makefile
@@ -26,7 +26,7 @@ $(install): $(out_base)/odb/.install
# Clean.
#
-$(clean): $(out_base)/odb/.clean $(out_base)/tests/.clean
+$(clean): $(out_base)/odb/.clean #$(out_base)/tests/.clean
$(call include,$(bld_root)/install.make)
diff --git a/odb/database.hxx b/odb/database.hxx
index 2a904a4..bfd6b0b 100644
--- a/odb/database.hxx
+++ b/odb/database.hxx
@@ -19,43 +19,59 @@ namespace odb
virtual
~database ();
- template <typename T, template <typename> class P>
+ // Object persistence API.
+ //
+ public:
+
+ // Make the object persistent.
+ //
+ template <typename T>
typename object_traits<T>::id_type
- persist (P<T> obj);
+ persist (T& object);
+
+ // Throw object_not_persistent if not found.
+ //
+ template <typename T>
+ typename object_traits<T>::pointer_type
+ load (typename object_traits<T>::id_type const& id);
+
+ template <typename T>
+ void
+ load (typename object_traits<T>::id_type const& id, T& object);
+ // Return NULL/false if not found.
+ //
template <typename T>
- typename object_traits<T>::shared_ptr
- load (typename object_traits<T>::id_type const&);
+ typename object_traits<T>::pointer_type
+ find (typename object_traits<T>::id_type const& id);
template <typename T>
- typename object_traits<T>::shared_ptr
- find (typename object_traits<T>::id_type const&);
+ bool
+ find (typename object_traits<T>::id_type const& id, T& object);
- template <typename T, template <typename> class P>
+ // Save the state of a modified objects.
+ //
+ template <typename T>
void
- erase (P<T> obj);
+ store (T& object);
- template <typename T, template <typename> class P>
+ // Make the object transient. Throw object_not_persistent if not
+ // found.
+ //
+ template <typename T>
void
- modified (P<T> obj);
+ erase (const T& object);
+
+ template <typename T>
+ void
+ erase (typename object_traits<T>::id_type const& id);
// Transaction API.
//
public:
- // Start a transaction. If an existing session can be obtained via
- // session::current(), the transaction is run as part of that session.
- // Otherwise a new session is created and will be automatically flushed
- // and destroyed when transaction ends.
- //
virtual transaction_impl*
begin_transaction () = 0;
- // Start a transaction as part of an existing session. The session
- // is not automatically flushed or destroyed when transaction ends.
- //
- virtual transaction_impl*
- begin_transaction (session&) = 0;
-
protected:
database ();
diff --git a/odb/database.txx b/odb/database.txx
index c507030..12edc85 100644
--- a/odb/database.txx
+++ b/odb/database.txx
@@ -4,7 +4,6 @@
// license : GNU GPL v2; see accompanying LICENSE file
#include <odb/exceptions.hxx>
-#include <odb/session.hxx>
#include <odb/transaction.hxx>
namespace odb
@@ -12,62 +11,85 @@ namespace odb
// @@ Should I make these inline?
//
- template <typename T, template <typename> class P>
+ template <typename T>
typename object_traits<T>::id_type database::
- persist (P<T> p)
+ persist (T& obj)
{
- // P<T> should be the same or convertible to
- // object_traits<T>::shared_ptr.
- //
- const typename object_traits<T>::shared_ptr& obj (p);
+ typedef object_traits<T> traits;
+
+ if (!transaction::has_current ())
+ throw not_in_transaction ();
- session& s (transaction::current ().session ());
- return s.persist<T> (*this, obj);
+ traits::insert (*this, obj);
+ return traits::id (obj);
}
template <typename T>
- typename object_traits<T>::shared_ptr database::
+ typename object_traits<T>::pointer_type database::
load (typename object_traits<T>::id_type const& id)
{
- typename object_traits<T>::shared_ptr r (find<T> (id));
+ typedef object_traits<T> traits;
+
+ typename traits::pointer_type r (find<T> (id));
- if (object_traits<T>::shared_ops::null_ptr (r))
+ if (traits::pointer_ops::null_ptr (r))
throw object_not_persistent ();
return r;
}
template <typename T>
- typename object_traits<T>::shared_ptr database::
+ void database::
+ load (typename object_traits<T>::id_type const& id, T& obj)
+ {
+ if (!find<T> (id, obj))
+ throw object_not_persistent ();
+ }
+
+ template <typename T>
+ typename object_traits<T>::pointer_type database::
find (typename object_traits<T>::id_type const& id)
{
- session& s (transaction::current ().session ());
- return s.find<T> (*this, id);
+ if (!transaction::has_current ())
+ throw not_in_transaction ();
+
+ return object_traits<T>::find (*this, id);
+ }
+
+ template <typename T>
+ bool database::
+ find (typename object_traits<T>::id_type const& id, T& obj)
+ {
+ if (!transaction::has_current ())
+ throw not_in_transaction ();
+
+ return object_traits<T>::find (*this, id, obj);
}
- template <typename T, template <typename> class P>
+ template <typename T>
void database::
- erase (P<T> p)
+ store (T& obj)
{
- // P<T> should be the same or convertible to
- // object_traits<T>::shared_ptr.
- //
- const typename object_traits<T>::shared_ptr& obj (p);
+ if (!transaction::has_current ())
+ throw not_in_transaction ();
- session& s (transaction::current ().session ());
- return s.erase (*this, obj);
+ object_traits<T>::update (*this, obj);
}
- template <typename T, template <typename> class P>
+ template <typename T>
+ void database::
+ erase (const T& obj)
+ {
+ erase<T> (object_traits<T>::id (obj));
+ }
+
+ template <typename T>
void database::
- modified (P<T> p)
+ erase (typename object_traits<T>::id_type const& id)
{
- // P<T> should be the same or convertible to
- // object_traits<T>::shared_ptr.
- //
- const typename object_traits<T>::shared_ptr& obj (p);
+ if (!transaction::has_current ())
+ throw not_in_transaction ();
- session& s (transaction::current ().session ());
- return s.modified (obj);
+ object_traits<T>::erase (*this, id);
}
}
diff --git a/odb/exceptions.hxx b/odb/exceptions.hxx
index 4b5909b..b677503 100644
--- a/odb/exceptions.hxx
+++ b/odb/exceptions.hxx
@@ -28,14 +28,6 @@ namespace odb
{
};
- struct already_in_session: odb::exception
- {
- };
-
- struct not_in_session: odb::exception
- {
- };
-
struct object_not_persistent: odb::exception
{
};
diff --git a/odb/forward.hxx b/odb/forward.hxx
index b59034f..8e91407 100644
--- a/odb/forward.hxx
+++ b/odb/forward.hxx
@@ -8,7 +8,6 @@
namespace odb
{
- class session;
class database;
class transaction;
@@ -31,7 +30,7 @@ namespace odb
class object_factory;
template <typename P>
- class shared_factory;
+ class pointer_factory;
};
}
diff --git a/odb/makefile b/odb/makefile
index 71c719a..fdeb6ea 100644
--- a/odb/makefile
+++ b/odb/makefile
@@ -6,10 +6,9 @@
include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make
cxx_tun := \
+shared-ptr/base.cxx \
exception.cxx \
exceptions.cxx \
-shared-ptr/base.cxx \
-session.cxx \
database.cxx \
transaction.cxx
diff --git a/odb/shared-ptr-traits.hxx b/odb/pointer-traits.hxx
index a1d5146..a715a9d 100644
--- a/odb/shared-ptr-traits.hxx
+++ b/odb/pointer-traits.hxx
@@ -1,10 +1,10 @@
-// file : odb/shared-ptr-traits.hxx
+// file : odb/pointer-traits.hxx
// author : Boris Kolpackov <boris@codesynthesis.com>
// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
// license : GNU GPL v2; see accompanying LICENSE file
-#ifndef ODB_SHARED_PTR_TRAITS_HXX
-#define ODB_SHARED_PTR_TRAITS_HXX
+#ifndef ODB_POINTER_TRAITS_HXX
+#define ODB_POINTER_TRAITS_HXX
#include <new> // operators new/delete
#include <cstddef> // std::size_t
@@ -14,7 +14,7 @@
namespace odb
{
template <typename P>
- class shared_ptr_traits;
+ class pointer_traits;
// Default implementation that should work for any sensible smart
// pointer with one template argument (object type). The only
@@ -23,16 +23,16 @@ namespace odb
// NULL.
//
template <typename T, template <typename> class P>
- class shared_ptr_traits< P<T> >
+ class pointer_traits< P<T> >
{
public:
typedef T type;
- typedef P<T> shared_ptr;
+ typedef P<T> pointer;
// Return underlying pointer, including NULL.
//
static type*
- get_ptr (const shared_ptr& p)
+ get_ptr (const pointer& p)
{
return p.operator-> ();
}
@@ -40,7 +40,7 @@ namespace odb
// Return reference to the pointed-to object.
//
static type&
- get_ref (const shared_ptr& p)
+ get_ref (const pointer& p)
{
return *p;
}
@@ -48,7 +48,7 @@ namespace odb
// Return true if the pointer is NULL.
//
static bool
- null_ptr (const shared_ptr& p)
+ null_ptr (const pointer& p)
{
return get_ptr () == 0;
}
@@ -64,7 +64,7 @@ namespace odb
// Free memory allocated for a shared object. This functions is
// only called if the constructor of the object being created
- // fails. Otherwise, shared_ptr is used to delete the object
+ // fails. Otherwise, pointer is used to delete the object
// and free the memory. This behavior is identical to the one
// used by operator delete overloading.
//
@@ -75,29 +75,72 @@ namespace odb
}
};
+ // Specialization for naked pointer.
+ //
+ template <typename T>
+ class pointer_traits<T*>
+ {
+ public:
+ typedef T type;
+ typedef T* pointer;
+
+ static type*
+ get_ptr (pointer p)
+ {
+ return p;
+ }
+
+ static type&
+ get_ref (pointer p)
+ {
+ return *p;
+ }
+
+ // Return true if the pointer is NULL.
+ //
+ static bool
+ null_ptr (pointer p)
+ {
+ return p == 0;
+ }
+
+ public:
+ static void*
+ allocate (std::size_t n)
+ {
+ return operator new (n);
+ }
+
+ static void
+ free (void* p)
+ {
+ operator delete (p);
+ }
+ };
+
// Specialization for odb::shared_ptr.
//
template <typename T>
- class shared_ptr_traits< shared_ptr<T> >
+ class pointer_traits< shared_ptr<T> >
{
public:
typedef T type;
- typedef odb::shared_ptr<T> shared_ptr;
+ typedef odb::shared_ptr<T> pointer;
static type*
- get_ptr (const shared_ptr& p)
+ get_ptr (const pointer& p)
{
return p.get ();
}
static type&
- get_ref (const shared_ptr& p)
+ get_ref (const pointer& p)
{
return *p;
}
static bool
- null_ptr (const shared_ptr& p)
+ null_ptr (const pointer& p)
{
return !p;
}
@@ -116,4 +159,4 @@ namespace odb
};
}
-#endif // ODB_SHARED_PTR_TRAITS_HXX
+#endif // ODB_POINTER_TRAITS_HXX
diff --git a/odb/session.cxx b/odb/session.cxx
deleted file mode 100644
index 9ee0104..0000000
--- a/odb/session.cxx
+++ /dev/null
@@ -1,120 +0,0 @@
-// file : odb/session.cxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
-// license : GNU GPL v2; see accompanying LICENSE file
-
-#include <utility> // std::make_pair
-
-#include <odb/session.hxx>
-#include <odb/transaction.hxx>
-
-namespace odb
-{
- session::type_map::
- ~type_map ()
- {
- }
-
- session::object_proxy::
- ~object_proxy ()
- {
- }
-
- //
- // session
- //
-
- static session* current_session = 0;
-
- session::
- session ()
- {
- if (current_session != 0)
- throw already_in_session ();
-
- current_session = this;
- }
-
- bool session::
- has_current ()
- {
- return current_session != 0;
- }
-
- session& session::
- current ()
- {
- if (current_session == 0)
- throw not_in_session ();
-
- return *current_session;
- }
-
- void session::
- current (session& s)
- {
- current_session = &s;
- }
-
- void session::
- reset_current ()
- {
- current_session = 0;
- }
-
- void session::
- flush ()
- {
- if (!transaction::has_current ())
- throw not_in_transaction ();
-
- // @@ Order of insertion and deletion can be important (triggers,
- // id assignment, constraints etc).
- //
-
- for (object_map::iterator i (object_map_.begin ()),
- e (object_map_.end ()); i != e;)
- {
- object_proxy& pxy (*i->second);
-
- switch (pxy.state_)
- {
- case object_proxy::transient:
- {
- pxy.persist ();
-
- // If the id is auto-assigned, then we only get it now, so
- // register with the id map.
- //
- if (pxy.id_source_ != ids_assigned)
- pxy.register_id (id_map_, i);
-
- pxy.state_ = object_proxy::clean;
- ++i;
- break;
- }
- case object_proxy::dirty:
- {
- pxy.update ();
- pxy.state_ = object_proxy::clean;
- ++i;
- break;
- }
- case object_proxy::erased:
- {
- pxy.erase ();
- pxy.unregister_id (id_map_);
- object_map_.erase (i++);
- break;
- }
- case object_proxy::clean:
- {
- // Nothing to do for this case.
- //
- ++i;
- break;
- }
- }
- }
- }
-}
diff --git a/odb/session.hxx b/odb/session.hxx
deleted file mode 100644
index 90df00d..0000000
--- a/odb/session.hxx
+++ /dev/null
@@ -1,190 +0,0 @@
-// file : odb/session.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
-// license : GNU GPL v2; see accompanying LICENSE file
-
-#ifndef ODB_SESSION_HXX
-#define ODB_SESSION_HXX
-
-#include <map>
-#include <typeinfo>
-
-#include <odb/forward.hxx>
-#include <odb/traits.hxx>
-
-namespace odb
-{
- class session
- {
- public:
- session ();
- ~session ()
- {
- reset_current ();
- }
-
- private:
- session (const session&);
- session& operator= (const session&);
-
- public:
- template <typename T, template <typename> class P>
- typename object_traits<T>::id_type
- persist (database&, P<T> obj);
-
- template <typename T>
- typename object_traits<T>::shared_ptr
- find (database&, typename object_traits<T>::id_type const&);
-
- template <typename T, template <typename> class P>
- void
- erase (database&, P<T> obj);
-
- template <typename T, template <typename> class P>
- void
- modified (P<T> obj);
-
- void
- flush ();
-
- public:
- // Return true if there is a session in effect.
- //
- static bool
- has_current ();
-
- // Get current thread's session. Throw if no session in effect.
- //
- static session&
- current ();
-
- // Set current thread's session.
- //
- static void
- current (session&);
-
- // Revert to the no session in effect state.
- //
- static void
- reset_current ();
-
- private:
- struct object_proxy;
- typedef std::map< void*, shared_ptr<object_proxy> > object_map;
-
- struct type_map
- {
- virtual
- ~type_map () = 0;
- };
-
- template <typename T>
- struct type_map_impl:
- type_map,
- std::map<typename object_traits<T>::id_type, object_map::iterator>
- {
- };
-
- struct type_info_comparator
- {
- bool
- operator() (const std::type_info* x, const std::type_info* y) const
- {
- // XL C++ on AIX has buggy type_info::before() in that
- // it returns true for two different type_info objects
- // that happened to be for the same type.
- //
-#if defined(__xlC__) && defined(_AIX)
- return *x != *y && x->before (*y);
-#else
- return x->before (*y);
-#endif
- }
- };
-
- typedef
- std::map<const std::type_info*, shared_ptr<type_map>, type_info_comparator>
- id_map;
-
- //
- //
- struct object_proxy
- {
- virtual
- ~object_proxy () = 0;
-
- object_proxy (database& db, id_source is)
- : id_source_ (is), db_ (db)
- {
- }
-
- enum state
- {
- transient, /* Persisted out of transaction. */
- clean,
- dirty, /* To be updated on flush. */
- erased /* To be deleted on flush. */
- };
-
- public:
- virtual void
- persist () = 0;
-
- virtual void
- update () = 0;
-
- virtual void
- erase () = 0;
-
- virtual void
- register_id (id_map&, object_map::iterator) = 0;
-
- virtual void
- unregister_id (id_map&) = 0;
-
- public:
- state state_;
- id_source id_source_;
- database& db_;
- };
-
- template <typename T>
- struct object_proxy_impl: object_proxy
- {
- typedef object_traits<T> traits;
- typedef typename traits::shared_ptr obj_ptr;
- typedef typename traits::shared_ops ptr_ops;
-
- object_proxy_impl (database& db, obj_ptr obj)
- : object_proxy (db, traits::id_source), obj_ (obj)
- {
- }
-
- public:
- virtual void
- persist ();
-
- virtual void
- update ();
-
- virtual void
- erase ();
-
- virtual void
- register_id (id_map&, object_map::iterator);
-
- virtual void
- unregister_id (id_map&);
-
- public:
- obj_ptr obj_;
- };
-
- object_map object_map_;
- id_map id_map_;
- };
-}
-
-#include <odb/session.txx>
-
-#endif // ODB_SESSION_HXX
diff --git a/odb/session.txx b/odb/session.txx
deleted file mode 100644
index 55155f7..0000000
--- a/odb/session.txx
+++ /dev/null
@@ -1,320 +0,0 @@
-// 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 <utility> // std::make_pair
-
-#include <odb/exceptions.hxx>
-#include <odb/transaction.hxx>
-
-#include <iostream> // @@ tmp
-
-namespace odb
-{
- //
- // session::object_proxy_impl
- //
-
- template <typename T>
- void session::object_proxy_impl<T>::
- persist ()
- {
- traits::insert (db_, ptr_ops::get_ref (obj_));
- }
-
- template <typename T>
- void session::object_proxy_impl<T>::
- update ()
- {
- traits::update (db_, ptr_ops::get_ref (obj_));
- }
-
- template <typename T>
- void session::object_proxy_impl<T>::
- erase ()
- {
- traits::erase (db_, traits::id (ptr_ops::get_ref (obj_)));
- }
-
- template <typename T>
- void session::object_proxy_impl<T>::
- register_id (id_map& idm, object_map::iterator i)
- {
- // For polymorphic types we should use the root of the hierarchy
- // (presumably defined in traits) as a type id so that all types
- // in this hierarchy end up in the same map. See also other places.
- //
- shared_ptr<type_map>& m (idm[&typeid (T)]);
-
- if (!m)
- m.reset (new (shared) type_map_impl<T>);
-
- type_map_impl<T>& mi (static_cast<type_map_impl<T>&> (*m));
-
- std::pair<typename type_map_impl<T>::iterator, bool> r (
- mi.insert (std::make_pair (traits::id (ptr_ops::get_ref (obj_)), i)));
-
- if (!r.second)
- throw object_already_persistent ();
- }
-
- template <typename T>
- void session::object_proxy_impl<T>::
- unregister_id (id_map& idm)
- {
- shared_ptr<type_map>& m (idm[&typeid (T)]);
-
- if (m)
- {
- type_map_impl<T>& mi (static_cast<type_map_impl<T>&> (*m));
- mi.erase (traits::id (ptr_ops::get_ref (obj_)));
- }
- }
-
- //
- // session
- //
-
- template <typename T, template <typename> class P>
- typename object_traits<T>::id_type session::
- persist (database& db, P<T> p)
- {
- typedef object_traits<T> traits;
- typedef typename traits::shared_ops ops;
-
- // P<T> should be the same or convertible to
- // object_traits<T>::shared_ptr.
- //
- const typename traits::shared_ptr& obj (p);
-
- // For polymorphic types we need to cast the pointer to the
- // root of the hierarchy.
- //
- void* ptr (ops::get_ptr (obj));
- T& ref (ops::get_ref (obj));
-
- // @@ What if the object that's already in the map is in the
- // erased state?
- //
- if (object_map_.find (ptr) != object_map_.end ())
- throw object_already_persistent ();
-
- shared_ptr<object_proxy> pxy (new (shared) object_proxy_impl<T> (db, obj));
-
- // If we are in a transaction, save this object immediately. This
- // helps with two things: (1) assignment of auto-generated ids and
- // (2) detection of duplicate objects.
- //
- if (transaction::has_current ())
- {
- // @@ What if the manually-assigned id is already in use by
- // an object waiting to be deleted?
- //
- traits::insert (db, ref);
- pxy->state_ = object_proxy::clean;
- }
- else
- pxy->state_ = object_proxy::transient;
-
- object_map::iterator i (
- object_map_.insert (std::make_pair (ptr, pxy)).first);
-
- // If this object has auto-assigned id and we haven't hit the db
- // yet, then the id is "NULL" and we cannot insert this object
- // into the id map.
- //
- if (pxy->state_ != object_proxy::transient ||
- traits::id_source == ids_assigned)
- {
- try
- {
- pxy->register_id (id_map_, i);
- }
- catch (...)
- {
- object_map_.erase (i);
- throw;
- }
- }
-
- return traits::id (ref);
- }
-
- template <typename T>
- typename object_traits<T>::shared_ptr session::
- find (database& db, typename object_traits<T>::id_type const& id)
- {
- typedef object_traits<T> traits;
- typedef typename traits::shared_ops ops;
- typedef typename traits::shared_ptr obj_ptr;
-
- // First see if we have this object in the maps.
- //
- shared_ptr<type_map>& m (id_map_[&typeid (T)]);
-
- if (m)
- {
- typedef type_map_impl<T> map_impl;
- map_impl& mi (static_cast<map_impl&> (*m));
- typename map_impl::iterator i (mi.find (id));
-
- if (i != mi.end ())
- {
- const object_map::iterator& j (i->second);
-
- if (j->second->state_ != object_proxy::erased)
- {
- object_proxy_impl<T>& pxy (
- static_cast<object_proxy_impl<T>&> (*j->second));
- return pxy.obj_;
- }
- else
- return obj_ptr ();
- }
- }
-
- // If we are in transaction then hit the database. Otherwise, the
- // object is not found.
- //
- if (!transaction::has_current ())
- return obj_ptr ();
-
- obj_ptr obj (traits::find (db, id));
-
- if (ops::null_ptr (obj))
- return obj;
-
- // Add this object to our maps.
- //
- void* ptr (ops::get_ptr (obj));
- shared_ptr<object_proxy> pxy (new (shared) object_proxy_impl<T> (db, obj));
- pxy->state_ = object_proxy::clean;
-
- object_map::iterator i (
- object_map_.insert (
- std::make_pair (ptr, pxy)).first);
-
- try
- {
- if (!m)
- m.reset (new (shared) type_map_impl<T>);
-
- type_map_impl<T>& mi (static_cast<type_map_impl<T>&> (*m));
- mi.insert (std::make_pair (id, i));
- }
- catch (...)
- {
- object_map_.erase (i);
- throw;
- }
-
- return obj;
- }
-
- template <typename T, template <typename> class P>
- void session::
- erase (database& db, P<T> p)
- {
- typedef object_traits<T> traits;
- typedef typename traits::shared_ops ops;
-
- // P<T> should be the same or convertible to
- // object_traits<T>::shared_ptr.
- //
- const typename traits::shared_ptr& obj (p);
-
- // For polymorphic types we need to cast the pointer to the
- // root of the hierarchy.
- //
- void* ptr (ops::get_ptr (obj));
- T& ref (ops::get_ref (obj));
-
- object_map::iterator i (object_map_.find (ptr));
-
- if (object_map_.find (ptr) == object_map_.end ())
- throw object_not_persistent ();
-
- object_proxy& pxy (*i->second);
-
- switch (pxy.state_)
- {
- case object_proxy::transient:
- {
- // If this object is still transient then all we need to do is
- // purge it from the maps.
- //
-
- // See if we are registered in the id map.
- //
- if (traits::id_source == ids_assigned)
- pxy.unregister_id (id_map_);
-
- object_map_.erase (i);
- break;
- }
- case object_proxy::clean:
- case object_proxy::dirty:
- {
- // Ideally we would need to store the object id as well as the
- // version (optimistic concurrency) since the user is free to
- // modify the object state.
- //
- pxy.state_ = object_proxy::erased;
- break;
- }
- case object_proxy::erased:
- {
- // Already erased. Throw to be consistent with the transient
- // case.
- //
- throw object_not_persistent ();
- }
- }
- }
-
- template <typename T, template <typename> class P>
- void session::
- modified (P<T> p)
- {
- typedef object_traits<T> traits;
- typedef typename traits::shared_ops ops;
-
- // P<T> should be the same or convertible to
- // object_traits<T>::shared_ptr.
- //
- const typename traits::shared_ptr& obj (p);
-
- // For polymorphic types we need to cast the pointer to the
- // root of the hierarchy.
- //
- void* ptr (ops::get_ptr (obj));
-
- object_map::iterator i (object_map_.find (ptr));
-
- if (object_map_.find (ptr) == object_map_.end ())
- throw object_not_persistent ();
-
- object_proxy& pxy (*i->second);
-
- switch (pxy.state_)
- {
- case object_proxy::transient:
- case object_proxy::dirty:
- {
- // Nothing to do here.
- //
- break;
- }
- case object_proxy::clean:
- {
- pxy.state_ = object_proxy::dirty;
- break;
- }
- case object_proxy::erased:
- {
- throw object_not_persistent ();
- }
- }
- }
-}
diff --git a/odb/traits.hxx b/odb/traits.hxx
index e8e109c..50d87eb 100644
--- a/odb/traits.hxx
+++ b/odb/traits.hxx
@@ -6,11 +6,9 @@
#ifndef ODB_TRAITS_HXX
#define ODB_TRAITS_HXX
-#include <memory> // std::auto_ptr
-
#include <odb/forward.hxx>
#include <odb/shared-ptr.hxx>
-#include <odb/shared-ptr-traits.hxx>
+#include <odb/pointer-traits.hxx>
namespace odb
{
@@ -19,53 +17,55 @@ namespace odb
ids_assigned /* Assigned by the application. */
};
- // Specializations should defined the following members:
+ // template <typename T>
+ // class access::object_traits;
+ //
+ // Specializations should inherit from object_memory, object_factory
+ // and define the following members:
//
// id_type - object id (primary key) type
// id_source - object id (primary key) source
// id_type id (const T&) - get object id
//
- // void insert (database&, const T&)
- // void update (database&, const T&)
+ // void insert (database&, T&)
+ // void update (database&, T&)
// void erase (database&, const id_type&)
- // memory_traits<T>::shared_ptr find (database&, const id_type&)
+ // pointer_type find (database&, const id_type&)
+ // bool find (database&, const id_type&, T&)
//
- // And inherit from object_memory and object_factory.
//
- // template <typename T>
- // class access::object_traits;
template <typename T>
class access::object_memory
{
public:
- typedef odb::shared_ptr<T> shared_ptr;
- typedef std::auto_ptr<T> unique_ptr;
+ typedef T* pointer_type;
};
template <typename T>
class access::object_factory
{
public:
- static typename object_memory<T>::shared_ptr
+ static typename object_memory<T>::pointer_type
create ()
{
- // By default use shared_ptr-specific construction.
+ // By default use pointer-specific construction.
//
- return shared_factory<typename object_memory<T>::shared_ptr>::create ();
+ return
+ pointer_factory<typename object_memory<T>::pointer_type>::create ();
}
};
template <typename P>
- class access::shared_factory
+ class access::pointer_factory
{
public:
- typedef typename shared_ptr_traits<P>::type object_type;
+ typedef typename pointer_traits<P>::type object_type;
static P
create ()
{
- void* v (shared_ptr_traits<P>::allocate (sizeof (object_type)));
+ void* v (pointer_traits<P>::allocate (sizeof (object_type)));
guard g (v);
P p (new (v) object_type);
g.release ();
@@ -75,7 +75,7 @@ namespace odb
struct guard
{
guard (void* p): p_ (p) {}
- ~guard () {if (p_) shared_ptr_traits<P>::free (p_);}
+ ~guard () {if (p_) pointer_traits<P>::free (p_);}
void release () {p_ = 0;}
void* p_;
};
@@ -85,8 +85,8 @@ namespace odb
struct object_traits: access::object_traits<T>
{
typedef
- shared_ptr_traits<typename access::object_traits<T>::shared_ptr>
- shared_ops;
+ pointer_traits<typename access::object_traits<T>::pointer_type>
+ pointer_ops;
};
}
diff --git a/odb/transaction.cxx b/odb/transaction.cxx
index 7b28ea2..de5d1f6 100644
--- a/odb/transaction.cxx
+++ b/odb/transaction.cxx
@@ -61,11 +61,6 @@ namespace odb
if (finilized_)
throw transaction_already_finilized ();
- // Flush the session if we are in the session-per-transaction mode.
- //
- if (impl_->own_session ())
- session ().flush ();
-
impl_->commit ();
finilized_ = true;
}
@@ -87,7 +82,5 @@ namespace odb
transaction_impl::
~transaction_impl ()
{
- if (own_session ())
- reinterpret_cast<session_type*> (&session_mem_)->~session ();
}
}
diff --git a/odb/transaction.hxx b/odb/transaction.hxx
index 01d4a38..8d09d9f 100644
--- a/odb/transaction.hxx
+++ b/odb/transaction.hxx
@@ -6,8 +6,6 @@
#ifndef ODB_TRANSACTION_HXX
#define ODB_TRANSACTION_HXX
-#include <new> // placement new
-
#include <odb/forward.hxx>
namespace odb
@@ -17,7 +15,6 @@ namespace odb
class transaction
{
public:
- typedef odb::session session_type;
typedef odb::database database_type;
explicit
@@ -39,11 +36,6 @@ namespace odb
database_type&
database ();
- // Return the session this transaction is part of.
- //
- session_type&
- session ();
-
// Return current transaction or throw if there is no transaction
// in effect.
//
@@ -69,30 +61,17 @@ namespace odb
bool finilized_;
transaction_impl* impl_;
};
-}
-
-#include <odb/session.hxx>
-namespace odb
-{
class transaction_impl
{
protected:
friend class transaction;
- typedef odb::session session_type;
typedef odb::database database_type;
- transaction_impl (database_type& db, session_type& s)
- : database_ (db), session_ (s)
- {
- }
-
transaction_impl (database_type& db)
- : database_ (db),
- session_ (*reinterpret_cast<session_type*> (&session_mem_))
+ : database_ (db)
{
- new (&session_mem_) session_type ();
}
virtual
@@ -104,33 +83,14 @@ namespace odb
virtual void
rollback () = 0;
- session_type&
- session ()
- {
- return session_;
- }
-
database_type&
database ()
{
return database_;
}
- bool
- own_session () const
- {
- return &session_ == reinterpret_cast<const session_type*> (&session_mem_);
- }
-
protected:
database_type& database_;
- session_type& session_;
-
- union
- {
- void* align_;
- char data_[sizeof (session_type)];
- } session_mem_;
};
}
diff --git a/odb/transaction.ixx b/odb/transaction.ixx
index e6247e6..6101f53 100644
--- a/odb/transaction.ixx
+++ b/odb/transaction.ixx
@@ -11,12 +11,6 @@ namespace odb
return impl_->database ();
}
- inline transaction::session_type& transaction::
- session ()
- {
- return impl_->session ();
- }
-
inline transaction_impl& transaction::
implementation ()
{