aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-09-16 16:03:25 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-09-16 16:03:25 +0200
commit02aed5f059797cd5e53a9fe6dde13714f86332d4 (patch)
treeb2bfce8921184f8767dddba221032792b1cb3214
parenta8b1a89c291ab5bd170568eab3d7666631adf035 (diff)
Support for views; integrated part
-rw-r--r--odb/sqlite/query.cxx50
-rw-r--r--odb/sqlite/query.hxx70
-rw-r--r--odb/sqlite/traits.cxx14
-rw-r--r--odb/sqlite/traits.hxx20
-rw-r--r--odb/sqlite/view-result.txx2
-rw-r--r--odb/sqlite/view-statements.hxx21
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_;
};
}
}