From c0af27a770b1505ad6a1226f57f90642ce395296 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 8 Oct 2012 16:09:07 +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/mysql/database.cxx | 18 +- odb/mysql/database.hxx | 186 ++++++++++++ odb/mysql/database.ixx | 383 +++++++++++++++++++++++++ odb/mysql/forward.hxx | 3 +- odb/mysql/no-id-object-result.hxx | 8 +- odb/mysql/no-id-object-result.txx | 2 +- odb/mysql/no-id-object-statements.hxx | 2 +- odb/mysql/polymorphic-object-result.hxx | 13 +- odb/mysql/polymorphic-object-result.txx | 6 +- odb/mysql/polymorphic-object-statements.hxx | 2 +- odb/mysql/query-const-expr.cxx | 2 +- odb/mysql/query.cxx | 46 +-- odb/mysql/query.hxx | 420 ++++++++++++++++------------ odb/mysql/query.ixx | 4 +- odb/mysql/query.txx | 27 +- odb/mysql/simple-object-result.hxx | 10 +- odb/mysql/simple-object-result.txx | 2 +- odb/mysql/simple-object-statements.hxx | 4 +- odb/mysql/statement-cache.hxx | 2 +- odb/mysql/statement-cache.txx | 7 +- odb/mysql/view-result.hxx | 8 +- odb/mysql/view-result.txx | 2 +- odb/mysql/view-statements.hxx | 2 +- 23 files changed, 901 insertions(+), 258 deletions(-) diff --git a/odb/mysql/database.cxx b/odb/mysql/database.cxx index e7137bb..b80c95a 100644 --- a/odb/mysql/database.cxx +++ b/odb/mysql/database.cxx @@ -34,7 +34,8 @@ namespace odb const char* charset, unsigned long client_flags, transfer_ptr factory) - : user_ (user ? user : ""), + : odb::database (id_mysql), + user_ (user ? user : ""), passwd_str_ (passwd ? passwd : ""), passwd_ (passwd ? passwd_str_.c_str () : 0), db_ (db ? db : ""), @@ -62,7 +63,8 @@ namespace odb const string& charset, unsigned long client_flags, transfer_ptr factory) - : user_ (user), + : odb::database (id_mysql), + user_ (user), passwd_str_ (passwd), passwd_ (passwd_str_.c_str ()), db_ (db), @@ -90,7 +92,8 @@ namespace odb const string& charset, unsigned long client_flags, transfer_ptr factory) - : user_ (user), + : odb::database (id_mysql), + user_ (user), passwd_str_ (passwd ? *passwd : ""), passwd_ (passwd ? passwd_str_.c_str () : 0), db_ (db), @@ -118,7 +121,8 @@ namespace odb const string& charset, unsigned long client_flags, transfer_ptr factory) - : user_ (user), + : odb::database (id_mysql), + user_ (user), passwd_str_ (passwd), passwd_ (passwd_str_.c_str ()), db_ (db), @@ -146,7 +150,8 @@ namespace odb const string& charset, unsigned long client_flags, transfer_ptr factory) - : user_ (user), + : odb::database (id_mysql), + user_ (user), passwd_str_ (passwd ? *passwd : ""), passwd_ (passwd ? passwd_str_.c_str () : 0), db_ (db), @@ -171,7 +176,8 @@ namespace odb const string& charset, unsigned long client_flags, transfer_ptr factory) - : passwd_ (0), + : odb::database (id_mysql), + passwd_ (0), socket_ (0), charset_ (charset), client_flags_ (client_flags), diff --git a/odb/mysql/database.hxx b/odb/mysql/database.hxx index 0008836..897134d 100644 --- a/odb/mysql/database.hxx +++ b/odb/mysql/database.hxx @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -167,6 +168,191 @@ namespace odb return client_flags_; } + // 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 mysql::query&); + + // Query API. + // + template + result + query (bool cache = true); + + template + result + query (const char*, bool cache = true); + + template + result + query (const std::string&, bool cache = true); + + template + result + query (const mysql::query&, bool cache = true); + public: virtual transaction_impl* begin (); diff --git a/odb/mysql/database.ixx b/odb/mysql/database.ixx index d0a3d56..b69a301 100644 --- a/odb/mysql/database.ixx +++ b/odb/mysql/database.ixx @@ -15,5 +15,388 @@ 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 (mysql::query ()); + } + + template + inline unsigned long long database:: + erase_query (const char* q) + { + // T is always object_type. + // + return erase_query (mysql::query (q)); + } + + template + inline unsigned long long database:: + erase_query (const std::string& q) + { + // T is always object_type. + // + return erase_query (mysql::query (q)); + } + + template + inline unsigned long long database:: + erase_query (const mysql::query& q) + { + // T is always object_type. + // + return object_traits_impl::erase_query (*this, q); + } + + template + inline result database:: + query (bool cache) + { + return query (mysql::query (), cache); + } + + template + inline result database:: + query (const char* q, bool cache) + { + return query (mysql::query (q), cache); + } + + template + inline result database:: + query (const std::string& q, bool cache) + { + return query (mysql::query (q), cache); + } + + template + inline result database:: + query (const mysql::query& q, bool cache) + { + // T is always object_type. We also don't need to check for transaction + // here; object_traits::query () does this. + // + result r (query_::call (*this, q)); + + if (cache) + r.cache (); + + return r; + } } } diff --git a/odb/mysql/forward.hxx b/odb/mysql/forward.hxx index 16bdc4c..7530329 100644 --- a/odb/mysql/forward.hxx +++ b/odb/mysql/forward.hxx @@ -20,7 +20,6 @@ namespace odb class statement; class transaction; class tracer; - class query; // Implementation details. // @@ -51,6 +50,8 @@ namespace odb template class container_statements; + + class query_base; } namespace details diff --git a/odb/mysql/no-id-object-result.hxx b/odb/mysql/no-id-object-result.hxx index eb562bf..5907d20 100644 --- a/odb/mysql/no-id-object-result.hxx +++ b/odb/mysql/no-id-object-result.hxx @@ -14,7 +14,7 @@ #include #include -#include // query +#include // query_base #include namespace odb @@ -28,9 +28,9 @@ namespace odb typedef odb::no_id_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::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; @@ -38,7 +38,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/mysql/no-id-object-result.txx b/odb/mysql/no-id-object-result.txx index 0f996d1..530eeb7 100644 --- a/odb/mysql/no-id-object-result.txx +++ b/odb/mysql/no-id-object-result.txx @@ -21,7 +21,7 @@ namespace odb template no_id_object_result_impl:: - no_id_object_result_impl (const query&, + no_id_object_result_impl (const query_base&, details::shared_ptr statement, statements_type& statements) : base_type (statements.connection ().database ()), diff --git a/odb/mysql/no-id-object-statements.hxx b/odb/mysql/no-id-object-statements.hxx index 89f736b..0778719 100644 --- a/odb/mysql/no-id-object-statements.hxx +++ b/odb/mysql/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/mysql/polymorphic-object-result.hxx b/odb/mysql/polymorphic-object-result.hxx index 59bb74d..7749e14 100644 --- a/odb/mysql/polymorphic-object-result.hxx +++ b/odb/mysql/polymorphic-object-result.hxx @@ -14,7 +14,7 @@ #include #include -#include // query +#include // query_base #include namespace odb @@ -28,23 +28,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/mysql/polymorphic-object-result.txx b/odb/mysql/polymorphic-object-result.txx index 1e341ff..518ff91 100644 --- a/odb/mysql/polymorphic-object-result.txx +++ b/odb/mysql/polymorphic-object-result.txx @@ -23,7 +23,7 @@ namespace odb template polymorphic_object_result_impl:: - polymorphic_object_result_impl (const query&, + polymorphic_object_result_impl (const query_base&, details::shared_ptr st, statements_type& sts) : base_type (sts.connection ().database ()), @@ -218,7 +218,7 @@ namespace odb { // Derived type version. // - typedef object_traits traits; + typedef object_traits_impl traits; static bool rebind (typename traits::statements_type& sts) @@ -243,7 +243,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/mysql/polymorphic-object-statements.hxx b/odb/mysql/polymorphic-object-statements.hxx index 748e3ef..060654a 100644 --- a/odb/mysql/polymorphic-object-statements.hxx +++ b/odb/mysql/polymorphic-object-statements.hxx @@ -153,7 +153,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/mysql/query-const-expr.cxx b/odb/mysql/query-const-expr.cxx index dd861c6..feb756e 100644 --- a/odb/mysql/query-const-expr.cxx +++ b/odb/mysql/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/mysql/query.cxx b/odb/mysql/query.cxx index ac710d8..bc0c4f0 100644 --- a/odb/mysql/query.cxx +++ b/odb/mysql/query.cxx @@ -20,10 +20,10 @@ namespace odb { } - // query + // query_base // - query:: - query (const query& q) + query_base:: + query_base (const query_base& q) : clause_ (q.clause_), parameters_ (q.parameters_), bind_ (q.bind_), @@ -43,8 +43,8 @@ namespace odb } } - query& query:: - operator= (const query& q) + query_base& query_base:: + operator= (const query_base& q) { if (this != &q) { @@ -61,8 +61,8 @@ 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 ()); @@ -84,7 +84,7 @@ namespace odb return *this; } - void query:: + void query_base:: append (const string& q) { if (!clause_.empty () && clause_.back ().kind == clause_part::native) @@ -107,7 +107,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); @@ -117,7 +117,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)); @@ -136,7 +136,7 @@ namespace odb p->bind (b); } - binding& query:: + binding& query_base:: parameters_binding () const { size_t n (parameters_.size ()); @@ -198,7 +198,7 @@ namespace odb return false; } - void query:: + void query_base:: optimize () { // Remove a single TRUE literal or one that is followe by one of @@ -218,7 +218,7 @@ namespace odb } } - const char* query:: + const char* query_base:: clause_prefix () const { if (!clause_.empty ()) @@ -234,7 +234,7 @@ namespace odb return ""; } - string query:: + string query_base:: clause () const { string r; @@ -306,8 +306,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. // @@ -322,7 +322,7 @@ namespace odb if (yt) return x; - query r ("("); + query_base r ("("); r += x; r += ") AND ("; r += y; @@ -330,10 +330,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; @@ -341,10 +341,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/mysql/query.hxx b/odb/mysql/query.hxx index 74d8671..a38b5cb 100644 --- a/odb/mysql/query.hxx +++ b/odb/mysql/query.hxx @@ -82,7 +82,7 @@ namespace odb template struct query_column; - class LIBODB_MYSQL_EXPORT query + class LIBODB_MYSQL_EXPORT query_base { public: struct clause_part @@ -104,7 +104,7 @@ namespace odb bool bool_part; }; - query () + query_base () : binding_ (0, 0) { } @@ -112,27 +112,27 @@ namespace odb // True or false literal. // explicit - query (bool v) + query_base (bool v) : binding_ (0, 0) { clause_.push_back (clause_part (v)); } explicit - query (const char* native) + query_base (const char* native) : binding_ (0, 0) { clause_.push_back (clause_part (clause_part::native, native)); } explicit - query (const std::string& native) + query_base (const std::string& native) : binding_ (0, 0) { clause_.push_back (clause_part (clause_part::native, native)); } - query (const char* table, const char* column) + query_base (const char* table, const char* column) : binding_ (0, 0) { append (table, column); @@ -140,7 +140,7 @@ namespace odb template explicit - query (val_bind v) + query_base (val_bind v) : binding_ (0, 0) { append::db_type_id> ( @@ -149,7 +149,7 @@ namespace odb template explicit - query (ref_bind r) + query_base (ref_bind r) : binding_ (0, 0) { append::db_type_id> ( @@ -157,12 +157,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 @@ -181,7 +181,7 @@ namespace odb return clause_.empty (); } - static const query true_expr; + static const query_base true_expr; bool const_true () const @@ -210,10 +210,10 @@ namespace odb } public: - query& - operator+= (const query&); + query_base& + operator+= (const query_base&); - query& + query_base& operator+= (const std::string& q) { append (q); @@ -221,7 +221,7 @@ namespace odb } template - query& + query_base& operator+= (val_bind v) { append::db_type_id> ( @@ -230,7 +230,7 @@ namespace odb } template - query& + query_base& operator+= (ref_bind r) { append::db_type_id> ( @@ -267,114 +267,114 @@ namespace odb mutable binding binding_; }; - 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_MYSQL_EXPORT query - operator&& (const query& x, const query& y); + LIBODB_MYSQL_EXPORT query_base + operator&& (const query_base& x, const query_base& y); - LIBODB_MYSQL_EXPORT query - operator|| (const query& x, const query& y); + LIBODB_MYSQL_EXPORT query_base + operator|| (const query_base& x, const query_base& y); - LIBODB_MYSQL_EXPORT query - operator! (const query& x); + LIBODB_MYSQL_EXPORT query_base + operator! (const query_base& x); // query_column // @@ -427,18 +427,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; } @@ -446,102 +446,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); @@ -550,83 +550,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); @@ -635,83 +635,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); @@ -720,83 +720,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); @@ -805,83 +805,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); @@ -890,83 +890,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); @@ -976,84 +976,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; @@ -1069,37 +1069,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; } @@ -1857,13 +1857,75 @@ namespace odb } } -// odb::query specialization for MySQL. +// odb::mysql::query and odb::query specialization for MySQL. // namespace odb { + namespace mysql + { + 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::mysql::query so that it can be + // implicitly converted in mysql::database::query() calls. + // template - class query: public mysql::query, - public query_selector::columns_type + class query: public mysql::query { public: // We don't define any typedefs here since they may clash with @@ -1876,44 +1938,44 @@ namespace odb explicit query (bool v) - : mysql::query (v) + : mysql::query (v) { } explicit query (const char* q) - : mysql::query (q) + : mysql::query (q) { } explicit query (const std::string& q) - : mysql::query (q) + : mysql::query (q) { } template explicit query (mysql::val_bind v) - : mysql::query (mysql::query (v)) + : mysql::query (v) { } template explicit query (mysql::ref_bind r) - : mysql::query (mysql::query (r)) + : mysql::query (r) { } - query (const mysql::query& q) - : mysql::query (q) + query (const mysql::query_base& q) + : mysql::query (q) { } template query (const mysql::query_column& qc) - : mysql::query (qc) + : mysql::query (qc) { } }; diff --git a/odb/mysql/query.ixx b/odb/mysql/query.ixx index 2508ae3..ce485f1 100644 --- a/odb/mysql/query.ixx +++ b/odb/mysql/query.ixx @@ -7,7 +7,7 @@ namespace odb namespace mysql { template - inline void query:: + inline void query_base:: append (val_bind v, const char* conv) { add ( @@ -17,7 +17,7 @@ namespace odb } template - inline void query:: + inline void query_base:: append (ref_bind r, const char* conv) { add ( diff --git a/odb/mysql/query.txx b/odb/mysql/query.txx index 80b6358..0dd0b9a 100644 --- a/odb/mysql/query.txx +++ b/odb/mysql/query.txx @@ -6,12 +6,12 @@ namespace odb { namespace mysql { - // query + // query_base // template - query:: - query (const query_column& c) + query_base:: + query_base (const query_column& c) : binding_ (0, 0) { // 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/mysql/simple-object-result.hxx b/odb/mysql/simple-object-result.hxx index b92c5ce..bcf74f7 100644 --- a/odb/mysql/simple-object-result.hxx +++ b/odb/mysql/simple-object-result.hxx @@ -14,7 +14,7 @@ #include #include -#include // query +#include // query_base #include namespace odb @@ -27,11 +27,11 @@ namespace odb public: typedef odb::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 object_traits::statements_type statements_type; @@ -39,7 +39,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/mysql/simple-object-result.txx b/odb/mysql/simple-object-result.txx index b5a5f3a..e341b16 100644 --- a/odb/mysql/simple-object-result.txx +++ b/odb/mysql/simple-object-result.txx @@ -23,7 +23,7 @@ namespace odb template object_result_impl:: - object_result_impl (const query&, + object_result_impl (const query_base&, details::shared_ptr statement, statements_type& statements) : base_type (statements.connection ().database ()), diff --git a/odb/mysql/simple-object-statements.hxx b/odb/mysql/simple-object-statements.hxx index d369313..27f65a1 100644 --- a/odb/mysql/simple-object-statements.hxx +++ b/odb/mysql/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 (MYSQL_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/mysql/statement-cache.hxx b/odb/mysql/statement-cache.hxx index f801972..faea870 100644 --- a/odb/mysql/statement-cache.hxx +++ b/odb/mysql/statement-cache.hxx @@ -32,7 +32,7 @@ namespace odb statement_cache (connection& conn): conn_ (conn) {} template - typename object_traits::statements_type& + typename object_traits_impl::statements_type& find_object (); diff --git a/odb/mysql/statement-cache.txx b/odb/mysql/statement-cache.txx index 3acc5fe..0517159 100644 --- a/odb/mysql/statement-cache.txx +++ b/odb/mysql/statement-cache.txx @@ -7,10 +7,13 @@ namespace odb namespace mysql { 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/mysql/view-result.hxx b/odb/mysql/view-result.hxx index ab59f03..14a6002 100644 --- a/odb/mysql/view-result.hxx +++ b/odb/mysql/view-result.hxx @@ -14,7 +14,7 @@ #include #include -#include // query, view_statements +#include // query_base, view_statements #include namespace odb @@ -28,9 +28,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; @@ -38,7 +38,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/mysql/view-result.txx b/odb/mysql/view-result.txx index bc56ebb..27eb1ab 100644 --- a/odb/mysql/view-result.txx +++ b/odb/mysql/view-result.txx @@ -21,7 +21,7 @@ namespace odb template view_result_impl:: - view_result_impl (const query&, + view_result_impl (const query_base&, details::shared_ptr statement, statements_type& statements) : base_type (statements.connection ().database ()), diff --git a/odb/mysql/view-statements.hxx b/odb/mysql/view-statements.hxx index 9905c51..9beb44d 100644 --- a/odb/mysql/view-statements.hxx +++ b/odb/mysql/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