From 9f994010f871ce0ea1aea58482ddef503cfc81c3 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 8 Oct 2012 16:09:08 +0200 Subject: Ground work for multi-database support All generated code now includes database id. The database-specific database class interface has been updated to include all the database operations. The database-specific tests now use this interface. --- odb/pgsql/database.cxx | 13 +- odb/pgsql/database.hxx | 186 ++++++++++++ odb/pgsql/database.ixx | 378 +++++++++++++++++++++++++ odb/pgsql/forward.hxx | 3 +- odb/pgsql/no-id-object-result.hxx | 8 +- odb/pgsql/no-id-object-result.txx | 2 +- odb/pgsql/no-id-object-statements.hxx | 2 +- odb/pgsql/polymorphic-object-result.hxx | 13 +- odb/pgsql/polymorphic-object-result.txx | 6 +- odb/pgsql/polymorphic-object-statements.hxx | 2 +- odb/pgsql/query-const-expr.cxx | 2 +- odb/pgsql/query.cxx | 46 +-- odb/pgsql/query.hxx | 420 ++++++++++++++++------------ odb/pgsql/query.ixx | 4 +- odb/pgsql/query.txx | 27 +- odb/pgsql/simple-object-result.hxx | 10 +- odb/pgsql/simple-object-result.txx | 2 +- odb/pgsql/simple-object-statements.hxx | 4 +- odb/pgsql/statement-cache.hxx | 2 +- odb/pgsql/statement-cache.txx | 7 +- odb/pgsql/view-result.hxx | 8 +- odb/pgsql/view-result.txx | 2 +- odb/pgsql/view-statements.hxx | 2 +- 23 files changed, 893 insertions(+), 256 deletions(-) (limited to 'odb') diff --git a/odb/pgsql/database.cxx b/odb/pgsql/database.cxx index 4777f79..49f6178 100644 --- a/odb/pgsql/database.cxx +++ b/odb/pgsql/database.cxx @@ -27,7 +27,8 @@ namespace odb unsigned int port, const string& extra_conninfo, transfer_ptr factory) - : user_ (user), + : odb::database (id_pgsql), + user_ (user), password_ (password), db_ (db), host_ (host), @@ -74,7 +75,8 @@ namespace odb const string& socket_ext, const string& extra_conninfo, transfer_ptr factory) - : user_ (user), + : odb::database (id_pgsql), + user_ (user), password_ (password), db_ (db), host_ (host), @@ -116,7 +118,10 @@ namespace odb database:: database (const string& conninfo, transfer_ptr factory) - : port_ (0), conninfo_ (conninfo), factory_ (factory.transfer ()) + : odb::database (id_pgsql), + port_ (0), + conninfo_ (conninfo), + factory_ (factory.transfer ()) { if (!factory_) factory_.reset (new connection_pool_factory ()); @@ -130,7 +135,7 @@ namespace odb bool erase, const string& extra_conninfo, transfer_ptr factory) - : port_ (0), factory_ (factory.transfer ()) + : odb::database (id_pgsql), port_ (0), factory_ (factory.transfer ()) { using namespace details; diff --git a/odb/pgsql/database.hxx b/odb/pgsql/database.hxx index 64bd792..6f40486 100644 --- a/odb/pgsql/database.hxx +++ b/odb/pgsql/database.hxx @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -80,6 +81,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 pgsql::query&); + + // Query API. + // + template + result + query (); + + template + result + query (const char*); + + template + result + query (const std::string&); + + template + result + query (const pgsql::query&); + // Transactions. // public: diff --git a/odb/pgsql/database.ixx b/odb/pgsql/database.ixx index d43cf83..bdd4390 100644 --- a/odb/pgsql/database.ixx +++ b/odb/pgsql/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 (pgsql::query ()); + } + + template + inline unsigned long long database:: + erase_query (const char* q) + { + // T is always object_type. + // + return erase_query (pgsql::query (q)); + } + + template + inline unsigned long long database:: + erase_query (const std::string& q) + { + // T is always object_type. + // + return erase_query (pgsql::query (q)); + } + + template + inline unsigned long long database:: + erase_query (const pgsql::query& q) + { + // T is always object_type. + // + return object_traits_impl::erase_query (*this, q); + } + + template + inline result database:: + query () + { + return query (pgsql::query ()); + } + + template + inline result database:: + query (const char* q) + { + return query (pgsql::query (q)); + } + + template + inline result database:: + query (const std::string& q) + { + return query (pgsql::query (q)); + } + + template + inline result database:: + query (const pgsql::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/pgsql/forward.hxx b/odb/pgsql/forward.hxx index 96b2266..e164bf1 100644 --- a/odb/pgsql/forward.hxx +++ b/odb/pgsql/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/pgsql/no-id-object-result.hxx b/odb/pgsql/no-id-object-result.hxx index 2bd1b47..09a5517 100644 --- a/odb/pgsql/no-id-object-result.hxx +++ b/odb/pgsql/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/pgsql/no-id-object-result.txx b/odb/pgsql/no-id-object-result.txx index 6b1e921..e9682b2 100644 --- a/odb/pgsql/no-id-object-result.txx +++ b/odb/pgsql/no-id-object-result.txx @@ -20,7 +20,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/pgsql/no-id-object-statements.hxx b/odb/pgsql/no-id-object-statements.hxx index 98e6a48..a8d7c4c 100644 --- a/odb/pgsql/no-id-object-statements.hxx +++ b/odb/pgsql/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/pgsql/polymorphic-object-result.hxx b/odb/pgsql/polymorphic-object-result.hxx index 795a864..896b0e3 100644 --- a/odb/pgsql/polymorphic-object-result.hxx +++ b/odb/pgsql/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/pgsql/polymorphic-object-result.txx b/odb/pgsql/polymorphic-object-result.txx index 02a71a0..5147fbe 100644 --- a/odb/pgsql/polymorphic-object-result.txx +++ b/odb/pgsql/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 ()), @@ -182,7 +182,7 @@ namespace odb { // Derived type version. // - typedef object_traits traits; + typedef object_traits_impl traits; static bool rebind (typename traits::statements_type& sts) @@ -207,7 +207,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/pgsql/polymorphic-object-statements.hxx b/odb/pgsql/polymorphic-object-statements.hxx index 8a85e3c..2f1a03a 100644 --- a/odb/pgsql/polymorphic-object-statements.hxx +++ b/odb/pgsql/polymorphic-object-statements.hxx @@ -166,7 +166,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/pgsql/query-const-expr.cxx b/odb/pgsql/query-const-expr.cxx index 3f2ccc5..09f16d2 100644 --- a/odb/pgsql/query-const-expr.cxx +++ b/odb/pgsql/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/pgsql/query.cxx b/odb/pgsql/query.cxx index 6c0bd4c..2233110 100644 --- a/odb/pgsql/query.cxx +++ b/odb/pgsql/query.cxx @@ -23,10 +23,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_), @@ -63,8 +63,8 @@ namespace odb } } - query& query:: - operator= (const query& q) + query_base& query_base:: + operator= (const query_base& q) { if (this != &q) { @@ -104,8 +104,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 ()); @@ -153,7 +153,7 @@ namespace odb return *this; } - void query:: + void query_base:: append (const string& q) { if (!clause_.empty () && clause_.back ().kind == clause_part::native) @@ -176,7 +176,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); @@ -186,7 +186,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)); @@ -222,7 +222,7 @@ namespace odb statement::bind_param (native_binding_, binding_); } - native_binding& query:: + native_binding& query_base:: parameters_binding () const { size_t n (parameters_.size ()); @@ -291,7 +291,7 @@ namespace odb return false; } - void query:: + void query_base:: optimize () { // Remove a single TRUE literal or one that is followe by one of @@ -311,7 +311,7 @@ namespace odb } } - const char* query:: + const char* query_base:: clause_prefix () const { if (!clause_.empty ()) @@ -327,7 +327,7 @@ namespace odb return ""; } - string query:: + string query_base:: clause () const { string r; @@ -404,8 +404,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. // @@ -420,7 +420,7 @@ namespace odb if (yt) return x; - query r ("("); + query_base r ("("); r += x; r += ") AND ("; r += y; @@ -428,10 +428,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; @@ -439,10 +439,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/pgsql/query.hxx b/odb/pgsql/query.hxx index 582ddcb..0c5e8f4 100644 --- a/odb/pgsql/query.hxx +++ b/odb/pgsql/query.hxx @@ -86,7 +86,7 @@ namespace odb template struct query_column; - class LIBODB_PGSQL_EXPORT query + class LIBODB_PGSQL_EXPORT query_base { public: struct clause_part @@ -108,7 +108,7 @@ namespace odb bool bool_part; }; - query () + query_base () : binding_ (0, 0), native_binding_ (0, 0, 0, 0) { } @@ -116,27 +116,27 @@ namespace odb // True or false literal. // explicit - query (bool v) + query_base (bool v) : binding_ (0, 0), native_binding_ (0, 0, 0, 0) { clause_.push_back (clause_part (v)); } explicit - query (const char* native) + query_base (const char* native) : binding_ (0, 0), native_binding_ (0, 0, 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), native_binding_ (0, 0, 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), native_binding_ (0, 0, 0, 0) { append (table, column); @@ -144,7 +144,7 @@ namespace odb template explicit - query (val_bind v) + query_base (val_bind v) : binding_ (0, 0), native_binding_ (0, 0, 0, 0) { append::db_type_id> ( @@ -153,7 +153,7 @@ namespace odb template explicit - query (ref_bind r) + query_base (ref_bind r) : binding_ (0, 0), native_binding_ (0, 0, 0, 0) { append::db_type_id> ( @@ -161,12 +161,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 @@ -197,7 +197,7 @@ namespace odb return clause_.empty (); } - static const query true_expr; + static const query_base true_expr; bool const_true () const @@ -226,10 +226,10 @@ namespace odb } public: - query& - operator+= (const query&); + query_base& + operator+= (const query_base&); - query& + query_base& operator+= (const std::string& q) { append (q); @@ -237,7 +237,7 @@ namespace odb } template - query& + query_base& operator+= (val_bind v) { append::db_type_id> ( @@ -246,7 +246,7 @@ namespace odb } template - query& + query_base& operator+= (ref_bind r) { append::db_type_id> ( @@ -290,114 +290,114 @@ namespace odb mutable native_binding native_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_PGSQL_EXPORT query - operator&& (const query&, const query&); + LIBODB_PGSQL_EXPORT query_base + operator&& (const query_base&, const query_base&); - LIBODB_PGSQL_EXPORT query - operator|| (const query&, const query&); + LIBODB_PGSQL_EXPORT query_base + operator|| (const query_base&, const query_base&); - LIBODB_PGSQL_EXPORT query - operator! (const query&); + LIBODB_PGSQL_EXPORT query_base + operator! (const query_base&); // query_column // @@ -450,18 +450,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; } @@ -469,102 +469,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); @@ -573,83 +573,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); @@ -658,83 +658,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); @@ -743,83 +743,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); @@ -828,83 +828,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); @@ -913,83 +913,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); @@ -999,84 +999,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; @@ -1092,37 +1092,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; } @@ -1758,13 +1758,75 @@ namespace odb } } -// odb::query specialization for PostgreSQL. +// odb::pgsql::query and odb::query specialization for PostgreSQL. // namespace odb { + namespace pgsql + { + 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::pgsql::query so that it can be + // implicitly converted in pgsql::database::query() calls. + // template - class query: public pgsql::query, - public query_selector::columns_type + class query: public pgsql::query { public: // We don't define any typedefs here since they may clash with @@ -1777,44 +1839,44 @@ namespace odb explicit query (bool v) - : pgsql::query (v) + : pgsql::query (v) { } explicit query (const char* q) - : pgsql::query (q) + : pgsql::query (q) { } explicit query (const std::string& q) - : pgsql::query (q) + : pgsql::query (q) { } template explicit query (pgsql::val_bind v) - : pgsql::query (pgsql::query (v)) + : pgsql::query (v) { } template explicit query (pgsql::ref_bind r) - : pgsql::query (pgsql::query (r)) + : pgsql::query (r) { } - query (const pgsql::query& q) - : pgsql::query (q) + query (const pgsql::query_base& q) + : pgsql::query (q) { } template query (const pgsql::query_column& qc) - : pgsql::query (qc) + : pgsql::query (qc) { } }; diff --git a/odb/pgsql/query.ixx b/odb/pgsql/query.ixx index d850c1a..ef8ea77 100644 --- a/odb/pgsql/query.ixx +++ b/odb/pgsql/query.ixx @@ -7,7 +7,7 @@ namespace odb namespace pgsql { 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/pgsql/query.txx b/odb/pgsql/query.txx index 274e703..84fd8ca 100644 --- a/odb/pgsql/query.txx +++ b/odb/pgsql/query.txx @@ -6,12 +6,12 @@ namespace odb { namespace pgsql { - // query + // query_base // template - query:: - query (const query_column& c) + query_base:: + query_base (const query_column& c) : binding_ (0, 0), native_binding_ (0, 0, 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/pgsql/simple-object-result.hxx b/odb/pgsql/simple-object-result.hxx index d572fea..c90065c 100644 --- a/odb/pgsql/simple-object-result.hxx +++ b/odb/pgsql/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/pgsql/simple-object-result.txx b/odb/pgsql/simple-object-result.txx index 81b5f73..26fe9cc 100644 --- a/odb/pgsql/simple-object-result.txx +++ b/odb/pgsql/simple-object-result.txx @@ -22,7 +22,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/pgsql/simple-object-statements.hxx b/odb/pgsql/simple-object-statements.hxx index 57cf685..772ff24 100644 --- a/odb/pgsql/simple-object-statements.hxx +++ b/odb/pgsql/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*, char** nv, int* nl, int* nf); @@ -171,7 +171,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/pgsql/statement-cache.hxx b/odb/pgsql/statement-cache.hxx index 90bc2f6..7eda0d7 100644 --- a/odb/pgsql/statement-cache.hxx +++ b/odb/pgsql/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/pgsql/statement-cache.txx b/odb/pgsql/statement-cache.txx index 40ed170..f3bbe07 100644 --- a/odb/pgsql/statement-cache.txx +++ b/odb/pgsql/statement-cache.txx @@ -7,10 +7,13 @@ namespace odb namespace pgsql { 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/pgsql/view-result.hxx b/odb/pgsql/view-result.hxx index 1bdb2d2..d0a21d6 100644 --- a/odb/pgsql/view-result.hxx +++ b/odb/pgsql/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/pgsql/view-result.txx b/odb/pgsql/view-result.txx index 9c22133..d596e7c 100644 --- a/odb/pgsql/view-result.txx +++ b/odb/pgsql/view-result.txx @@ -20,7 +20,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/pgsql/view-statements.hxx b/odb/pgsql/view-statements.hxx index b884ee2..1e44cd3 100644 --- a/odb/pgsql/view-statements.hxx +++ b/odb/pgsql/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