diff options
Diffstat (limited to 'odb/relational/common.cxx')
-rw-r--r-- | odb/relational/common.cxx | 205 |
1 files changed, 101 insertions, 104 deletions
diff --git a/odb/relational/common.cxx b/odb/relational/common.cxx index e9b3485..b8d2c60 100644 --- a/odb/relational/common.cxx +++ b/odb/relational/common.cxx @@ -17,6 +17,15 @@ namespace relational // query_alias_traits // + query_alias_traits:: + query_alias_traits (semantics::class_& c, bool decl) + : decl_ (decl) + { + scope_ = "access::"; + scope_ += (object (c) ? "object_traits_impl" : "view_traits_impl"); + scope_ += "< " + class_fq_name (c) + ", id_" + db.string () + " >"; + } + void query_alias_traits:: traverse_object (semantics::class_& c) { @@ -26,101 +35,110 @@ namespace relational } void query_alias_traits:: - traverse_pointer (semantics::data_member& m, semantics::class_& c) + traverse_composite (semantics::data_member* m, semantics::class_& c) { - // Ignore polymorphic id references. - // - if (m.count ("polymorphic-ref")) - return; - - // Come up with a table alias. Generally, we want it to be based - // on the column name. This is straightforward for single-column - // references. In case of a composite id, we will need to use the - // column prefix which is based on the data member name, unless - // overridden by the user. In the latter case the prefix can be - // empty, in which case we will just fall back on the member's - // public name. + // Base type. // - string alias; + if (m == 0) { - string n; - - if (composite_wrapper (utype (*id_member (c)))) - { - n = column_prefix (m, key_prefix_, default_name_); + object_columns_base::traverse_composite (m, c); + return; + } - if (n.empty ()) - n = public_name_db (m); - else - n.resize (n.size () - 1); // Remove trailing underscore. - } - else - n = column_name (m, key_prefix_, default_name_); + string old_scope (scope_); + scope_ += "::" + public_name (*m) + "_tag"; - alias = compose_name (column_prefix_, n); - } + object_columns_base::traverse_composite (m, c); - generate (alias, c); + scope_ = old_scope; } void query_alias_traits:: - generate (string const& alias, semantics::class_& c) + traverse_pointer (semantics::data_member& m, semantics::class_& c) { - string tag (escape (alias + "_alias_tag")); + // Ignore polymorphic id references. + // + if (m.count ("polymorphic-ref")) + return; - if (tags_.find (tag) == tags_.end ()) + if (decl_) + generate_decl (public_name (m), c); + else { - os << "class " << tag << ";" - << endl; + // Come up with a table alias. Generally, we want it to be based + // on the column name. This is straightforward for single-column + // references. In case of a composite id, we will need to use the + // column prefix which is based on the data member name, unless + // overridden by the user. In the latter case the prefix can be + // empty, in which case we will just fall back on the member's + // public name. + // + string alias; + { + string n; - tags_.insert (tag); - } + if (composite_wrapper (utype (*id_member (c)))) + { + n = column_prefix (m, key_prefix_, default_name_); - // Generate the alias_traits specialization. - // - generate_specialization (alias, tag, c); + if (n.empty ()) + n = public_name_db (m); + else + n.resize (n.size () - 1); // Remove trailing underscore. + } + else + n = column_name (m, key_prefix_, default_name_); + + alias = compose_name (column_prefix_, n); + } + + generate_def (public_name (m), c, alias); + } } void query_alias_traits:: - generate_specialization (string const& alias, - string const& tag, - semantics::class_& c) + generate_decl (string const& tag, semantics::class_& c) { - string const& fq_name (class_fq_name (c)); - string guard ( - make_guard ("ODB_" + string (db.string ()) + "_ALIAS_TRAITS_" + - alias + "_FOR_" + flat_name (fq_name))); - - if (specs_.find (guard) != specs_.end ()) - return; - else - specs_.insert (guard); - semantics::class_* poly_root (polymorphic (c)); bool poly_derived (poly_root != 0 && poly_root != &c); semantics::class_* poly_base (poly_derived ? &polymorphic_base (c) : 0); if (poly_derived) - generate_specialization (alias, tag, *poly_base); - - os << "#ifndef " << guard << endl - << "#define " << guard << endl; + generate_decl (tag, *poly_base); - os << "template <bool d>" << endl - << "struct alias_traits< " << fq_name << ", id_" << db << ", " << - tag << ", d >" + os << "template <>" << endl + << "struct alias_traits<" << endl + << " " << class_fq_name (c) << "," << endl + << " id_" << db << "," << endl + << " " << scope_ << "::" << tag << "_tag>" << "{" << "static const char table_name[];"; if (poly_derived) - os << "typedef alias_traits< " << class_fq_name (*poly_base) << ", " << - "id_" << db << ", " << tag << " > base_traits;"; + os << endl + << "typedef alias_traits<" << endl + << " " << class_fq_name (*poly_base) << "," << endl + << " id_" << db << "," << endl + << " " << scope_ << "::" << tag << "_tag>" << endl + << "base_traits;"; os << "};"; + } + + void query_alias_traits:: + generate_def (string const& tag, semantics::class_& c, string const& alias) + { + semantics::class_* poly_root (polymorphic (c)); + bool poly_derived (poly_root != 0 && poly_root != &c); + semantics::class_* poly_base (poly_derived ? &polymorphic_base (c) : 0); - os << "template <bool d>" << endl - << "const char alias_traits< " << fq_name << ", id_" << db << ", " << - tag << ", d >::" << endl + if (poly_derived) + generate_def (tag, *poly_base, alias); + + os << "const char alias_traits<" + << " " << class_fq_name (c) << "," << endl + << " id_" << db << "," << endl + << " " << scope_ << "::" << tag << "_tag>::" << endl << "table_name[] = "; if (poly_root != 0) @@ -129,25 +147,22 @@ namespace relational os << strlit (quote_id (alias)); os << ";" - << "#endif // " << guard << endl << endl; } - // query_columns_base // query_columns_base:: - query_columns_base () - : decl_ (true) + query_columns_base (semantics::class_& c, bool decl) + : decl_ (decl) { - } + string const& n (class_fq_name (c)); - query_columns_base:: - query_columns_base (semantics::class_& c) //@@ context::{cur,top}_object - : decl_ (false) - { - scope_ = "query_columns_base< " + class_fq_name (c) + ", id_" + + if (!decl) + scope_ = "query_columns_base< " + n + ", id_" + db.string () + " >"; + + tag_scope_ = "access::object_traits_impl< " + n + ", id_" + db.string () + " >"; } @@ -184,17 +199,25 @@ namespace relational << "struct " << name << "_base_" << "{"; + string old_tag_scope (tag_scope_); + tag_scope_ += "::" + name + "_tag"; + object_columns_base::traverse_composite (m, c); + tag_scope_ = old_tag_scope; + os << "};"; } else { string old_scope (scope_); + string old_tag_scope (tag_scope_); scope_ += "::" + name + "_base_"; + tag_scope_ += "::" + name + "_tag"; object_columns_base::traverse_composite (m, c); + tag_scope_ = old_tag_scope; scope_ = old_scope; } } @@ -215,39 +238,13 @@ namespace relational os << "// " << name << endl << "//" << endl; - // Come up with a table alias. Generally, we want it to be based - // on the column name. This is straightforward for single-column - // references. In case of a composite id, we will need to use the - // column prefix which is based on the data member name, unless - // overridden by the user. In the latter case the prefix can be - // empty, in which case we will just fall back on the member's - // public name. - // - string alias; - { - string n; - - if (composite_wrapper (utype (*id_member (c)))) - { - n = column_prefix (m, key_prefix_, default_name_); - - if (n.empty ()) - n = public_name_db (m); - else - n.resize (n.size () - 1); // Remove trailing underscore. - } - else - n = column_name (m, key_prefix_, default_name_); - - alias = compose_name (column_prefix_, n); - } - - string tag (escape (alias + "_alias_tag")); string const& fq_name (class_fq_name (c)); os << "typedef" << endl - << "odb::alias_traits< " << fq_name << ", id_" << db << ", " << - tag << " >" << endl + << "odb::alias_traits<" << endl + << " " << fq_name << "," << endl + << " id_" << db << "," << endl + << " " << tag_scope_ << "::" << name << "_tag>" << endl << name << "_alias_;" << endl; |