From d3261c7ed4ac622c8807ba88b39bd41632577c4f 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/mssql/database.cxx | 15 +- odb/mssql/database.hxx | 186 ++++++++++++ odb/mssql/database.ixx | 378 +++++++++++++++++++++++++ odb/mssql/forward.hxx | 3 +- odb/mssql/no-id-object-result.hxx | 8 +- odb/mssql/no-id-object-result.txx | 2 +- odb/mssql/no-id-object-statements.hxx | 2 +- odb/mssql/polymorphic-object-result.hxx | 13 +- odb/mssql/polymorphic-object-result.txx | 6 +- odb/mssql/polymorphic-object-statements.hxx | 2 +- odb/mssql/query-const-expr.cxx | 2 +- odb/mssql/query.cxx | 46 +-- odb/mssql/query.hxx | 420 ++++++++++++++++------------ odb/mssql/query.ixx | 4 +- odb/mssql/query.txx | 27 +- odb/mssql/simple-object-result.hxx | 10 +- odb/mssql/simple-object-result.txx | 2 +- odb/mssql/simple-object-statements.hxx | 4 +- odb/mssql/statement-cache.hxx | 2 +- odb/mssql/statement-cache.txx | 7 +- odb/mssql/view-result.hxx | 8 +- odb/mssql/view-result.txx | 2 +- odb/mssql/view-statements.hxx | 2 +- 23 files changed, 894 insertions(+), 257 deletions(-) diff --git a/odb/mssql/database.cxx b/odb/mssql/database.cxx index a56181f..1c42c80 100644 --- a/odb/mssql/database.cxx +++ b/odb/mssql/database.cxx @@ -29,7 +29,8 @@ namespace odb const std::string& extra_connect_string, SQLHENV environment, transfer_ptr factory) - : user_ (user), + : odb::database (id_mssql), + user_ (user), password_ (password), db_ (db), protocol_ (protocol_auto), @@ -54,7 +55,8 @@ namespace odb const std::string& extra_connect_string, SQLHENV environment, transfer_ptr factory) - : user_ (user), + : odb::database (id_mssql), + user_ (user), password_ (password), db_ (db), protocol_ (protocol), @@ -79,7 +81,8 @@ namespace odb const std::string& extra_connect_string, SQLHENV environment, transfer_ptr factory) - : user_ (user), + : odb::database (id_mssql), + user_ (user), password_ (password), db_ (db), protocol_ (protocol_tcp), @@ -97,7 +100,8 @@ namespace odb database (const string& connect_string, SQLHENV environment, transfer_ptr factory) - : protocol_ (protocol_auto), + : odb::database (id_mssql), + protocol_ (protocol_auto), port_ (0), connect_string_ (connect_string), environment_ (environment), @@ -113,7 +117,8 @@ namespace odb const std::string& extra_connect_string, SQLHENV environment, transfer_ptr factory) - : protocol_ (protocol_auto), + : odb::database (id_mssql), + protocol_ (protocol_auto), port_ (0), extra_connect_string_ (extra_connect_string), environment_ (environment), diff --git a/odb/mssql/database.hxx b/odb/mssql/database.hxx index 66b3a86..1bd419b 100644 --- a/odb/mssql/database.hxx +++ b/odb/mssql/database.hxx @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -125,6 +126,191 @@ namespace odb static void print_usage (std::ostream&); + // 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 mssql::query&); + + // Query API. + // + template + result + query (); + + template + result + query (const char*); + + template + result + query (const std::string&); + + template + result + query (const mssql::query&); + public: virtual transaction_impl* begin (); diff --git a/odb/mssql/database.ixx b/odb/mssql/database.ixx index 258f74b..d73332e 100644 --- a/odb/mssql/database.ixx +++ b/odb/mssql/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 (mssql::query ()); + } + + template + inline unsigned long long database:: + erase_query (const char* q) + { + // T is always object_type. + // + return erase_query (mssql::query (q)); + } + + template + inline unsigned long long database:: + erase_query (const std::string& q) + { + // T is always object_type. + // + return erase_query (mssql::query (q)); + } + + template + inline unsigned long long database:: + erase_query (const mssql::query& q) + { + // T is always object_type. + // + return object_traits_impl::erase_query (*this, q); + } + + template + inline result database:: + query () + { + return query (mssql::query ()); + } + + template + inline result database:: + query (const char* q) + { + return query (mssql::query (q)); + } + + template + inline result database:: + query (const std::string& q) + { + return query (mssql::query (q)); + } + + template + inline result database:: + query (const mssql::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/mssql/forward.hxx b/odb/mssql/forward.hxx index 5fbaacf..2a91c62 100644 --- a/odb/mssql/forward.hxx +++ b/odb/mssql/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/mssql/no-id-object-result.hxx b/odb/mssql/no-id-object-result.hxx index d0246aa..97f49f9 100644 --- a/odb/mssql/no-id-object-result.hxx +++ b/odb/mssql/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/mssql/no-id-object-result.txx b/odb/mssql/no-id-object-result.txx index f3674fb..c7e9914 100644 --- a/odb/mssql/no-id-object-result.txx +++ b/odb/mssql/no-id-object-result.txx @@ -32,7 +32,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/mssql/no-id-object-statements.hxx b/odb/mssql/no-id-object-statements.hxx index 468b632..8eae7c7 100644 --- a/odb/mssql/no-id-object-statements.hxx +++ b/odb/mssql/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/mssql/polymorphic-object-result.hxx b/odb/mssql/polymorphic-object-result.hxx index e370661..d9e5c1e 100644 --- a/odb/mssql/polymorphic-object-result.hxx +++ b/odb/mssql/polymorphic-object-result.hxx @@ -14,7 +14,7 @@ #include #include -#include // query +#include // query_base #include namespace odb @@ -28,24 +28,25 @@ 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::image_type image_type; 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/mssql/polymorphic-object-result.txx b/odb/mssql/polymorphic-object-result.txx index 02e2cd1..e469511 100644 --- a/odb/mssql/polymorphic-object-result.txx +++ b/odb/mssql/polymorphic-object-result.txx @@ -36,7 +36,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 ()), @@ -195,7 +195,7 @@ namespace odb { // Derived type version. // - typedef object_traits traits; + typedef object_traits_impl traits; static void rebind (typename traits::statements_type& sts) @@ -217,7 +217,7 @@ namespace odb { // Root type version. // - typedef object_traits traits; + typedef object_traits_impl traits; static void rebind (typename traits::statements_type& sts) diff --git a/odb/mssql/polymorphic-object-statements.hxx b/odb/mssql/polymorphic-object-statements.hxx index 79e9875..bc58f6f 100644 --- a/odb/mssql/polymorphic-object-statements.hxx +++ b/odb/mssql/polymorphic-object-statements.hxx @@ -147,7 +147,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/mssql/query-const-expr.cxx b/odb/mssql/query-const-expr.cxx index ea35dba..5413704 100644 --- a/odb/mssql/query-const-expr.cxx +++ b/odb/mssql/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/mssql/query.cxx b/odb/mssql/query.cxx index 953835f..a0371c7 100644 --- a/odb/mssql/query.cxx +++ b/odb/mssql/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; @@ -311,8 +311,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. // @@ -327,7 +327,7 @@ namespace odb if (yt) return x; - query r ("("); + query_base r ("("); r += x; r += ") AND ("; r += y; @@ -335,10 +335,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; @@ -346,10 +346,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/mssql/query.hxx b/odb/mssql/query.hxx index 636b7b6..08e3319 100644 --- a/odb/mssql/query.hxx +++ b/odb/mssql/query.hxx @@ -104,7 +104,7 @@ namespace odb template struct query_column; - class LIBODB_MSSQL_EXPORT query + class LIBODB_MSSQL_EXPORT query_base { public: struct clause_part @@ -126,7 +126,7 @@ namespace odb bool bool_part; }; - query () + query_base () : binding_ (0, 0) { } @@ -134,27 +134,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); @@ -162,7 +162,7 @@ namespace odb template explicit - query (val_bind v) + query_base (val_bind v) : binding_ (0, 0) { append::db_type_id> ( @@ -171,7 +171,7 @@ namespace odb template explicit - query (ref_bind r) + query_base (ref_bind r) : binding_ (0, 0) { append::db_type_id> ( @@ -179,12 +179,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 @@ -203,7 +203,7 @@ namespace odb return clause_.empty (); } - static const query true_expr; + static const query_base true_expr; bool const_true () const @@ -232,10 +232,10 @@ namespace odb } public: - query& - operator+= (const query&); + query_base& + operator+= (const query_base&); - query& + query_base& operator+= (const std::string& q) { append (q); @@ -243,7 +243,7 @@ namespace odb } template - query& + query_base& operator+= (val_bind v) { append::db_type_id> ( @@ -252,7 +252,7 @@ namespace odb } template - query& + query_base& operator+= (ref_bind r) { append::db_type_id> ( @@ -289,114 +289,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_MSSQL_EXPORT query - operator&& (const query& x, const query& y); + LIBODB_MSSQL_EXPORT query_base + operator&& (const query_base& x, const query_base& y); - LIBODB_MSSQL_EXPORT query - operator|| (const query& x, const query& y); + LIBODB_MSSQL_EXPORT query_base + operator|| (const query_base& x, const query_base& y); - LIBODB_MSSQL_EXPORT query - operator! (const query& x); + LIBODB_MSSQL_EXPORT query_base + operator! (const query_base& x); // query_column // @@ -466,18 +466,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; } @@ -485,108 +485,108 @@ 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 { v.prec = prec_; v.scale = scale_; - 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 { r.prec = prec_; r.scale = scale_; - 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); @@ -595,89 +595,89 @@ namespace odb // != // public: - query + query_base unequal (const T& v) const { return unequal (val_bind (v)); } - query + query_base unequal (val_bind v) const { v.prec = prec_; v.scale = scale_; - 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 { r.prec = prec_; r.scale = scale_; - 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); @@ -686,89 +686,89 @@ namespace odb // < // public: - query + query_base less (const T& v) const { return less (val_bind (v)); } - query + query_base less (val_bind v) const { v.prec = prec_; v.scale = scale_; - 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 { r.prec = prec_; r.scale = scale_; - 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); @@ -777,89 +777,89 @@ namespace odb // > // public: - query + query_base greater (const T& v) const { return greater (val_bind (v)); } - query + query_base greater (val_bind v) const { v.prec = prec_; v.scale = scale_; - 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 { r.prec = prec_; r.scale = scale_; - 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); @@ -868,89 +868,89 @@ 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 { v.prec = prec_; v.scale = scale_; - 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 { r.prec = prec_; r.scale = scale_; - 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); @@ -959,89 +959,89 @@ 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 { v.prec = prec_; v.scale = scale_; - 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 { r.prec = prec_; r.scale = scale_; - 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); @@ -1051,84 +1051,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; @@ -1147,37 +1147,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; } @@ -2262,13 +2262,75 @@ namespace odb } } -// odb::query specialization for SQL Server. +// odb::mssql::query and odb::query specialization for SQL Server. // namespace odb { + namespace mssql + { + 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::mssql::query so that it can be + // implicitly converted in mssql::database::query() calls. + // template - class query: public mssql::query, - public query_selector::columns_type + class query: public mssql::query { public: // We don't define any typedefs here since they may clash with @@ -2281,44 +2343,44 @@ namespace odb explicit query (bool v) - : mssql::query (v) + : mssql::query (v) { } explicit query (const char* q) - : mssql::query (q) + : mssql::query (q) { } explicit query (const std::string& q) - : mssql::query (q) + : mssql::query (q) { } template explicit query (mssql::val_bind v) - : mssql::query (mssql::query (v)) + : mssql::query (v) { } template explicit query (mssql::ref_bind r) - : mssql::query (mssql::query (r)) + : mssql::query (r) { } - query (const mssql::query& q) - : mssql::query (q) + query (const mssql::query_base& q) + : mssql::query (q) { } template query (const mssql::query_column& qc) - : mssql::query (qc) + : mssql::query (qc) { } }; diff --git a/odb/mssql/query.ixx b/odb/mssql/query.ixx index 0476b26..18b856c 100644 --- a/odb/mssql/query.ixx +++ b/odb/mssql/query.ixx @@ -7,7 +7,7 @@ namespace odb namespace mssql { 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/mssql/query.txx b/odb/mssql/query.txx index 522059a..d77ea83 100644 --- a/odb/mssql/query.txx +++ b/odb/mssql/query.txx @@ -6,12 +6,12 @@ namespace odb { namespace mssql { - // 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- @@ -26,10 +26,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, prec_, scale_), conversion_); q += ","; @@ -39,10 +39,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, prec_, scale_), conversion_); q += ","; @@ -54,10 +54,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, prec_, scale_), conversion_); q += ","; @@ -71,10 +71,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, prec_, scale_), conversion_); q += ","; @@ -91,10 +91,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) @@ -104,6 +104,7 @@ namespace odb q.append (val_bind (*i, prec_, scale_), conversion_); } + q += ")"; return q; } diff --git a/odb/mssql/simple-object-result.hxx b/odb/mssql/simple-object-result.hxx index 3fa101b..bdbd3ec 100644 --- a/odb/mssql/simple-object-result.hxx +++ b/odb/mssql/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/mssql/simple-object-result.txx b/odb/mssql/simple-object-result.txx index 3606f68..68f4316 100644 --- a/odb/mssql/simple-object-result.txx +++ b/odb/mssql/simple-object-result.txx @@ -34,7 +34,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/mssql/simple-object-statements.hxx b/odb/mssql/simple-object-statements.hxx index f892153..fc46f5b 100644 --- a/odb/mssql/simple-object-statements.hxx +++ b/odb/mssql/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/mssql/statement-cache.hxx b/odb/mssql/statement-cache.hxx index 9f2cb47..5d70af2 100644 --- a/odb/mssql/statement-cache.hxx +++ b/odb/mssql/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 (); template diff --git a/odb/mssql/statement-cache.txx b/odb/mssql/statement-cache.txx index 655f861..73acb87 100644 --- a/odb/mssql/statement-cache.txx +++ b/odb/mssql/statement-cache.txx @@ -7,10 +7,13 @@ namespace odb namespace mssql { 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/mssql/view-result.hxx b/odb/mssql/view-result.hxx index a847306..7215641 100644 --- a/odb/mssql/view-result.hxx +++ b/odb/mssql/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/mssql/view-result.txx b/odb/mssql/view-result.txx index 5058dc7..208d511 100644 --- a/odb/mssql/view-result.txx +++ b/odb/mssql/view-result.txx @@ -32,7 +32,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/mssql/view-statements.hxx b/odb/mssql/view-statements.hxx index db23460..5a93e03 100644 --- a/odb/mssql/view-statements.hxx +++ b/odb/mssql/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