aboutsummaryrefslogtreecommitdiff
path: root/odb/relational
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-06-16 08:19:25 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-06-16 08:19:25 +0200
commit521216e0a696fa698c88fc1e18958c82626873cc (patch)
treedd95f00470fc1f9bbc3d1ec2f0bf3c9314f8e166 /odb/relational
parente269daa6cd5e88bc7ada0e148b052aabd65044d8 (diff)
Implement support for nested members in inverse pragma
Diffstat (limited to 'odb/relational')
-rw-r--r--odb/relational/pgsql/source.cxx4
-rw-r--r--odb/relational/processor.cxx4
-rw-r--r--odb/relational/source.cxx54
-rw-r--r--odb/relational/source.hxx91
4 files changed, 76 insertions, 77 deletions
diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx
index ec900dc..d009a7c 100644
--- a/odb/relational/pgsql/source.cxx
+++ b/odb/relational/pgsql/source.cxx
@@ -873,8 +873,8 @@ namespace relational
string const& pn (public_name (m));
string scope (scope_ + "::" + flat_prefix_ + pn + "_traits");
- semantics::data_member* inv_m (inverse (m, "value"));
- bool inv (inv_m != 0);
+ data_member_path* imp (inverse (m, "value"));
+ bool inv (imp != 0);
bool smart (!inv && !unordered (m) && container_smart (t));
diff --git a/odb/relational/processor.cxx b/odb/relational/processor.cxx
index 782abcf..0dbacbd 100644
--- a/odb/relational/processor.cxx
+++ b/odb/relational/processor.cxx
@@ -1536,9 +1536,9 @@ namespace relational
// miss it since we don't examine inside poly bases on the
// backwards scan (see above).
//
- if (semantics::data_member* im = inverse (m))
+ if (data_member_path* imp = inverse (m))
{
- if (&im->scope () == &c) // Direct member.
+ if (&imp->front ()->scope () == &c) // Direct member.
return;
}
diff --git a/odb/relational/source.cxx b/odb/relational/source.cxx
index 4540bb4..c2144b4 100644
--- a/odb/relational/source.cxx
+++ b/odb/relational/source.cxx
@@ -4912,7 +4912,7 @@ traverse_view (type& c)
using semantics::data_member;
data_member& m (*e.member_path.back ());
- data_member* im (inverse (m));
+ data_member_path* imp (inverse (m));
// Resolve the pointed-to object to view_object and do
// some sanity checks while at it.
@@ -4989,11 +4989,10 @@ traverse_view (type& c)
// e.vo - us
// e.member_path - in us
//
- if (im == 0)
+ if (imp == 0)
rel_map.insert (make_pair (e.member_path, make_pair (e.vo, vo)));
else
- rel_map.insert (
- make_pair (data_member_path (*im), make_pair (vo, e.vo)));
+ rel_map.insert (make_pair (*imp, make_pair (vo, e.vo)));
// Left and right-hand side table names.
//
@@ -5042,7 +5041,7 @@ traverse_view (type& c)
// First join the container table if necessary.
//
- semantics::type* cont (container (im != 0 ? *im : m));
+ semantics::type* cont (container (imp != 0 ? *imp->back () : m));
string ct; // Container table.
if (cont != 0)
@@ -5063,10 +5062,10 @@ traverse_view (type& c)
// In a polymorphic hierarchy the member can be in a base (see
// above).
//
- if (class_* root = polymorphic (im != 0 ? *vo->obj : *e.vo->obj))
+ if (class_* root = polymorphic (imp != 0 ? *vo->obj : *e.vo->obj))
{
class_* c;
- if (im == 0)
+ if (imp == 0)
{
c = &static_cast<class_&> (e.member_path.front ()->scope ());
@@ -5077,17 +5076,17 @@ traverse_view (type& c)
}
else
{
- c = &static_cast<class_&> (im->scope ());
+ c = &static_cast<class_&> (imp->front ()->scope ());
if (!polymorphic (*c))
c = root;
- t = table_name (*im, table_prefix (*c));
+ t = table_name (*c, *imp);
}
}
else
- t = im != 0
- ? table_name (*im, table_prefix (*vo->obj))
+ t = imp != 0
+ ? table_name (*vo->obj, *imp)
: table_name (*e.vo->obj, e.member_path);
// The tricky part is to figure out which view_object, vo
@@ -5096,7 +5095,7 @@ traverse_view (type& c)
// might not make intuitive sense, but it has been verified
// with the truth table.
//
- string const& a (im != 0 ? vo->alias : e.vo->alias);
+ string const& a (imp != 0 ? vo->alias : e.vo->alias);
if (a.empty ())
{
@@ -5124,15 +5123,17 @@ traverse_view (type& c)
qname* ot; // Object table (either lt or rt).
- if (im != 0)
+ if (imp != 0)
{
+ semantics::data_member& imb (*imp->back ());
+
if (&o == c)
{
// container.value = pointer.id
//
semantics::data_member& id (*id_member (*e.vo->obj));
- c_cols->traverse (*im, utype (id), "value", "value");
+ c_cols->traverse (imb, utype (id), "value", "value");
o_cols->traverse (id);
ot = &lt;
}
@@ -5142,8 +5143,7 @@ traverse_view (type& c)
//
semantics::data_member& id (*id_member (*vo->obj));
- c_cols->traverse (
- *im, utype (id), "id", "object_id", vo->obj);
+ c_cols->traverse (imb, utype (id), "id", "object_id", vo->obj);
o_cols->traverse (id);
ot = &rt;
}
@@ -5217,15 +5217,17 @@ traverse_view (type& c)
qname* ot; // Object table (either lt or rt).
- if (im != 0)
+ if (imp != 0)
{
+ semantics::data_member& imb (*imp->back ());
+
if (&o == c)
{
// container.id = pointed-to.id
//
semantics::data_member& id (*id_member (*vo->obj));
- c_cols->traverse (*im, utype (id), "id", "object_id", vo->obj);
+ c_cols->traverse (imb, utype (id), "id", "object_id", vo->obj);
o_cols->traverse (id);
ot = &rt;
}
@@ -5235,7 +5237,7 @@ traverse_view (type& c)
//
semantics::data_member& id (*id_member (*e.vo->obj));
- c_cols->traverse (*im, utype (id), "value", "value");
+ c_cols->traverse (imb, utype (id), "value", "value");
o_cols->traverse (id);
ot = &lt;
}
@@ -5285,26 +5287,22 @@ traverse_view (type& c)
}
else
{
- column_prefix col_prefix;
-
- if (im == 0)
- col_prefix = column_prefix (e.member_path);
-
- instance<object_columns_list> l_cols (col_prefix);
+ instance<object_columns_list> l_cols;
instance<object_columns_list> r_cols;
- if (im != 0)
+ if (imp != 0)
{
// our.id = pointed-to.pointer
//
l_cols->traverse (*id_member (*e.vo->obj));
- r_cols->traverse (*im);
+ r_cols->traverse (*imp->back (), column_prefix (*imp));
}
else
{
// our.pointer = pointed-to.id
//
- l_cols->traverse (*e.member_path.back ());
+ l_cols->traverse (*e.member_path.back (),
+ column_prefix (e.member_path));
r_cols->traverse (*id_member (*vo->obj));
}
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx
index 716aa10..7774739 100644
--- a/odb/relational/source.hxx
+++ b/odb/relational/source.hxx
@@ -188,31 +188,33 @@ namespace relational
if (sk_ == statement_select && m.count ("polymorphic-ref"))
return;
- semantics::data_member* im (inverse (m, key_prefix_));
+ data_member_path* imp (inverse (m, key_prefix_));
// Ignore certain columns depending on what kind of statement we are
// generating. Columns corresponding to the inverse members are
// only present in the select statements.
//
- if (im != 0 && sk_ != statement_select)
+ if (imp != 0 && sk_ != statement_select)
return;
// Inverse object pointers come from a joined table.
//
- if (im != 0)
+ if (imp != 0)
{
bool poly (polymorphic (c) != 0);
+ semantics::data_member& imf (*imp->front ());
+ semantics::data_member& imb (*imp->back ());
// In a polymorphic hierarchy the inverse member can be in
// the base class, in which case we should use that table.
//
semantics::class_& imc (
- poly ? dynamic_cast<semantics::class_&> (im->scope ()) : c);
+ poly ? dynamic_cast<semantics::class_&> (imf.scope ()) : c);
semantics::data_member& id (*id_member (imc));
semantics::type& idt (utype (id));
- if (container (*im))
+ if (container (imb))
{
// This container is a direct member of the class so the table
// prefix is just the class table name. We don't assign join
@@ -229,11 +231,11 @@ namespace relational
if (table_name_resolver_ != 0)
table = table_name_resolver_->resolve_pointer (m);
else
- table = table_qname (*im, table_prefix (imc));
+ table = table_qname (imc, *imp);
}
instance<object_columns> oc (table, sk_, sc_);
- oc->traverse (*im, idt, "id", "object_id", &imc);
+ oc->traverse (imb, idt, "id", "object_id", &imc);
}
else
{
@@ -373,14 +375,14 @@ namespace relational
{
view_object& us (*ptr_->get<view_object*> ("view-object"));
- semantics::data_member& im (*inverse (m));
+ data_member_path& imp (*inverse (m));
+ semantics::data_member& imf (*imp.front ());
+ semantics::data_member& imb (*imp.back ());
+ using semantics::class_;
typedef view_relationship_map::const_iterator iterator;
- std::pair<iterator, iterator> r (
- rel_map_.equal_range (data_member_path (im)));
-
- using semantics::class_;
+ std::pair<iterator, iterator> r (rel_map_.equal_range (imp));
for (; r.first != r.second; ++r.first)
{
@@ -396,7 +398,7 @@ namespace relational
{
// Can be in base.
//
- c = &static_cast<class_&> (im.scope ());
+ c = &static_cast<class_&> (imf.scope ());
if (!polymorphic (*c))
c = root;
@@ -404,13 +406,13 @@ namespace relational
string const& a (vo.alias);
- if (container (im))
+ if (container (imb))
{
// If this is a container, then object_columns will use the
// column from the container table, not from the object table
// (which, strictly speaking, might not have been JOIN'ed).
//
- qname t (table_name (im, table_prefix (*c)));
+ qname t (table_name (*c, imp));
return a.empty ()
? quote_id (t)
: quote_id (a + '_' + t.uname ());
@@ -447,7 +449,7 @@ namespace relational
class_* o (object_pointer (utype (m)));
if (class_* root = polymorphic (*o))
{
- o = &static_cast<class_&> (im.scope ());
+ o = &static_cast<class_&> (imf.scope ());
if (!polymorphic (*o))
o = root;
@@ -456,11 +458,7 @@ namespace relational
string const& a (us.alias);
string lt (a.empty () ? table_qname (*us.obj) : quote_id (a));
string rt;
-
- qname ct (
- container (im)
- ? table_name (im, table_prefix (*o))
- : table_name (*o));
+ qname ct (container (imb) ? table_name (*o, imp) : table_name (*o));
string l ("LEFT JOIN ");
@@ -490,10 +488,10 @@ namespace relational
l_cols->traverse (id);
- if (container (im))
- r_cols->traverse (im, utype (id), "value", "value");
+ if (container (imb))
+ r_cols->traverse (imb, utype (id), "value", "value");
else
- r_cols->traverse (im);
+ r_cols->traverse (imb, column_prefix (imp));
for (object_columns_list::iterator b (l_cols->begin ()), i (b),
j (r_cols->begin ()); i != l_cols->end (); ++i, ++j)
@@ -973,25 +971,28 @@ namespace relational
semantics::class_* joined_obj (0);
- if (semantics::data_member* im = inverse (m, key_prefix_))
+ if (data_member_path* imp = inverse (m, key_prefix_))
{
+ semantics::data_member& imf (*imp->front ());
+ semantics::data_member& imb (*imp->back ());
+
// In a polymorphic hierarchy the inverse member can be in
// the base class, in which case we should use that table.
//
semantics::class_& imc (
- poly ? dynamic_cast<semantics::class_&> (im->scope ()) : c);
+ poly ? dynamic_cast<semantics::class_&> (imf.scope ()) : c);
- if (container (*im))
+ if (container (imb))
{
// This container is a direct member of the class so the table
// prefix is just the class table name.
//
- t = table_qname (*im, table_prefix (imc));
+ t = table_qname (imc, *imp);
// Container's value is our id.
//
instance<object_columns_list> id_cols;
- id_cols->traverse (*im, utype (id_), "value", "value");
+ id_cols->traverse (imb, utype (id_), "value", "value");
for (object_columns_list::iterator b (id_cols->begin ()), i (b),
j (id_cols_->begin ()); i != id_cols->end (); ++i, ++j)
@@ -1021,7 +1022,7 @@ namespace relational
instance<object_columns_list> oid_cols, cid_cols;
oid_cols->traverse (id);
- cid_cols->traverse (*im, utype (id), "id", "object_id", &c);
+ cid_cols->traverse (imb, utype (id), "id", "object_id", &c);
for (object_columns_list::iterator b (cid_cols->begin ()), i (b),
j (oid_cols->begin ()); i != cid_cols->end (); ++i, ++j)
@@ -1045,7 +1046,7 @@ namespace relational
a = quote_id (poly ? alias + "_" + table.uname () : alias);
instance<object_columns_list> id_cols;
- id_cols->traverse (*im);
+ id_cols->traverse (imb, column_prefix (*imp));
for (object_columns_list::iterator b (id_cols->begin ()), i (b),
j (id_cols_->begin ()); i != id_cols->end (); ++i, ++j)
@@ -1210,7 +1211,6 @@ namespace relational
traverse_container (semantics::data_member& m, semantics::type& t)
{
semantics::type& vt (container_vt (t));
- semantics::data_member* im (inverse (m, "value"));
if (semantics::class_* cvt = composite_wrapper (vt))
{
@@ -1222,12 +1222,12 @@ namespace relational
session_ = session_ || t->session_;
}
else if (semantics::class_* c = object_pointer (vt))
- check (m, im, vt, *c);
+ check (m, inverse (m, "value"), vt, *c);
}
void
check (semantics::data_member& m,
- semantics::data_member* im,
+ data_member_path* imp,
semantics::type& pt, // Pointer type.
semantics::class_& c)
{
@@ -1257,13 +1257,12 @@ namespace relational
typedef view_relationship_map::const_iterator iterator;
std::pair<iterator, iterator> r (
- rel_map_.equal_range (
- im != 0 ? data_member_path (*im) : member_path_));
+ rel_map_.equal_range (imp != 0 ? *imp : member_path_));
if (r.first == r.second)
return; // This relationship does not figure in the view.
- view_object& vo (*(im != 0
+ view_object& vo (*(imp != 0
? r.first->second.first
: r.first->second.second));
@@ -3393,10 +3392,10 @@ namespace relational
type* it (0);
type* kt (0);
- semantics::data_member* im (context::inverse (m, "value"));
+ data_member_path* imp (context::inverse (m, "value"));
bool ordered (false);
- bool inverse (im != 0);
+ bool inverse (imp != 0);
bool grow (false);
switch (ck)
@@ -3504,13 +3503,15 @@ namespace relational
if (inverse)
{
semantics::class_* c (object_pointer (vt));
+ semantics::data_member& imf (*imp->front ());
+ semantics::data_member& imb (*imp->back ());
// In a polymorphic hierarchy the inverse member can be in
// the base class, in which case we should use that class
// for the table name, etc.
//
if (polymorphic (*c))
- c = &dynamic_cast<semantics::class_&> (im->scope ());
+ c = &dynamic_cast<semantics::class_&> (imf.scope ());
semantics::data_member& inv_id (*id_member (*c));
@@ -3521,7 +3522,7 @@ namespace relational
// column (ref to us).
statement_columns sc;
- if (container (*im))
+ if (container (imb))
{
// many(i)-to-many
//
@@ -3529,11 +3530,11 @@ namespace relational
// This other container is a direct member of the class so the
// table prefix is just the class table name.
//
- inv_table = table_name (*im, table_prefix (*c));
+ inv_table = table_name (*c, *imp);
inv_qtable = quote_id (inv_table);
- inv_id_cols->traverse (*im, utype (inv_id), "id", "object_id", c);
- inv_fid_cols->traverse (*im, idt, "value", "value");
+ inv_id_cols->traverse (imb, utype (inv_id), "id", "object_id", c);
+ inv_fid_cols->traverse (imb, idt, "value", "value");
for (object_columns_list::iterator i (inv_id_cols->begin ());
i != inv_id_cols->end (); ++i)
@@ -3558,7 +3559,7 @@ namespace relational
inv_qtable = quote_id (inv_table);
inv_id_cols->traverse (inv_id);
- inv_fid_cols->traverse (*im);
+ inv_fid_cols->traverse (imb, column_prefix (*imp));
for (object_columns_list::iterator i (inv_id_cols->begin ());
i != inv_id_cols->end (); ++i)