diff options
-rw-r--r-- | odb/sqlite/query.cxx | 50 | ||||
-rw-r--r-- | odb/sqlite/query.hxx | 70 | ||||
-rw-r--r-- | odb/sqlite/traits.cxx | 14 | ||||
-rw-r--r-- | odb/sqlite/traits.hxx | 20 | ||||
-rw-r--r-- | odb/sqlite/view-result.txx | 2 | ||||
-rw-r--r-- | odb/sqlite/view-statements.hxx | 21 |
6 files changed, 135 insertions, 42 deletions
diff --git a/odb/sqlite/query.cxx b/odb/sqlite/query.cxx index ab158bb..16d8cc2 100644 --- a/odb/sqlite/query.cxx +++ b/odb/sqlite/query.cxx @@ -197,6 +197,47 @@ namespace odb parameters_->add (p); } + 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 { @@ -243,14 +284,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/sqlite/query.hxx b/odb/sqlite/query.hxx index 9731d10..c712b58 100644 --- a/odb/sqlite/query.hxx +++ b/odb/sqlite/query.hxx @@ -136,6 +136,22 @@ namespace odb { } + // True or false literal. + // + explicit + query (bool v) + : parameters_ (new (details::shared) query_params) + { + clause_.push_back (clause_part (clause_part::native, v ? "1" : "0")); + } + + explicit + query (const char* native) + : parameters_ (new (details::shared) query_params) + { + clause_.push_back (clause_part (clause_part::native, native)); + } + explicit query (const std::string& native) : parameters_ (new (details::shared) query_params) @@ -177,6 +193,9 @@ namespace odb std::string clause () const; + const char* + clause_prefix () const; + binding& parameters_binding () const; @@ -1061,6 +1080,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> @@ -1227,6 +1285,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/sqlite/traits.cxx b/odb/sqlite/traits.cxx index 62093e9..8a9f310 100644 --- a/odb/sqlite/traits.cxx +++ b/odb/sqlite/traits.cxx @@ -20,10 +20,7 @@ namespace odb // void default_value_traits<string, id_text>:: - set_image (buffer& b, - size_t& n, - bool& is_null, - const string& v) + set_image (buffer& b, size_t& n, bool& is_null, const string& v) { is_null = false; n = v.size (); @@ -36,14 +33,11 @@ namespace odb } // - // default_value_traits<const char*> + // c_string_value_traits // - void default_value_traits<const char*, id_text>:: - set_image (buffer& b, - size_t& n, - bool& is_null, - const char* v) + void c_string_value_traits:: + set_image (buffer& b, size_t& n, bool& is_null, const char* v) { is_null = false; n = strlen (v); diff --git a/odb/sqlite/traits.hxx b/odb/sqlite/traits.hxx index e2a4a4d..e712aa7 100644 --- a/odb/sqlite/traits.hxx +++ b/odb/sqlite/traits.hxx @@ -236,8 +236,7 @@ namespace odb // of an image from the value but not the other way around. This way // we can pass such values to the queries. // - template <> - struct LIBODB_SQLITE_EXPORT default_value_traits<const char*, id_text> + struct LIBODB_SQLITE_EXPORT c_string_value_traits { typedef const char* value_type; typedef const char* query_type; @@ -250,6 +249,17 @@ namespace odb const char*); }; + template <> + struct LIBODB_SQLITE_EXPORT default_value_traits<const char*, id_text>: + c_string_value_traits + { + }; + + template <std::size_t n> + struct default_value_traits<char[n], id_text>: c_string_value_traits + { + }; + // std::vector<char> (buffer) specialization. // template <> @@ -386,6 +396,12 @@ namespace odb { static const database_type_id db_type_id = id_text; }; + + template <std::size_t n> + struct default_type_traits<char[n]> + { + static const database_type_id db_type_id = id_text; + }; } } diff --git a/odb/sqlite/view-result.txx b/odb/sqlite/view-result.txx index eec8b0a..2facc24 100644 --- a/odb/sqlite/view-result.txx +++ b/odb/sqlite/view-result.txx @@ -66,7 +66,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/sqlite/view-statements.hxx b/odb/sqlite/view-statements.hxx index e940495..6126f08 100644 --- a/odb/sqlite/view-statements.hxx +++ b/odb/sqlite/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 sqlite::select_statement query_statement_type; - public: view_statements (connection_type&); @@ -73,23 +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, - image_binding_)); - - query_->cached (true); - } - - return *query_; - } - private: view_statements (const view_statements&); view_statements& operator= (const view_statements&); @@ -100,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_; }; } } |