diff options
-rw-r--r-- | odb/pgsql/query.cxx | 50 | ||||
-rw-r--r-- | odb/pgsql/query.hxx | 71 | ||||
-rw-r--r-- | odb/pgsql/traits.hxx | 16 | ||||
-rw-r--r-- | odb/pgsql/view-result.txx | 2 | ||||
-rw-r--r-- | odb/pgsql/view-statements.hxx | 19 |
5 files changed, 130 insertions, 28 deletions
diff --git a/odb/pgsql/query.cxx b/odb/pgsql/query.cxx index 6739b06..945db7a 100644 --- a/odb/pgsql/query.cxx +++ b/odb/pgsql/query.cxx @@ -259,6 +259,47 @@ namespace odb return native_binding_; } + const char* query:: + clause_prefix () const + { + if (!clause_.empty ()) + { + const clause_part& p (clause_.front ()); + + if (p.kind == clause_part::native) + { + const string& s (p.part); + string::size_type n; + + // It is easier to compare to upper and lower-case versions + // rather than getting involved with the portable case- + // insensitive string comparison mess. + // + if (s.compare (0, (n = 5), "WHERE") == 0 || + s.compare (0, (n = 5), "where") == 0 || + s.compare (0, (n = 6), "SELECT") == 0 || + s.compare (0, (n = 6), "select") == 0 || + s.compare (0, (n = 8), "ORDER BY") == 0 || + s.compare (0, (n = 8), "order by") == 0 || + s.compare (0, (n = 8), "GROUP BY") == 0 || + s.compare (0, (n = 8), "group by") == 0 || + s.compare (0, (n = 6), "HAVING") == 0 || + s.compare (0, (n = 6), "having") == 0) + { + // It either has to be an exact match, or there should be + // a whitespace following the keyword. + // + if (s.size () == n || s[n] == ' ' || s[n] =='\t') + return ""; + } + } + + return "WHERE "; + } + + return ""; + } + string query:: clause () const { @@ -309,14 +350,7 @@ namespace odb } } - if (r.empty () || - r.compare (0, 6, "WHERE ") == 0 || - r.compare (0, 9, "ORDER BY ") == 0 || - r.compare (0, 9, "GROUP BY ") == 0 || - r.compare (0, 7, "HAVING ") == 0) - return r; - else - return "WHERE " + r; + return clause_prefix () + r; } } } diff --git a/odb/pgsql/query.hxx b/odb/pgsql/query.hxx index 7fd66d7..438f2f5 100644 --- a/odb/pgsql/query.hxx +++ b/odb/pgsql/query.hxx @@ -110,6 +110,23 @@ namespace odb { } + // True or false literal. + // + explicit + query (bool v) + : binding_ (0, 0), native_binding_ (0, 0, 0, 0) + { + clause_.push_back ( + clause_part (clause_part::native, v ? "TRUE" : "FALSE")); + } + + explicit + query (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) : binding_ (0, 0), native_binding_ (0, 0, 0, 0) @@ -151,6 +168,9 @@ namespace odb std::string clause () const; + const char* + clause_prefix () const; + native_binding& parameters_binding () const; @@ -1054,6 +1074,45 @@ namespace odb const char* column_; }; + // Provide operator+() for using columns to construct native + // query fragments (e.g., ORDER BY). + // + template <typename T, database_type_id ID> + inline query + operator+ (const query_column<T, ID>& c, const std::string& s) + { + query q (c.table (), c.column ()); + q += s; + return q; + } + + template <typename T, database_type_id ID> + inline query + operator+ (const std::string& s, const query_column<T, ID>& c) + { + query q (s); + q.append (c.table (), c.column ()); + return q; + } + + template <typename T, database_type_id ID> + inline query + operator+ (const query_column<T, ID>& c, const query& q) + { + query r (c.table (), c.column ()); + r += q; + return r; + } + + template <typename T, database_type_id ID> + inline query + operator+ (const query& q, const query_column<T, ID>& c) + { + query r (q); + r.append (c.table (), c.column ()); + return r; + } + // // template <typename T, database_type_id> @@ -1702,6 +1761,18 @@ namespace odb } explicit + query (bool v) + : query_selector<T>::type (v) + { + } + + explicit + query (const char* q) + : query_selector<T>::type (q) + { + } + + explicit query (const std::string& q) : query_selector<T>::type (q) { diff --git a/odb/pgsql/traits.hxx b/odb/pgsql/traits.hxx index e0aff15..5fe65b6 100644 --- a/odb/pgsql/traits.hxx +++ b/odb/pgsql/traits.hxx @@ -438,6 +438,16 @@ namespace odb { }; + template <std::size_t n> + struct default_value_traits<char[n], id_numeric>: c_string_value_traits + { + }; + + template <std::size_t n> + struct default_value_traits<char[n], id_string>: c_string_value_traits + { + }; + // std::vector<char> (buffer) specialization. // template <> @@ -574,6 +584,12 @@ namespace odb { static const database_type_id db_type_id = id_string; }; + + template <std::size_t n> + struct default_type_traits<char[n]> + { + static const database_type_id db_type_id = id_string; + }; } } diff --git a/odb/pgsql/view-result.txx b/odb/pgsql/view-result.txx index 63e5444..f7aff89 100644 --- a/odb/pgsql/view-result.txx +++ b/odb/pgsql/view-result.txx @@ -65,7 +65,7 @@ namespace odb odb::database& db (this->database ()); view_traits::callback (db, view, callback_event::pre_load); - view_traits::init (view, im); + view_traits::init (view, im, db); view_traits::callback (db, view, callback_event::post_load); } diff --git a/odb/pgsql/view-statements.hxx b/odb/pgsql/view-statements.hxx index e1e5614..e90549b 100644 --- a/odb/pgsql/view-statements.hxx +++ b/odb/pgsql/view-statements.hxx @@ -33,8 +33,6 @@ namespace odb typedef typename view_traits::pointer_type pointer_type; typedef typename view_traits::image_type image_type; - typedef pgsql::select_statement query_statement_type; - public: view_statements (connection_type&); @@ -73,21 +71,6 @@ namespace odb return image_truncated_; } - query_statement_type& - query_statement () - { - if (query_ == 0) - { - query_.reset ( - new (details::shared) query_statement_type ( - conn_, - view_traits::query_statement_name, - image_binding_)); - } - - return *query_; - } - private: view_statements (const view_statements&); view_statements& operator= (const view_statements&); @@ -98,8 +81,6 @@ namespace odb binding image_binding_; bind image_bind_[view_traits::column_count]; bool image_truncated_[view_traits::column_count]; - - details::shared_ptr<query_statement_type> query_; }; } } |