From 3a1eed21d4d5d0e7f6a9f400420fdc28d7be9b61 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 17 Feb 2012 10:08:18 +0200 Subject: Add support for composite object ids New pragma id_type (member). New test: common/composite-id. The composite example has also been updated. --- odb/common.cxx | 254 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 160 insertions(+), 94 deletions(-) (limited to 'odb/common.cxx') diff --git a/odb/common.cxx b/odb/common.cxx index 230e674..6261b85 100644 --- a/odb/common.cxx +++ b/odb/common.cxx @@ -16,6 +16,12 @@ traverse_simple (semantics::data_member&) } void object_members_base:: +traverse_pointer (semantics::data_member& m, semantics::class_& c) +{ + traverse_member (m, utype (*id_member (c))); +} + +void object_members_base:: traverse_composite (semantics::data_member*, semantics::class_& c) { inherits (c); @@ -51,26 +57,6 @@ traverse_view (semantics::class_& c) } void object_members_base:: -traverse (semantics::data_member& m, semantics::class_& c) -{ - // We are starting from the member. Add an empty chain which - // corresponds to the scope that contains this member. - // - //member_scope_.push_back (class_inheritance_chain ()); - //member_path_.push_back (&m); - - member_scope_.push_back (class_inheritance_chain ()); - member_scope_.back ().push_back (&c); - - traverse_composite_wrapper (&m, c, 0); - - member_scope_.pop_back (); - - //member_path_.pop_back (); - //member_scope_.pop_back (); -} - -void object_members_base:: traverse (semantics::class_& c) { class_kind_type k (class_kind (c)); @@ -156,68 +142,73 @@ traverse (semantics::class_& c) context::cur_object = prev; } -void object_members_base::member:: -traverse (semantics::data_member& m) +void object_members_base:: +traverse_member (semantics::data_member& m, semantics::type& t) { - if (transient (m)) - return; - - om_.member_path_.push_back (&m); - - semantics::type& t (utype (m)); - if (semantics::class_* comp = context::composite_wrapper (t)) { - om_.member_scope_.push_back (class_inheritance_chain ()); - om_.member_scope_.back ().push_back (comp); + member_scope_.push_back (class_inheritance_chain ()); + member_scope_.back ().push_back (comp); qname old_table_prefix; string old_flat_prefix, old_member_prefix; - if (om_.build_flat_prefix_) + if (build_flat_prefix_) { - old_flat_prefix = om_.flat_prefix_; - om_.flat_prefix_ += om_.public_name (m); - om_.flat_prefix_ += '_'; + old_flat_prefix = flat_prefix_; + flat_prefix_ += public_name (m); + flat_prefix_ += '_'; } - if (om_.build_member_prefix_) + if (build_member_prefix_) { - old_member_prefix = om_.member_prefix_; - om_.member_prefix_ += m.name (); - om_.member_prefix_ += '.'; + old_member_prefix = member_prefix_; + member_prefix_ += m.name (); + member_prefix_ += '.'; } - if (om_.build_table_prefix_) + if (build_table_prefix_) { - old_table_prefix = om_.table_prefix_.prefix; - append (m, om_.table_prefix_); + old_table_prefix = table_prefix_.prefix; + append (m, table_prefix_); } - om_.traverse_composite_wrapper (&m, *comp, (wrapper (t) ? &t : 0)); + traverse_composite_wrapper (&m, *comp, (wrapper (t) ? &t : 0)); - if (om_.build_table_prefix_) + if (build_table_prefix_) { - om_.table_prefix_.level--; - om_.table_prefix_.prefix = old_table_prefix; + table_prefix_.level--; + table_prefix_.prefix = old_table_prefix; } - if (om_.build_flat_prefix_) - om_.flat_prefix_ = old_flat_prefix; + if (build_flat_prefix_) + flat_prefix_ = old_flat_prefix; - if (om_.build_member_prefix_) - om_.member_prefix_ = old_member_prefix; + if (build_member_prefix_) + member_prefix_ = old_member_prefix; - om_.member_scope_.pop_back (); + member_scope_.pop_back (); } - else if (semantics::type* c = context::container (m)) - { + else + traverse_simple (m); +} + +void object_members_base::member:: +traverse (semantics::data_member& m) +{ + if (transient (m)) + return; + + om_.member_path_.push_back (&m); + + semantics::type& t (utype (m)); + + if (semantics::type* c = context::container (m)) om_.traverse_container (m, *c); - } + else if (semantics::class_* c = object_pointer (t)) + om_.traverse_pointer (m, *c); else - { - om_.traverse_simple (m); - } + om_.traverse_member (m, t); om_.member_path_.pop_back (); } @@ -283,6 +274,18 @@ flush () { } +bool object_columns_base:: +traverse_column (semantics::data_member&, string const&, bool) +{ + return false; +} + +void object_columns_base:: +traverse_pointer (semantics::data_member& m, semantics::class_& c) +{ + traverse_member (m, utype (*id_member (c))); +} + void object_columns_base:: traverse_composite (semantics::data_member*, semantics::class_& c) { @@ -307,30 +310,39 @@ traverse_view (semantics::class_& c) void object_columns_base:: traverse (semantics::data_member& m, - semantics::class_& c, - string const& key_prefix, - string const& default_name) + semantics::type& t, + std::string const& kp, + std::string const& dn, + semantics::class_* to) { - // We are starting from the member. Add an empty chain which - // corresponds to the scope that contains this member. - // - //member_scope_.push_back (class_inheritance_chain ()); - //member_path_.push_back (&m); + semantics::class_* oto (context::top_object); - member_scope_.push_back (class_inheritance_chain ()); - member_scope_.back ().push_back (&c); + if (to != 0) + context::top_object = to; - column_prefix_ = column_prefix (m, key_prefix, default_name); + semantics::class_* c (object_pointer (t)); + semantics::type* rt (c == 0 ? &t : &utype (*id_member (*c))); - traverse_composite (&m, c); + root_ = &m; + root_id_ = (kp.empty () ? context::id (m) : kp == "id"); + root_op_ = (c != 0); - if (!member_.first_) - flush (); + key_prefix_ = kp; + default_name_ = dn; - member_scope_.pop_back (); + if (root_op_) + traverse_pointer (m, *c); + else + traverse_member (m, *rt); + + key_prefix_.clear (); + default_name_.clear (); + + if (!first_ && composite_wrapper (*rt)) + flush (); - //member_path_.pop_back (); - //member_scope_.pop_back (); + root_ = 0; + context::top_object = oto; } void object_columns_base:: @@ -386,7 +398,7 @@ traverse (semantics::class_& c) context::cur_object = prev; } - if (f && !member_.first_) + if (f && !first_) flush (); } @@ -421,48 +433,102 @@ column_prefix (semantics::data_member& m, string const& kp, string const& dn) return r; } -void object_columns_base::member:: -traverse (semantics::data_member& m) +string object_columns_base:: +column_prefix (data_member_path const& mp) { - if (transient (m)) - return; + if (mp.size () < 2) + return ""; - oc_.member_path_.push_back (&m); + string r; - semantics::type& t (utype (m)); + for (data_member_path::const_iterator i (mp.begin ()), e (mp.end () - 1); + i != e; ++i) + r += column_prefix (**i); + + return r; +} +void object_columns_base:: +traverse_member (semantics::data_member& m, semantics::type& t) +{ if (semantics::class_* comp = composite_wrapper (t)) { - oc_.member_scope_.push_back (class_inheritance_chain ()); - oc_.member_scope_.back ().push_back (comp); + member_scope_.push_back (class_inheritance_chain ()); + member_scope_.back ().push_back (comp); - string old_prefix (oc_.column_prefix_); - oc_.column_prefix_ += column_prefix (m); + string old_prefix (column_prefix_); + column_prefix_ += column_prefix (m, key_prefix_, default_name_); - oc_.traverse_composite (&m, *comp); + // Save and clear the key prefix and default name. + // + string old_kp, old_dn; + old_kp.swap (key_prefix_); + old_dn.swap (default_name_); - oc_.column_prefix_ = old_prefix; + traverse_composite (&m, *comp); - oc_.member_scope_.pop_back (); - } - else if (container (m)) - { - // Container gets its own table, so nothing to do here. - // + old_kp.swap (key_prefix_); + old_dn.swap (default_name_); + + column_prefix_ = old_prefix; + member_scope_.pop_back (); } else { - if (oc_.traverse_column (m, oc_.column_prefix_ + column_name (m), first_)) + string name (column_prefix_ + column_name (m, key_prefix_, default_name_)); + + if (traverse_column (m, name, first_)) { if (first_) first_ = false; } } +} + +void object_columns_base::member:: +traverse (semantics::data_member& m) +{ + if (transient (m)) + return; + + // Container gets its own table, so nothing to do here. + // + if (container (m)) + return; + + oc_.member_path_.push_back (&m); + + semantics::type& t (utype (m)); + + if (semantics::class_* c = object_pointer (t)) + oc_.traverse_pointer (m, *c); + else + oc_.traverse_member (m, t); oc_.member_path_.pop_back (); } // +// object_columns_list +// + +void object_columns_list:: +traverse_pointer (semantics::data_member& m, semantics::class_& c) +{ + // Ignore inverse object pointers. + // + if (!ignore_inverse_ || !inverse (m, key_prefix_)) + object_columns_base::traverse_pointer (m, c); +} + +bool object_columns_list:: +traverse_column (semantics::data_member& m, std::string const& name, bool) +{ + columns_.push_back (column (name, column_type (), m)); + return true; +} + +// // typedefs // -- cgit v1.1