aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-06-13 18:25:00 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-06-13 18:25:00 +0200
commit617407a3353e5bfce0dc9144776015899d7a4e65 (patch)
tree51e550501e657664832acc1d203c27535805c155
parent70163be20183541e6fc26898d86b15b929d8b800 (diff)
Add support for native views that call stored procedures
-rw-r--r--odb/context.hxx3
-rw-r--r--odb/relational/processor.cxx29
-rw-r--r--odb/relational/source.cxx40
-rw-r--r--odb/relational/source.hxx3
4 files changed, 58 insertions, 17 deletions
diff --git a/odb/context.hxx b/odb/context.hxx
index c06a9c4..306d2e4 100644
--- a/odb/context.hxx
+++ b/odb/context.hxx
@@ -178,7 +178,8 @@ struct view_query
enum kind_type
{
runtime,
- complete,
+ complete_select, // SELECT query.
+ complete_execute, // Stored procedure call.
condition
};
diff --git a/odb/relational/processor.cxx b/odb/relational/processor.cxx
index 5523b1e..3efeec4 100644
--- a/odb/relational/processor.cxx
+++ b/odb/relational/processor.cxx
@@ -1238,22 +1238,35 @@ namespace relational
if (!vq.literal.empty ())
{
string q (upcase (vq.literal));
- vq.kind = (q.compare (0, 7, "SELECT ") == 0)
- ? view_query::complete
- : view_query::condition;
+
+ if (q.compare (0, 7, "SELECT ") == 0)
+ vq.kind = view_query::complete_select;
+ else if (q.compare (0, 5, "EXEC ") == 0 ||
+ q.compare (0, 5, "CALL ") == 0 ||
+ q.compare (0, 8, "EXECUTE ") == 0)
+ vq.kind = view_query::complete_execute;
+ else
+ vq.kind = view_query::condition;
}
else if (!vq.expr.empty ())
{
// If the first token in the expression is a string and
- // it starts with "SELECT " or is equal to "SELECT", then
- // we have a complete query.
+ // it starts with "SELECT " or is equal to "SELECT" or
+ // one of the stored procedure call keywords, then we
+ // have a complete query.
//
if (vq.expr.front ().type == CPP_STRING)
{
string q (upcase (vq.expr.front ().literal));
- vq.kind = (q.compare (0, 7, "SELECT ") == 0 || q == "SELECT")
- ? view_query::complete
- : view_query::condition;
+
+ if (q.compare (0, 7, "SELECT ") == 0 || q == "SELECT")
+ vq.kind = view_query::complete_select;
+ else if (q.compare (0, 5, "EXEC ") == 0 || q == "EXEC" ||
+ q.compare (0, 5, "CALL ") == 0 || q == "CALL" ||
+ q.compare (0, 8, "EXECUTE ") == 0 || q == "EXECUTE")
+ vq.kind = view_query::complete_execute;
+ else
+ vq.kind = view_query::condition;
}
else
vq.kind = view_query::condition;
diff --git a/odb/relational/source.cxx b/odb/relational/source.cxx
index ceb8538..8d7c913 100644
--- a/odb/relational/source.cxx
+++ b/odb/relational/source.cxx
@@ -3074,11 +3074,13 @@ traverse_view (type& c)
<< "query_statement (const query_base_type& q)"
<< "{";
- if (vq.kind == view_query::complete)
+ if (vq.kind == view_query::complete_select ||
+ vq.kind == view_query::complete_execute)
{
os << "query_base_type r (" << endl;
bool ph (false);
+ bool pred (vq.kind == view_query::complete_select);
if (!vq.literal.empty ())
{
@@ -3094,9 +3096,21 @@ traverse_view (type& c)
if (p != string::npos)
{
ph = true;
- os << strlit (string (vq.literal, 0, p + 1)) << " +" << endl
- << "(q.empty () ? query_base_type::true_expr : q) +" << endl
- << strlit (string (vq.literal, p + 2));
+ // For the SELECT query we keep the parenthesis in (?) and
+ // also handle the case where the query expression is empty.
+ //
+ if (pred)
+ os << strlit (string (vq.literal, 0, p + 1)) << " +" << endl
+ << "(q.empty () ? query_base_type::true_expr : q) +" << endl
+ << strlit (string (vq.literal, p + 2));
+ else
+ {
+ os << strlit (string (vq.literal, 0, p)) << " + q";
+
+ p += 3;
+ if (p != vq.literal.size ())
+ os << strlit (string (vq.literal, p));
+ }
}
else
os << strlit (vq.literal);
@@ -3110,7 +3124,7 @@ traverse_view (type& c)
//
os << "// From " << location_string (vq.loc, true) << endl
<< translate_expression (
- c, vq.expr, scope, vq.loc, "query", &ph).value;
+ c, vq.expr, scope, vq.loc, "query", &ph, pred).value;
}
os << ");";
@@ -4232,7 +4246,8 @@ namespace relational
semantics::scope& scope,
location_t loc,
string const& prag,
- bool* placeholder)
+ bool* placeholder,
+ bool predicate)
{
// This code is similar to translate() from context.cxx.
//
@@ -4427,8 +4442,19 @@ namespace relational
if (tt == CPP_CLOSE_PAREN)
{
- r += "q.empty () ? query_base_type::true_expr : q";
*placeholder = true;
+
+ // Predicate is true if this is a SELECT statement clause.
+ // Otherwise it is a stored procedure parameters.
+ //
+ if (predicate)
+ r += "q.empty () ? query_base_type::true_expr : q";
+ else
+ {
+ r.resize (r.size () - 1); // Remove opening paren.
+ r += "q";
+ break; // Skip the closing paren as well.
+ }
}
else
{
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx
index f8987a8..d27110e 100644
--- a/odb/relational/source.hxx
+++ b/odb/relational/source.hxx
@@ -3874,7 +3874,8 @@ namespace relational
semantics::scope& start_scope,
location_t loc,
string const& prag,
- bool* placeholder = 0);
+ bool* placeholder = 0,
+ bool predicate = true);
//
// composite
//