aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--odb/common.cxx8
-rw-r--r--odb/common.hxx5
-rw-r--r--odb/context.cxx19
-rw-r--r--odb/context.hxx21
-rw-r--r--odb/relational/header.hxx30
-rw-r--r--odb/relational/mysql/common.cxx11
-rw-r--r--odb/relational/mysql/common.hxx9
-rw-r--r--odb/relational/pgsql/common.cxx11
-rw-r--r--odb/relational/pgsql/common.hxx9
-rw-r--r--odb/relational/pgsql/schema.cxx3
-rw-r--r--odb/relational/pgsql/source.cxx11
-rw-r--r--odb/relational/schema.hxx7
-rw-r--r--odb/relational/source.hxx33
-rw-r--r--odb/relational/sqlite/common.cxx11
-rw-r--r--odb/relational/sqlite/common.hxx9
-rw-r--r--odb/relational/type-processor.cxx7
16 files changed, 134 insertions, 70 deletions
diff --git a/odb/common.cxx b/odb/common.cxx
index 794afc1..18d1580 100644
--- a/odb/common.cxx
+++ b/odb/common.cxx
@@ -17,7 +17,7 @@ simple (semantics::data_member&)
}
void object_members_base::
-container (semantics::data_member&)
+container (semantics::data_member&, semantics::type&)
{
}
@@ -172,9 +172,9 @@ traverse (semantics::data_member& m)
if (om_.build_prefix_)
om_.prefix_ = old_prefix;
}
- else if (context::container (t))
+ else if (semantics::type* c = context::container_wrapper (t))
{
- om_.container (m);
+ om_.container (m, *c);
}
else
{
@@ -307,7 +307,7 @@ traverse (semantics::data_member& m)
prefix_ = old_prefix;
}
- else if (container (t))
+ else if (container_wrapper (t))
{
// Container gets its own table, so nothing to do here.
//
diff --git a/odb/common.hxx b/odb/common.hxx
index 86a39c7..e3b4285 100644
--- a/odb/common.hxx
+++ b/odb/common.hxx
@@ -18,8 +18,11 @@ struct object_members_base: traversal::class_, virtual context
virtual void
simple (semantics::data_member&);
+ // The second argument is the actual container type in case m.type ()
+ // is a wrapper.
+ //
virtual void
- container (semantics::data_member&);
+ container (semantics::data_member&, semantics::type&);
// If you override this function, you can call the base to traverse
// bases and members. The first argument is the data member and can
diff --git a/odb/context.cxx b/odb/context.cxx
index 9d89879..fc82f29 100644
--- a/odb/context.cxx
+++ b/odb/context.cxx
@@ -318,7 +318,14 @@ member_type (semantics::data_member& m, string const& key_prefix)
if (m.count (key))
return *indirect_value<semantics::type*> (m, key);
- return *indirect_value<semantics::type*> (m.type (), key);
+ // "See throught" wrappers.
+ //
+ semantics::type& t (m.type ());
+
+ if (semantics::type* wt = wrapper (t))
+ return *indirect_value<semantics::type*> (*wt, key);
+ else
+ return *indirect_value<semantics::type*> (t, key);
}
bool context::
@@ -938,7 +945,7 @@ namespace
}
virtual void
- container (semantics::data_member& m)
+ container (semantics::data_member& m, semantics::type& c)
{
// We don't cross the container boundaries (separate table).
//
@@ -947,7 +954,7 @@ namespace
flags_ & (context::test_container |
context::test_straight_container |
context::test_inverse_container),
- context::container_vt (m.type ()),
+ context::container_vt (c),
"value");
}
@@ -982,17 +989,17 @@ is_a (semantics::data_member& m,
if (f & test_container)
{
- r = r || container (m.type ());
+ r = r || container_wrapper (m.type ());
}
if (f & test_straight_container)
{
- r = r || (container (m.type ()) && !inverse (m, kp));
+ r = r || (container_wrapper (m.type ()) && !inverse (m, kp));
}
if (f & test_inverse_container)
{
- r = r || (container (m.type ()) && inverse (m, kp));
+ r = r || (container_wrapper (m.type ()) && inverse (m, kp));
}
return r;
diff --git a/odb/context.hxx b/odb/context.hxx
index 3a09805..6449daf 100644
--- a/odb/context.hxx
+++ b/odb/context.hxx
@@ -132,6 +132,19 @@ public:
return t.count ("container-kind");
}
+ // As above but also "sees through" wrappers. Returns the actual
+ // container type or NULL if not a container.
+ //
+ static semantics::type*
+ container_wrapper (semantics::type& t)
+ {
+ if (container (t))
+ return &t;
+ else if (semantics::type* wt = wrapper (t))
+ return container (*wt) ? wt : 0;
+ else return 0;
+ }
+
static semantics::class_*
object_pointer (semantics::type& t)
{
@@ -320,7 +333,13 @@ public:
static bool
unordered (semantics::data_member& m)
{
- return m.count ("unordered") || m.type ().count ("unordered");
+ if (m.count ("unordered"))
+ return true;
+
+ if (semantics::type* c = container_wrapper (m.type ()))
+ return c->count ("unordered");
+
+ return false;
}
// The 'is a' and 'has a' tests. The has_a test currently does not
diff --git a/odb/relational/header.hxx b/odb/relational/header.hxx
index fb18598..900fb45 100644
--- a/odb/relational/header.hxx
+++ b/odb/relational/header.hxx
@@ -212,7 +212,7 @@ namespace relational
}
virtual void
- container (semantics::data_member& m)
+ container (semantics::data_member& m, semantics::type& c)
{
using semantics::type;
using semantics::class_;
@@ -233,10 +233,9 @@ namespace relational
abst = true; // Always abstract.
}
- type& t (m.type ());
- container_kind_type ck (container_kind (t));
+ container_kind_type ck (container_kind (c));
- type& vt (container_vt (t));
+ type& vt (container_vt (c));
type* it (0);
type* kt (0);
@@ -249,7 +248,7 @@ namespace relational
{
if (!unordered (m))
{
- it = &container_it (t);
+ it = &container_it (c);
ordered = true;
}
break;
@@ -257,7 +256,7 @@ namespace relational
case ck_map:
case ck_multimap:
{
- kt = &container_kt (t);
+ kt = &container_kt (c);
break;
}
case ck_set:
@@ -387,8 +386,23 @@ namespace relational
// key_type
// value_type
//
- os << "typedef " << t.fq_name (m.belongs ().hint ()) <<
- " container_type;";
+ os << "typedef ";
+
+ {
+ semantics::type& t (m.type ());
+
+ if (wrapper (t))
+ // Use the hint from the wrapper.
+ //
+ os << c.fq_name (t.get<semantics::names*> ("wrapper-hint"));
+ else
+ // t and c are the same.
+ //
+ os << c.fq_name (m.belongs ().hint ());
+ }
+
+ os << " container_type;";
+
os << "typedef odb::access::container_traits< container_type > " <<
"container_traits;";
diff --git a/odb/relational/mysql/common.cxx b/odb/relational/mysql/common.cxx
index f9028d7..4599b87 100644
--- a/odb/relational/mysql/common.cxx
+++ b/odb/relational/mysql/common.cxx
@@ -35,22 +35,23 @@ namespace relational
semantics::type& t (type_override_ != 0 ? *type_override_ : m.type ());
- if (semantics::class_* comp = comp_value_wrapper (t))
+ if (semantics::class_* c = comp_value_wrapper (t))
{
// If t is a wrapper, pass the wrapped type. Also pass the
// original, wrapper type.
//
- member_info mi (
- m, *comp, (wrapper (t) ? &t : 0), var, fq_type_override_);
+ member_info mi (m, *c, (wrapper (t) ? &t : 0), var, fq_type_override_);
if (pre (mi))
{
traverse_composite (mi);
post (mi);
}
}
- else if (container (t))
+ else if (semantics::type* c = container_wrapper (t))
{
- member_info mi (m, t, 0, var, fq_type_override_);
+ // The same unwrapping logic as for composite values.
+ //
+ member_info mi (m, *c, (wrapper (t) ? &t : 0), var, fq_type_override_);
if (pre (mi))
{
traverse_container (mi);
diff --git a/odb/relational/mysql/common.hxx b/odb/relational/mysql/common.hxx
index 69ee515..a85a75e 100644
--- a/odb/relational/mysql/common.hxx
+++ b/odb/relational/mysql/common.hxx
@@ -40,10 +40,13 @@ namespace relational
string
fq_type (bool unwrap = true) const
{
- // At the moment a wrapped type can only be a composite value.
- //
if (wrapper != 0 && unwrap)
- return t.fq_name ();
+ {
+ // Use the hint from the wrapper.
+ //
+ return t.fq_name (
+ wrapper->get<semantics::names*> ("wrapper-hint"));
+ }
// Use the original type from 'm' instead of 't' since the hint
// may be invalid for a different type. Plus, if a type is
diff --git a/odb/relational/pgsql/common.cxx b/odb/relational/pgsql/common.cxx
index d6ef9c3..e4d97cc 100644
--- a/odb/relational/pgsql/common.cxx
+++ b/odb/relational/pgsql/common.cxx
@@ -35,22 +35,23 @@ namespace relational
semantics::type& t (type_override_ != 0 ? *type_override_ : m.type ());
- if (semantics::class_* comp = comp_value_wrapper (t))
+ if (semantics::class_* c = comp_value_wrapper (t))
{
// If t is a wrapper, pass the wrapped type. Also pass the
// original, wrapper type.
//
- member_info mi (
- m, *comp, (wrapper (t) ? &t : 0), var, fq_type_override_);
+ member_info mi (m, *c, (wrapper (t) ? &t : 0), var, fq_type_override_);
if (pre (mi))
{
traverse_composite (mi);
post (mi);
}
}
- else if (container (t))
+ else if (semantics::type* c = container_wrapper (t))
{
- member_info mi (m, t, 0, var, fq_type_override_);
+ // The same unwrapping logic as for composite values.
+ //
+ member_info mi (m, *c, (wrapper (t) ? &t : 0), var, fq_type_override_);
if (pre (mi))
{
traverse_container (mi);
diff --git a/odb/relational/pgsql/common.hxx b/odb/relational/pgsql/common.hxx
index f41ca8c..a91c40a 100644
--- a/odb/relational/pgsql/common.hxx
+++ b/odb/relational/pgsql/common.hxx
@@ -40,10 +40,13 @@ namespace relational
string
fq_type (bool unwrap = true) const
{
- // At the moment a wrapped type can only be a composite value.
- //
if (wrapper != 0 && unwrap)
- return t.fq_name ();
+ {
+ // Use the hint from the wrapper.
+ //
+ return t.fq_name (
+ wrapper->get<semantics::names*> ("wrapper-hint"));
+ }
// Use the original type from 'm' instead of 't' since the hint
// may be invalid for a different type. Plus, if a type is
diff --git a/odb/relational/pgsql/schema.cxx b/odb/relational/pgsql/schema.cxx
index 5bfbc71..0e66e79 100644
--- a/odb/relational/pgsql/schema.cxx
+++ b/odb/relational/pgsql/schema.cxx
@@ -186,7 +186,7 @@ namespace relational
}
virtual void
- container (semantics::data_member& m)
+ container (semantics::data_member& m, semantics::type& t)
{
using semantics::type;
using semantics::data_member;
@@ -201,7 +201,6 @@ namespace relational
if (tables_.count (name))
return;
- type& t (m.type ());
type& vt (container_vt (t));
// object_id
diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx
index 1bba68a..331463d 100644
--- a/odb/relational/pgsql/source.cxx
+++ b/odb/relational/pgsql/source.cxx
@@ -1003,7 +1003,7 @@ namespace relational
container_traits (base const& x): base (x) {}
virtual void
- container_extra (semantics::data_member& m)
+ container_extra (semantics::data_member& m, semantics::type& t)
{
if (!c_.count ("object") || abstract (c_))
return;
@@ -1039,8 +1039,7 @@ namespace relational
semantics::data_member* inv_m (inverse (m, "value"));
bool inv (inv_m != 0);
- semantics::type& mt (m.type ());
- semantics::type& vt (container_vt (mt));
+ semantics::type& vt (container_vt (t));
string id_oid (oids[column_sql_type (m, "id").type]);
@@ -1055,7 +1054,7 @@ namespace relational
{
// many(i)-to-many
//
- if (context::container (inv_m->type ()))
+ if (container_wrapper (inv_m->type ()))
os << oids[column_sql_type (*inv_m, "value").type];
// many(i)-to-one
@@ -1080,7 +1079,7 @@ namespace relational
{
os << id_oid << ",";
- switch (container_kind (mt))
+ switch (container_kind (t))
{
case ck_ordered:
{
@@ -1093,7 +1092,7 @@ namespace relational
case ck_multimap:
{
if (semantics::class_* ktc =
- comp_value_wrapper (container_kt (mt)))
+ comp_value_wrapper (container_kt (t)))
{
instance<statement_oids> st;
st->traverse_composite (m, *ktc, "key", "key");
diff --git a/odb/relational/schema.hxx b/odb/relational/schema.hxx
index 5f253c4..5c985da 100644
--- a/odb/relational/schema.hxx
+++ b/odb/relational/schema.hxx
@@ -83,7 +83,7 @@ namespace relational
}
virtual void
- container (semantics::data_member& m)
+ container (semantics::data_member& m, semantics::type& c)
{
// Ignore inverse containers of object pointers.
//
@@ -109,7 +109,7 @@ namespace relational
drop_index (name, column_name (m, "id", "object_id"));
post_statement ();
- if (container_kind (m.type ()) == ck_ordered && !unordered (m))
+ if (container_kind (c) == ck_ordered && !unordered (m))
{
pre_statement ();
drop_index (name, column_name (m, "index", "index"));
@@ -372,7 +372,7 @@ namespace relational
}
virtual void
- container (semantics::data_member& m)
+ container (semantics::data_member& m, semantics::type& t)
{
using semantics::type;
using semantics::data_member;
@@ -382,7 +382,6 @@ namespace relational
if (inverse (m, "value"))
return;
- type& t (m.type ());
container_kind_type ck (container_kind (t));
type& vt (container_vt (t));
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx
index 7d0c079..c825159 100644
--- a/odb/relational/source.hxx
+++ b/odb/relational/source.hxx
@@ -86,7 +86,7 @@ namespace relational
{
semantics::class_* c (object_pointer (m.type ()));
- if (container (im->type ()))
+ if (container_wrapper (im->type ()))
{
// This container is a direct member of the class so the table
// prefix is just the class table name.
@@ -220,7 +220,7 @@ namespace relational
if (semantics::data_member* im = inverse (m))
{
- if (container (im->type ()))
+ if (container_wrapper (im->type ()))
{
// This container is a direct member of the class so the table
// prefix is just the class table name.
@@ -619,12 +619,12 @@ namespace relational
}
virtual void
- container_extra (semantics::data_member&)
+ container_extra (semantics::data_member&, semantics::type&)
{
}
virtual void
- container (semantics::data_member& m)
+ container (semantics::data_member& m, semantics::type& t)
{
using semantics::type;
@@ -644,7 +644,6 @@ namespace relational
abst = true; // Always abstract.
}
- type& t (m.type ());
container_kind_type ck (container_kind (t));
type& vt (container_vt (t));
@@ -695,7 +694,7 @@ namespace relational
<< "//" << endl
<< endl;
- container_extra (m);
+ container_extra (m, t);
//
// Statements.
@@ -717,7 +716,7 @@ namespace relational
string inv_id; // Other id column.
string inv_fid; // Other foreign id column (ref to us).
- if (context::container (im->type ()))
+ if (container_wrapper (im->type ()))
{
// many(i)-to-many
//
@@ -1637,7 +1636,7 @@ namespace relational
}
virtual void
- container (semantics::data_member& m)
+ container (semantics::data_member& m, semantics::type&)
{
string traits (prefix_ + public_name (m) + "_traits");
os << db << "::container_statements_impl< " << traits << " > " <<
@@ -1655,7 +1654,7 @@ namespace relational
}
virtual void
- container (semantics::data_member& m)
+ container (semantics::data_member& m, semantics::type&)
{
if (first_)
{
@@ -1732,7 +1731,7 @@ namespace relational
}
virtual void
- container (semantics::data_member& m)
+ container (semantics::data_member& m, semantics::type&)
{
using semantics::type;
@@ -1743,6 +1742,20 @@ namespace relational
string sts_name (prefix_ + name);
string traits (prefix_ + public_name (m) + "_traits");
+ // If this is a wrapped container, then we need to "unwrap" it.
+ //
+ {
+ semantics::type& t (m.type ());
+ if (wrapper (t))
+ {
+ string const& type (t.fq_name (m.belongs ().hint ()));
+
+ obj_name = "wrapper_traits< " + type + " >::" +
+ (call_ == load_call ? "set_ref" : "get_ref") +
+ " (" + obj_name + ")";
+ }
+ }
+
switch (call_)
{
case persist_call:
diff --git a/odb/relational/sqlite/common.cxx b/odb/relational/sqlite/common.cxx
index d9f79b0..1531e75 100644
--- a/odb/relational/sqlite/common.cxx
+++ b/odb/relational/sqlite/common.cxx
@@ -35,22 +35,23 @@ namespace relational
semantics::type& t (type_override_ != 0 ? *type_override_ : m.type ());
- if (semantics::class_* comp = comp_value_wrapper (t))
+ if (semantics::class_* c = comp_value_wrapper (t))
{
// If t is a wrapper, pass the wrapped type. Also pass the
// original, wrapper type.
//
- member_info mi (
- m, *comp, (wrapper (t) ? &t : 0), var, fq_type_override_);
+ member_info mi (m, *c, (wrapper (t) ? &t : 0), var, fq_type_override_);
if (pre (mi))
{
traverse_composite (mi);
post (mi);
}
}
- else if (container (t))
+ else if (semantics::type* c = container_wrapper (t))
{
- member_info mi (m, t, 0, var, fq_type_override_);
+ // The same unwrapping logic as for composite values.
+ //
+ member_info mi (m, *c, (wrapper (t) ? &t : 0), var, fq_type_override_);
if (pre (mi))
{
traverse_container (mi);
diff --git a/odb/relational/sqlite/common.hxx b/odb/relational/sqlite/common.hxx
index e3f81a5..e8663af 100644
--- a/odb/relational/sqlite/common.hxx
+++ b/odb/relational/sqlite/common.hxx
@@ -40,10 +40,13 @@ namespace relational
string
fq_type (bool unwrap = true) const
{
- // At the moment a wrapped type can only be a composite value.
- //
if (wrapper != 0 && unwrap)
- return t.fq_name ();
+ {
+ // Use the hint from the wrapper.
+ //
+ return t.fq_name (
+ wrapper->get<semantics::names*> ("wrapper-hint"));
+ }
// Use the original type from 'm' instead of 't' since the hint
// may be invalid for a different type. Plus, if a type is
diff --git a/odb/relational/type-processor.cxx b/odb/relational/type-processor.cxx
index 24a7325..e53126f 100644
--- a/odb/relational/type-processor.cxx
+++ b/odb/relational/type-processor.cxx
@@ -195,7 +195,8 @@ namespace relational
// See if this is a container type.
//
- if (process_container (m))
+ if (process_container (m, t) ||
+ (wt != 0 && process_container (m, *wt)))
return;
// If it is none of the above then we have an error.
@@ -306,7 +307,7 @@ namespace relational
}
bool
- process_container (semantics::data_member& m)
+ process_container (semantics::data_member& m, semantics::type& t)
{
// The overall idea is as follows: try to instantiate the container
// traits class template. If we are successeful, then this is a
@@ -314,8 +315,6 @@ namespace relational
// the instantiation. Otherwise, this is not a container.
//
- semantics::type& t (m.type ());
-
container_kind_type ck;
semantics::type* vt (0);
semantics::type* it (0);