diff options
Diffstat (limited to 'odb/relational/source.hxx')
-rw-r--r-- | odb/relational/source.hxx | 181 |
1 files changed, 62 insertions, 119 deletions
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx index a3ef5de..f83ad24 100644 --- a/odb/relational/source.hxx +++ b/odb/relational/source.hxx @@ -91,7 +91,8 @@ namespace relational if (container_wrapper (im->type ())) { // This container is a direct member of the class so the table - // prefix is just the class table name. + // prefix is just the class table name. We don't assign join + // aliases for container tables so use the actual table name. // column ( *im, "id", @@ -104,8 +105,12 @@ namespace relational else { semantics::data_member& id (*id_member (*c)); + + // Use the join alias (column name) instead of the actual + // table name unless we are handling a container. + // column (id, "", - table_name_.empty () ? table_name_ : table_qname (*c), + table_name_.empty () ? table_name_ : quote_id (name), column_qname (id)); } } @@ -162,7 +167,7 @@ namespace relational { typedef object_joins base; - //@@ context::{cur,top}_object Might have to be created every time. + //@@ context::{cur,top}_object; might have to be created every time. // object_joins (semantics::class_& scope, bool query) : query_ (query), @@ -188,38 +193,25 @@ namespace relational string line (" LEFT JOIN "); line += i->table; - // If this is a self-join, alias it as '_' to resolve any - // ambiguities. - // - if (i->table == table_) - line += " AS _"; + if (!i->alias.empty ()) + line += " AS " + i->alias; line += " ON "; - - for (conditions::iterator b (i->cond.begin ()), j (b); - j != i->cond.end (); ++j) - { - if (j != b) - line += " OR "; - - line += *j; - } + line += i->cond; os << strlit (line) << endl; } } virtual bool - traverse_column (semantics::data_member& m, - string const& col_name, - bool) + traverse_column (semantics::data_member& m, string const& column, bool) { semantics::class_* c (object_pointer (m.type ())); if (c == 0) - return true; + return false; - string t, dt; + string t, a, dt, da; std::ostringstream cond, dcond; // @@ diversion? if (semantics::data_member* im = inverse (m)) @@ -243,33 +235,20 @@ namespace relational if (query_) { dt = quote_id (ct); - string const& id (column_qname (*im, "id", "object_id")); + da = quote_id (column); - // If this is a self-join, use the '_' alias instead of the - // table name. - // - if (dt == table_) - dcond << "_"; - else - dcond << dt; + string const& id (column_qname (*im, "id", "object_id")); - dcond << '.' << column_qname (*id_member (*c)) << " = " << + dcond << da << '.' << column_qname (*id_member (*c)) << " = " << t << '.' << id; } } else { t = table_qname (*c); + a = quote_id (column); - // If this is a self-join, use the '_' alias instead of the - // table name. - // - if (t == table_) - cond << "_"; - else - cond << t; - - cond << '.' << column_qname (*im) << " = " << + cond << a << '.' << column_qname (*im) << " = " << table_ << "." << column_qname (id_); } } @@ -279,61 +258,29 @@ namespace relational // in the WHERE clause. // t = table_qname (*c); + a = quote_id (column); - // If this is a self-join, use the '_' alias instead of the - // table name. - // - if (t == table_) - cond << "_"; - else - cond << t; - - cond << '.' << column_qname (*id_member (*c)) << " = " << - table_ << "." << quote_id (col_name); + cond << a << '.' << column_qname (*id_member (*c)) << " = " << + table_ << "." << quote_id (column); } if (!t.empty ()) { - size_t i; - table_map::iterator it (table_map_.find (t)); - - if (it != table_map_.end ()) - i = it->second; - else - { - i = joins_.size (); - joins_.push_back (join ()); - table_map_[t] = i; - } - - joins_[i].table = t; - joins_[i].cond.insert (cond.str ()); + joins_.push_back (join ()); + joins_.back ().table = t; + joins_.back ().alias = a; + joins_.back ().cond = cond.str (); } + // Add dependent join (i.e., an object table join via the + // container table). + // if (!dt.empty ()) { - // Add dependent join. If one already exists, move it to the - // bottom. - // - size_t i; - table_map::iterator it (table_map_.find (dt)); - - if (it != table_map_.end ()) - { - i = joins_.size (); - joins_.push_back (join ()); - joins_[it->second].swap (joins_.back ()); - it->second = i; - } - else - { - i = joins_.size (); - joins_.push_back (join ()); - table_map_[dt] = i; - } - - joins_[i].table = dt; - joins_[i].cond.insert (dcond.str ()); + joins_.push_back (join ()); + joins_.back ().table = dt; + joins_.back ().alias = da; + joins_.back ().cond = dcond.str (); } return true; @@ -341,29 +288,19 @@ namespace relational private: bool query_; - string table_; //@@ No longer used because of the _ alias. + string table_; semantics::data_member& id_; - typedef std::set<string> conditions; - struct join { string table; - conditions cond; - - void - swap (join& o) - { - table.swap (o.table); - cond.swap (o.cond); - } + string alias; + string cond; }; typedef std::vector<join> joins; - typedef std::map<string, size_t> table_map; joins joins_; - table_map table_map_; }; // @@ -715,8 +652,8 @@ namespace relational // select_all_statement // - os << "const char* const " << scope << - "::select_all_statement =" << endl; + os << "const char " << scope << + "::select_all_statement[] =" << endl; if (inverse) { @@ -830,8 +767,8 @@ namespace relational // insert_one_statement // - os << "const char* const " << scope << - "::insert_one_statement =" << endl; + os << "const char " << scope << + "::insert_one_statement[] =" << endl; if (inverse) os << strlit ("") << ";" @@ -901,8 +838,8 @@ namespace relational // delete_all_statement // - os << "const char* const " << scope << - "::delete_all_statement =" << endl; + os << "const char " << scope << + "::delete_all_statement[] =" << endl; if (inverse) os << strlit ("") << ";" @@ -1935,7 +1872,7 @@ namespace relational object_query_statement_ctor_args (type&) { os << "sts.connection ()," << endl - << "query_clause + q.clause (table_name)," << endl + << "query_clause + q.clause ()," << endl << "q.parameters_binding ()," << endl << "imb"; } @@ -1944,7 +1881,7 @@ namespace relational object_erase_query_statement_ctor_args (type&) { os << "conn," << endl - << "erase_query_clause + q.clause (table_name)," << endl + << "erase_query_clause + q.clause ()," << endl << "q.parameters_binding ()"; } @@ -1956,6 +1893,7 @@ namespace relational string traits ("access::object_traits< " + type + " >"); bool grow (context::grow (c)); + bool has_ptr (has_a (c, test_pointer)); semantics::data_member* id (id_member (c)); bool auto_id (id ? id->count ("auto") : false); @@ -1974,8 +1912,13 @@ namespace relational if (options.generate_query ()) { - instance<query_columns> t (c); - t->traverse (c); + // query_columns_base + // + if (has_ptr) + { + instance<query_columns_base> t (c); + t->traverse (c); + } } // @@ -2147,7 +2090,7 @@ namespace relational // persist_statement // { - os << "const char* const " << traits << "::persist_statement " << + os << "const char " << traits << "::persist_statement[] " << "=" << endl << strlit ("INSERT INTO " + table + " (") << endl; @@ -2165,7 +2108,7 @@ namespace relational // find_statement // { - os << "const char* const " << traits << "::find_statement =" << endl + os << "const char " << traits << "::find_statement[] =" << endl << strlit ("SELECT ") << endl; instance<object_columns> t (table, true); @@ -2187,7 +2130,7 @@ namespace relational // update_statement // { - os << "const char* const " << traits << "::update_statement " << + os << "const char " << traits << "::update_statement[] " << "=" << endl << strlit ("UPDATE " + table + " SET ") << endl; @@ -2203,7 +2146,7 @@ namespace relational // { instance<query_parameters> qp; - os << "const char* const " << traits << "::erase_statement =" << endl + os << "const char " << traits << "::erase_statement[] =" << endl << strlit ("DELETE FROM " + table) << endl << strlit (" WHERE " + id_col + "=" + qp->next ()) << ";" << endl; @@ -2220,7 +2163,7 @@ namespace relational // We only need DISTINCT if there are joins (object pointers) // and can optimize it out otherwise. // - os << "const char* const " << traits << "::query_clause =" << endl + os << "const char " << traits << "::query_clause[] =" << endl << strlit (oj->count () ? "SELECT DISTINCT " : "SELECT ") << endl; { @@ -2235,7 +2178,7 @@ namespace relational // erase_query_clause // - os << "const char* const " << traits << "::erase_query_clause =" << endl + os << "const char " << traits << "::erase_query_clause[] =" << endl << strlit ("DELETE FROM " + table) << endl; // DELETE JOIN: @@ -2251,8 +2194,8 @@ namespace relational // table_name // - os << "const char* const " << traits << "::table_name =" << endl - << strlit (table) << ";" + os << "const char " << traits << "::table_name[] =" << endl + << strlit (table_name (c)) << ";" // Use unquoted name. << endl; } @@ -2849,7 +2792,7 @@ namespace relational view_query_statement_ctor_args (type&) { os << "sts.connection ()," << endl - << "query_statement + q.clause (\"\")," << endl + << "query_statement + q.clause ()," << endl << "q.parameters_binding ()," << endl << "imb"; } @@ -2917,7 +2860,7 @@ namespace relational // query_statement // - os << "const char* const " << traits << "::query_statement =" << endl + os << "const char " << traits << "::query_statement[] =" << endl << strlit (c.get<string> ("query")) << endl << strlit (" ") << ";" << endl << endl; |