aboutsummaryrefslogtreecommitdiff
path: root/odb/pgsql/query.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'odb/pgsql/query.cxx')
-rw-r--r--odb/pgsql/query.cxx155
1 files changed, 83 insertions, 72 deletions
diff --git a/odb/pgsql/query.cxx b/odb/pgsql/query.cxx
index 1c5f9d4..856c031 100644
--- a/odb/pgsql/query.cxx
+++ b/odb/pgsql/query.cxx
@@ -28,7 +28,6 @@ namespace odb
query (const query& q)
: clause_ (q.clause_),
parameters_ (q.parameters_),
- parameter_offsets_ (q.parameter_offsets_),
bind_ (q.bind_),
binding_ (0, 0),
values_ (q.values_),
@@ -70,7 +69,6 @@ namespace odb
{
clause_ = q.clause_;
parameters_ = q.parameters_;
- parameter_offsets_ = q.parameter_offsets_;
bind_ = q.bind_;
size_t n (bind_.size ());
@@ -108,56 +106,7 @@ namespace odb
query& query::
operator+= (const query& q)
{
- size_t cur_pos (0);
-
- // Append the argument clause to the clause of this instance.
- //
- for (size_t i (0),
- p (parameters_.size () + 1),
- e (q.parameter_offsets_.size ());
- i < e;
- ++i, ++p)
- {
- size_t n (clause_.size ());
-
- if (n != 0 && clause_[n - 1] != ' ' && q.clause_[cur_pos] != ' ')
- clause_ += ' ';
-
- parameter_offset o (q.parameter_offsets_[i]);
-
- // Append all characters up to the start of the current
- // parameter specifier, including the '$'.
- //
- clause_.append (q.clause_, cur_pos, o.first - cur_pos + 1);
-
- // Advance current position in source clause to 1 element past
- // the current parameter specifier.
- //
- cur_pos = o.second;
-
- // Insert the correct parameter number and update the parameter
- // offset to describe its offset in the new clause.
- //
- o.first = clause_.size () - 1;
- ostringstream os;
- os << p;
- clause_.append (os.str ());
- o.second = clause_.size ();
-
- parameter_offsets_.push_back (o);
- }
-
- // Copy any remaining characters in q.clause_.
- //
- if (cur_pos < q.clause_.size ())
- {
- size_t n (clause_.size ());
-
- if (n != 0 && clause_[n - 1] != ' ' && q.clause_[cur_pos] != ' ')
- clause_ += ' ';
-
- clause_.append (q.clause_, cur_pos, string::npos);
- }
+ clause_.insert (clause_.end (), q.clause_.begin (), q.clause_.end ());
size_t n (bind_.size ());
@@ -204,22 +153,34 @@ namespace odb
}
void query::
- add (details::shared_ptr<query_param> p)
+ append (const string& q, clause_part::kind_type k)
{
- size_t n (clause_.size ());
+ if (k == clause_part::native &&
+ !clause_.empty () &&
+ clause_.back ().kind == clause_part::native)
+ {
+ string& s (clause_.back ().part);
- if (n != 0 && clause_[n - 1] != ' ')
- clause_ += ' ';
+ char first (!q.empty () ? q[0] : ' ');
+ char last (!s.empty () ? s[s.size () - 1] : ' ');
- parameter_offset o;
- o.first = clause_.size ();
+ // We don't want extra spaces after '(' as well as before ','
+ // and ')'.
+ //
+ if (last != ' ' && last != '(' &&
+ first != ' ' && first != ',' && first != ')')
+ s += ' ';
- ostringstream ss;
- ss << parameters_.size () + 1;
- clause_ += '$' + ss.str ();
+ s += q;
+ }
+ else
+ clause_.push_back (clause_part (k, q));
+ }
- o.second = clause_.size ();
- parameter_offsets_.push_back (o);
+ void query::
+ add (details::shared_ptr<query_param> p)
+ {
+ clause_.push_back (clause_part (clause_part::param));
parameters_.push_back (p);
bind_.push_back (bind ());
@@ -288,17 +249,67 @@ namespace odb
return native_binding_;
}
- std::string query::
- clause () const
+ string query::
+ clause (string const& table) const
{
- if (clause_.empty () ||
- clause_.compare (0, 6, "WHERE ") == 0 ||
- clause_.compare (0, 9, "ORDER BY ") == 0 ||
- clause_.compare (0, 9, "GROUP BY ") == 0 ||
- clause_.compare (0, 7, "HAVING ") == 0)
- return clause_;
+ string r;
+ size_t param (1);
+
+ for (clause_type::const_iterator i (clause_.begin ()),
+ end (clause_.end ()); i != end; ++i)
+ {
+ char last (!r.empty () ? r[r.size () - 1] : ' ');
+
+ switch (i->kind)
+ {
+ case clause_part::column:
+ {
+ if (last != ' ' && last != '(')
+ r += ' ';
+
+ if (i->part[0] == '.')
+ r += table;
+
+ r += i->part;
+ break;
+ }
+ case clause_part::param:
+ {
+ if (last != ' ' && last != '(')
+ r += ' ';
+
+ ostringstream os;
+ os << param++;
+ r += '$';
+ r += os.str ();
+ break;
+ }
+ case clause_part::native:
+ {
+ // We don't want extra spaces after '(' as well as before ','
+ // and ')'.
+ //
+ const string& p (i->part);
+ char first (!p.empty () ? p[0] : ' ');
+
+ if (last != ' ' && last != '(' &&
+ first != ' ' && first != ',' && first != ')')
+ r += ' ';
+
+ r += p;
+ break;
+ }
+ }
+ }
+
+ 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 " + clause_;
+ return "WHERE " + r;
}
}
}