From 4eb0df751704345ec8744fe012e64064d5cdb754 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 8 Oct 2012 16:09:08 +0200 Subject: Ground work for multi-database support All generated code now includes database id. The database-specific database class interface has been updated to include all the database operations. The database-specific tests now use this interface. --- odb/relational/header.cxx | 319 ++++++++++++++++++++++++++++------------------ 1 file changed, 195 insertions(+), 124 deletions(-) (limited to 'odb/relational/header.cxx') diff --git a/odb/relational/header.cxx b/odb/relational/header.cxx index 538962b..41b4960 100644 --- a/odb/relational/header.cxx +++ b/odb/relational/header.cxx @@ -41,23 +41,6 @@ traverse_object (type& c) << "static const class_kind kind = class_object;" << "};"; - // pointer_query_columns & query_columns - // - if (options.generate_query ()) - { - // If we don't have object pointers, then also generate - // query_columns (in this case pointer_query_columns and - // query_columns are the same and the former inherits from - // the latter). Otherwise we have to postpone query_columns - // generation until the second pass to deal with forward- - // declared objects. - // - if (!has_a (c, test_pointer | include_base)) - query_columns_type_->traverse (c); - - pointer_query_columns_type_->traverse (c); - } - // object_traits // os << "template <>" << endl @@ -65,8 +48,6 @@ traverse_object (type& c) << "{" << "public:" << endl; - object_public_extra_pre (c); - // object_type & pointer_type // os << "typedef " << type << " object_type;" @@ -76,31 +57,30 @@ traverse_object (type& c) // polymorphic, root_type, base_type, etc. // - os << "static const bool polymorphic = " << (poly ? "true" : "false") << ";"; + os << "static const bool polymorphic = " << (poly ? "true" : "false") << ";" + << endl; if (poly) { - os << "typedef " << class_fq_name (*poly_root) << " root_type;" - << "typedef object_traits root_traits;"; + os << "typedef " << class_fq_name (*poly_root) << " root_type;"; if (poly_derived) { os << "typedef " << class_fq_name (*poly_base) << " base_type;" - << "typedef object_traits base_traits;" - << "typedef root_traits::discriminator_type discriminator_type;" - << "typedef odb::polymorphic_concrete_info info_type;"; + << "typedef object_traits::discriminator_type " << + "discriminator_type;" + << "typedef polymorphic_concrete_info info_type;"; if (abst) - os << "typedef odb::polymorphic_abstract_info " << + os << "typedef polymorphic_abstract_info " << "abstract_info_type;"; - else - os << "typedef odb::polymorphic_entry entry_type;"; // Calculate our hierarchy depth (number of classes). // size_t depth (polymorphic_depth (c)); - os << "static const std::size_t depth = " << depth << "UL;"; + os << endl + << "static const std::size_t depth = " << depth << "UL;"; } else { @@ -108,35 +88,21 @@ traverse_object (type& c) semantics::type& t (utype (*discriminator, hint)); os << "typedef " << t.fq_name (hint) << " discriminator_type;" - << endl; - - os << "struct discriminator_image_type" - << "{"; - - discriminator_image_member_->traverse (*discriminator); - - if (optimistic != 0) - version_image_member_->traverse (*optimistic); - - os << "std::size_t version;" - << "};"; - - os << "typedef odb::polymorphic_map map_type;" - << "typedef odb::polymorphic_concrete_info info_type;"; + << "typedef polymorphic_map map_type;" + << "typedef polymorphic_concrete_info info_type;"; if (abst) - os << "typedef odb::polymorphic_abstract_info " << + os << "typedef polymorphic_abstract_info " << "abstract_info_type;"; - else - os << "typedef odb::polymorphic_entry entry_type;"; - os << "static const std::size_t depth = 1UL;"; + os << endl + << "static const std::size_t depth = 1UL;"; } - } - os << endl; + os << endl; + } - // id_type & id_image_type + // id_type, version_type, etc. // if (id != 0) { @@ -152,17 +118,13 @@ traverse_object (type& c) os << "typedef object_traits< " << type << " >::version_type " << "version_type;"; + os << endl; + if (poly_derived) - os << "typedef object_traits< " << type << " >:: id_image_type " << - "id_image_type;" - << "static const bool auto_id = false;" - << endl; + os << "static const bool auto_id = false;"; else - os << "typedef object_traits< " << type << " >::id_image_type " << - "id_image_type;" - << "static const bool auto_id = object_traits< " << type << - " >::auto_id;" - << endl; + os << "static const bool auto_id = object_traits< " << type << + " >::auto_id;"; } else { @@ -179,26 +141,18 @@ traverse_object (type& c) os << "typedef " << t.fq_name (hint) << " version_type;"; } - os << "static const bool auto_id = " << (auto_id ? "true;" : "false;") - << endl; - - os << "struct id_image_type" - << "{"; - - id_image_member_->traverse (*id); - - if (optimistic != 0) - version_image_member_->traverse (*optimistic); - - os << "std::size_t version;" - << "};"; + os << endl + << "static const bool auto_id = " << (auto_id ? "true;" : "false;"); } + + os << endl; } else if (!reuse_abst) { // Object without id. // os << "typedef void id_type;" + << endl << "static const bool auto_id = false;" << endl; } @@ -208,6 +162,157 @@ traverse_object (type& c) os << "static const bool abstract = " << (abst ? "true" : "false") << ";" << endl; + // id () + // + if (id != 0 || !reuse_abst) + { + // We want to generate a dummy void id() accessor even if this + // object has no id to help us in the runtime. This way we can + // write generic code that will work for both void and non-void + // ids. + // + os << "static id_type" << endl + << "id (const object_type&);" + << endl; + } + + if (!reuse_abst) + { + // Cache traits typedefs. + // + if (id == 0) + { + os << "typedef" << endl + << "no_id_pointer_cache_traits" << endl + << "pointer_cache_traits;" + << endl + << "typedef" << endl + << "no_id_reference_cache_traits" << endl + << "reference_cache_traits;" + << endl; + } + else + { + char const* p (session (c) ? "odb::" : "no_op_"); + + if (poly_derived) + { + os << "typedef" << endl + << p << "pointer_cache_traits<" << + "object_traits::pointer_type>" << endl + << "pointer_cache_traits;" + << endl + << "typedef" << endl + << p << "reference_cache_traits" << endl + << "reference_cache_traits;" + << endl; + } + else + { + os << "typedef" << endl + << p << "pointer_cache_traits" << endl + << "pointer_cache_traits;" + << endl + << "typedef" << endl + << p << "reference_cache_traits" << endl + << "reference_cache_traits;" + << endl; + } + } + } + + os << "};"; + + // pointer_query_columns & query_columns + // + if (options.generate_query ()) + { + // If we don't have object pointers, then also generate + // query_columns (in this case pointer_query_columns and + // query_columns are the same and the former inherits from + // the latter). Otherwise we have to postpone query_columns + // generation until the second pass to deal with forward- + // declared objects. + // + if (!has_a (c, test_pointer | include_base)) + query_columns_type_->traverse (c); + + pointer_query_columns_type_->traverse (c); + } + + // object_traits_impl + // + os << "template <>" << endl + << "class access::object_traits_impl< " << type << ", id_" << db << + " >:" << endl + << " public access::object_traits< " << type << " >" + << "{" + << "public:" << endl; + + object_public_extra_pre (c); + + // Polymorphic root_traits, base_traits, and discriminator_image_type. + // + if (poly) + { + if (!abst) + os << "typedef polymorphic_entry entry_type;"; + + os << "typedef object_traits_impl " << + "root_traits;"; + + if (poly_derived) + { + os << "typedef object_traits_impl " << + "base_traits;" + << endl; + } + else + { + os << endl + << "struct discriminator_image_type" + << "{"; + + discriminator_image_member_->traverse (*discriminator); + + if (optimistic != 0) + version_image_member_->traverse (*optimistic); + + os << "std::size_t version;" + << "};"; + } + } + + // id_image_type + // + if (id != 0) + { + if (base_id) + { + semantics::class_& b ( + dynamic_cast (id->scope ())); + string const& type (); + + os << "typedef object_traits_impl< " << class_fq_name (b) << ", " << + "id_" << db << " >::id_image_type id_image_type;" + << endl; + } + else + { + os << "struct id_image_type" + << "{"; + + id_image_member_->traverse (*id); + + if (optimistic != 0) + version_image_member_->traverse (*optimistic); + + os << "std::size_t version;" + << "};"; + } + } + // Polymorphic map. // if (poly) @@ -236,19 +341,9 @@ traverse_object (type& c) // Functions (abstract and concrete). // - // id () - // if (id != 0 || !reuse_abst) - { - // We want to generate a dummy void id() accessor even if this - // object has no id to help us in the runtime. This way we can - // write generic code that will work for both void and non-void - // ids. - // - os << "static id_type" << endl - << "id (const object_type&);" + os << "using object_traits::id;" << endl; - } if (!poly_derived && id != 0) { @@ -370,45 +465,6 @@ traverse_object (type& c) return; } - // Cache traits typedefs. - // - if (id == 0) - { - os << "typedef" << endl - << "odb::no_id_pointer_cache_traits" << endl - << "pointer_cache_traits;" - << "typedef" << endl - << "odb::no_id_reference_cache_traits" << endl - << "reference_cache_traits;" - << endl; - } - else - { - char const* p (session (c) ? "" : "no_op_"); - - if (poly_derived) - { - os << "typedef" << endl - << "odb::" << p << "pointer_cache_traits<" << - "root_traits::pointer_type>" << endl - << "pointer_cache_traits;" - << "typedef" << endl - << "odb::" << p << "reference_cache_traits" << endl - << "reference_cache_traits;" - << endl; - } - else - { - os << "typedef" << endl - << "odb::" << p << "pointer_cache_traits" << endl - << "pointer_cache_traits;" - << "typedef" << endl - << "odb::" << p << "reference_cache_traits" << endl - << "reference_cache_traits;" - << endl; - } - } - // Statements typedefs. // if (poly) @@ -418,6 +474,7 @@ traverse_object (type& c) << db << "::polymorphic_derived_object_statements" << "" << endl << "statements_type;" + << endl << "typedef" << endl << db << "::polymorphic_root_object_statements" << endl << "root_statements_type;" @@ -426,6 +483,7 @@ traverse_object (type& c) os << "typedef" << endl << db << "::polymorphic_root_object_statements" << endl << "statements_type;" + << endl << "typedef statements_type root_statements_type;" << "typedef " << db << "::object_statements " << "base_statements_type;" @@ -451,7 +509,7 @@ traverse_object (type& c) { // query_base_type // - os << "typedef " << db << "::query query_base_type;" + os << "typedef " << db << "::query_base query_base_type;" << endl; } @@ -736,6 +794,19 @@ traverse_object (type& c) } os << "};"; + + + // object_traits_impl< , id_default> + // + // Note that it is not generated for reuse-abstract classes. + // + os << "template <>" << endl + << "class access::object_traits_impl< " << type << ", " << + "id_default >:" << endl + << " public access::object_traits_impl< " << type << ", " << + "id_" << db << " >" + << "{" + << "};"; } void relational::header:: -- cgit v1.1