| database.hxx | | database.hxx | |
| // file : odb/database.hxx | | // file : odb/database.hxx | |
| // author : Boris Kolpackov <boris@codesynthesis.com> | | // author : Boris Kolpackov <boris@codesynthesis.com> | |
|
| // copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #ifndef ODB_DATABASE_HXX | | #ifndef ODB_DATABASE_HXX | |
| #define ODB_DATABASE_HXX | | #define ODB_DATABASE_HXX | |
| | | | |
| #include <odb/pre.hxx> | | #include <odb/pre.hxx> | |
| | | | |
| #include <string> | | #include <string> | |
|
| | | #include <cstddef> // std::size_t | |
| | | | |
| #include <odb/traits.hxx> | | #include <odb/traits.hxx> | |
| #include <odb/forward.hxx> | | #include <odb/forward.hxx> | |
| #include <odb/query.hxx> | | #include <odb/query.hxx> | |
| #include <odb/result.hxx> | | #include <odb/result.hxx> | |
| #include <odb/exceptions.hxx> | | #include <odb/exceptions.hxx> | |
| | | | |
| #include <odb/details/export.hxx> | | #include <odb/details/export.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| | | | |
| skipping to change at line 39 | | skipping to change at line 40 | |
| ~database (); | | ~database (); | |
| | | | |
| // Object persistence API. | | // Object persistence API. | |
| // | | // | |
| public: | | public: | |
| | | | |
| // Make the object persistent. | | // Make the object persistent. | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| typename object_traits<T>::id_type | | typename object_traits<T>::id_type | |
|
| persist (const T& object); | | persist (T& object); | |
| | | | |
| template <typename T> | | template <typename T> | |
| typename object_traits<T>::id_type | | typename object_traits<T>::id_type | |
|
| persist (T& object); | | persist (T* obj_ptr); | |
| | | | |
| | | template <typename T, template <typename> class P> | |
| | | typename object_traits<T>::id_type | |
| | | persist (const P<T>& obj_ptr); | |
| | | | |
| | | template <typename T, template <typename> class P> | |
| | | typename object_traits<T>::id_type | |
| | | persist (P<T>& obj_ptr); | |
| | | | |
| | | template <typename T> | |
| | | typename object_traits<T>::id_type | |
| | | persist (const typename object_traits<T>::pointer_type& obj_ptr); | |
| | | | |
| // Throw object_not_persistent if not found. | | // Throw object_not_persistent if not found. | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| typename object_traits<T>::pointer_type | | typename object_traits<T>::pointer_type | |
| load (const typename object_traits<T>::id_type& id); | | load (const typename object_traits<T>::id_type& id); | |
| | | | |
| template <typename T> | | template <typename T> | |
| void | | void | |
| load (const typename object_traits<T>::id_type& id, T& object); | | load (const typename object_traits<T>::id_type& id, T& object); | |
| | | | |
| skipping to change at line 69 | | skipping to change at line 82 | |
| find (const typename object_traits<T>::id_type& id); | | find (const typename object_traits<T>::id_type& id); | |
| | | | |
| template <typename T> | | template <typename T> | |
| bool | | bool | |
| find (const typename object_traits<T>::id_type& id, T& object); | | find (const typename object_traits<T>::id_type& id, T& object); | |
| | | | |
| // Update the state of a modified objects. | | // Update the state of a modified objects. | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| void | | void | |
|
| update (const T& object); | | update (T& object); | |
| | | | |
| | | template <typename T> | |
| | | void | |
| | | update (T* obj_ptr); | |
| | | | |
| | | template <typename T, template <typename> class P> | |
| | | void | |
| | | update (const P<T>& obj_ptr); | |
| | | | |
| | | template <typename T, template <typename> class P> | |
| | | void | |
| | | update (P<T>& obj_ptr); | |
| | | | |
| | | template <typename T> | |
| | | void | |
| | | update (const typename object_traits<T>::pointer_type& obj_ptr); | |
| | | | |
| // Make the object transient. Throw object_not_persistent if not | | // Make the object transient. Throw object_not_persistent if not | |
| // found. | | // found. | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| void | | void | |
|
| erase (const T& object); | | erase (const typename object_traits<T>::id_type& id); | |
| | | | |
| template <typename T> | | template <typename T> | |
| void | | void | |
|
| erase (const typename object_traits<T>::id_type& id); | | erase (T& object); | |
| | | | |
| | | template <typename T> | |
| | | void | |
| | | erase (T* obj_ptr); | |
| | | | |
| | | template <typename T, template <typename> class P> | |
| | | void | |
| | | erase (const P<T>& obj_ptr); | |
| | | | |
| | | template <typename T, template <typename> class P> | |
| | | void | |
| | | erase (P<T>& obj_ptr); | |
| | | | |
| | | template <typename T> | |
| | | void | |
| | | erase (const typename object_traits<T>::pointer_type& obj_ptr); | |
| | | | |
| // Query API. | | // Query API. | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| result<T> | | result<T> | |
| query (bool cache = true); | | query (bool cache = true); | |
| | | | |
| template <typename T> | | template <typename T> | |
| result<T> | | result<T> | |
| query (const char*, bool cache = true); | | query (const char*, bool cache = true); | |
| | | | |
| template <typename T> | | template <typename T> | |
| result<T> | | result<T> | |
| query (const std::string&, bool cache = true); | | query (const std::string&, bool cache = true); | |
| | | | |
| template <typename T> | | template <typename T> | |
| result<T> | | result<T> | |
|
| query (const odb::query<T>&, bool cache = true); | | query (const odb::query<typename object_traits<T>::object_type>&, | |
| | | bool cache = true); | |
| | | | |
| | | // Native database statement execution. | |
| | | // | |
| | | public: | |
| | | unsigned long long | |
| | | execute (const char* statement); | |
| | | | |
| | | unsigned long long | |
| | | execute (const std::string& statement); | |
| | | | |
| | | virtual unsigned long long | |
| | | execute (const char* statement, std::size_t length) = 0; | |
| | | | |
| // Transaction API. | | // Transaction API. | |
| // | | // | |
| public: | | public: | |
| virtual transaction_impl* | | virtual transaction_impl* | |
| begin () = 0; | | begin () = 0; | |
| | | | |
| protected: | | protected: | |
| database (); | | database (); | |
| | | | |
|
| | | protected: | |
| | | template <typename T> | |
| | | typename object_traits<T>::id_type | |
| | | persist_ (const typename object_traits<T>::pointer_type&); | |
| | | | |
| | | template <typename T> | |
| | | void | |
| | | update_ (const typename object_traits<T>::pointer_type&); | |
| | | | |
| | | template <typename T> | |
| | | void | |
| | | erase_ (const typename object_traits<T>::pointer_type&); | |
| | | | |
| private: | | private: | |
| database (const database&); | | database (const database&); | |
| database& operator= (const database&); | | database& operator= (const database&); | |
| }; | | }; | |
| } | | } | |
| | | | |
| #include <odb/database.ixx> | | #include <odb/database.ixx> | |
| #include <odb/database.txx> | | #include <odb/database.txx> | |
| | | | |
| #include <odb/post.hxx> | | #include <odb/post.hxx> | |
| | | | |
End of changes. 9 change blocks. |
| 7 lines changed or deleted | | 78 lines changed or added | |
|
| database.ixx | | database.ixx | |
| // file : odb/database.ixx | | // file : odb/database.ixx | |
| // author : Boris Kolpackov <boris@codesynthesis.com> | | // author : Boris Kolpackov <boris@codesynthesis.com> | |
|
| // copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
|
| | | #include <cstring> // std::string | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| inline database:: | | inline database:: | |
| database () | | database () | |
| { | | { | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| | | inline typename object_traits<T>::id_type database:: | |
| | | persist (T* p) | |
| | | { | |
| | | typedef typename object_traits<T>::pointer_type object_pointer; | |
| | | | |
| | | // The passed pointer should be the same or implicit-convertible | |
| | | // to the object pointer. This way we make sure the object pointer | |
| | | // does not assume ownership of the passed object. | |
| | | // | |
| | | const object_pointer& pobj (p); | |
| | | | |
| | | return persist_<T> (pobj); | |
| | | } | |
| | | | |
| | | template <typename T, template <typename> class P> | |
| | | inline typename object_traits<T>::id_type database:: | |
| | | persist (const P<T>& p) | |
| | | { | |
| | | typedef typename object_traits<T>::pointer_type object_pointer; | |
| | | | |
| | | // The passed pointer should be the same or implicit-convertible | |
| | | // to the object pointer. This way we make sure the object pointer | |
| | | // does not assume ownership of the passed object. | |
| | | // | |
| | | const object_pointer& pobj (p); | |
| | | | |
| | | return persist_<T> (pobj); | |
| | | } | |
| | | | |
| | | template <typename T, template <typename> class P> | |
| | | inline typename object_traits<T>::id_type database:: | |
| | | persist (P<T>& p) | |
| | | { | |
| | | const P<T>& cr (p); | |
| | | return persist<T, P> (cr); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | inline typename object_traits<T>::id_type database:: | |
| | | persist (const typename object_traits<T>::pointer_type& pobj) | |
| | | { | |
| | | return persist_<T> (pobj); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | inline void database:: | |
| | | update (T* p) | |
| | | { | |
| | | typedef typename object_traits<T>::pointer_type object_pointer; | |
| | | | |
| | | // The passed pointer should be the same or implicit-convertible | |
| | | // to the object pointer. This way we make sure the object pointer | |
| | | // does not assume ownership of the passed object. | |
| | | // | |
| | | const object_pointer& pobj (p); | |
| | | | |
| | | update_<T> (pobj); | |
| | | } | |
| | | | |
| | | template <typename T, template <typename> class P> | |
| | | inline void database:: | |
| | | update (const P<T>& p) | |
| | | { | |
| | | typedef typename object_traits<T>::pointer_type object_pointer; | |
| | | | |
| | | // The passed pointer should be the same or implicit-convertible | |
| | | // to the object pointer. This way we make sure the object pointer | |
| | | // does not assume ownership of the passed object. | |
| | | // | |
| | | const object_pointer& pobj (p); | |
| | | | |
| | | update_<T> (pobj); | |
| | | } | |
| | | | |
| | | template <typename T, template <typename> class P> | |
| | | inline void database:: | |
| | | update (P<T>& p) | |
| | | { | |
| | | const P<T>& cr (p); | |
| | | update<T, P> (cr); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | inline void database:: | |
| | | update (const typename object_traits<T>::pointer_type& pobj) | |
| | | { | |
| | | update_<T> (pobj); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | inline void database:: | |
| | | erase (T& obj) | |
| | | { | |
| | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename odb::object_traits<T>::object_type object_type; | |
| | | typedef odb::object_traits<object_type> object_traits; | |
| | | | |
| | | erase<T> (object_traits::id (obj)); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | inline void database:: | |
| | | erase (T* p) | |
| | | { | |
| | | typedef typename object_traits<T>::pointer_type object_pointer; | |
| | | | |
| | | // The passed pointer should be the same or implicit-convertible | |
| | | // to the object pointer. This way we make sure the object pointer | |
| | | // does not assume ownership of the passed object. | |
| | | // | |
| | | const object_pointer& pobj (p); | |
| | | | |
| | | erase_<T> (pobj); | |
| | | } | |
| | | | |
| | | template <typename T, template <typename> class P> | |
| | | inline void database:: | |
| | | erase (const P<T>& p) | |
| | | { | |
| | | typedef typename object_traits<T>::pointer_type object_pointer; | |
| | | | |
| | | // The passed pointer should be the same or implicit-convertible | |
| | | // to the object pointer. This way we make sure the object pointer | |
| | | // does not assume ownership of the passed object. | |
| | | // | |
| | | const object_pointer& pobj (p); | |
| | | | |
| | | erase_<T> (pobj); | |
| | | } | |
| | | | |
| | | template <typename T, template <typename> class P> | |
| | | inline void database:: | |
| | | erase (P<T>& p) | |
| | | { | |
| | | const P<T>& cr (p); | |
| | | erase<T, P> (cr); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | inline void database:: | |
| | | erase (const typename object_traits<T>::pointer_type& pobj) | |
| | | { | |
| | | erase_<T> (pobj); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| inline void database:: | | inline void database:: | |
|
| erase (const T& obj) | | erase_ (const typename object_traits<T>::pointer_type& pobj) | |
| { | | { | |
|
| erase<T> (object_traits<T>::id (obj)); | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename odb::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; | |
| | | | |
| | | erase<T> (object_traits::id (pointer_traits::get_ref (pobj))); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| inline result<T> database:: | | inline result<T> database:: | |
| query (bool cache) | | query (bool cache) | |
| { | | { | |
|
| return query (odb::query<T> (), cache); | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename odb::object_traits<T>::object_type object_type; | |
| | | | |
| | | return query<T> (odb::query<object_type> (), cache); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| inline result<T> database:: | | inline result<T> database:: | |
| query (const char* q, bool cache) | | query (const char* q, bool cache) | |
| { | | { | |
|
| return query (odb::query<T> (q), cache); | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename odb::object_traits<T>::object_type object_type; | |
| | | | |
| | | return query<T> (odb::query<object_type> (q), cache); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| inline result<T> database:: | | inline result<T> database:: | |
| query (const std::string& q, bool cache) | | query (const std::string& q, bool cache) | |
| { | | { | |
|
| return query (odb::query<T> (q), cache); | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename odb::object_traits<T>::object_type object_type; | |
| | | | |
| | | return query<T> (odb::query<object_type> (q), cache); | |
| | | } | |
| | | | |
| | | inline unsigned long long database:: | |
| | | execute (const char* statement) | |
| | | { | |
| | | return execute (statement, std::strlen (statement)); | |
| | | } | |
| | | | |
| | | inline unsigned long long database:: | |
| | | execute (const std::string& statement) | |
| | | { | |
| | | return execute (statement.c_str (), statement.size ()); | |
| } | | } | |
| } | | } | |
| | | | |
End of changes. 8 change blocks. |
| 6 lines changed or deleted | | 187 lines changed or added | |
|
| database.txx | | database.txx | |
| // file : odb/database.txx | | // file : odb/database.txx | |
| // author : Boris Kolpackov <boris@codesynthesis.com> | | // author : Boris Kolpackov <boris@codesynthesis.com> | |
|
| // copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #include <odb/exceptions.hxx> | | #include <odb/exceptions.hxx> | |
| #include <odb/transaction.hxx> | | #include <odb/transaction.hxx> | |
|
| | | #include <odb/session.hxx> | |
| | | #include <odb/cache-traits.hxx> | |
| | | #include <odb/pointer-traits.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| template <typename T> | | template <typename T> | |
| typename object_traits<T>::id_type database:: | | typename object_traits<T>::id_type database:: | |
|
| persist (const T& obj) | | persist (T& obj) | |
| { | | { | |
|
| typedef object_traits<T> traits; | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename odb::object_traits<T>::object_type object_type; | |
| | | typedef odb::object_traits<object_type> object_traits; | |
| | | | |
| if (!transaction::has_current ()) | | if (!transaction::has_current ()) | |
| throw not_in_transaction (); | | throw not_in_transaction (); | |
| | | | |
|
| traits::persist (*this, obj); | | object_traits::persist (*this, obj); | |
| return traits::id (obj); | | const typename object_traits::id_type& id (object_traits::id (obj)); | |
| | | reference_cache_traits<T>::insert (*this, id, obj); | |
| | | return id; | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| typename object_traits<T>::id_type database:: | | typename object_traits<T>::id_type database:: | |
|
| persist (T& obj) | | persist_ (const typename object_traits<T>::pointer_type& pobj) | |
| { | | { | |
|
| typedef object_traits<T> traits; | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename odb::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; | |
| | | | |
| if (!transaction::has_current ()) | | if (!transaction::has_current ()) | |
| throw not_in_transaction (); | | throw not_in_transaction (); | |
| | | | |
|
| traits::persist (*this, obj); | | T& obj (pointer_traits::get_ref (pobj)); | |
| return traits::id (obj); | | object_traits::persist (*this, obj); | |
| | | const typename object_traits::id_type& id (object_traits::id (obj)); | |
| | | pointer_cache_traits<pointer_type>::insert (*this, id, pobj); | |
| | | return id; | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| typename object_traits<T>::pointer_type database:: | | typename object_traits<T>::pointer_type database:: | |
| load (const typename object_traits<T>::id_type& id) | | load (const typename object_traits<T>::id_type& id) | |
| { | | { | |
|
| typedef object_traits<T> traits; | | typedef typename object_traits<T>::pointer_type pointer_type; | |
| typename traits::pointer_type r (find<T> (id)); | | typedef odb::pointer_traits<pointer_type> pointer_traits; | |
| | | | |
|
| if (traits::pointer_traits::null_ptr (r)) | | pointer_type r (find<T> (id)); | |
| | | | |
| | | if (pointer_traits::null_ptr (r)) | |
| throw object_not_persistent (); | | throw object_not_persistent (); | |
| | | | |
| return r; | | return r; | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void database:: | | void database:: | |
| load (const typename object_traits<T>::id_type& id, T& obj) | | load (const typename object_traits<T>::id_type& id, T& obj) | |
| { | | { | |
| if (!find<T> (id, obj)) | | if (!find<T> (id, obj)) | |
| throw object_not_persistent (); | | throw object_not_persistent (); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| typename object_traits<T>::pointer_type database:: | | typename object_traits<T>::pointer_type database:: | |
| find (const typename object_traits<T>::id_type& id) | | find (const typename object_traits<T>::id_type& id) | |
| { | | { | |
|
| | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename odb::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; | |
| | | | |
| | | // First check the session. | |
| | | // | |
| | | { | |
| | | pointer_type p ( | |
| | | pointer_cache_traits<pointer_type>::find (*this, id)); | |
| | | | |
| | | if (!pointer_traits::null_ptr (p)) | |
| | | return p; | |
| | | } | |
| | | | |
| if (!transaction::has_current ()) | | if (!transaction::has_current ()) | |
| throw not_in_transaction (); | | throw not_in_transaction (); | |
| | | | |
|
| return object_traits<T>::find (*this, id); | | // Compiler error pointing here? Perhaps the object doesn't have the | |
| | | // default constructor? | |
| | | // | |
| | | return pointer_type (object_traits::find (*this, id)); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| bool database:: | | bool database:: | |
| find (const typename object_traits<T>::id_type& id, T& obj) | | find (const typename object_traits<T>::id_type& id, T& obj) | |
| { | | { | |
|
| | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename odb::object_traits<T>::object_type object_type; | |
| | | typedef odb::object_traits<object_type> object_traits; | |
| | | | |
| if (!transaction::has_current ()) | | if (!transaction::has_current ()) | |
| throw not_in_transaction (); | | throw not_in_transaction (); | |
| | | | |
|
| return object_traits<T>::find (*this, id, obj); | | return object_traits::find (*this, id, obj); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void database:: | | void database:: | |
|
| update (const T& obj) | | update (T& obj) | |
| { | | { | |
|
| | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename odb::object_traits<T>::object_type object_type; | |
| | | typedef odb::object_traits<object_type> object_traits; | |
| | | | |
| if (!transaction::has_current ()) | | if (!transaction::has_current ()) | |
| throw not_in_transaction (); | | throw not_in_transaction (); | |
| | | | |
|
| object_traits<T>::update (*this, obj); | | object_traits::update (*this, obj); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | void database:: | |
| | | update_ (const typename object_traits<T>::pointer_type& pobj) | |
| | | { | |
| | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename odb::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; | |
| | | | |
| | | if (!transaction::has_current ()) | |
| | | throw not_in_transaction (); | |
| | | | |
| | | object_traits::update (*this, pointer_traits::get_ref (pobj)); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void database:: | | void database:: | |
| erase (const typename object_traits<T>::id_type& id) | | erase (const typename object_traits<T>::id_type& id) | |
| { | | { | |
|
| | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename odb::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; | |
| | | | |
| if (!transaction::has_current ()) | | if (!transaction::has_current ()) | |
| throw not_in_transaction (); | | throw not_in_transaction (); | |
| | | | |
|
| object_traits<T>::erase (*this, id); | | object_traits::erase (*this, id); | |
| | | pointer_cache_traits<pointer_type>::erase (*this, id); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| result<T> database:: | | result<T> database:: | |
|
| query (const odb::query<T>& q, bool cache) | | query (const odb::query<typename object_traits<T>::object_type>& q, | |
| | | bool cache) | |
| { | | { | |
|
| | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename odb::object_traits<T>::object_type object_type; | |
| | | typedef odb::object_traits<object_type> object_traits; | |
| | | | |
| if (!transaction::has_current ()) | | if (!transaction::has_current ()) | |
| throw not_in_transaction (); | | throw not_in_transaction (); | |
| | | | |
|
| result<T> r (object_traits<T>::query (*this, q)); | | result<T> r (object_traits::template query<T> (*this, q)); | |
| | | | |
| if (cache) | | if (cache) | |
| r.cache (); | | r.cache (); | |
| | | | |
| return r; | | return r; | |
| } | | } | |
| } | | } | |
| | | | |
End of changes. 22 change blocks. |
| 19 lines changed or deleted | | 101 lines changed or added | |
|
| exceptions.hxx | | exceptions.hxx | |
| // file : odb/exceptions.hxx | | // file : odb/exceptions.hxx | |
| // author : Boris Kolpackov <boris@codesynthesis.com> | | // author : Boris Kolpackov <boris@codesynthesis.com> | |
|
| // copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #ifndef ODB_EXCEPTIONS_HXX | | #ifndef ODB_EXCEPTIONS_HXX | |
| #define ODB_EXCEPTIONS_HXX | | #define ODB_EXCEPTIONS_HXX | |
| | | | |
| #include <odb/pre.hxx> | | #include <odb/pre.hxx> | |
| | | | |
| #include <odb/exception.hxx> | | #include <odb/exception.hxx> | |
| | | | |
| #include <odb/details/export.hxx> | | #include <odb/details/export.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
|
| | | struct LIBODB_EXPORT null_pointer: odb::exception | |
| | | { | |
| | | virtual const char* | |
| | | what () const throw (); | |
| | | }; | |
| | | | |
| | | // Transaction exceptions. | |
| | | // | |
| struct LIBODB_EXPORT already_in_transaction: odb::exception | | struct LIBODB_EXPORT already_in_transaction: odb::exception | |
| { | | { | |
| virtual const char* | | virtual const char* | |
| what () const throw (); | | what () const throw (); | |
| }; | | }; | |
| | | | |
| struct LIBODB_EXPORT not_in_transaction: odb::exception | | struct LIBODB_EXPORT not_in_transaction: odb::exception | |
| { | | { | |
| virtual const char* | | virtual const char* | |
| what () const throw (); | | what () const throw (); | |
| }; | | }; | |
| | | | |
| struct LIBODB_EXPORT transaction_already_finalized: odb::exception | | struct LIBODB_EXPORT transaction_already_finalized: odb::exception | |
| { | | { | |
| virtual const char* | | virtual const char* | |
| what () const throw (); | | what () const throw (); | |
| }; | | }; | |
| | | | |
|
| | | // Session exceptions. | |
| | | // | |
| | | struct LIBODB_EXPORT already_in_session: odb::exception | |
| | | { | |
| | | virtual const char* | |
| | | what () const throw (); | |
| | | }; | |
| | | | |
| | | struct LIBODB_EXPORT not_in_session: odb::exception | |
| | | { | |
| | | virtual const char* | |
| | | what () const throw (); | |
| | | }; | |
| | | | |
| | | struct LIBODB_EXPORT const_object: odb::exception | |
| | | { | |
| | | virtual const char* | |
| | | what () const throw (); | |
| | | }; | |
| | | | |
| | | // Database operations exceptions. | |
| | | // | |
| struct LIBODB_EXPORT deadlock: odb::exception | | struct LIBODB_EXPORT deadlock: odb::exception | |
| { | | { | |
| virtual const char* | | virtual const char* | |
| what () const throw (); | | what () const throw (); | |
| }; | | }; | |
| | | | |
| struct LIBODB_EXPORT object_not_persistent: odb::exception | | struct LIBODB_EXPORT object_not_persistent: odb::exception | |
| { | | { | |
| virtual const char* | | virtual const char* | |
| what () const throw (); | | what () const throw (); | |
| | | | |
End of changes. 3 change blocks. |
| 1 lines changed or deleted | | 31 lines changed or added | |
|
| pointer-traits.hxx | | pointer-traits.hxx | |
| // file : odb/pointer-traits.hxx | | // file : odb/pointer-traits.hxx | |
| // author : Boris Kolpackov <boris@codesynthesis.com> | | // author : Boris Kolpackov <boris@codesynthesis.com> | |
|
| // copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #ifndef ODB_POINTER_TRAITS_HXX | | #ifndef ODB_POINTER_TRAITS_HXX | |
| #define ODB_POINTER_TRAITS_HXX | | #define ODB_POINTER_TRAITS_HXX | |
| | | | |
| #include <odb/pre.hxx> | | #include <odb/pre.hxx> | |
| | | | |
| #include <new> // operators new/delete | | #include <new> // operators new/delete | |
|
| | | #include <memory> // std::auto_ptr | |
| #include <cstddef> // std::size_t | | #include <cstddef> // std::size_t | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
|
| | | enum pointer_kind | |
| | | { | |
| | | pk_raw, // Raw pointer or equivalent (i.e., unmanaged). | |
| | | pk_unique, // Smart pointer that doesn't support sharing. | |
| | | pk_shared, // Smart pointer that supports sharing. | |
| | | pk_weak // Weak counterpart for shared pointer. | |
| | | }; | |
| | | | |
| template <typename P> | | template <typename P> | |
| class pointer_traits; | | class pointer_traits; | |
| | | | |
|
| | | // | |
| | | // Standard pointer guards. | |
| | | // | |
| | | | |
| | | // Raw pointer guard. | |
| | | // | |
| | | template <typename P> | |
| | | class raw_ptr_guard | |
| | | { | |
| | | public: | |
| | | ~raw_ptr_guard () {delete p_;} | |
| | | raw_ptr_guard (): p_ (0) {} | |
| | | | |
| | | explicit | |
| | | raw_ptr_guard (P p): p_ (p) {} | |
| | | | |
| | | void | |
| | | release () {p_ = 0;} | |
| | | | |
| | | void | |
| | | reset (P p) {delete p_; p_ = p;} | |
| | | | |
| | | private: | |
| | | P p_; | |
| | | }; | |
| | | | |
| // No-op pointer guard for smart pointers. | | // No-op pointer guard for smart pointers. | |
| // | | // | |
| template <typename P> | | template <typename P> | |
|
| class nop_guard | | class smart_ptr_guard | |
| { | | { | |
| public: | | public: | |
|
| nop_guard () {} | | smart_ptr_guard () {} | |
| | | | |
| explicit | | explicit | |
|
| nop_guard (P) {} | | smart_ptr_guard (const P&) {} | |
| | | | |
| void | | void | |
| release () {} | | release () {} | |
| | | | |
| void | | void | |
|
| reset (P) {} | | reset (const P&) {} | |
| }; | | }; | |
| | | | |
|
| // Default implementation that should work for any sensible smart | | // Specialization for raw pointers. | |
| // pointer with one template argument (object type). The only | | | |
| // assumptions that we make are the availability of operator-> and | | | |
| // operator*, and that the former does not throw if the pointer is | | | |
| // NULL. | | | |
| // | | // | |
|
| template <typename T, template <typename> class P> | | template <typename T> | |
| class pointer_traits< P<T> > | | class pointer_traits<T*> | |
| { | | { | |
| public: | | public: | |
|
| typedef T type; | | static pointer_kind const kind = pk_raw; | |
| typedef P<T> pointer; | | static bool const lazy = false; | |
| typedef nop_guard<pointer> guard; | | | |
| | | | |
|
| // Return underlying pointer, including NULL. | | typedef T element_type; | |
| | | typedef T* pointer_type; | |
| | | typedef const T* const_pointer_type; | |
| | | typedef raw_ptr_guard<pointer_type> guard; | |
| | | | |
| | | // Return raw pointer to the pointed-to element, including NULL. | |
| // | | // | |
|
| static type* | | static element_type* | |
| get_ptr (const pointer& p) | | get_ptr (pointer_type p) | |
| { | | { | |
|
| return p.operator-> (); | | return p; | |
| } | | } | |
| | | | |
|
| // Return reference to the pointed-to object. | | // Return reference to the pointed-to element. | |
| // | | // | |
|
| static type& | | static element_type& | |
| get_ref (const pointer& p) | | get_ref (pointer_type p) | |
| { | | { | |
| return *p; | | return *p; | |
| } | | } | |
| | | | |
| // Return true if the pointer is NULL. | | // Return true if the pointer is NULL. | |
| // | | // | |
| static bool | | static bool | |
|
| null_ptr (const pointer& p) | | null_ptr (pointer_type p) | |
| { | | { | |
|
| return get_ptr () == 0; | | return p == 0; | |
| } | | } | |
| | | | |
| public: | | public: | |
|
| // Allocate memory for a shared object. | | // Allocate memory for an element that will be managed by this | |
| | | // pointer. | |
| // | | // | |
| static void* | | static void* | |
| allocate (std::size_t n) | | allocate (std::size_t n) | |
| { | | { | |
| return operator new (n); | | return operator new (n); | |
| } | | } | |
| | | | |
|
| // Free memory allocated for a shared object. This functions is | | // Free memory allocated for an element. This functions is only | |
| // only called if the constructor of the object being created | | // called if the constructor of the element being created fails. | |
| // fails. Otherwise, pointer is used to delete the object | | // Otherwise, the pointer (or guard) is used to delete the object | |
| // and free the memory. This behavior is identical to the one | | // and free the memory. This behavior is identical to the one | |
| // used by operator delete overloading. | | // used by operator delete overloading. | |
| // | | // | |
| static void | | static void | |
| free (void* p) | | free (void* p) | |
| { | | { | |
| operator delete (p); | | operator delete (p); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| // Specialization for naked pointer. | | // Specialization for std::auto_ptr. | |
| // | | // | |
|
| template <typename P> | | | |
| class nptr_guard | | | |
| { | | | |
| public: | | | |
| ~nptr_guard () {delete p_;} | | | |
| nptr_guard (): p_ (0) {} | | | |
| | | | |
| explicit | | | |
| nptr_guard (P p): p_ (p) {} | | | |
| | | | |
| void | | | |
| release () {p_ = 0;} | | | |
| | | | |
| void | | | |
| reset (P p) {delete p_; p_ = p;} | | | |
| | | | |
| private: | | | |
| P p_; | | | |
| }; | | | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| class pointer_traits<T*> | | class pointer_traits< std::auto_ptr<T> > | |
| { | | { | |
| public: | | public: | |
|
| typedef T type; | | static pointer_kind const kind = pk_unique; | |
| typedef T* pointer; | | static bool const lazy = false; | |
| typedef nptr_guard<pointer> guard; | | | |
| | | typedef T element_type; | |
| | | typedef std::auto_ptr<element_type> pointer_type; | |
| | | typedef std::auto_ptr<const element_type> const_pointer_type; | |
| | | typedef smart_ptr_guard<pointer_type> guard; | |
| | | | |
|
| static type* | | static element_type* | |
| get_ptr (pointer p) | | get_ptr (const pointer_type& p) | |
| { | | { | |
|
| return p; | | return p.get (); | |
| } | | } | |
| | | | |
|
| static type& | | static element_type& | |
| get_ref (pointer p) | | get_ref (const pointer_type& p) | |
| { | | { | |
| return *p; | | return *p; | |
| } | | } | |
| | | | |
|
| // Return true if the pointer is NULL. | | | |
| // | | | |
| static bool | | static bool | |
|
| null_ptr (pointer p) | | null_ptr (const pointer_type& p) | |
| { | | { | |
|
| return p == 0; | | return p.get () == 0; | |
| } | | } | |
| | | | |
| public: | | public: | |
| static void* | | static void* | |
| allocate (std::size_t n) | | allocate (std::size_t n) | |
| { | | { | |
| return operator new (n); | | return operator new (n); | |
| } | | } | |
| | | | |
| static void | | static void | |
| | | | |
End of changes. 30 change blocks. |
| 62 lines changed or deleted | | 80 lines changed or added | |
|
| result.hxx | | result.hxx | |
| // file : odb/result.hxx | | // file : odb/result.hxx | |
| // author : Boris Kolpackov <boris@codesynthesis.com> | | // author : Boris Kolpackov <boris@codesynthesis.com> | |
|
| // copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #ifndef ODB_RESULT_HXX | | #ifndef ODB_RESULT_HXX | |
| #define ODB_RESULT_HXX | | #define ODB_RESULT_HXX | |
| | | | |
| #include <odb/pre.hxx> | | #include <odb/pre.hxx> | |
| | | | |
| #include <cstddef> // std::ptrdiff_t, std::size_t | | #include <cstddef> // std::ptrdiff_t, std::size_t | |
| #include <iterator> // iterator categories | | #include <iterator> // iterator categories | |
| | | | |
| | | | |
| skipping to change at line 33 | | skipping to change at line 33 | |
| | | | |
| template <typename T> | | template <typename T> | |
| class result_iterator; | | class result_iterator; | |
| | | | |
| template <typename T> | | template <typename T> | |
| class result_impl: public details::shared_base | | class result_impl: public details::shared_base | |
| { | | { | |
| public: | | public: | |
| virtual | | virtual | |
| ~result_impl (); | | ~result_impl (); | |
|
| result_impl () : end_ (false), current_ () {} | | | |
| | | | |
| protected: | | protected: | |
| friend class result<T>; | | friend class result<T>; | |
| friend class result_iterator<T>; | | friend class result_iterator<T>; | |
| | | | |
|
| typedef object_traits<T> traits; | | typedef odb::database database_type; | |
| typedef typename traits::pointer_type pointer_type; | | | |
| typedef typename traits::pointer_traits pointer_traits; | | | |
| | | | |
|
| pointer_type | | typedef typename odb::object_traits<T>::pointer_type pointer_type; | |
| current (bool release) | | typedef odb::pointer_traits<pointer_type> pointer_traits; | |
| | | | |
| | | typedef typename odb::object_traits<T>::object_type object_type; | |
| | | typedef typename odb::object_traits<T>::id_type id_type; | |
| | | typedef odb::object_traits<object_type> object_traits; | |
| | | | |
| | | result_impl (database_type& db) | |
| | | : begin_ (true), end_ (false), db_ (db), current_ () | |
| { | | { | |
|
| if (pointer_traits::null_ptr (current_) && !end_) | | } | |
| current (); | | | |
| | | | |
|
| pointer_type r (current_); | | database_type& | |
| | | database () const | |
| | | { | |
| | | return db_; | |
| | | } | |
| | | | |
| | | // To make this work with all kinds of pointers (raw, std::auto_ptr, | |
| | | // shared), we need to make sure we don't make any copies of the | |
| | | // pointer on the return path. | |
| | | // | |
| | | pointer_type& | |
| | | current (); | |
| | | | |
|
| if (release) | | void | |
| | | release () | |
| | | { | |
| | | current_ = pointer_type (); | |
| | | guard_.release (); | |
| | | } | |
| | | | |
| | | void | |
| | | begin () | |
| | | { | |
| | | if (begin_) | |
| { | | { | |
|
| current_ = pointer_type (); | | next (); | |
| guard_.release (); | | begin_ = false; | |
| } | | } | |
|
| | | | |
| return r; | | | |
| } | | } | |
| | | | |
| bool | | bool | |
| end () const | | end () const | |
| { | | { | |
| return end_; | | return end_; | |
| } | | } | |
| | | | |
| protected: | | protected: | |
| virtual void | | virtual void | |
|
| current () = 0; | | load (object_type&) = 0; | |
| | | | |
|
| virtual void | | virtual id_type | |
| current (T&) = 0; | | load_id () = 0; | |
| | | | |
| virtual void | | virtual void | |
| next () = 0; | | next () = 0; | |
| | | | |
| virtual void | | virtual void | |
| cache () = 0; | | cache () = 0; | |
| | | | |
| virtual std::size_t | | virtual std::size_t | |
| size () = 0; | | size () = 0; | |
| | | | |
| protected: | | protected: | |
| void | | void | |
| current (pointer_type p) | | current (pointer_type p) | |
| { | | { | |
| current_ = p; | | current_ = p; | |
| guard_.reset (current_); | | guard_.reset (current_); | |
| } | | } | |
| | | | |
|
| | | bool begin_; | |
| bool end_; | | bool end_; | |
| | | | |
| private: | | private: | |
|
| | | database_type& db_; | |
| pointer_type current_; | | pointer_type current_; | |
| typename pointer_traits::guard guard_; | | typename pointer_traits::guard guard_; | |
| }; | | }; | |
| | | | |
| template <typename T> | | template <typename T> | |
| class result_iterator | | class result_iterator | |
| { | | { | |
| public: | | public: | |
| typedef T value_type; | | typedef T value_type; | |
| typedef value_type& reference; | | typedef value_type& reference; | |
| typedef value_type* pointer; | | typedef value_type* pointer; | |
| typedef std::ptrdiff_t difference_type; | | typedef std::ptrdiff_t difference_type; | |
| typedef std::input_iterator_tag iterator_category; | | typedef std::input_iterator_tag iterator_category; | |
| | | | |
|
| | | // T might be const T, but object_type is always T. | |
| | | // | |
| | | typedef typename object_traits<T>::object_type object_type; | |
| | | typedef typename object_traits<T>::id_type id_type; | |
| | | | |
| public: | | public: | |
| explicit | | explicit | |
| result_iterator (result_impl<T>* res = 0) | | result_iterator (result_impl<T>* res = 0) | |
| : res_ (res) | | : res_ (res) | |
| { | | { | |
| } | | } | |
| | | | |
| // Input iterator requirements. | | // Input iterator requirements. | |
| // | | // | |
| public: | | public: | |
| reference | | reference | |
| operator* () const | | operator* () const | |
| { | | { | |
|
| return pointer_traits::get_ref (res_->current (false)); | | return pointer_traits::get_ref (res_->current ()); | |
| } | | } | |
| | | | |
| // Our value_type is already a pointer so return it instead of | | // Our value_type is already a pointer so return it instead of | |
| // a pointer to it (operator-> will just have to go one deeper | | // a pointer to it (operator-> will just have to go one deeper | |
| // in the latter case). | | // in the latter case). | |
| // | | // | |
| pointer | | pointer | |
| operator-> () const | | operator-> () const | |
| { | | { | |
|
| return pointer_traits::get_ptr (res_->current (false)); | | return pointer_traits::get_ptr (res_->current ()); | |
| } | | } | |
| | | | |
| result_iterator& | | result_iterator& | |
| operator++ () | | operator++ () | |
| { | | { | |
| res_->next (); | | res_->next (); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| result_iterator | | result_iterator | |
| | | | |
| skipping to change at line 153 | | skipping to change at line 182 | |
| // All non-end iterators for a result object move together. | | // All non-end iterators for a result object move together. | |
| // | | // | |
| res_->next (); | | res_->next (); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| public: | | public: | |
| typename object_traits<T>::pointer_type | | typename object_traits<T>::pointer_type | |
| load () | | load () | |
| { | | { | |
|
| return res_->current (true); | | typename object_traits<T>::pointer_type r (res_->current ()); | |
| | | res_->release (); | |
| | | return r; | |
| } | | } | |
| | | | |
| void | | void | |
|
| load (T& x) | | load (object_type&); | |
| { | | | |
| res_->current (x); | | | |
| } | | | |
| | | | |
| public: | | public: | |
| bool | | bool | |
| equal (result_iterator j) const | | equal (result_iterator j) const | |
| { | | { | |
| return (res_ ? res_->end () : true) == (j.res_ ? j.res_->end () : tr
ue); | | return (res_ ? res_->end () : true) == (j.res_ ? j.res_->end () : tr
ue); | |
| } | | } | |
| | | | |
| private: | | private: | |
|
| typedef typename object_traits<T>::pointer_traits pointer_traits; | | typedef | |
| | | odb::pointer_traits<typename object_traits<T>::pointer_type> | |
| | | pointer_traits; | |
| | | | |
| result_impl<T>* res_; | | result_impl<T>* res_; | |
| }; | | }; | |
| | | | |
| // Input iterator requirements. | | // Input iterator requirements. | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| inline bool | | inline bool | |
| operator== (result_iterator<T> i, result_iterator<T> j) | | operator== (result_iterator<T> i, result_iterator<T> j) | |
| { | | { | |
| | | | |
| skipping to change at line 253 | | skipping to change at line 283 | |
| // | | // | |
| details::shared_ptr<result_impl<T> > p (impl_); | | details::shared_ptr<result_impl<T> > p (impl_); | |
| impl_ = r.impl_; | | impl_ = r.impl_; | |
| r.impl_ = p; | | r.impl_ = p; | |
| } | | } | |
| | | | |
| public: | | public: | |
| iterator | | iterator | |
| begin () | | begin () | |
| { | | { | |
|
| | | if (impl_) | |
| | | impl_->begin (); | |
| | | | |
| return iterator (impl_.get ()); | | return iterator (impl_.get ()); | |
| } | | } | |
| | | | |
| iterator | | iterator | |
| end () | | end () | |
| { | | { | |
| return iterator (); | | return iterator (); | |
| } | | } | |
| | | | |
| // Cache the result instead of fetching the data from the database | | // Cache the result instead of fetching the data from the database | |
| | | | |
| skipping to change at line 278 | | skipping to change at line 311 | |
| cache () | | cache () | |
| { | | { | |
| if (impl_) | | if (impl_) | |
| impl_->cache (); | | impl_->cache (); | |
| } | | } | |
| | | | |
| public: | | public: | |
| bool | | bool | |
| empty () const | | empty () const | |
| { | | { | |
|
| return impl_ == 0 || impl_->end (); | | if (impl_ == 0) | |
| | | return true; | |
| | | | |
| | | impl_->begin (); | |
| | | return impl_->end (); | |
| } | | } | |
| | | | |
| // Size is only known in cached results. | | // Size is only known in cached results. | |
| // | | // | |
| size_type | | size_type | |
| size () const | | size () const | |
| { | | { | |
| return impl_ ? impl_->size () : 0; | | return impl_ ? impl_->size () : 0; | |
| } | | } | |
| | | | |
| | | | |
End of changes. 21 change blocks. |
| 27 lines changed or deleted | | 64 lines changed or added | |
|
| result.txx | | result.txx | |
| // file : odb/result.txx | | // file : odb/result.txx | |
| // author : Boris Kolpackov <boris@codesynthesis.com> | | // author : Boris Kolpackov <boris@codesynthesis.com> | |
|
| // copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
|
| | | #include <odb/session.hxx> | |
| | | #include <odb/cache-traits.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| template <typename T> | | template <typename T> | |
| result_impl<T>:: | | result_impl<T>:: | |
| ~result_impl () | | ~result_impl () | |
| { | | { | |
| } | | } | |
|
| | | | |
| | | template <typename T> | |
| | | typename result_impl<T>::pointer_type& result_impl<T>:: | |
| | | current () | |
| | | { | |
| | | typedef typename object_traits::pointer_type unrestricted_pointer_type; | |
| | | typedef typename object_traits::pointer_traits unrestricted_pointer_tra | |
| | | its; | |
| | | | |
| | | if (pointer_traits::null_ptr (current_) && !end_) | |
| | | { | |
| | | if (!session::has_current ()) | |
| | | { | |
| | | unrestricted_pointer_type up (object_traits::create ()); | |
| | | object_type& obj (unrestricted_pointer_traits::get_ref (up)); | |
| | | current (pointer_type (up)); | |
| | | load (obj); | |
| | | } | |
| | | else | |
| | | { | |
| | | // First check the session. | |
| | | // | |
| | | const id_type& id (load_id ()); | |
| | | | |
| | | pointer_type p ( | |
| | | pointer_cache_traits<pointer_type>::find (database (), id)); | |
| | | | |
| | | if (!pointer_traits::null_ptr (p)) | |
| | | current (p); | |
| | | else | |
| | | { | |
| | | unrestricted_pointer_type up (object_traits::create ()); | |
| | | | |
| | | typename | |
| | | pointer_cache_traits<unrestricted_pointer_type>::insert_guard i | |
| | | g ( | |
| | | pointer_cache_traits<unrestricted_pointer_type>::insert ( | |
| | | database (), id, up)); | |
| | | | |
| | | object_type& obj (unrestricted_pointer_traits::get_ref (up)); | |
| | | current (pointer_type (up)); | |
| | | load (obj); | |
| | | ig.release (); | |
| | | } | |
| | | } | |
| | | } | |
| | | | |
| | | return current_; | |
| | | } | |
| | | | |
| | | // | |
| | | // result_iterator | |
| | | // | |
| | | | |
| | | template <typename T> | |
| | | void result_iterator<T>:: | |
| | | load (object_type& obj) | |
| | | { | |
| | | if (res_->end ()) | |
| | | return; | |
| | | | |
| | | if (!session::has_current ()) | |
| | | res_->load (obj); | |
| | | else | |
| | | { | |
| | | typename reference_cache_traits<object_type>::insert_guard ig ( | |
| | | reference_cache_traits<object_type>::insert ( | |
| | | res_->database (), res_->load_id (), obj)); | |
| | | res_->load (obj); | |
| | | ig.release (); | |
| | | } | |
| | | } | |
| } | | } | |
| | | | |
End of changes. 3 change blocks. |
| 1 lines changed or deleted | | 76 lines changed or added | |
|
| traits.hxx | | traits.hxx | |
| // file : odb/traits.hxx | | // file : odb/traits.hxx | |
| // author : Boris Kolpackov <boris@codesynthesis.com> | | // author : Boris Kolpackov <boris@codesynthesis.com> | |
|
| // copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #ifndef ODB_TRAITS_HXX | | #ifndef ODB_TRAITS_HXX | |
| #define ODB_TRAITS_HXX | | #define ODB_TRAITS_HXX | |
| | | | |
| #include <odb/pre.hxx> | | #include <odb/pre.hxx> | |
| | | | |
| #include <odb/forward.hxx> | | #include <odb/forward.hxx> | |
| #include <odb/pointer-traits.hxx> | | #include <odb/pointer-traits.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| // template <typename T> | | // template <typename T> | |
| // class access::object_traits; | | // class access::object_traits; | |
| // | | // | |
|
| // Specializations should inherit from object_memory, object_factory | | // Specializations should define the following members: | |
| // and define the following members: | | | |
| // | | // | |
| // id_type - object id (primary key) type | | // id_type - object id (primary key) type | |
| // id_type id (const T&) - get object id | | // id_type id (const T&) - get object id | |
| // | | // | |
| // void persist (database&, T&) | | // void persist (database&, T&) | |
| // void update (database&, T&) | | // void update (database&, T&) | |
| // void erase (database&, const id_type&) | | // void erase (database&, const id_type&) | |
| // pointer_type find (database&, const id_type&) | | // pointer_type find (database&, const id_type&) | |
| // bool find (database&, const id_type&, T&) | | // bool find (database&, const id_type&, T&) | |
| // | | // | |
| // | | // | |
| | | | |
|
| template <typename T> | | template <typename T, typename P> | |
| class access::object_memory | | | |
| { | | | |
| public: | | | |
| typedef T* pointer_type; | | | |
| }; | | | |
| | | | |
| template <typename T> | | | |
| class access::object_factory | | class access::object_factory | |
| { | | { | |
| public: | | public: | |
|
| static typename object_memory<T>::pointer_type | | typedef T object_type; | |
| | | typedef P pointer_type; | |
| | | | |
| | | static P | |
| create () | | create () | |
| { | | { | |
| // By default use pointer-specific construction. | | // By default use pointer-specific construction. | |
| // | | // | |
|
| return | | return pointer_factory<T, P>::create (); | |
| pointer_factory<typename object_memory<T>::pointer_type>::create () | | | |
| ; | | | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| template <typename P> | | template <typename T, typename P> | |
| class access::pointer_factory | | class access::pointer_factory | |
| { | | { | |
| public: | | public: | |
|
| typedef typename pointer_traits<P>::type object_type; | | typedef T object_type; | |
| | | typedef P pointer_type; | |
| | | | |
| static P | | static P | |
| create () | | create () | |
| { | | { | |
|
| void* v (pointer_traits<P>::allocate (sizeof (object_type))); | | void* v (pointer_traits<P>::allocate (sizeof (T))); | |
| mem_guard g (v); | | mem_guard g (v); | |
|
| P p (new (v) object_type); | | P p (new (v) T); | |
| g.release (); | | g.release (); | |
| return p; | | return p; | |
| } | | } | |
| private: | | private: | |
| struct mem_guard | | struct mem_guard | |
| { | | { | |
| mem_guard (void* p): p_ (p) {} | | mem_guard (void* p): p_ (p) {} | |
| ~mem_guard () {if (p_) pointer_traits<P>::free (p_);} | | ~mem_guard () {if (p_) pointer_traits<P>::free (p_);} | |
| void release () {p_ = 0;} | | void release () {p_ = 0;} | |
| void* p_; | | void* p_; | |
| }; | | }; | |
| }; | | }; | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| struct object_traits: access::object_traits<T> | | struct object_traits: | |
| | | access::object_traits<T>, | |
| | | access::object_factory<T, typename access::object_traits<T>::pointer_ty | |
| | | pe> | |
| | | { | |
| | | // | |
| | | // If a C++ compiler issues an error pointing to this struct and | |
| | | // saying that it is incomplete, then you are most likely trying to | |
| | | // perform a database operation on a C++ type that is not a persistent | |
| | | // object. Or you forgot to include the corresponding -odb.hxx file. | |
| | | // | |
| | | | |
| | | typedef | |
| | | odb::pointer_traits<typename access::object_traits<T>::pointer_type> | |
| | | pointer_traits; | |
| | | | |
| | | typedef typename access::object_traits<T>::object_type object_type; | |
| | | typedef typename access::object_traits<T>::pointer_type pointer_type; | |
| | | typedef typename pointer_traits::const_pointer_type const_pointer_type; | |
| | | }; | |
| | | | |
| | | // Specialization for const objects. It only defines the id, object, | |
| | | // pointer, and const_pointer types with pointer and const_pointer | |
| | | // being the same. The idea is to only use this specialization in the | |
| | | // interfaces, with the implementations detecting this situation and | |
| | | // using the non-const object_traits version. | |
| | | // | |
| | | template <typename T> | |
| | | struct object_traits<const T> | |
| { | | { | |
|
| | | private: | |
| typedef | | typedef | |
| odb::pointer_traits<typename access::object_traits<T>::pointer_type> | | odb::pointer_traits<typename access::object_traits<T>::pointer_type> | |
| pointer_traits; | | pointer_traits; | |
|
| | | | |
| | | public: | |
| | | typedef typename access::object_traits<T>::id_type id_type; | |
| | | typedef typename access::object_traits<T>::object_type object_type; | |
| | | typedef typename pointer_traits::const_pointer_type const_pointer_type; | |
| | | typedef const_pointer_type pointer_type; | |
| | | }; | |
| | | | |
| | | // Specializations for pointer types to allow the C++ compiler to | |
| | | // instantiate persist(), etc., signatures in class database. The | |
| | | // overloads that use these specializations would never actually | |
| | | // be selected by the compiler. | |
| | | // | |
| | | template <typename T> | |
| | | struct object_traits<T*> | |
| | | { | |
| | | struct id_type {}; | |
| | | }; | |
| | | | |
| | | template <typename T> | |
| | | struct object_traits<T* const> | |
| | | { | |
| | | struct id_type {}; | |
| | | }; | |
| | | | |
| | | template <typename T, template <typename> class P> | |
| | | struct object_traits< P<T> > | |
| | | { | |
| | | struct id_type {}; | |
| | | }; | |
| | | | |
| | | template <typename T, template <typename> class P> | |
| | | struct object_traits< const P<T> > | |
| | | { | |
| | | struct id_type {}; | |
| | | }; | |
| | | | |
| | | template <typename T> | |
| | | struct composite_value_traits: access::composite_value_traits<T> | |
| | | { | |
| }; | | }; | |
| } | | } | |
| | | | |
| #include <odb/post.hxx> | | #include <odb/post.hxx> | |
| | | | |
| #endif // ODB_TRAITS_HXX | | #endif // ODB_TRAITS_HXX | |
| | | | |
End of changes. 12 change blocks. |
| 20 lines changed or deleted | | 83 lines changed or added | |
|