diff options
-rw-r--r-- | makefile | 2 | ||||
-rw-r--r-- | odb/database.hxx | 58 | ||||
-rw-r--r-- | odb/database.txx | 84 | ||||
-rw-r--r-- | odb/exceptions.hxx | 8 | ||||
-rw-r--r-- | odb/forward.hxx | 3 | ||||
-rw-r--r-- | odb/makefile | 3 | ||||
-rw-r--r-- | odb/pointer-traits.hxx (renamed from odb/shared-ptr-traits.hxx) | 75 | ||||
-rw-r--r-- | odb/session.cxx | 120 | ||||
-rw-r--r-- | odb/session.hxx | 190 | ||||
-rw-r--r-- | odb/session.txx | 320 | ||||
-rw-r--r-- | odb/traits.hxx | 42 | ||||
-rw-r--r-- | odb/transaction.cxx | 7 | ||||
-rw-r--r-- | odb/transaction.hxx | 42 | ||||
-rw-r--r-- | odb/transaction.ixx | 6 |
14 files changed, 174 insertions, 786 deletions
@@ -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 () { |