aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--odb/pgsql/query.cxx50
-rw-r--r--odb/pgsql/query.hxx71
-rw-r--r--odb/pgsql/traits.hxx16
-rw-r--r--odb/pgsql/view-result.txx2
-rw-r--r--odb/pgsql/view-statements.hxx19
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_;
};
}
}