From 47d344f31f7a1a980d807c142e0a36b09db3b1f3 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 19 Aug 2011 14:08:16 +0200 Subject: Rework query machinery not to use '_' as primary table alias Now we always qualify with the actual table name and use the '_' alias for situations where an object is referencing itself. --- odb/mysql/query.cxx | 104 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 82 insertions(+), 22 deletions(-) (limited to 'odb/mysql/query.cxx') diff --git a/odb/mysql/query.cxx b/odb/mysql/query.cxx index e5c1705..ca858b1 100644 --- a/odb/mysql/query.cxx +++ b/odb/mysql/query.cxx @@ -63,15 +63,9 @@ namespace odb query& query:: operator+= (const query& q) { - size_t n (clause_.size ()); + clause_.insert (clause_.end (), q.clause_.begin (), q.clause_.end ()); - if (n != 0 && clause_[n - 1] != ' ' && - !q.clause_.empty () && q.clause_[0] != ' ') - clause_ += ' '; - - clause_ += q.clause_; - - n = bind_.size (); + size_t n (bind_.size ()); parameters_.insert ( parameters_.end (), q.parameters_.begin (), q.parameters_.end ()); @@ -90,14 +84,34 @@ namespace odb } void query:: - add (details::shared_ptr 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] : ' '); - clause_ += '?'; + // We don't want extra spaces after '(' as well as before ',' + // and ')'. + // + if (last != ' ' && last != '(' && + first != ' ' && first != ',' && first != ')') + s += ' '; + + s += q; + } + else + clause_.push_back (clause_part (k, q)); + } + + void query:: + add (details::shared_ptr p) + { + clause_.push_back (clause_part (clause_part::param)); parameters_.push_back (p); bind_.push_back (MYSQL_BIND ()); @@ -142,17 +156,63 @@ namespace odb return r; } - 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; + + 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 += ' '; + + r += '?'; + 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; } } } -- cgit v1.1