summaryrefslogtreecommitdiff
path: root/odb/common.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-02-17 10:08:18 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-02-22 12:29:43 +0200
commit3a1eed21d4d5d0e7f6a9f400420fdc28d7be9b61 (patch)
tree97ba7338fb804c264c9eaaaa41085b08f6483c68 /odb/common.cxx
parent3f73cc933b64d7d9a88325d33a3c33a0e28720c6 (diff)
Add support for composite object ids
New pragma id_type (member). New test: common/composite-id. The composite example has also been updated.
Diffstat (limited to 'odb/common.cxx')
-rw-r--r--odb/common.cxx254
1 files changed, 160 insertions, 94 deletions
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
//