From 382035d872a2cbb22fc14d3c87db93b1f39b407b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 8 Oct 2012 16:09:08 +0200 Subject: Ground work for multi-database support All generated code now includes database id. The database-specific database class interface has been updated to include all the database operations. The database-specific tests now use this interface. --- odb/sqlite/database.cxx | 9 +- odb/sqlite/database.hxx | 186 ++++++++++++ odb/sqlite/database.ixx | 378 ++++++++++++++++++++++++ odb/sqlite/forward.hxx | 2 +- odb/sqlite/no-id-object-result.hxx | 8 +- odb/sqlite/no-id-object-result.txx | 2 +- odb/sqlite/no-id-object-statements.hxx | 2 +- odb/sqlite/polymorphic-object-result.hxx | 13 +- odb/sqlite/polymorphic-object-result.txx | 6 +- odb/sqlite/polymorphic-object-statements.hxx | 2 +- odb/sqlite/query-const-expr.cxx | 2 +- odb/sqlite/query.cxx | 44 +-- odb/sqlite/query.hxx | 424 +++++++++++++++------------ odb/sqlite/query.ixx | 8 +- odb/sqlite/query.txx | 27 +- odb/sqlite/result.cxx | 3 +- odb/sqlite/result.hxx | 5 +- odb/sqlite/simple-object-result.hxx | 10 +- odb/sqlite/simple-object-result.txx | 2 +- odb/sqlite/simple-object-statements.hxx | 4 +- odb/sqlite/statement-cache.hxx | 2 +- odb/sqlite/statement-cache.txx | 7 +- odb/sqlite/view-result.hxx | 8 +- odb/sqlite/view-result.txx | 2 +- odb/sqlite/view-statements.hxx | 2 +- 25 files changed, 897 insertions(+), 261 deletions(-) diff --git a/odb/sqlite/database.cxx b/odb/sqlite/database.cxx index 0f1138f..00618b5 100644 --- a/odb/sqlite/database.cxx +++ b/odb/sqlite/database.cxx @@ -38,7 +38,8 @@ namespace odb bool foreign_keys, const string& vfs, transfer_ptr factory) - : name_ (name), + : odb::database (id_sqlite), + name_ (name), flags_ (flags), foreign_keys_ (foreign_keys), vfs_ (vfs), @@ -57,7 +58,8 @@ namespace odb bool foreign_keys, const string& vfs, transfer_ptr factory) - : flags_ (flags), + : odb::database (id_sqlite), + flags_ (flags), foreign_keys_ (foreign_keys), vfs_ (vfs), factory_ (factory.transfer ()) @@ -114,7 +116,8 @@ namespace odb bool foreign_keys, const string& vfs, transfer_ptr factory) - : flags_ (flags), + : odb::database (id_sqlite), + flags_ (flags), foreign_keys_ (foreign_keys), vfs_ (vfs), factory_ (factory.transfer ()) diff --git a/odb/sqlite/database.hxx b/odb/sqlite/database.hxx index bbb01f6..aa15a9b 100644 --- a/odb/sqlite/database.hxx +++ b/odb/sqlite/database.hxx @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -102,6 +103,191 @@ namespace odb return vfs_; } + // Object persistence API. + // + public: + + // Make the object persistent. + // + template + typename object_traits::id_type + persist (T& object); + + template + typename object_traits::id_type + persist (T* obj_ptr); + + template class P> + typename object_traits::id_type + persist (const P& obj_ptr); + + template class P> + typename object_traits::id_type + persist (const P& obj_ptr); + + template class P> + typename object_traits::id_type + persist (P& obj_ptr); + + template class P> + typename object_traits::id_type + persist (P& obj_ptr); + + template + typename object_traits::id_type + persist (const typename object_traits::pointer_type& obj_ptr); + + // Load an object. Throw object_not_persistent if not found. + // + template + typename object_traits::pointer_type + load (const typename object_traits::id_type& id); + + template + void + load (const typename object_traits::id_type& id, T& object); + + // Reload an object. + // + template + void + reload (T& object); + + template + void + reload (T* obj_ptr); + + template class P> + void + reload (const P& obj_ptr); + + template class P> + void + reload (const P& obj_ptr); + + template class P> + void + reload (P& obj_ptr); + + template class P> + void + reload (P& obj_ptr); + + template + void + reload (const typename object_traits::pointer_type& obj_ptr); + + // Loan an object if found. Return NULL/false if not found. + // + template + typename object_traits::pointer_type + find (const typename object_traits::id_type& id); + + template + bool + find (const typename object_traits::id_type& id, T& object); + + // Update the state of a modified objects. + // + template + void + update (T& object); + + template + void + update (T* obj_ptr); + + template class P> + void + update (const P& obj_ptr); + + template class P> + void + update (const P& obj_ptr); + + template class P> + void + update (P& obj_ptr); + + template class P> + void + update (P& obj_ptr); + + template + void + update (const typename object_traits::pointer_type& obj_ptr); + + // Make the object transient. Throw object_not_persistent if not + // found. + // + template + void + erase (const typename object_traits::id_type& id); + + template + void + erase (T& object); + + template + void + erase (T* obj_ptr); + + template class P> + void + erase (const P& obj_ptr); + + template class P> + void + erase (const P& obj_ptr); + + template class P> + void + erase (P& obj_ptr); + + template class P> + void + erase (P& obj_ptr); + + template + void + erase (const typename object_traits::pointer_type& obj_ptr); + + // Erase multiple objects matching a query predicate. + // + template + unsigned long long + erase_query (); + + template + unsigned long long + erase_query (const char*); + + template + unsigned long long + erase_query (const std::string&); + + template + unsigned long long + erase_query (const sqlite::query&); + + // Query API. + // + template + result + query (); + + template + result + query (const char*); + + template + result + query (const std::string&); + + template + result + query (const sqlite::query&); + // Transactions. // public: diff --git a/odb/sqlite/database.ixx b/odb/sqlite/database.ixx index ab0f09b..c8b2a30 100644 --- a/odb/sqlite/database.ixx +++ b/odb/sqlite/database.ixx @@ -15,5 +15,383 @@ namespace odb return connection_ptr ( static_cast (connection_ ())); } + + template + inline typename object_traits::id_type database:: + persist (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 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 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:: + 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 unsigned long long database:: + erase_query () + { + // T is always object_type. + // + return erase_query (sqlite::query ()); + } + + template + inline unsigned long long database:: + erase_query (const char* q) + { + // T is always object_type. + // + return erase_query (sqlite::query (q)); + } + + template + inline unsigned long long database:: + erase_query (const std::string& q) + { + // T is always object_type. + // + return erase_query (sqlite::query (q)); + } + + template + inline unsigned long long database:: + erase_query (const sqlite::query& q) + { + // T is always object_type. + // + return object_traits_impl::erase_query (*this, q); + } + + template + inline result database:: + query () + { + return query (sqlite::query ()); + } + + template + inline result database:: + query (const char* q) + { + return query (sqlite::query (q)); + } + + template + inline result database:: + query (const std::string& q) + { + return query (sqlite::query (q)); + } + + template + inline result database:: + query (const sqlite::query& q) + { + // T is always object_type. We also don't need to check for transaction + // here; object_traits::query () does this. + // + return query_::call (*this, q); + } } } diff --git a/odb/sqlite/forward.hxx b/odb/sqlite/forward.hxx index 9be506f..e2f4df1 100644 --- a/odb/sqlite/forward.hxx +++ b/odb/sqlite/forward.hxx @@ -20,7 +20,6 @@ namespace odb class statement; class transaction; class tracer; - class query; // Implementation details. // @@ -52,6 +51,7 @@ namespace odb template class container_statements; + class query_base; class query_params; } diff --git a/odb/sqlite/no-id-object-result.hxx b/odb/sqlite/no-id-object-result.hxx index 84a7265..7079678 100644 --- a/odb/sqlite/no-id-object-result.hxx +++ b/odb/sqlite/no-id-object-result.hxx @@ -14,7 +14,7 @@ #include #include -#include // query +#include // query_base #include #include @@ -29,10 +29,10 @@ namespace odb public: typedef odb::no_id_object_result_impl base_type; - typedef typename base_type::object_traits object_traits; typedef typename base_type::object_type object_type; - typedef typename base_type::pointer_type pointer_type; + + typedef object_traits_impl object_traits; typedef typename base_type::pointer_traits pointer_traits; typedef typename object_traits::statements_type statements_type; @@ -40,7 +40,7 @@ namespace odb virtual ~no_id_object_result_impl (); - no_id_object_result_impl (const query&, + no_id_object_result_impl (const query_base&, details::shared_ptr, statements_type&); diff --git a/odb/sqlite/no-id-object-result.txx b/odb/sqlite/no-id-object-result.txx index 8519c47..5dad5b2 100644 --- a/odb/sqlite/no-id-object-result.txx +++ b/odb/sqlite/no-id-object-result.txx @@ -21,7 +21,7 @@ namespace odb template no_id_object_result_impl:: - no_id_object_result_impl (const query& q, + no_id_object_result_impl (const query_base& q, details::shared_ptr statement, statements_type& statements) : base_type (statements.connection ().database ()), diff --git a/odb/sqlite/no-id-object-statements.hxx b/odb/sqlite/no-id-object-statements.hxx index 04d46ce..93aedb0 100644 --- a/odb/sqlite/no-id-object-statements.hxx +++ b/odb/sqlite/no-id-object-statements.hxx @@ -34,7 +34,7 @@ namespace odb { public: typedef T object_type; - typedef odb::object_traits object_traits; + typedef object_traits_impl object_traits; typedef typename object_traits::pointer_type pointer_type; typedef typename object_traits::image_type image_type; diff --git a/odb/sqlite/polymorphic-object-result.hxx b/odb/sqlite/polymorphic-object-result.hxx index 54f4092..6023248 100644 --- a/odb/sqlite/polymorphic-object-result.hxx +++ b/odb/sqlite/polymorphic-object-result.hxx @@ -14,7 +14,7 @@ #include #include -#include // query +#include // query_base #include #include @@ -30,23 +30,24 @@ namespace odb public: typedef odb::polymorphic_object_result_impl base_type; - typedef typename base_type::object_type object_type; - typedef typename base_type::object_traits object_traits; typedef typename base_type::id_type id_type; - + typedef typename base_type::object_type object_type; typedef typename base_type::pointer_type pointer_type; + + typedef object_traits_impl object_traits; typedef typename base_type::pointer_traits pointer_traits; typedef typename base_type::root_type root_type; - typedef typename base_type::root_traits root_traits; typedef typename base_type::discriminator_type discriminator_type; + typedef object_traits_impl root_traits; + typedef typename object_traits::statements_type statements_type; virtual ~polymorphic_object_result_impl (); - polymorphic_object_result_impl (const query&, + polymorphic_object_result_impl (const query_base&, details::shared_ptr, statements_type&); diff --git a/odb/sqlite/polymorphic-object-result.txx b/odb/sqlite/polymorphic-object-result.txx index dfff9ff..7e751b3 100644 --- a/odb/sqlite/polymorphic-object-result.txx +++ b/odb/sqlite/polymorphic-object-result.txx @@ -23,7 +23,7 @@ namespace odb template polymorphic_object_result_impl:: - polymorphic_object_result_impl (const query& q, + polymorphic_object_result_impl (const query_base& q, details::shared_ptr st, statements_type& sts) : base_type (sts.connection ().database ()), @@ -179,7 +179,7 @@ namespace odb { // Derived type version. // - typedef object_traits traits; + typedef object_traits_impl traits; static bool rebind (typename traits::statements_type& sts) @@ -204,7 +204,7 @@ namespace odb { // Root type version. // - typedef object_traits traits; + typedef object_traits_impl traits; static bool rebind (typename traits::statements_type& sts) diff --git a/odb/sqlite/polymorphic-object-statements.hxx b/odb/sqlite/polymorphic-object-statements.hxx index 54319ee..286b9e3 100644 --- a/odb/sqlite/polymorphic-object-statements.hxx +++ b/odb/sqlite/polymorphic-object-statements.hxx @@ -156,7 +156,7 @@ namespace odb { public: typedef T object_type; - typedef odb::object_traits object_traits; + typedef object_traits_impl object_traits; typedef typename object_traits::id_type id_type; typedef typename object_traits::pointer_type pointer_type; typedef typename object_traits::id_image_type id_image_type; diff --git a/odb/sqlite/query-const-expr.cxx b/odb/sqlite/query-const-expr.cxx index c4eba2e..9e48ace 100644 --- a/odb/sqlite/query-const-expr.cxx +++ b/odb/sqlite/query-const-expr.cxx @@ -10,6 +10,6 @@ namespace odb { // Sun CC cannot handle this in query.cxx. // - const query query::true_expr (true); + const query_base query_base::true_expr (true); } } diff --git a/odb/sqlite/query.cxx b/odb/sqlite/query.cxx index d979379..15934fb 100644 --- a/odb/sqlite/query.cxx +++ b/odb/sqlite/query.cxx @@ -124,18 +124,18 @@ namespace odb return r; } - // query + // query_base // - query:: - query (const query& q) + query_base:: + query_base (const query_base& q) : clause_ (q.clause_), parameters_ (new (details::shared) query_params (*q.parameters_)) { } - query& query:: - operator= (const query& q) + query_base& query_base:: + operator= (const query_base& q) { if (this != &q) { @@ -146,15 +146,15 @@ namespace odb return *this; } - query& query:: - operator+= (const query& q) + query_base& query_base:: + operator+= (const query_base& q) { clause_.insert (clause_.end (), q.clause_.begin (), q.clause_.end ()); *parameters_ += *q.parameters_; return *this; } - void query:: + void query_base:: append (const string& q) { if (!clause_.empty () && clause_.back ().kind == clause_part::native) @@ -177,7 +177,7 @@ namespace odb clause_.push_back (clause_part (clause_part::native, q)); } - void query:: + void query_base:: append (const char* table, const char* column) { string s (table); @@ -187,7 +187,7 @@ namespace odb clause_.push_back (clause_part (clause_part::column, s)); } - void query:: + void query_base:: add (details::shared_ptr p, const char* conv) { clause_.push_back (clause_part (clause_part::param)); @@ -228,7 +228,7 @@ namespace odb return false; } - void query:: + void query_base:: optimize () { // Remove a single TRUE literal or one that is followe by one of @@ -248,7 +248,7 @@ namespace odb } } - const char* query:: + const char* query_base:: clause_prefix () const { if (!clause_.empty ()) @@ -264,7 +264,7 @@ namespace odb return ""; } - string query:: + string query_base:: clause () const { string r; @@ -336,8 +336,8 @@ namespace odb return clause_prefix () + r; } - query - operator&& (const query& x, const query& y) + query_base + operator&& (const query_base& x, const query_base& y) { // Optimize cases where one or both sides are constant truth. // @@ -352,7 +352,7 @@ namespace odb if (yt) return x; - query r ("("); + query_base r ("("); r += x; r += ") AND ("; r += y; @@ -360,10 +360,10 @@ namespace odb return r; } - query - operator|| (const query& x, const query& y) + query_base + operator|| (const query_base& x, const query_base& y) { - query r ("("); + query_base r ("("); r += x; r += ") OR ("; r += y; @@ -371,10 +371,10 @@ namespace odb return r; } - query - operator! (const query& x) + query_base + operator! (const query_base& x) { - query r ("NOT ("); + query_base r ("NOT ("); r += x; r += ")"; return r; diff --git a/odb/sqlite/query.hxx b/odb/sqlite/query.hxx index ffd3559..fdae3a2 100644 --- a/odb/sqlite/query.hxx +++ b/odb/sqlite/query.hxx @@ -75,7 +75,7 @@ namespace odb const void* value_; }; - class query; + class query_base; class LIBODB_SQLITE_EXPORT query_params: public details::shared_base { @@ -86,7 +86,7 @@ namespace odb binding (); private: - friend class query; + friend class query_base; query_params (): binding_ (0, 0) {} query_params (const query_params&); @@ -113,7 +113,7 @@ namespace odb template struct query_column; - class LIBODB_SQLITE_EXPORT query + class LIBODB_SQLITE_EXPORT query_base { public: struct clause_part @@ -135,7 +135,7 @@ namespace odb bool bool_part; }; - query () + query_base () : parameters_ (new (details::shared) query_params) { } @@ -143,27 +143,27 @@ namespace odb // True or false literal. // explicit - query (bool v) + query_base (bool v) : parameters_ (new (details::shared) query_params) { clause_.push_back (clause_part (v)); } explicit - query (const char* native) + query_base (const char* native) : parameters_ (new (details::shared) query_params) { clause_.push_back (clause_part (clause_part::native, native)); } explicit - query (const std::string& native) + query_base (const std::string& native) : parameters_ (new (details::shared) query_params) { clause_.push_back (clause_part (clause_part::native, native)); } - query (const char* table, const char* column) + query_base (const char* table, const char* column) : parameters_ (new (details::shared) query_params) { append (table, column); @@ -171,7 +171,7 @@ namespace odb template explicit - query (val_bind v) + query_base (val_bind v) : parameters_ (new (details::shared) query_params) { append::db_type_id> ( @@ -180,7 +180,7 @@ namespace odb template explicit - query (ref_bind r) + query_base (ref_bind r) : parameters_ (new (details::shared) query_params) { append::db_type_id> ( @@ -188,12 +188,12 @@ namespace odb } template - query (const query_column&); + query_base (const query_column&); - query (const query&); + query_base (const query_base&); - query& - operator= (const query&); + query_base& + operator= (const query_base&); public: std::string @@ -215,7 +215,7 @@ namespace odb return clause_.empty (); } - static const query true_expr; + static const query_base true_expr; bool const_true () const @@ -244,10 +244,10 @@ namespace odb } public: - query& - operator+= (const query&); + query_base& + operator+= (const query_base&); - query& + query_base& operator+= (const std::string& q) { append (q); @@ -255,7 +255,7 @@ namespace odb } template - query& + query_base& operator+= (val_bind v) { append::db_type_id> ( @@ -264,7 +264,7 @@ namespace odb } template - query& + query_base& operator+= (ref_bind r) { append::db_type_id> ( @@ -298,114 +298,114 @@ namespace odb details::shared_ptr parameters_; }; - inline query - operator+ (const query& x, const query& y) + inline query_base + operator+ (const query_base& x, const query_base& y) { - query r (x); + query_base r (x); r += y; return r; } template - inline query - operator+ (const query& q, val_bind b) + inline query_base + operator+ (const query_base& q, val_bind b) { - query r (q); + query_base r (q); r += b; return r; } template - inline query - operator+ (const query& q, ref_bind b) + inline query_base + operator+ (const query_base& q, ref_bind b) { - query r (q); + query_base r (q); r += b; return r; } template - inline query - operator+ (val_bind b, const query& q) + inline query_base + operator+ (val_bind b, const query_base& q) { - query r; + query_base r; r += b; r += q; return r; } template - inline query - operator+ (ref_bind b, const query& q) + inline query_base + operator+ (ref_bind b, const query_base& q) { - query r; + query_base r; r += b; r += q; return r; } - inline query - operator+ (const query& q, const std::string& s) + inline query_base + operator+ (const query_base& q, const std::string& s) { - query r (q); + query_base r (q); r += s; return r; } - inline query - operator+ (const std::string& s, const query& q) + inline query_base + operator+ (const std::string& s, const query_base& q) { - query r (s); + query_base r (s); r += q; return r; } template - inline query + inline query_base operator+ (const std::string& s, val_bind b) { - query r (s); + query_base r (s); r += b; return r; } template - inline query + inline query_base operator+ (const std::string& s, ref_bind b) { - query r (s); + query_base r (s); r += b; return r; } template - inline query + inline query_base operator+ (val_bind b, const std::string& s) { - query r; + query_base r; r += b; r += s; return r; } template - inline query + inline query_base operator+ (ref_bind b, const std::string& s) { - query r; + query_base r; r += b; r += s; return r; } - LIBODB_SQLITE_EXPORT query - operator&& (const query&, const query&); + LIBODB_SQLITE_EXPORT query_base + operator&& (const query_base&, const query_base&); - LIBODB_SQLITE_EXPORT query - operator|| (const query&, const query&); + LIBODB_SQLITE_EXPORT query_base + operator|| (const query_base&, const query_base&); - LIBODB_SQLITE_EXPORT query - operator! (const query&); + LIBODB_SQLITE_EXPORT query_base + operator! (const query_base&); // query_column // @@ -458,18 +458,18 @@ namespace odb // is_null, is_not_null // public: - query + query_base is_null () const { - query q (table_, column_); + query_base q (table_, column_); q += "IS NULL"; return q; } - query + query_base is_not_null () const { - query q (table_, column_); + query_base q (table_, column_); q += "IS NOT NULL"; return q; } @@ -477,102 +477,102 @@ namespace odb // in // public: - query + query_base in (const T&, const T&) const; - query + query_base in (const T&, const T&, const T&) const; - query + query_base in (const T&, const T&, const T&, const T&) const; - query + query_base in (const T&, const T&, const T&, const T&, const T&) const; template - query + query_base in_range (I begin, I end) const; // = // public: - query + query_base equal (const T& v) const { return equal (val_bind (v)); } - query + query_base equal (val_bind v) const { - query q (table_, column_); + query_base q (table_, column_); q += "="; q.append (v, conversion_); return q; } template - query + query_base equal (val_bind v) const { copy_bind c (v.val); return equal (c); } - query + query_base equal (ref_bind r) const { - query q (table_, column_); + query_base q (table_, column_); q += "="; q.append (r, conversion_); return q; } - friend query + friend query_base operator== (const query_column& c, const T& v) { return c.equal (v); } - friend query + friend query_base operator== (const T& v, const query_column& c) { return c.equal (v); } - friend query + friend query_base operator== (const query_column& c, val_bind v) { return c.equal (v); } - friend query + friend query_base operator== (val_bind v, const query_column& c) { return c.equal (v); } template - friend query + friend query_base operator== (const query_column& c, val_bind v) { return c.equal (v); } template - friend query + friend query_base operator== (val_bind v, const query_column& c) { return c.equal (v); } - friend query + friend query_base operator== (const query_column& c, ref_bind r) { return c.equal (r); } - friend query + friend query_base operator== (ref_bind r, const query_column& c) { return c.equal (r); @@ -581,83 +581,83 @@ namespace odb // != // public: - query + query_base unequal (const T& v) const { return unequal (val_bind (v)); } - query + query_base unequal (val_bind v) const { - query q (table_, column_); + query_base q (table_, column_); q += "!="; q.append (v, conversion_); return q; } template - query + query_base unequal (val_bind v) const { copy_bind c (v.val); return unequal (c); } - query + query_base unequal (ref_bind r) const { - query q (table_, column_); + query_base q (table_, column_); q += "!="; q.append (r, conversion_); return q; } - friend query + friend query_base operator!= (const query_column& c, const T& v) { return c.unequal (v); } - friend query + friend query_base operator!= (const T& v, const query_column& c) { return c.unequal (v); } - friend query + friend query_base operator!= (const query_column& c, val_bind v) { return c.unequal (v); } - friend query + friend query_base operator!= (val_bind v, const query_column& c) { return c.unequal (v); } template - friend query + friend query_base operator!= (const query_column& c, val_bind v) { return c.unequal (v); } template - friend query + friend query_base operator!= (val_bind v, const query_column& c) { return c.unequal (v); } - friend query + friend query_base operator!= (const query_column& c, ref_bind r) { return c.unequal (r); } - friend query + friend query_base operator!= (ref_bind r, const query_column& c) { return c.unequal (r); @@ -666,83 +666,83 @@ namespace odb // < // public: - query + query_base less (const T& v) const { return less (val_bind (v)); } - query + query_base less (val_bind v) const { - query q (table_, column_); + query_base q (table_, column_); q += "<"; q.append (v, conversion_); return q; } template - query + query_base less (val_bind v) const { copy_bind c (v.val); return less (c); } - query + query_base less (ref_bind r) const { - query q (table_, column_); + query_base q (table_, column_); q += "<"; q.append (r, conversion_); return q; } - friend query + friend query_base operator< (const query_column& c, const T& v) { return c.less (v); } - friend query + friend query_base operator< (const T& v, const query_column& c) { return c.greater (v); } - friend query + friend query_base operator< (const query_column& c, val_bind v) { return c.less (v); } - friend query + friend query_base operator< (val_bind v, const query_column& c) { return c.greater (v); } template - friend query + friend query_base operator< (const query_column& c, val_bind v) { return c.less (v); } template - friend query + friend query_base operator< (val_bind v, const query_column& c) { return c.greater (v); } - friend query + friend query_base operator< (const query_column& c, ref_bind r) { return c.less (r); } - friend query + friend query_base operator< (ref_bind r, const query_column& c) { return c.greater (r); @@ -751,83 +751,83 @@ namespace odb // > // public: - query + query_base greater (const T& v) const { return greater (val_bind (v)); } - query + query_base greater (val_bind v) const { - query q (table_, column_); + query_base q (table_, column_); q += ">"; q.append (v, conversion_); return q; } template - query + query_base greater (val_bind v) const { copy_bind c (v.val); return greater (c); } - query + query_base greater (ref_bind r) const { - query q (table_, column_); + query_base q (table_, column_); q += ">"; q.append (r, conversion_); return q; } - friend query + friend query_base operator> (const query_column& c, const T& v) { return c.greater (v); } - friend query + friend query_base operator> (const T& v, const query_column& c) { return c.less (v); } - friend query + friend query_base operator> (const query_column& c, val_bind v) { return c.greater (v); } - friend query + friend query_base operator> (val_bind v, const query_column& c) { return c.less (v); } template - friend query + friend query_base operator> (const query_column& c, val_bind v) { return c.greater (v); } template - friend query + friend query_base operator> (val_bind v, const query_column& c) { return c.less (v); } - friend query + friend query_base operator> (const query_column& c, ref_bind r) { return c.greater (r); } - friend query + friend query_base operator> (ref_bind r, const query_column& c) { return c.less (r); @@ -836,83 +836,83 @@ namespace odb // <= // public: - query + query_base less_equal (const T& v) const { return less_equal (val_bind (v)); } - query + query_base less_equal (val_bind v) const { - query q (table_, column_); + query_base q (table_, column_); q += "<="; q.append (v, conversion_); return q; } template - query + query_base less_equal (val_bind v) const { copy_bind c (v.val); return less_equal (c); } - query + query_base less_equal (ref_bind r) const { - query q (table_, column_); + query_base q (table_, column_); q += "<="; q.append (r, conversion_); return q; } - friend query + friend query_base operator<= (const query_column& c, const T& v) { return c.less_equal (v); } - friend query + friend query_base operator<= (const T& v, const query_column& c) { return c.greater_equal (v); } - friend query + friend query_base operator<= (const query_column& c, val_bind v) { return c.less_equal (v); } - friend query + friend query_base operator<= (val_bind v, const query_column& c) { return c.greater_equal (v); } template - friend query + friend query_base operator<= (const query_column& c, val_bind v) { return c.less_equal (v); } template - friend query + friend query_base operator<= (val_bind v, const query_column& c) { return c.greater_equal (v); } - friend query + friend query_base operator<= (const query_column& c, ref_bind r) { return c.less_equal (r); } - friend query + friend query_base operator<= (ref_bind r, const query_column& c) { return c.greater_equal (r); @@ -921,83 +921,83 @@ namespace odb // >= // public: - query + query_base greater_equal (const T& v) const { return greater_equal (val_bind (v)); } - query + query_base greater_equal (val_bind v) const { - query q (table_, column_); + query_base q (table_, column_); q += ">="; q.append (v, conversion_); return q; } template - query + query_base greater_equal (val_bind v) const { copy_bind c (v.val); return greater_equal (c); } - query + query_base greater_equal (ref_bind r) const { - query q (table_, column_); + query_base q (table_, column_); q += ">="; q.append (r, conversion_); return q; } - friend query + friend query_base operator>= (const query_column& c, const T& v) { return c.greater_equal (v); } - friend query + friend query_base operator>= (const T& v, const query_column& c) { return c.less_equal (v); } - friend query + friend query_base operator>= (const query_column& c, val_bind v) { return c.greater_equal (v); } - friend query + friend query_base operator>= (val_bind v, const query_column& c) { return c.less_equal (v); } template - friend query + friend query_base operator>= (const query_column& c, val_bind v) { return c.greater_equal (v); } template - friend query + friend query_base operator>= (val_bind v, const query_column& c) { return c.less_equal (v); } - friend query + friend query_base operator>= (const query_column& c, ref_bind r) { return c.greater_equal (r); } - friend query + friend query_base operator>= (ref_bind r, const query_column& c) { return c.less_equal (r); @@ -1007,84 +1007,84 @@ namespace odb // public: template - query + query_base operator== (const query_column& c) const { // We can compare columns only if we can compare their C++ types. // (void) (sizeof (type_instance () == type_instance ())); - query q (table_, column_); + query_base q (table_, column_); q += "="; q.append (c.table (), c.column ()); return q; } template - query + query_base operator!= (const query_column& c) const { // We can compare columns only if we can compare their C++ types. // (void) (sizeof (type_instance () != type_instance ())); - query q (table_, column_); + query_base q (table_, column_); q += "!="; q.append (c.table (), c.column ()); return q; } template - query + query_base operator< (const query_column& c) const { // We can compare columns only if we can compare their C++ types. // (void) (sizeof (type_instance () < type_instance ())); - query q (table_, column_); + query_base q (table_, column_); q += "<"; q.append (c.table (), c.column ()); return q; } template - query + query_base operator> (const query_column& c) const { // We can compare columns only if we can compare their C++ types. // (void) (sizeof (type_instance () > type_instance ())); - query q (table_, column_); + query_base q (table_, column_); q += ">"; q.append (c.table (), c.column ()); return q; } template - query + query_base operator<= (const query_column& c) const { // We can compare columns only if we can compare their C++ types. // (void) (sizeof (type_instance () <= type_instance ())); - query q (table_, column_); + query_base q (table_, column_); q += "<="; q.append (c.table (), c.column ()); return q; } template - query + query_base operator>= (const query_column& c) const { // We can compare columns only if we can compare their C++ types. // (void) (sizeof (type_instance () >= type_instance ())); - query q (table_, column_); + query_base q (table_, column_); q += ">="; q.append (c.table (), c.column ()); return q; @@ -1100,37 +1100,37 @@ namespace odb // query fragments (e.g., ORDER BY). // template - inline query + inline query_base operator+ (const query_column& c, const std::string& s) { - query q (c.table (), c.column ()); + query_base q (c.table (), c.column ()); q += s; return q; } template - inline query + inline query_base operator+ (const std::string& s, const query_column& c) { - query q (s); + query_base q (s); q.append (c.table (), c.column ()); return q; } template - inline query - operator+ (const query_column& c, const query& q) + inline query_base + operator+ (const query_column& c, const query_base& q) { - query r (c.table (), c.column ()); + query_base r (c.table (), c.column ()); r += q; return r; } template - inline query - operator+ (const query& q, const query_column& c) + inline query_base + operator+ (const query_base& q, const query_column& c) { - query r (q); + query_base r (q); r.append (c.table (), c.column ()); return r; } @@ -1284,13 +1284,75 @@ namespace odb } } -// odb::query specialization for SQLite. +// odb::sqlite::query and odb::query specialization for SQLite. // namespace odb { + namespace sqlite + { + template + class query: public query_base, + public query_selector::columns_type + { + public: + // We don't define any typedefs here since they may clash with + // column names defined by our base type. + // + + query () + { + } + + explicit + query (bool v) + : query_base (v) + { + } + + explicit + query (const char* q) + : query_base (q) + { + } + + explicit + query (const std::string& q) + : query_base (q) + { + } + + template + explicit + query (val_bind v) + : query_base (v) + { + } + + template + explicit + query (ref_bind r) + : query_base (r) + { + } + + query (const query_base& q) + : query_base (q) + { + } + + template + query (const query_column& qc) + : query_base (qc) + { + } + }; + } + + // Derive odb::query from odb::sqlite::query so that it can be + // implicitly converted in sqlite::database::query() calls. + // template - class query: public sqlite::query, - public query_selector::columns_type + class query: public sqlite::query { public: // We don't define any typedefs here since they may clash with @@ -1303,44 +1365,44 @@ namespace odb explicit query (bool v) - : sqlite::query (v) + : sqlite::query (v) { } explicit query (const char* q) - : sqlite::query (q) + : sqlite::query (q) { } explicit query (const std::string& q) - : sqlite::query (q) + : sqlite::query (q) { } template explicit query (sqlite::val_bind v) - : sqlite::query (sqlite::query (v)) + : sqlite::query (v) { } template explicit query (sqlite::ref_bind r) - : sqlite::query (sqlite::query (r)) + : sqlite::query (r) { } - query (const sqlite::query& q) - : sqlite::query (q) + query (const sqlite::query_base& q) + : sqlite::query (q) { } template query (const sqlite::query_column& qc) - : sqlite::query (qc) + : sqlite::query (qc) { } }; diff --git a/odb/sqlite/query.ixx b/odb/sqlite/query.ixx index 113b376..631749f 100644 --- a/odb/sqlite/query.ixx +++ b/odb/sqlite/query.ixx @@ -6,20 +6,20 @@ namespace odb { namespace sqlite { - inline binding& query:: + inline binding& query_base:: parameters_binding () const { return parameters_->binding (); } - inline details::shared_ptr query:: + inline details::shared_ptr query_base:: parameters () const { return parameters_; } template - inline void query:: + inline void query_base:: append (val_bind v, const char* conv) { add ( @@ -29,7 +29,7 @@ namespace odb } template - inline void query:: + inline void query_base:: append (ref_bind r, const char* conv) { add ( diff --git a/odb/sqlite/query.txx b/odb/sqlite/query.txx index ba3fac1..f719ece 100644 --- a/odb/sqlite/query.txx +++ b/odb/sqlite/query.txx @@ -6,12 +6,12 @@ namespace odb { namespace sqlite { - // query + // query_base // template - query:: - query (const query_column& c) + query_base:: + query_base (const query_column& c) : parameters_ (new (details::shared) query_params) { // Cannot use IS TRUE here since database type can be a non- @@ -25,10 +25,10 @@ namespace odb // query_column // template - query query_column:: + query_base query_column:: in (const T& v1, const T& v2) const { - query q (table_, column_); + query_base q (table_, column_); q += "IN ("; q.append (val_bind (v1), conversion_); q += ","; @@ -38,10 +38,10 @@ namespace odb } template - query query_column:: + query_base query_column:: in (const T& v1, const T& v2, const T& v3) const { - query q (table_, column_); + query_base q (table_, column_); q += "IN ("; q.append (val_bind (v1), conversion_); q += ","; @@ -53,10 +53,10 @@ namespace odb } template - query query_column:: + query_base query_column:: in (const T& v1, const T& v2, const T& v3, const T& v4) const { - query q (table_, column_); + query_base q (table_, column_); q += "IN ("; q.append (val_bind (v1), conversion_); q += ","; @@ -70,10 +70,10 @@ namespace odb } template - query query_column:: + query_base query_column:: in (const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) const { - query q (table_, column_); + query_base q (table_, column_); q += "IN ("; q.append (val_bind (v1), conversion_); q += ","; @@ -90,10 +90,10 @@ namespace odb template template - query query_column:: + query_base query_column:: in_range (I begin, I end) const { - query q (table_, column_); + query_base q (table_, column_); q += "IN ("; for (I i (begin); i != end; ++i) @@ -103,6 +103,7 @@ namespace odb q.append (val_bind (*i), conversion_); } + q += ")"; return q; } diff --git a/odb/sqlite/result.cxx b/odb/sqlite/result.cxx index 2c950d0..f8b1073 100644 --- a/odb/sqlite/result.cxx +++ b/odb/sqlite/result.cxx @@ -10,7 +10,8 @@ namespace odb namespace sqlite { result_impl_base:: - result_impl_base (const query& q, details::shared_ptr s) + result_impl_base (const query_base& q, + details::shared_ptr s) : params_ (q.parameters ()), statement_ (s) { } diff --git a/odb/sqlite/result.hxx b/odb/sqlite/result.hxx index 92c1bb1..cd2d376 100644 --- a/odb/sqlite/result.hxx +++ b/odb/sqlite/result.hxx @@ -10,7 +10,7 @@ #include #include -#include // query, query_params +#include // query_base, query_params #include #include @@ -22,7 +22,8 @@ namespace odb class LIBODB_SQLITE_EXPORT result_impl_base { public: - result_impl_base (const query&, details::shared_ptr); + result_impl_base (const query_base&, + details::shared_ptr); protected: // We need to hold on to the query parameters because SQLite uses diff --git a/odb/sqlite/simple-object-result.hxx b/odb/sqlite/simple-object-result.hxx index 8c748bc..08132b1 100644 --- a/odb/sqlite/simple-object-result.hxx +++ b/odb/sqlite/simple-object-result.hxx @@ -14,7 +14,7 @@ #include #include -#include // query +#include // query_base #include #include @@ -29,11 +29,11 @@ namespace odb public: typedef odb::object_result_impl base_type; - typedef typename base_type::object_traits object_traits; - typedef typename base_type::object_type object_type; typedef typename base_type::id_type id_type; - + typedef typename base_type::object_type object_type; typedef typename base_type::pointer_type pointer_type; + + typedef object_traits_impl object_traits; typedef typename base_type::pointer_traits pointer_traits; typedef typename object_traits::statements_type statements_type; @@ -41,7 +41,7 @@ namespace odb virtual ~object_result_impl (); - object_result_impl (const query&, + object_result_impl (const query_base&, details::shared_ptr, statements_type&); diff --git a/odb/sqlite/simple-object-result.txx b/odb/sqlite/simple-object-result.txx index 2152a21..34eaab5 100644 --- a/odb/sqlite/simple-object-result.txx +++ b/odb/sqlite/simple-object-result.txx @@ -23,7 +23,7 @@ namespace odb template object_result_impl:: - object_result_impl (const query& q, + object_result_impl (const query_base& q, details::shared_ptr statement, statements_type& statements) : base_type (statements.connection ().database ()), diff --git a/odb/sqlite/simple-object-statements.hxx b/odb/sqlite/simple-object-statements.hxx index 90f2494..66dc0f9 100644 --- a/odb/sqlite/simple-object-statements.hxx +++ b/odb/sqlite/simple-object-statements.hxx @@ -147,7 +147,7 @@ namespace odb struct optimistic_data { typedef T object_type; - typedef odb::object_traits object_traits; + typedef object_traits_impl object_traits; optimistic_data (bind*); @@ -170,7 +170,7 @@ namespace odb { public: typedef T object_type; - typedef odb::object_traits object_traits; + typedef object_traits_impl object_traits; typedef typename object_traits::id_type id_type; typedef typename object_traits::pointer_type pointer_type; typedef typename object_traits::image_type image_type; diff --git a/odb/sqlite/statement-cache.hxx b/odb/sqlite/statement-cache.hxx index 5d94296..b08e4c7 100644 --- a/odb/sqlite/statement-cache.hxx +++ b/odb/sqlite/statement-cache.hxx @@ -69,7 +69,7 @@ namespace odb } template - typename object_traits::statements_type& + typename object_traits_impl::statements_type& find_object (); template diff --git a/odb/sqlite/statement-cache.txx b/odb/sqlite/statement-cache.txx index b702712..775a6a8 100644 --- a/odb/sqlite/statement-cache.txx +++ b/odb/sqlite/statement-cache.txx @@ -7,10 +7,13 @@ namespace odb namespace sqlite { template - typename object_traits::statements_type& statement_cache:: + typename object_traits_impl::statements_type& + statement_cache:: find_object () { - typedef typename object_traits::statements_type statements_type; + typedef + typename object_traits_impl::statements_type + statements_type; map::iterator i (map_.find (&typeid (T))); diff --git a/odb/sqlite/view-result.hxx b/odb/sqlite/view-result.hxx index 82910db..846504f 100644 --- a/odb/sqlite/view-result.hxx +++ b/odb/sqlite/view-result.hxx @@ -14,7 +14,7 @@ #include #include -#include // query, view_statements +#include // query_base, view_statements #include namespace odb @@ -29,9 +29,9 @@ namespace odb typedef odb::view_result_impl base_type; typedef typename base_type::view_type view_type; - typedef typename base_type::view_traits view_traits; - typedef typename base_type::pointer_type pointer_type; + + typedef view_traits_impl view_traits; typedef typename base_type::pointer_traits pointer_traits; typedef view_statements statements_type; @@ -39,7 +39,7 @@ namespace odb virtual ~view_result_impl (); - view_result_impl (const query&, + view_result_impl (const query_base&, details::shared_ptr, statements_type&); diff --git a/odb/sqlite/view-result.txx b/odb/sqlite/view-result.txx index f2170c9..7d8ac5f 100644 --- a/odb/sqlite/view-result.txx +++ b/odb/sqlite/view-result.txx @@ -21,7 +21,7 @@ namespace odb template view_result_impl:: - view_result_impl (const query& q, + view_result_impl (const query_base& q, details::shared_ptr statement, statements_type& statements) : base_type (statements.connection ().database ()), diff --git a/odb/sqlite/view-statements.hxx b/odb/sqlite/view-statements.hxx index 9a4f566..ca99bb1 100644 --- a/odb/sqlite/view-statements.hxx +++ b/odb/sqlite/view-statements.hxx @@ -26,7 +26,7 @@ namespace odb { public: typedef T view_type; - typedef odb::view_traits view_traits; + typedef view_traits_impl view_traits; typedef typename view_traits::pointer_type pointer_type; typedef typename view_traits::image_type image_type; -- cgit v1.1