// file : odb/database.ixx // copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include // std::strlen() #include // std::move #include #include #include namespace odb { template struct object_pointer_traits { typedef details::meta::no result_type; typedef T object_type; static const T& get_ref (const T& x) {return x;} }; template struct object_pointer_traits { typedef details::meta::yes result_type; typedef T object_type; static const T& get_ref (const T* p) {return *p;} }; template struct object_pointer_traits { typedef details::meta::yes result_type; typedef T object_type; static const T& get_ref (const T* p) {return *p;} }; template class P> struct object_pointer_traits > { typedef details::meta::yes result_type; typedef T object_type; static const T& get_ref (const P& p) { return pointer_traits >::get_ref (p);} }; template class P> struct object_pointer_traits > { typedef details::meta::yes result_type; typedef T object_type; static const T& get_ref (const P& p) { return pointer_traits >::get_ref (p);} }; template class P> struct object_pointer_traits > { typedef details::meta::yes result_type; typedef T object_type; static const T& get_ref (const P& p) { return pointer_traits >::get_ref (p);} }; template class P> struct object_pointer_traits > { typedef details::meta::yes result_type; typedef T object_type; static const T& get_ref (const P& p) { return pointer_traits >::get_ref (p);} }; inline database:: database (database_id id) : id_ (id), tracer_ (0), mutex_ (new details::mutex), schema_version_seq_ (1) { } inline database_id database:: id () const { return id_; } inline database::schema_version_type database:: schema_version (const std::string& name) const { return schema_version_migration (name).version; } inline bool database:: schema_migration (const std::string& name) const { return schema_version_migration (name).migration; } inline void database:: schema_version_migration (schema_version_type v, bool m, const std::string& name) { schema_version_migration (schema_version_migration_type (v, m), name); } inline void database:: schema_version_table (const std::string& tname) { schema_version_table_ = tname; } inline void database:: schema_version_table (const std::string& tname, const std::string& sname) { schema_version_map_[sname].version_table = tname; } inline unsigned int database:: schema_version_sequence () const { return schema_version_seq_; } inline connection_ptr database:: connection () { return connection_ptr (connection_ ()); } #ifndef ODB_CXX11 inline void database:: query_factory (const char* name, query_factory_ptr f) { query_factory (name, query_factory_wrapper (f)); } #endif inline void database:: tracer (tracer_type& t) { tracer_ = &t; } inline void database:: tracer (tracer_type* t) { tracer_ = t; } inline database::tracer_type* database:: tracer () const { return tracer_; } template inline typename object_traits::id_type database:: persist (T& obj) { return persist_ (obj); } template inline typename object_traits::id_type database:: persist (const T& obj) { return persist_ (obj); } template inline typename object_traits::id_type database:: persist (T* p) { typedef typename object_traits::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_ (pobj); } template class P> inline typename object_traits::id_type database:: persist (const P& p) { typedef typename object_traits::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_ (pobj); } template class P> inline typename object_traits::id_type database:: persist (const P& p) { typedef typename object_traits::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_ (pobj); } template class P> inline typename object_traits::id_type database:: persist (P& p) { const P& cr (p); return persist (cr); } template class P> inline typename object_traits::id_type database:: persist (P& p) { const P& cr (p); return persist (cr); } template inline typename object_traits::id_type database:: persist (const typename object_traits::pointer_type& pobj) { return persist_ (pobj); } template inline void database:: persist (I b, I e, bool cont) { persist_ (b, e, cont); } template inline typename object_traits::pointer_type database:: load (const typename object_traits::id_type& id) { return load_ (id); } template inline void database:: load (const typename object_traits::id_type& id, T& obj) { return load_ (id, obj); } template inline void database:: load (T& obj, section& s) { return load_ (obj, s); } template inline typename object_traits::pointer_type database:: find (const typename object_traits::id_type& id) { return find_ (id); } template inline bool database:: find (const typename object_traits::id_type& id, T& obj) { return find_ (id, obj); } template inline void database:: reload (T& obj) { reload_ (obj); } template inline void database:: reload (T* p) { reload (*p); } template class P> inline void database:: reload (const P& p) { reload (odb::pointer_traits< P >::get_ref (p)); } template class P> inline void database:: reload (const P& p) { reload (odb::pointer_traits< P >::get_ref (p)); } template class P> inline void database:: reload (P& p) { reload (odb::pointer_traits< P >::get_ref (p)); } template class P> inline void database:: reload (P& p) { reload (odb::pointer_traits< P >::get_ref (p)); } template inline void database:: reload (const typename object_traits::pointer_type& pobj) { typedef typename object_traits::pointer_type pointer_type; reload (odb::pointer_traits::get_ref (pobj)); } template inline void database:: update (T& obj) { update_ (obj); } template inline void database:: update (T* p) { typedef typename object_traits::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_ (pobj); } template class P> inline void database:: update (const P& p) { typedef typename object_traits::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_ (pobj); } template class P> inline void database:: update (const P& p) { typedef typename object_traits::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_ (pobj); } template class P> inline void database:: update (P& p) { const P& cr (p); update (cr); } template class P> inline void database:: update (P& p) { const P& cr (p); update (cr); } template inline void database:: update (const typename object_traits::pointer_type& pobj) { update_ (pobj); } template inline void database:: update (I b, I e, bool cont) { update_ (b, e, cont); } template inline void database:: update (const T& obj, const section& s) { update_ (obj, s); } template inline void database:: erase (const typename object_traits::id_type& id) { return erase_ (id); } template inline void database:: erase (T& obj) { return erase_ (obj); } template inline void database:: erase (T* p) { typedef typename object_traits::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_ (pobj); } template class P> inline void database:: erase (const P& p) { typedef typename object_traits::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_ (pobj); } template class P> inline void database:: erase (const P& p) { typedef typename object_traits::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_ (pobj); } template class P> inline void database:: erase (P& p) { const P& cr (p); erase (cr); } template class P> inline void database:: erase (P& p) { const P& cr (p); erase (cr); } template inline void database:: erase (const typename object_traits::pointer_type& pobj) { erase_ (pobj); } template inline void database:: erase (I idb, I ide, bool cont) { erase_id_ (idb, ide, cont); } template inline void database:: erase (I ob, I oe, bool cont) { erase_object_ (ob, oe, cont); } template inline unsigned long long database:: erase_query () { // T is always object_type. // return erase_query (odb::query ()); } template inline unsigned long long database:: erase_query (const char* q) { // T is always object_type. // return erase_query (odb::query (q)); } template inline unsigned long long database:: erase_query (const std::string& q) { // T is always object_type. // return erase_query (odb::query (q)); } template inline unsigned long long database:: erase_query (const odb::query& q) { // T is always object_type. // return object_traits_impl::erase_query (*this, q); } template inline result database:: query (bool cache) { return query (odb::query (), cache); } template inline result database:: query (const char* q, bool cache) { return query (odb::query (q), cache); } template inline result database:: query (const std::string& q, bool cache) { return query (odb::query (q), cache); } template inline typename result::pointer_type database:: query_one () { return query_one (odb::query ()); } template inline bool database:: query_one (T& o) { return query_one (odb::query (), o); } template inline T database:: query_value () { return query_value (odb::query ()); } template inline typename result::pointer_type database:: query_one (const char* q) { return query_one (odb::query (q)); } template inline bool database:: query_one (const char* q, T& o) { return query_one (odb::query (q), o); } template inline T database:: query_value (const char* q) { return query_value (odb::query (q)); } template inline typename result::pointer_type database:: query_one (const std::string& q) { return query_one (odb::query (q)); } template inline bool database:: query_one (const std::string& q, T& o) { return query_one (odb::query (q), o); } template inline T database:: query_value (const std::string& q) { return query_value (odb::query (q)); } template inline bool database:: query_one (const odb::query& q, T& o) { return query_one_ (q, o); } template inline typename result::pointer_type database:: query_one (const odb::query& q) { return query_one_ (q); } template inline T database:: query_value (const odb::query& q) { return query_value_ (q); } template inline prepared_query database:: prepare_query (const char* n, const char* q) { return prepare_query (n, odb::query (q)); } template inline prepared_query database:: prepare_query (const char* n, const std::string& q) { return prepare_query (n, odb::query (q)); } template inline prepared_query database:: prepare_query (const char* n, const odb::query& q) { connection_type& c (transaction::current ().connection ()); return c.prepare_query (n, q); } template inline void database:: cache_query (const prepared_query& pq) { connection_type& c (transaction::current ().connection ()); c.cache_query (pq); } #ifdef ODB_CXX11 template inline void database:: cache_query (const prepared_query& pq, std::unique_ptr

params) { connection_type& c (transaction::current ().connection ()); c.cache_query (pq, std::move (params)); } #else template inline void database:: cache_query (const prepared_query& pq, std::auto_ptr

params) { connection_type& c (transaction::current ().connection ()); c.cache_query (pq, params); } #endif template inline prepared_query database:: lookup_query (const char* name) const { connection_type& c (transaction::current ().connection ()); return c.lookup_query (name); } template inline prepared_query database:: lookup_query (const char* name, P*& params) const { connection_type& c (transaction::current ().connection ()); return c.lookup_query (name, params); } // Implementations (i.e., the *_() functions). // template inline void database:: persist_ (I b, I e, bool cont) { // Sun CC with non-standard STL does not have iterator_traits. // #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC typedef typename std::iterator_traits::value_type value_type; #else // Assume iterator is just a pointer. // typedef typename object_pointer_traits::object_type value_type; #endif typedef object_pointer_traits opt; persist_ ( b, e, cont, typename opt::result_type ()); } template inline typename object_traits::pointer_type database:: find_ (const typename object_traits::id_type& id) { // T is always object_type. // // Compiler error pointing here? Perhaps the object doesn't have the // default constructor? // return object_traits_impl::find (*this, id); } template inline bool database:: find_ (const typename object_traits::id_type& id, T& obj) { // T is always object_type. // return object_traits_impl::find (*this, id, obj); } template inline void database:: update_ (T& obj) { // T can be const T while object_type will always be T. // typedef typename object_traits::object_type object_type; // Compiler error pointing here? Perhaps the object is readonly or // doesn't have an object id? Such objects cannot be updated. // object_traits_impl::update (*this, obj); } template inline void database:: update_ (const typename object_traits::pointer_type& pobj) { // T can be const T while object_type will always be T. // typedef typename object_traits::object_type object_type; typedef typename object_traits::pointer_type pointer_type; T& obj (pointer_traits::get_ref (pobj)); // Compiler error pointing here? Perhaps the object is readonly or // doesn't have an object id? Such objects cannot be updated. // object_traits_impl::update (*this, obj); } template inline void database:: erase_ (const typename object_traits::id_type& id) { // T is always object_type. // object_traits_impl::erase (*this, id); } template inline void database:: erase_ (T& obj) { // T can be const T while object_type will always be T. // typedef typename object_traits::object_type object_type; object_traits_impl::erase (*this, obj); } template inline void database:: erase_ (const typename object_traits::pointer_type& pobj) { typedef typename object_traits::pointer_type pointer_type; erase_ (pointer_traits::get_ref (pobj)); } template inline typename result::pointer_type database:: query_one_ (const Q& q) { result r (query_::call (*this, q)); // We still have to cache the result since loading the object // may result in loading of it's related objects and that would // invalidate the result even for just getting the 'end' status. // r.cache (); return r.one (); } template inline bool database:: query_one_ (const Q& q, T& o) { result r (query_::call (*this, q)); r.cache (); // See above. return r.one (o); } template inline T database:: query_value_ (const Q& q) { result r (query_::call (*this, q)); r.cache (); // See above. // Compiler error pointing here? The object must be default-constructible // in order to use the return-by-value API. // T o; r.value (o); return o; } // execute() // 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 ()); } }