| cache-traits.hxx | | cache-traits.hxx | |
| | | | |
| skipping to change at line 24 | | skipping to change at line 24 | |
| #include <odb/pointer-traits.hxx> | | #include <odb/pointer-traits.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| // Caching traits for objects passed by pointer. | | // Caching traits for objects passed by pointer. | |
| // | | // | |
| template <typename P, pointer_kind = pointer_traits<P>::kind> | | template <typename P, pointer_kind = pointer_traits<P>::kind> | |
| struct pointer_cache_traits | | struct pointer_cache_traits | |
| { | | { | |
| typedef P pointer_type; | | typedef P pointer_type; | |
|
| typedef typename pointer_traits<pointer_type>::element_type element_typ | | typedef odb::pointer_traits<pointer_type> pointer_traits; | |
| e; | | typedef typename pointer_traits::element_type element_type; | |
| | | | |
| | | // element_type can be const while object_type is always non-const. | |
| | | // | |
| | | typedef typename object_traits<element_type>::object_type object_type; | |
| typedef typename object_traits<element_type>::id_type id_type; | | typedef typename object_traits<element_type>::id_type id_type; | |
|
| typedef session::object_position<element_type> position_type; | | typedef session::object_position<object_type> position_type; | |
| | | | |
| struct insert_guard | | struct insert_guard | |
| { | | { | |
| insert_guard (const position_type& pos): pos_ (pos) {} | | insert_guard (const position_type& pos): pos_ (pos) {} | |
| ~insert_guard () {erase (pos_);} | | ~insert_guard () {erase (pos_);} | |
| | | | |
| position_type | | position_type | |
| position () const {return pos_;} | | position () const {return pos_;} | |
| | | | |
| void | | void | |
| | | | |
| skipping to change at line 49 | | skipping to change at line 54 | |
| private: | | private: | |
| position_type pos_; | | position_type pos_; | |
| }; | | }; | |
| | | | |
| // Qualify the database type to resolve a phony ambiguity in VC 10. | | // Qualify the database type to resolve a phony ambiguity in VC 10. | |
| // | | // | |
| static position_type | | static position_type | |
| insert (odb::database& db, const id_type& id, const pointer_type& p) | | insert (odb::database& db, const id_type& id, const pointer_type& p) | |
| { | | { | |
| if (session::has_current ()) | | if (session::has_current ()) | |
|
| return session::current ().insert<element_type> (db, id, p); | | // Cast away constness if any. | |
| | | // | |
| | | return session::current ().insert<object_type> ( | |
| | | db, id, pointer_traits::cast (p)); | |
| else | | else | |
| return position_type (); | | return position_type (); | |
| } | | } | |
| | | | |
| static pointer_type | | static pointer_type | |
| find (odb::database& db, const id_type& id) | | find (odb::database& db, const id_type& id) | |
| { | | { | |
| if (session::has_current ()) | | if (session::has_current ()) | |
|
| return session::current ().find<element_type> (db, id); | | return session::current ().find<object_type> (db, id); | |
| else | | else | |
| return pointer_type (); | | return pointer_type (); | |
| } | | } | |
| | | | |
| static void | | static void | |
| erase (odb::database& db, const id_type& id) | | erase (odb::database& db, const id_type& id) | |
| { | | { | |
| if (session::has_current ()) | | if (session::has_current ()) | |
|
| session::current ().erase<element_type> (db, id); | | session::current ().erase<object_type> (db, id); | |
| } | | } | |
| | | | |
| static void | | static void | |
| erase (const position_type& p) | | erase (const position_type& p) | |
| { | | { | |
| if (p.map_ != 0) | | if (p.map_ != 0) | |
|
| session::current ().erase<element_type> (p); | | session::current ().erase<object_type> (p); | |
| } | | } | |
| }; | | }; | |
| | | | |
| // Unique pointers don't work with the object cache. | | // Unique pointers don't work with the object cache. | |
| // | | // | |
| template <typename P> | | template <typename P> | |
| struct pointer_cache_traits<P, pk_unique> | | struct pointer_cache_traits<P, pk_unique> | |
| { | | { | |
| typedef P pointer_type; | | typedef P pointer_type; | |
| typedef typename pointer_traits<pointer_type>::element_type element_typ
e; | | typedef typename pointer_traits<pointer_type>::element_type element_typ
e; | |
| | | | |
End of changes. 6 change blocks. |
| 7 lines changed or deleted | | 14 lines changed or added | |
|
| database.hxx | | database.hxx | |
| | | | |
| skipping to change at line 18 | | skipping to change at line 18 | |
| | | | |
| #include <odb/pre.hxx> | | #include <odb/pre.hxx> | |
| | | | |
| #include <string> | | #include <string> | |
| #include <cstddef> // std::size_t | | #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/connection.hxx> | |
| #include <odb/exceptions.hxx> | | #include <odb/exceptions.hxx> | |
| | | | |
| #include <odb/details/export.hxx> | | #include <odb/details/export.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| class transaction_impl; | | class transaction_impl; | |
| | | | |
| class LIBODB_EXPORT database | | class LIBODB_EXPORT database | |
| { | | { | |
| | | | |
| skipping to change at line 127 | | skipping to change at line 128 | |
| erase (const P<T>& obj_ptr); | | erase (const P<T>& obj_ptr); | |
| | | | |
| template <typename T, template <typename> class P> | | template <typename T, template <typename> class P> | |
| void | | void | |
| erase (P<T>& obj_ptr); | | erase (P<T>& obj_ptr); | |
| | | | |
| template <typename T> | | template <typename T> | |
| void | | void | |
| erase (const typename object_traits<T>::pointer_type& obj_ptr); | | erase (const typename object_traits<T>::pointer_type& obj_ptr); | |
| | | | |
|
| | | // Erase multiple objects matching a query predicate. | |
| | | // | |
| | | template <typename T> | |
| | | unsigned long long | |
| | | erase_query (); | |
| | | | |
| | | template <typename T> | |
| | | unsigned long long | |
| | | erase_query (const char*); | |
| | | | |
| | | template <typename T> | |
| | | unsigned long long | |
| | | erase_query (const std::string&); | |
| | | | |
| | | template <typename T> | |
| | | unsigned long long | |
| | | erase_query (const odb::query<T>&); | |
| | | | |
| // 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<typename object_traits<T>::object_type>&, | | query (const odb::query<T>&, bool cache = true); | |
| bool cache = true); | | | |
| | | | |
| // Native database statement execution. | | // Native database statement execution. | |
| // | | // | |
| public: | | public: | |
| unsigned long long | | unsigned long long | |
| execute (const char* statement); | | execute (const char* statement); | |
| | | | |
| unsigned long long | | unsigned long long | |
| execute (const std::string& statement); | | execute (const std::string& statement); | |
| | | | |
|
| virtual unsigned long long | | unsigned long long | |
| execute (const char* statement, std::size_t length) = 0; | | execute (const char* statement, std::size_t length); | |
| | | | |
|
| // Transaction API. | | // Transactions. | |
| // | | // | |
| public: | | public: | |
| virtual transaction_impl* | | virtual transaction_impl* | |
| begin () = 0; | | begin () = 0; | |
| | | | |
|
| | | // Connections. | |
| | | // | |
| | | public: | |
| | | connection_ptr | |
| | | connection (); | |
| | | | |
| protected: | | protected: | |
| database (); | | database (); | |
| | | | |
| protected: | | protected: | |
|
| | | typedef odb::connection connection_type; | |
| | | | |
| | | virtual connection_type* | |
| | | connection_ () = 0; | |
| | | | |
| | | protected: | |
| template <typename T> | | template <typename T> | |
| typename object_traits<T>::id_type | | typename object_traits<T>::id_type | |
| persist_ (const typename object_traits<T>::pointer_type&); | | persist_ (const typename object_traits<T>::pointer_type&); | |
| | | | |
| template <typename T> | | template <typename T> | |
| void | | void | |
| update_ (const typename object_traits<T>::pointer_type&); | | update_ (const typename object_traits<T>::pointer_type&); | |
| | | | |
| template <typename T> | | template <typename T> | |
| void | | void | |
| erase_ (const typename object_traits<T>::pointer_type&); | | erase_ (const typename object_traits<T>::pointer_type&); | |
| | | | |
|
| | | template <typename T, class_kind kind> | |
| | | struct query_; | |
| | | | |
| 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. 8 change blocks. |
| 5 lines changed or deleted | | 38 lines changed or added | |
|
| database.ixx | | database.ixx | |
| | | | |
| skipping to change at line 15 | | skipping to change at line 15 | |
| | | | |
| #include <cstring> // std::string | | #include <cstring> // std::string | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| inline database:: | | inline database:: | |
| database () | | database () | |
| { | | { | |
| } | | } | |
| | | | |
|
| | | inline connection_ptr database:: | |
| | | connection () | |
| | | { | |
| | | return connection_ptr (connection_ ()); | |
| | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| inline typename object_traits<T>::id_type database:: | | inline typename object_traits<T>::id_type database:: | |
| persist (T* p) | | persist (T* p) | |
| { | | { | |
| typedef typename object_traits<T>::pointer_type object_pointer; | | typedef typename object_traits<T>::pointer_type object_pointer; | |
| | | | |
| // The passed pointer should be the same or implicit-convertible | | // The passed pointer should be the same or implicit-convertible | |
| // to the object pointer. This way we make sure the object pointer | | // to the object pointer. This way we make sure the object pointer | |
| // does not assume ownership of the passed object. | | // does not assume ownership of the passed object. | |
| // | | // | |
| | | | |
| skipping to change at line 161 | | skipping to change at line 167 | |
| inline void database:: | | inline void database:: | |
| erase_ (const typename object_traits<T>::pointer_type& pobj) | | erase_ (const typename object_traits<T>::pointer_type& pobj) | |
| { | | { | |
| typedef typename object_traits<T>::pointer_type pointer_type; | | typedef typename object_traits<T>::pointer_type pointer_type; | |
| typedef pointer_traits<pointer_type> pointer_traits; | | typedef pointer_traits<pointer_type> pointer_traits; | |
| | | | |
| erase<T> (pointer_traits::get_ref (pobj)); | | erase<T> (pointer_traits::get_ref (pobj)); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| inline result<T> database:: | | inline unsigned long long database:: | |
| query (bool cache) | | erase_query () | |
| { | | { | |
|
| // T can be const T while object_type will always be T. | | // T is always object_type. | |
| // | | // | |
|
| typedef typename odb::object_traits<T>::object_type object_type; | | return erase_query<T> (odb::query<T> ()); | |
| | | } | |
| | | | |
|
| return query<T> (odb::query<object_type> (), cache); | | template <typename T> | |
| | | inline unsigned long long database:: | |
| | | erase_query (const char* q) | |
| | | { | |
| | | // T is always object_type. | |
| | | // | |
| | | return erase_query<T> (odb::query<T> (q)); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| inline result<T> database:: | | inline unsigned long long database:: | |
| query (const char* q, bool cache) | | erase_query (const std::string& q) | |
| { | | { | |
|
| // T can be const T while object_type will always be T. | | // T is always object_type. | |
| // | | // | |
|
| typedef typename odb::object_traits<T>::object_type object_type; | | return erase_query<T> (odb::query<T> (q)); | |
| | | } | |
| | | | |
|
| return query<T> (odb::query<object_type> (q), cache); | | template <typename T> | |
| | | inline result<T> database:: | |
| | | query (bool cache) | |
| | | { | |
| | | return query<T> (odb::query<T> (), cache); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| inline result<T> database:: | | inline result<T> database:: | |
|
| query (const std::string& q, bool cache) | | query (const char* q, bool cache) | |
| { | | { | |
|
| // T can be const T while object_type will always be T. | | return query<T> (odb::query<T> (q), cache); | |
| // | | } | |
| typedef typename odb::object_traits<T>::object_type object_type; | | | |
| | | | |
|
| return query<T> (odb::query<object_type> (q), cache); | | template <typename T> | |
| | | inline result<T> database:: | |
| | | query (const std::string& q, bool cache) | |
| | | { | |
| | | return query<T> (odb::query<T> (q), cache); | |
| } | | } | |
| | | | |
| inline unsigned long long database:: | | inline unsigned long long database:: | |
| execute (const char* statement) | | execute (const char* statement) | |
| { | | { | |
| return execute (statement, std::strlen (statement)); | | return execute (statement, std::strlen (statement)); | |
| } | | } | |
| | | | |
| inline unsigned long long database:: | | inline unsigned long long database:: | |
| execute (const std::string& statement) | | execute (const std::string& statement) | |
| | | | |
End of changes. 12 change blocks. |
| 15 lines changed or deleted | | 36 lines changed or added | |
|
| database.txx | | database.txx | |
| | | | |
| skipping to change at line 66 | | skipping to change at line 66 | |
| | | | |
| const typename object_traits::id_type& id (object_traits::id (obj)); | | const typename object_traits::id_type& id (object_traits::id (obj)); | |
| pointer_cache_traits<pointer_type>::insert (*this, id, pobj); | | pointer_cache_traits<pointer_type>::insert (*this, id, pobj); | |
| return id; | | 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) | |
| { | | { | |
|
| | | // T is always object_type. | |
| | | // | |
| typedef typename object_traits<T>::pointer_type pointer_type; | | typedef typename object_traits<T>::pointer_type pointer_type; | |
| typedef odb::pointer_traits<pointer_type> pointer_traits; | | typedef odb::pointer_traits<pointer_type> pointer_traits; | |
| | | | |
| pointer_type r (find<T> (id)); | | pointer_type r (find<T> (id)); | |
| | | | |
| if (pointer_traits::null_ptr (r)) | | if (pointer_traits::null_ptr (r)) | |
| throw object_not_persistent (); | | throw object_not_persistent (); | |
| | | | |
| return r; | | return r; | |
| } | | } | |
| | | | |
| skipping to change at line 89 | | skipping to change at line 91 | |
| 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. | | // T is always object_type. | |
| // | | // | |
|
| typedef typename odb::object_traits<T>::object_type object_type; | | typedef odb::object_traits<T> object_traits; | |
| typedef odb::object_traits<object_type> object_traits; | | typedef typename object_traits::pointer_type pointer_type; | |
| | | | |
| typedef typename odb::object_traits<T>::pointer_type pointer_type; | | | |
| typedef odb::pointer_traits<pointer_type> pointer_traits; | | typedef odb::pointer_traits<pointer_type> pointer_traits; | |
| | | | |
| // First check the session. | | // First check the session. | |
| // | | // | |
| { | | { | |
| pointer_type p ( | | pointer_type p ( | |
| pointer_cache_traits<pointer_type>::find (*this, id)); | | pointer_cache_traits<pointer_type>::find (*this, id)); | |
| | | | |
| if (!pointer_traits::null_ptr (p)) | | if (!pointer_traits::null_ptr (p)) | |
| return p; | | return p; | |
| | | | |
| skipping to change at line 120 | | skipping to change at line 120 | |
| // Compiler error pointing here? Perhaps the object doesn't have the | | // Compiler error pointing here? Perhaps the object doesn't have the | |
| // default constructor? | | // default constructor? | |
| // | | // | |
| return pointer_type (object_traits::find (*this, id)); | | 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. | | // T is always object_type. | |
| // | | // | |
|
| 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::find (*this, id, obj); | | return object_traits<T>::find (*this, id, obj); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void database:: | | void database:: | |
| update (T& obj) | | update (T& obj) | |
| { | | { | |
| // T can be const T while object_type will always be T. | | // T can be const T while object_type will always be T. | |
| // | | // | |
| typedef typename odb::object_traits<T>::object_type object_type; | | typedef typename odb::object_traits<T>::object_type object_type; | |
| typedef odb::object_traits<object_type> object_traits; | | typedef odb::object_traits<object_type> object_traits; | |
| | | | |
| skipping to change at line 174 | | skipping to change at line 171 | |
| | | | |
| object_traits::callback (*this, obj, callback_event::pre_update); | | object_traits::callback (*this, obj, callback_event::pre_update); | |
| object_traits::update (*this, obj); | | object_traits::update (*this, obj); | |
| object_traits::callback (*this, obj, callback_event::post_update); | | object_traits::callback (*this, obj, callback_event::post_update); | |
| } | | } | |
| | | | |
| 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. | | // T is always object_type. | |
| // | | // | |
|
| typedef typename odb::object_traits<T>::object_type object_type; | | typedef odb::object_traits<T> object_traits; | |
| typedef odb::object_traits<object_type> object_traits; | | typedef typename object_traits::pointer_type pointer_type; | |
| | | | |
| 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::erase (*this, id); | | object_traits::erase (*this, id); | |
| pointer_cache_traits<pointer_type>::erase (*this, id); | | pointer_cache_traits<pointer_type>::erase (*this, id); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void database:: | | void database:: | |
| erase (T& obj) | | erase (T& obj) | |
| { | | { | |
| // T can be const T while object_type will always be T. | | // T can be const T while object_type will always be T. | |
| // | | // | |
| typedef typename odb::object_traits<T>::object_type object_type; | | typedef typename odb::object_traits<T>::object_type object_type; | |
| typedef odb::object_traits<object_type> object_traits; | | typedef odb::object_traits<object_type> object_traits; | |
|
| | | typedef typename object_traits::pointer_type pointer_type; | |
| 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 (); | |
| | | | |
| typename object_traits::id_type id (object_traits::id (obj)); | | typename object_traits::id_type id (object_traits::id (obj)); | |
| | | | |
| object_traits::callback (*this, obj, callback_event::pre_erase); | | object_traits::callback (*this, obj, callback_event::pre_erase); | |
| object_traits::erase (*this, id); | | object_traits::erase (*this, id); | |
| pointer_cache_traits<pointer_type>::erase (*this, id); | | pointer_cache_traits<pointer_type>::erase (*this, id); | |
| object_traits::callback (*this, obj, callback_event::post_erase); | | object_traits::callback (*this, obj, callback_event::post_erase); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| result<T> database:: | | unsigned long long database:: | |
| query (const odb::query<typename object_traits<T>::object_type>& q, | | erase_query (const odb::query<T>& q) | |
| bool cache) | | | |
| { | | { | |
|
| // T can be const T while object_type will always be T. | | // T is always object_type. | |
| // | | // | |
|
| typedef typename odb::object_traits<T>::object_type object_type; | | if (!transaction::has_current ()) | |
| typedef odb::object_traits<object_type> object_traits; | | throw not_in_transaction (); | |
| | | | |
| | | return object_traits<T>::erase_query (*this, q); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | struct database::query_<T, class_object> | |
| | | { | |
| | | static result<T> | |
| | | call (database& db, const odb::query<T>& q) | |
| | | { | |
| | | return object_traits<T>::query (db, q); | |
| | | } | |
| | | }; | |
| | | | |
|
| | | template <typename T> | |
| | | struct database::query_<T, class_view> | |
| | | { | |
| | | static result<T> | |
| | | call (database& db, const odb::query<T>& q) | |
| | | { | |
| | | return view_traits<T>::query (db, q); | |
| | | } | |
| | | }; | |
| | | | |
| | | template <typename T> | |
| | | result<T> database:: | |
| | | query (const odb::query<T>& q, bool cache) | |
| | | { | |
| | | // T is always object_type. | |
| | | // | |
| if (!transaction::has_current ()) | | if (!transaction::has_current ()) | |
| throw not_in_transaction (); | | throw not_in_transaction (); | |
| | | | |
|
| result<T> r (object_traits::template query<T> (*this, q)); | | result<T> r (query_<T, class_traits<T>::kind>::call (*this, q)); | |
| | | | |
| if (cache) | | if (cache) | |
| r.cache (); | | r.cache (); | |
| | | | |
| return r; | | return r; | |
| } | | } | |
| } | | } | |
| | | | |
End of changes. 14 change blocks. |
| 24 lines changed or deleted | | 46 lines changed or added | |
|
| pointer-traits.hxx | | pointer-traits.hxx | |
| | | | |
| skipping to change at line 15 | | skipping to change at line 15 | |
| | | | |
| #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 <memory> // std::auto_ptr | |
| #include <cstddef> // std::size_t | | #include <cstddef> // std::size_t | |
| | | | |
|
| | | #include <odb/details/meta/remove-const.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| enum pointer_kind | | enum pointer_kind | |
| { | | { | |
| pk_raw, // Raw pointer or equivalent (i.e., unmanaged). | | pk_raw, // Raw pointer or equivalent (i.e., unmanaged). | |
| pk_unique, // Smart pointer that doesn't support sharing. | | pk_unique, // Smart pointer that doesn't support sharing. | |
| pk_shared, // Smart pointer that supports sharing. | | pk_shared, // Smart pointer that supports sharing. | |
| pk_weak // Weak counterpart for shared pointer. | | pk_weak // Weak counterpart for shared pointer. | |
| }; | | }; | |
| | | | |
| | | | |
| skipping to change at line 84 | | skipping to change at line 86 | |
| template <typename T> | | template <typename T> | |
| class pointer_traits<T*> | | class pointer_traits<T*> | |
| { | | { | |
| public: | | public: | |
| static const pointer_kind kind = pk_raw; | | static const pointer_kind kind = pk_raw; | |
| static const bool lazy = false; | | static const bool lazy = false; | |
| | | | |
| typedef T element_type; | | typedef T element_type; | |
| typedef T* pointer_type; | | typedef T* pointer_type; | |
| typedef const T* const_pointer_type; | | typedef const T* const_pointer_type; | |
|
| | | typedef typename odb::details::meta::remove_const<T>::result* | |
| | | unrestricted_pointer_type; | |
| typedef raw_ptr_guard<pointer_type> guard; | | typedef raw_ptr_guard<pointer_type> guard; | |
| | | | |
| // Return raw pointer to the pointed-to element, including NULL. | | // Return raw pointer to the pointed-to element, including NULL. | |
| // | | // | |
| static element_type* | | static element_type* | |
| get_ptr (pointer_type p) | | get_ptr (pointer_type p) | |
| { | | { | |
| return p; | | return p; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 110 | | skipping to change at line 114 | |
| } | | } | |
| | | | |
| // Return true if the pointer is NULL. | | // Return true if the pointer is NULL. | |
| // | | // | |
| static bool | | static bool | |
| null_ptr (pointer_type p) | | null_ptr (pointer_type p) | |
| { | | { | |
| return p == 0; | | return p == 0; | |
| } | | } | |
| | | | |
|
| | | // Cast away constness. | |
| | | // | |
| | | static unrestricted_pointer_type | |
| | | cast (pointer_type p) | |
| | | { | |
| | | return const_cast<unrestricted_pointer_type> (p); | |
| | | } | |
| | | | |
| public: | | public: | |
| // Allocate memory for an element that will be managed by this | | // Allocate memory for an element that will be managed by this | |
| // pointer. | | // pointer. | |
| // | | // | |
| static void* | | static void* | |
| allocate (std::size_t n) | | allocate (std::size_t n) | |
| { | | { | |
| return operator new (n); | | return operator new (n); | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 165 | | skipping to change at line 177 | |
| { | | { | |
| return *p; | | return *p; | |
| } | | } | |
| | | | |
| static bool | | static bool | |
| null_ptr (const pointer_type& p) | | null_ptr (const pointer_type& p) | |
| { | | { | |
| return p.get () == 0; | | return p.get () == 0; | |
| } | | } | |
| | | | |
|
| | | // cast() is not provided since it transfers the ownership. | |
| | | // | |
| | | | |
| 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 | |
| free (void* p) | | free (void* p) | |
| { | | { | |
| | | | |
End of changes. 4 change blocks. |
| 0 lines changed or deleted | | 15 lines changed or added | |
|
| result.hxx | | result.hxx | |
| | | | |
| skipping to change at line 12 | | skipping to change at line 12 | |
| // author : Boris Kolpackov <boris@codesynthesis.com> | | // author : Boris Kolpackov <boris@codesynthesis.com> | |
| // copyright : Copyright (c) 2009-2011 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 <odb/forward.hxx> | | #include <odb/forward.hxx> // result | |
| #include <odb/pointer-traits.hxx> | | #include <odb/traits.hxx> | |
| | | | |
| #include <odb/details/shared-ptr.hxx> | | | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
|
| template <typename T> | | template <typename T, class_kind kind> | |
| class result; | | class result_base; | |
| | | | |
| template <typename T> | | | |
| class result_iterator; | | | |
| | | | |
| template <typename T> | | | |
| class result_impl: public details::shared_base | | | |
| { | | | |
| public: | | | |
| virtual | | | |
| ~result_impl (); | | | |
| | | | |
| protected: | | | |
| friend class result<T>; | | | |
| friend class result_iterator<T>; | | | |
| | | | |
| typedef odb::database database_type; | | | |
| | | | |
| typedef typename odb::object_traits<T>::pointer_type pointer_type; | | | |
| 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_ () | | | |
| { | | | |
| } | | | |
| | | | |
| 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 (); | | | |
| | | | |
| void | | | |
| release () | | | |
| { | | | |
| current_ = pointer_type (); | | | |
| guard_.release (); | | | |
| } | | | |
| | | | |
| void | | | |
| begin () | | | |
| { | | | |
| if (begin_) | | | |
| { | | | |
| next (); | | | |
| begin_ = false; | | | |
| } | | | |
| } | | | |
| | | | |
| bool | | | |
| end () const | | | |
| { | | | |
| return end_; | | | |
| } | | | |
| | | | |
| protected: | | | |
| virtual void | | | |
| load (object_type&) = 0; | | | |
| | | | |
| virtual id_type | | | |
| load_id () = 0; | | | |
| | | | |
| virtual void | | | |
| next () = 0; | | | |
| | | | |
| virtual void | | | |
| cache () = 0; | | | |
| | | | |
| virtual std::size_t | | | |
| size () = 0; | | | |
| | | | |
| protected: | | | |
| void | | | |
| current (pointer_type p) | | | |
| { | | | |
| current_ = p; | | | |
| guard_.reset (current_); | | | |
| } | | | |
| | | | |
| bool begin_; | | | |
| bool end_; | | | |
| | | | |
| private: | | | |
| database_type& db_; | | | |
| pointer_type current_; | | | |
| typename pointer_traits::guard guard_; | | | |
| }; | | | |
| | | | |
| template <typename T> | | | |
| class result_iterator | | | |
| { | | | |
| public: | | | |
| typedef T value_type; | | | |
| typedef value_type& reference; | | | |
| typedef value_type* pointer; | | | |
| typedef std::ptrdiff_t difference_type; | | | |
| 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: | | | |
| explicit | | | |
| result_iterator (result_impl<T>* res = 0) | | | |
| : res_ (res) | | | |
| { | | | |
| } | | | |
| | | | |
|
| // Input iterator requirements. | | template <typename T, class_kind kind> | |
| // | | class result_impl; | |
| public: | | | |
| reference | | | |
| operator* () const | | | |
| { | | | |
| return pointer_traits::get_ref (res_->current ()); | | | |
| } | | | |
| | | | |
| // Our value_type is already a pointer so return it instead of | | | |
| // a pointer to it (operator-> will just have to go one deeper | | | |
| // in the latter case). | | | |
| // | | | |
| pointer | | | |
| operator-> () const | | | |
| { | | | |
| return pointer_traits::get_ptr (res_->current ()); | | | |
| } | | | |
| | | | |
| result_iterator& | | | |
| operator++ () | | | |
| { | | | |
| res_->next (); | | | |
| return *this; | | | |
| } | | | |
| | | | |
| result_iterator | | | |
| operator++ (int) | | | |
| { | | | |
| // All non-end iterators for a result object move together. | | | |
| // | | | |
| res_->next (); | | | |
| return *this; | | | |
| } | | | |
| | | | |
| public: | | | |
| typename object_traits<T>::pointer_type | | | |
| load () | | | |
| { | | | |
| typename object_traits<T>::pointer_type r (res_->current ()); | | | |
| res_->release (); | | | |
| return r; | | | |
| } | | | |
| | | | |
| void | | | |
| load (object_type&); | | | |
| | | | |
| public: | | | |
| bool | | | |
| equal (result_iterator j) const | | | |
| { | | | |
| return (res_ ? res_->end () : true) == (j.res_ ? j.res_->end () : tr | | | |
| ue); | | | |
| } | | | |
| | | | |
| private: | | | |
| typedef | | | |
| odb::pointer_traits<typename object_traits<T>::pointer_type> | | | |
| pointer_traits; | | | |
| | | | |
|
| result_impl<T>* res_; | | template <typename T, class_kind kind = class_traits<T>::kind> | |
| }; | | class result_iterator; | |
| | | | |
| // Input iterator requirements. | | // Input iterator requirements. | |
| // | | // | |
|
| template <typename T> | | template <typename T, class_kind kind> | |
| inline bool | | inline bool | |
|
| operator== (result_iterator<T> i, result_iterator<T> j) | | operator== (result_iterator<T, kind> i, result_iterator<T, kind> j) | |
| { | | { | |
| return i.equal (j); | | return i.equal (j); | |
| } | | } | |
| | | | |
|
| template <typename T> | | template <typename T, class_kind kind> | |
| inline bool | | inline bool | |
|
| operator!= (result_iterator<T> i, result_iterator<T> j) | | operator!= (result_iterator<T, kind> i, result_iterator<T, kind> j) | |
| { | | { | |
| return !i.equal (j); | | return !i.equal (j); | |
| } | | } | |
| | | | |
|
| // | | | |
| // | | | |
| template <typename T> | | template <typename T> | |
|
| class result | | class result: result_base<T, class_traits<T>::kind> | |
| { | | { | |
| public: | | public: | |
|
| typedef typename object_traits<T>::pointer_type value_type; | | static const class_kind kind = class_traits<T>::kind; | |
| typedef value_type* pointer; | | | |
| typedef const value_type* const_pointer; | | typedef result_base<T, kind> base; | |
| typedef value_type& reference; | | | |
| typedef const value_type& const_reference; | | | |
| | | | |
|
| typedef result_iterator<T> iterator; | | typedef typename base::value_type value_type; | |
| | | typedef value_type* pointer; | |
| | | typedef const value_type* const_pointer; | |
| | | typedef value_type& reference; | |
| | | typedef const value_type& const_reference; | |
| | | | |
|
| typedef std::size_t size_type; | | typedef result_iterator<T, kind> iterator; | |
| typedef std::ptrdiff_t difference_type; | | | |
| | | typedef std::size_t size_type; | |
| | | typedef std::ptrdiff_t difference_type; | |
| | | | |
| | | // T can be const T while result_impl's argument is always non-const. | |
| | | // | |
| | | typedef typename base::result_impl_type result_impl_type; | |
| | | | |
| public: | | public: | |
| result () | | result () | |
| { | | { | |
| } | | } | |
| | | | |
| explicit | | explicit | |
|
| result (details::shared_ptr<result_impl<T> > impl) | | result (details::shared_ptr<result_impl_type> impl) | |
| : impl_ (impl) | | : impl_ (impl) | |
| { | | { | |
| } | | } | |
| | | | |
|
| // Copying or assignment of a result object leads to one instance | | // Copying or assignment of a result instance leads to one instance | |
| // being an alias for another. Think of copying a result as copying | | // being an alias for another. Think of copying a result as copying | |
| // a file handle -- the file you access through either of them is | | // a file handle -- the file you access through either of them is | |
| // still the same. | | // still the same. | |
| // | | // | |
| public: | | public: | |
| result (const result& r) | | result (const result& r) | |
| : impl_ (r.impl_) | | : impl_ (r.impl_) | |
| { | | { | |
| } | | } | |
| | | | |
| result& | | result& | |
| operator= (const result& r) | | operator= (const result& r) | |
| { | | { | |
| if (impl_ != r.impl_) | | if (impl_ != r.impl_) | |
| impl_ = r.impl_; | | impl_ = r.impl_; | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| | | // Conversion from result<T> to result<const T>. | |
| | | // | |
| | | template <typename UT> | |
| | | result (const result<UT>& r) | |
| | | // | |
| | | // If you get a compiler error pointing to the line below saying | |
| | | // that the impl_ member is inaccessible, then you are most likely | |
| | | // trying to perform an illegal result conversion, for example, | |
| | | // from result<const obj> to result<obj>. | |
| | | // | |
| | | : impl_ (r.impl_) | |
| | | { | |
| | | } | |
| | | | |
| | | template <typename UT> | |
| | | result& | |
| | | operator= (const result<UT>& r) | |
| | | { | |
| | | // If you get a compiler error pointing to the line below saying | |
| | | // that the impl_ member is inaccessible, then you are most likely | |
| | | // trying to perform an illegal result conversion, for example, | |
| | | // from result<const obj> to result<obj>. | |
| | | // | |
| | | if (impl_ != r.impl_) | |
| | | impl_ = r.impl_; | |
| | | | |
| | | return *this; | |
| | | } | |
| | | | |
| void | | void | |
| swap (result& r) | | swap (result& r) | |
| { | | { | |
| // @@ add swap() to shared_ptr. | | // @@ add swap() to shared_ptr. | |
| // | | // | |
|
| details::shared_ptr<result_impl<T> > p (impl_); | | details::shared_ptr<result_impl_type> p (impl_); | |
| impl_ = r.impl_; | | impl_ = r.impl_; | |
| r.impl_ = p; | | r.impl_ = p; | |
| } | | } | |
| | | | |
| public: | | public: | |
| iterator | | iterator | |
| begin () | | begin () | |
| { | | { | |
| if (impl_) | | if (impl_) | |
| impl_->begin (); | | impl_->begin (); | |
| | | | |
| skipping to change at line 296 | | skipping to change at line 153 | |
| 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 | |
|
| // one object at a time. This is necessary if you plan on performing | | // one row at a time. This is necessary if you plan on performing | |
| // database operations while iterating over the result. | | // database operations while iterating over the result. | |
| // | | // | |
| public: | | public: | |
| void | | void | |
| cache () | | cache () | |
| { | | { | |
| if (impl_) | | if (impl_) | |
| impl_->cache (); | | impl_->cache (); | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 327 | | skipping to change at line 184 | |
| | | | |
| // 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; | |
| } | | } | |
| | | | |
| private: | | private: | |
|
| details::shared_ptr<result_impl<T> > impl_; | | friend class result<const T>; | |
| | | | |
| | | details::shared_ptr<result_impl_type> impl_; | |
| }; | | }; | |
| | | | |
| namespace core | | namespace core | |
| { | | { | |
| using odb::result; | | using odb::result; | |
|
| | | using odb::result_iterator; | |
| } | | } | |
| } | | } | |
| | | | |
|
| #include <odb/result.txx> | | | |
| | | | |
| #include <odb/post.hxx> | | #include <odb/post.hxx> | |
| | | | |
| #endif // ODB_RESULT_HXX | | #endif // ODB_RESULT_HXX | |
|
| | | | |
| | | // Include result specializations so that the user code only needs | |
| | | // to include this header. | |
| | | // | |
| | | | |
| | | #include <odb/object-result.hxx> | |
| | | #include <odb/view-result.hxx> | |
| | | | |
End of changes. 23 change blocks. |
| 209 lines changed or deleted | | 66 lines changed or added | |
|
| session.txx | | session.txx | |
| | | | |
| skipping to change at line 16 | | skipping to change at line 16 | |
| #include <odb/pointer-traits.hxx> | | #include <odb/pointer-traits.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| template <typename T> | | template <typename T> | |
| typename session::object_position<T> session:: | | typename session::object_position<T> session:: | |
| insert (database_type& db, | | insert (database_type& db, | |
| const typename object_traits<T>::id_type& id, | | const typename object_traits<T>::id_type& id, | |
| const typename object_traits<T>::pointer_type& obj) | | const typename object_traits<T>::pointer_type& obj) | |
| { | | { | |
|
| // T can be const T while object_type will always be T. | | typedef odb::object_traits<T> object_traits; | |
| // | | typedef typename object_traits::pointer_type pointer_type; | |
| typedef typename object_traits<T>::object_type object_type; | | | |
| typedef odb::object_traits<object_type> object_traits; | | | |
| | | | |
| typedef typename odb::object_traits<T>::pointer_type pointer_type; | | | |
| typedef odb::pointer_traits<pointer_type> pointer_traits; | | typedef odb::pointer_traits<pointer_type> pointer_traits; | |
| | | | |
| type_map& tm (db_map_[&db]); | | type_map& tm (db_map_[&db]); | |
|
| details::shared_ptr<object_map_base>& pom (tm[&typeid (object_type)]); | | details::shared_ptr<object_map_base>& pom (tm[&typeid (T)]); | |
| | | | |
| if (!pom) | | if (!pom) | |
|
| pom.reset (new (details::shared) object_map<object_type>); | | pom.reset (new (details::shared) object_map<T>); | |
| | | | |
|
| object_map<object_type>& om ( | | object_map<T>& om (static_cast<object_map<T>&> (*pom)); | |
| static_cast<object_map<object_type>&> (*pom)); | | | |
| | | | |
|
| typename object_map<object_type>::value_type vt ( | | typename object_map<T>::value_type vt (id, obj); | |
| id, object_pointers<object_type> ()); | | std::pair<typename object_map<T>::iterator, bool> r (om.insert (vt)); | |
| vt.second.set (obj); | | | |
| std::pair<typename object_map<object_type>::iterator, bool> r ( | | | |
| om.insert (vt)); | | | |
| | | | |
| // In what situation may we possibly attempt to reinsert the object? | | // In what situation may we possibly attempt to reinsert the object? | |
| // For example, when the user loads the same object in to different | | // For example, when the user loads the same object in to different | |
| // instances (i.e., load into a pre-allocated object). In this case | | // instances (i.e., load into a pre-allocated object). In this case | |
| // we should probably update our entries accordingly. | | // we should probably update our entries accordingly. | |
| // | | // | |
| if (!r.second) | | if (!r.second) | |
|
| r.first->second.set (obj); | | r.first->second = obj; | |
| | | | |
| return object_position<T> (om, r.first); | | return object_position<T> (om, r.first); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| typename object_traits<T>::pointer_type session:: | | typename object_traits<T>::pointer_type session:: | |
| find (database_type& db, const typename object_traits<T>::id_type& id) co
nst | | find (database_type& db, const typename object_traits<T>::id_type& id) co
nst | |
| { | | { | |
|
| // T can be const T while object_type will always be T. | | | |
| // | | | |
| typedef typename object_traits<T>::object_type object_type; | | | |
| typedef typename object_traits<T>::pointer_type pointer_type; | | typedef typename object_traits<T>::pointer_type pointer_type; | |
| | | | |
| database_map::const_iterator di (db_map_.find (&db)); | | database_map::const_iterator di (db_map_.find (&db)); | |
| | | | |
| if (di == db_map_.end ()) | | if (di == db_map_.end ()) | |
| return pointer_type (); | | return pointer_type (); | |
| | | | |
| const type_map& tm (di->second); | | const type_map& tm (di->second); | |
|
| type_map::const_iterator ti (tm.find (&typeid (object_type))); | | type_map::const_iterator ti (tm.find (&typeid (T))); | |
| | | | |
| if (ti == tm.end ()) | | if (ti == tm.end ()) | |
| return pointer_type (); | | return pointer_type (); | |
| | | | |
|
| const object_map<object_type>& om ( | | const object_map<T>& om (static_cast<const object_map<T>&> (*ti->second | |
| static_cast<const object_map<object_type>&> (*ti->second)); | | )); | |
| typename object_map<object_type>::const_iterator oi (om.find (id)); | | typename object_map<T>::const_iterator oi (om.find (id)); | |
| | | | |
| if (oi == om.end ()) | | if (oi == om.end ()) | |
| return pointer_type (); | | return pointer_type (); | |
| | | | |
|
| pointer_type r; | | return oi->second; | |
| oi->second.get (r); | | | |
| return r; | | | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void session:: | | void session:: | |
| erase (database_type& db, const typename object_traits<T>::id_type& id) | | erase (database_type& db, const typename object_traits<T>::id_type& id) | |
| { | | { | |
|
| // T can be const T while object_type will always be T. | | | |
| // | | | |
| typedef typename object_traits<T>::object_type object_type; | | | |
| | | | |
| database_map::iterator di (db_map_.find (&db)); | | database_map::iterator di (db_map_.find (&db)); | |
| | | | |
| if (di == db_map_.end ()) | | if (di == db_map_.end ()) | |
| return; | | return; | |
| | | | |
| type_map& tm (di->second); | | type_map& tm (di->second); | |
|
| type_map::iterator ti (tm.find (&typeid (object_type))); | | type_map::iterator ti (tm.find (&typeid (T))); | |
| | | | |
| if (ti == tm.end ()) | | if (ti == tm.end ()) | |
| return; | | return; | |
| | | | |
|
| object_map<object_type>& om ( | | object_map<T>& om (static_cast<object_map<T>&> (*ti->second)); | |
| static_cast<object_map<object_type>&> (*ti->second)); | | typename object_map<T>::iterator oi (om.find (id)); | |
| typename object_map<object_type>::iterator oi (om.find (id)); | | | |
| | | | |
| if (oi == om.end ()) | | if (oi == om.end ()) | |
| return; | | return; | |
| | | | |
| om.erase (oi); | | om.erase (oi); | |
| | | | |
| if (om.empty ()) | | if (om.empty ()) | |
| tm.erase (ti); | | tm.erase (ti); | |
| | | | |
| if (tm.empty ()) | | if (tm.empty ()) | |
| | | | |
End of changes. 13 change blocks. |
| 34 lines changed or deleted | | 16 lines changed or added | |
|
| traits.hxx | | traits.hxx | |
| | | | |
| skipping to change at line 16 | | skipping to change at line 16 | |
| #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> | | | |
| // class access::object_traits; | | | |
| // | | | |
| // Specializations should define the following members: | | | |
| // | | | |
| // id_type - object id (primary key) type | | | |
| // id_type id (const T&) - get object id | | | |
| // | | | |
| // void persist (database&, T&) | | | |
| // void update (database&, T&) | | | |
| // void erase (database&, const id_type&) | | | |
| // pointer_type find (database&, const id_type&) | | | |
| // bool find (database&, const id_type&, T&) | | | |
| // | | | |
| // | | | |
| | | | |
| template <typename T, typename P> | | template <typename T, typename P> | |
| class access::object_factory | | class access::object_factory | |
| { | | { | |
| public: | | public: | |
| typedef T object_type; | | typedef T object_type; | |
| typedef P pointer_type; | | typedef P pointer_type; | |
| | | | |
| static P | | static P | |
| create () | | create () | |
| { | | { | |
| // By default use pointer-specific construction. | | // By default use pointer-specific construction. | |
| // | | // | |
| return pointer_factory<T, P>::create (); | | return pointer_factory<T, P>::create (); | |
| } | | } | |
| }; | | }; | |
| | | | |
| template <typename T, typename P> | | template <typename T, typename P> | |
|
| | | class access::view_factory | |
| | | { | |
| | | public: | |
| | | typedef T view_type; | |
| | | typedef P pointer_type; | |
| | | | |
| | | static P | |
| | | create () | |
| | | { | |
| | | // By default use pointer-specific construction. | |
| | | // | |
| | | return pointer_factory<T, P>::create (); | |
| | | } | |
| | | }; | |
| | | | |
| | | template <typename T, typename P> | |
| class access::pointer_factory | | class access::pointer_factory | |
| { | | { | |
| public: | | public: | |
|
| typedef T object_type; | | typedef T value_type; | |
| typedef P pointer_type; | | typedef P pointer_type; | |
| | | | |
| static P | | static P | |
| create () | | create () | |
| { | | { | |
| void* v (pointer_traits<P>::allocate (sizeof (T))); | | void* v (pointer_traits<P>::allocate (sizeof (T))); | |
| mem_guard g (v); | | mem_guard g (v); | |
| P p (new (v) T); | | 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_; | |
| }; | | }; | |
| }; | | }; | |
| | | | |
|
| | | // | |
| | | // class_traits | |
| | | // | |
| | | enum class_kind | |
| | | { | |
| | | class_object, | |
| | | class_view, | |
| | | class_composite, | |
| | | class_other | |
| | | }; | |
| | | | |
| | | template <typename T> | |
| | | struct class_traits | |
| | | { | |
| | | static const class_kind kind = class_other; | |
| | | }; | |
| | | | |
| | | template <typename T> | |
| | | struct class_traits<const T> | |
| | | { | |
| | | static const class_kind kind = class_traits<T>::kind; | |
| | | }; | |
| | | | |
| | | // | |
| | | // object_traits | |
| | | // | |
| | | | |
| template <typename T> | | template <typename T> | |
| struct object_traits: | | struct object_traits: | |
| access::object_traits<T>, | | access::object_traits<T>, | |
| access::object_factory<T, typename access::object_traits<T>::pointer_ty
pe> | | access::object_factory<T, typename access::object_traits<T>::pointer_ty
pe> | |
| { | | { | |
| // | | // | |
| // If a C++ compiler issues an error pointing to this struct and | | // If a C++ compiler issues an error pointing to this struct and | |
| // saying that it is incomplete, then you are most likely trying to | | // 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 | | // perform a database operation on a C++ type that is not a persistent | |
| // object. Or you forgot to include the corresponding -odb.hxx file. | | // object. Or you forgot to include the corresponding -odb.hxx file. | |
| | | | |
| skipping to change at line 145 | | skipping to change at line 173 | |
| { | | { | |
| struct id_type {}; | | struct id_type {}; | |
| }; | | }; | |
| | | | |
| template <typename T, template <typename> class P> | | template <typename T, template <typename> class P> | |
| struct object_traits< const P<T> > | | struct object_traits< const P<T> > | |
| { | | { | |
| struct id_type {}; | | struct id_type {}; | |
| }; | | }; | |
| | | | |
|
| | | // | |
| | | // view_traits | |
| | | // | |
| | | | |
| | | template <typename T> | |
| | | struct view_traits: | |
| | | access::view_traits<T>, | |
| | | access::view_factory<T, typename access::view_traits<T>::pointer_type> | |
| | | { | |
| | | // | |
| | | // 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 view | |
| | | // Or you forgot to include the corresponding -odb.hxx file. | |
| | | // | |
| | | | |
| | | typedef | |
| | | odb::pointer_traits<typename access::view_traits<T>::pointer_type> | |
| | | pointer_traits; | |
| | | | |
| | | typedef typename access::view_traits<T>::view_type view_type; | |
| | | typedef typename access::view_traits<T>::pointer_type pointer_type; | |
| | | }; | |
| | | | |
| | | // Specialization for const views. It only defines the view, pointer, | |
| | | // and const_pointer types with pointer and const_pointer being the | |
| | | // same. Similar to objects, the idea is to only use this specialization | |
| | | // in the interfaces, with the implementations detecting this situation | |
| | | // and using the non-const view_traits version. | |
| | | // | |
| | | template <typename T> | |
| | | struct view_traits<const T> | |
| | | { | |
| | | private: | |
| | | typedef | |
| | | odb::pointer_traits<typename access::view_traits<T>::pointer_type> | |
| | | pointer_traits; | |
| | | | |
| | | public: | |
| | | typedef typename access::view_traits<T>::view_type view_type; | |
| | | typedef typename pointer_traits::const_pointer_type const_pointer_type; | |
| | | typedef const_pointer_type pointer_type; | |
| | | }; | |
| | | | |
| | | // | |
| | | // composite_value_traits | |
| | | // | |
| | | | |
| template <typename T> | | template <typename T> | |
| struct composite_value_traits: access::composite_value_traits<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. 6 change blocks. |
| 17 lines changed or deleted | | 93 lines changed or added | |
|
| transaction.hxx | | transaction.hxx | |
| | | | |
| skipping to change at line 23 | | skipping to change at line 23 | |
| #include <odb/details/export.hxx> | | #include <odb/details/export.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| class transaction_impl; | | class transaction_impl; | |
| | | | |
| class LIBODB_EXPORT transaction | | class LIBODB_EXPORT transaction | |
| { | | { | |
| public: | | public: | |
| typedef odb::database database_type; | | typedef odb::database database_type; | |
|
| | | typedef odb::connection connection_type; | |
| | | | |
|
| | | // If the second argument is false, then this transaction is not | |
| | | // made the current transaction of the thread. | |
| | | // | |
| explicit | | explicit | |
|
| transaction (transaction_impl*); | | transaction (transaction_impl*, bool make_current = true); | |
| | | | |
| // Unless the transaction has already been finalized (explicitly | | // Unless the transaction has already been finalized (explicitly | |
| // committed or rolled back), the destructor will roll it back. | | // committed or rolled back), the destructor will roll it back. | |
| // | | // | |
| ~transaction (); | | ~transaction (); | |
| | | | |
| void | | void | |
| commit (); | | commit (); | |
| | | | |
| void | | void | |
| rollback (); | | rollback (); | |
| | | | |
| // Return the database this transaction is on. | | // Return the database this transaction is on. | |
| // | | // | |
| database_type& | | database_type& | |
| database (); | | database (); | |
| | | | |
|
| | | // Return the connection this transaction is on. | |
| | | // | |
| | | connection_type& | |
| | | connection (); | |
| | | | |
| | | // Return true if there is a transaction in effect. | |
| | | // | |
| | | static bool | |
| | | has_current (); | |
| | | | |
| // Return current transaction or throw if there is no transaction | | // Return current transaction or throw if there is no transaction | |
| // in effect. | | // in effect. | |
| // | | // | |
| static transaction& | | static transaction& | |
| current (); | | current (); | |
| | | | |
|
| // Return true if there is a transaction in effect. | | // Set the current thread's transaction. | |
| // | | // | |
|
| static bool | | static void | |
| has_current (); | | current (transaction&); | |
| | | | |
| | | // Revert to the no transaction in effect state for the current thread. | |
| | | // | |
| | | static void | |
| | | reset_current (); | |
| | | | |
| public: | | public: | |
| transaction_impl& | | transaction_impl& | |
| implementation (); | | implementation (); | |
| | | | |
| // Copying or assignment of transactions is not supported. | | // Copying or assignment of transactions is not supported. | |
| // | | // | |
| private: | | private: | |
| transaction (const transaction&); | | transaction (const transaction&); | |
| transaction& operator= (const transaction&); | | transaction& operator= (const transaction&); | |
| | | | |
| protected: | | protected: | |
| bool finalized_; | | bool finalized_; | |
| transaction_impl* impl_; | | transaction_impl* impl_; | |
| }; | | }; | |
| | | | |
| class LIBODB_EXPORT transaction_impl | | class LIBODB_EXPORT transaction_impl | |
| { | | { | |
|
| protected: | | public: | |
| friend class transaction; | | | |
| | | | |
| typedef odb::database database_type; | | typedef odb::database database_type; | |
|
| | | typedef odb::connection connection_type; | |
| transaction_impl (database_type& db) | | | |
| : database_ (db) | | | |
| { | | | |
| } | | | |
| | | | |
| virtual | | virtual | |
| ~transaction_impl (); | | ~transaction_impl (); | |
| | | | |
| virtual void | | virtual void | |
|
| | | start () = 0; | |
| | | | |
| | | virtual void | |
| commit () = 0; | | commit () = 0; | |
| | | | |
| virtual void | | virtual void | |
| rollback () = 0; | | rollback () = 0; | |
| | | | |
| database_type& | | database_type& | |
| database () | | database () | |
| { | | { | |
| return database_; | | return database_; | |
| } | | } | |
| | | | |
|
| | | connection_type& | |
| | | connection () | |
| | | { | |
| | | return *connection_; | |
| | | } | |
| | | | |
| | | protected: | |
| | | transaction_impl (database_type& db) | |
| | | : database_ (db), connection_ (0) | |
| | | { | |
| | | } | |
| | | | |
| | | transaction_impl (database_type& db, connection_type& c) | |
| | | : database_ (db), connection_ (&c) | |
| | | { | |
| | | } | |
| | | | |
| protected: | | protected: | |
| database_type& database_; | | database_type& database_; | |
|
| | | connection_type* connection_; | |
| }; | | }; | |
| } | | } | |
| | | | |
| #include <odb/transaction.ixx> | | #include <odb/transaction.ixx> | |
| | | | |
| #include <odb/post.hxx> | | #include <odb/post.hxx> | |
| | | | |
| #endif // ODB_TRANSACTION_HXX | | #endif // ODB_TRANSACTION_HXX | |
| | | | |
End of changes. 11 change blocks. |
| 12 lines changed or deleted | | 46 lines changed or added | |
|