diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2011-04-25 15:02:43 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2011-04-25 15:02:43 +0200 |
commit | 1a6a0652a6ef5b319cfc8ad05a0acee6910f7560 (patch) | |
tree | 40605db91ed90c342a9074308bd7406008b4f10b /odb/relational/source.hxx | |
parent | 9c5b2f928699a6752d7c3d1a062bac7efc247c64 (diff) |
Add support for abstract object types
Diffstat (limited to 'odb/relational/source.hxx')
-rw-r--r-- | odb/relational/source.hxx | 283 |
1 files changed, 150 insertions, 133 deletions
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx index 5b2ec8d..9a23ca4 100644 --- a/odb/relational/source.hxx +++ b/odb/relational/source.hxx @@ -111,7 +111,7 @@ namespace relational } else { - semantics::data_member& id (id_member (*c)); + semantics::data_member& id (*id_member (*c)); column (id, "", table_name_.empty () ? table_name_ : table_qname (*c), column_qname (id)); @@ -172,7 +172,7 @@ namespace relational object_joins (semantics::class_& scope, bool query) : query_ (query), table_ (table_qname (scope)), - id_ (id_member (scope)) + id_ (*id_member (scope)) { } @@ -240,7 +240,7 @@ namespace relational dt = ct; string const& id (column_qname (*im, "id", "object_id")); - dcond << dt << '.' << column_qname (id_member (*c)) << " = " << + dcond << dt << '.' << column_qname (*id_member (*c)) << " = " << t << '.' << id; } } @@ -259,7 +259,7 @@ namespace relational // t = table_qname (*c); - cond << t << '.' << column_qname (id_member (*c)) << " = _." << + cond << t << '.' << column_qname (*id_member (*c)) << " = _." << quote_id (col_name); } @@ -703,7 +703,7 @@ namespace relational // many(i)-to-one // inv_table = table_qname (*c); - inv_id = column_qname (id_member (*c)); + inv_id = column_qname (*id_member (*c)); inv_fid = column_qname (*im); } @@ -873,8 +873,6 @@ namespace relational // bind() // { - instance<bind_member> bind_id ("id_", "id"); - // bind (cond_image_type) // os << "void " << scope << "::" << endl @@ -1795,160 +1793,57 @@ namespace relational virtual void traverse_object (type& c) { + bool abst (abstract (c)); string const& type (c.fq_name ()); string traits ("access::object_traits< " + type + " >"); bool grow (context::grow (c)); - semantics::data_member& id (id_member (c)); - bool auto_id (id.count ("auto")); - bool grow_id (context::grow (id)); - bool base_id (&id.scope () != &c); // Id comes from a base class. + semantics::data_member* id (id_member (c)); + bool auto_id (id ? id->count ("auto") : false); + bool grow_id (id ? context::grow (*id) : false); + bool base_id (id ? &id->scope () != &c : false); // Comes from base. os << "// " << c.name () << endl << "//" << endl << endl; // - // Containers. - // - bool straight_containers (has_a (c, test_straight_container)); - bool containers (straight_containers || has_a (c, test_container)); - - // Statement cache (definition). + // Query. // - { - os << "struct " << traits << "::container_statement_cache_type" - << "{"; - - instance<container_cache_members> cm; - cm->traverse (c); - - os << (containers ? "\n" : "") - << "container_statement_cache_type (" << db << "::connection&" << - (containers ? " c" : "") << ")"; - - instance<container_cache_init_members> im; - im->traverse (c); - - os << "{" - << "}" - << "};"; - } - - // Traits types. - // - if (containers) - { - instance<container_traits> t (c); - t->traverse (c); - } - // query columns - // if (options.generate_query ()) { instance<query_columns> t (c); t->traverse (c); } - string const& table (table_qname (c)); - string const& id_col (column_qname (id)); - - // persist_statement // - os << "const char* const " << traits << "::persist_statement =" << endl - << strlit ("INSERT INTO " + table + " (") << endl; - - { - instance<object_columns> t (false); - t->traverse (c); - } - - string values; - for (size_t i (0), n (in_column_count (c)); i < n; ++i) - values += i != 0 ? ",?" : "?"; - - os << strlit (") VALUES (" + values + ")") << ";" - << endl; - - // find_statement - // - os << "const char* const " << traits << "::find_statement =" << endl - << strlit ("SELECT ") << endl; - - { - instance<object_columns> t (table, true); - t->traverse (c); - } - - os << strlit (" FROM " + table + " AS _") << endl; - - { - bool f (false); - instance<object_joins> t (c, f); // @@ (im)perfect forwarding - t->traverse (c); - t->write (); - } - - os << strlit (" WHERE _." + id_col + " = ?") << ";" - << endl; - - // update_statement + // Containers (abstract and concrete). // - os << "const char* const " << traits << "::update_statement =" << endl - << strlit ("UPDATE " + table + " SET ") << endl; + bool straight_containers (has_a (c, test_straight_container)); + bool containers (straight_containers || has_a (c, test_container)); + if (containers) { - instance<object_columns> t (false, true, " = ?"); + instance<container_traits> t (c); t->traverse (c); } - os << strlit (" WHERE " + id_col + " = ?") << ";" - << endl; - - // erase_statement // - os << "const char* const " << traits << "::erase_statement =" << endl - << strlit ("DELETE FROM " + table) << endl - << strlit (" WHERE " + id_col + " = ?") << ";" - << endl; - - // query_clause + // Functions (abstract and concrete). // - if (options.generate_query ()) - { - bool t (true); - instance<object_joins> oj (c, t); //@@ (im)perfect forwarding - oj->traverse (c); - - // We only need DISTINCT if there are joins (object pointers) - // and can optimize it out otherwise. - // - os << "const char* const " << traits << "::query_clause =" << endl - << strlit (oj->count () ? "SELECT DISTINCT " : "SELECT ") << endl; - - { - instance<object_columns> oc (table, true); - oc->traverse (c); - } - - os << strlit (" FROM " + table + " AS _") << endl; - oj->write (); - os << strlit (" ") << ";" - << endl; - } // id (image_type) // - if (options.generate_query () && !base_id) + if (id != 0 && options.generate_query () && !base_id) { os << traits << "::id_type" << endl << traits << "::" << endl << "id (const image_type& i)" << "{" << "id_type id;"; - init_id_value_member_->traverse (id); + init_id_value_member_->traverse (*id); os << "return id;" << "}"; } @@ -1988,13 +1883,13 @@ namespace relational // bind (id_image_type) // - if (!base_id) + if (id != 0 && !base_id) { os << "void " << traits << "::" << endl << "bind (" << bind_vector << " b, id_image_type& i)" << "{" << "std::size_t n (0);"; - bind_id_member_->traverse (id); + bind_id_member_->traverse (*id); os << "}"; } @@ -2032,7 +1927,7 @@ namespace relational // init (id_image, id) // - if (!base_id) + if (id != 0 && !base_id) { os << "void " << traits << "::" << endl << "init (id_image_type& i, const id_type& id)" @@ -2041,7 +1936,7 @@ namespace relational if (grow_id) os << "bool grew (false);"; - init_id_image_member_->traverse (id); + init_id_image_member_->traverse (*id); if (grow_id) os << endl @@ -2051,6 +1946,128 @@ namespace relational os << "}"; } + // + // The rest only applies to concrete objects. + // + if (abst) + return; + + // + // Containers (concrete). + // + + // Statement cache (definition). + // + { + os << "struct " << traits << "::container_statement_cache_type" + << "{"; + + instance<container_cache_members> cm; + cm->traverse (c); + + os << (containers ? "\n" : "") + << "container_statement_cache_type (" << db << "::connection&" << + (containers ? " c" : "") << ")"; + + instance<container_cache_init_members> im; + im->traverse (c); + + os << "{" + << "}" + << "};"; + } + + // + // Statements. + // + + string const& table (table_qname (c)); + string const& id_col (column_qname (*id)); + + // persist_statement + // + os << "const char* const " << traits << "::persist_statement =" << endl + << strlit ("INSERT INTO " + table + " (") << endl; + + { + instance<object_columns> t (false); + t->traverse (c); + } + + string values; + for (size_t i (0), n (in_column_count (c)); i < n; ++i) + values += i != 0 ? ",?" : "?"; + + os << strlit (") VALUES (" + values + ")") << ";" + << endl; + + // find_statement + // + os << "const char* const " << traits << "::find_statement =" << endl + << strlit ("SELECT ") << endl; + + { + instance<object_columns> t (table, true); + t->traverse (c); + } + + os << strlit (" FROM " + table + " AS _") << endl; + + { + bool f (false); + instance<object_joins> t (c, f); // @@ (im)perfect forwarding + t->traverse (c); + t->write (); + } + + os << strlit (" WHERE _." + id_col + " = ?") << ";" + << endl; + + // update_statement + // + os << "const char* const " << traits << "::update_statement =" << endl + << strlit ("UPDATE " + table + " SET ") << endl; + + { + instance<object_columns> t (false, true, " = ?"); + t->traverse (c); + } + + os << strlit (" WHERE " + id_col + " = ?") << ";" + << endl; + + // erase_statement + // + os << "const char* const " << traits << "::erase_statement =" << endl + << strlit ("DELETE FROM " + table) << endl + << strlit (" WHERE " + id_col + " = ?") << ";" + << endl; + + // query_clause + // + if (options.generate_query ()) + { + bool t (true); + instance<object_joins> oj (c, t); //@@ (im)perfect forwarding + oj->traverse (c); + + // We only need DISTINCT if there are joins (object pointers) + // and can optimize it out otherwise. + // + os << "const char* const " << traits << "::query_clause =" << endl + << strlit (oj->count () ? "SELECT DISTINCT " : "SELECT ") << endl; + + { + instance<object_columns> oc (table, true); + oc->traverse (c); + } + + os << strlit (" FROM " + table + " AS _") << endl; + oj->write (); + os << strlit (" ") << ";" + << endl; + } + // persist () // os << "void " << traits << "::" << endl @@ -2072,9 +2089,9 @@ namespace relational if (auto_id) { - string const& n (id.name ()); + string const& n (id->name ()); string var ("im." + n + (n[n.size () - 1] == '_' ? "" : "_")); - init_auto_id (id, var); + init_auto_id (*id, var); os << endl; } @@ -2090,7 +2107,7 @@ namespace relational << endl; if (auto_id) - os << "obj." << id.name () << " = static_cast<id_type> (st.id ());" + os << "obj." << id->name () << " = static_cast<id_type> (st.id ());" << endl; if (straight_containers) @@ -2098,7 +2115,7 @@ namespace relational // Initialize id_image and binding. // os << "id_image_type& i (sts.id_image ());" - << "init (i, obj." << id.name () << ");" + << "init (i, obj." << id->name () << ");" << endl << "binding& idb (sts.id_image_binding ());" << "if (i.version != sts.id_image_version () || idb.version == 0)" @@ -2130,7 +2147,7 @@ namespace relational // Initialize id image. // os << "id_image_type& i (sts.id_image ());" - << "init (i, obj." << id.name () << ");" + << "init (i, obj." << id->name () << ");" << endl; os << "binding& idb (sts.id_image_binding ());" |