aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-08-26 12:13:18 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-08-28 14:15:45 +0200
commit64d0ceffaaf5f57a3d24a5210bf0ad2a8474a618 (patch)
tree98115a01b0bd2e9ddfdc6ff3a0f7470915de483a
parent061a16256eef2c2df53e2e145d16f17270c2de82 (diff)
Add wrapper support for composite values
NULL semantics for composite values is not yet supported.
-rw-r--r--odb/common.cxx18
-rw-r--r--odb/common.hxx11
-rw-r--r--odb/context.hxx24
-rw-r--r--odb/relational/header.hxx6
-rw-r--r--odb/relational/mysql/common.cxx15
-rw-r--r--odb/relational/mysql/common.hxx17
-rw-r--r--odb/relational/mysql/source.cxx35
-rw-r--r--odb/relational/pgsql/common.cxx15
-rw-r--r--odb/relational/pgsql/common.hxx17
-rw-r--r--odb/relational/pgsql/schema.cxx2
-rw-r--r--odb/relational/pgsql/source.cxx40
-rw-r--r--odb/relational/schema.hxx4
-rw-r--r--odb/relational/source.hxx42
-rw-r--r--odb/relational/sqlite/common.cxx15
-rw-r--r--odb/relational/sqlite/common.hxx17
-rw-r--r--odb/relational/sqlite/source.cxx35
-rw-r--r--odb/relational/type-processor.cxx4
17 files changed, 259 insertions, 58 deletions
diff --git a/odb/common.cxx b/odb/common.cxx
index 130d5ec..794afc1 100644
--- a/odb/common.cxx
+++ b/odb/common.cxx
@@ -29,6 +29,14 @@ composite (semantics::data_member*, semantics::class_& c)
}
void object_members_base::
+composite_wrapper (semantics::data_member* m,
+ semantics::class_& c,
+ semantics::type*)
+{
+ composite (m, c);
+}
+
+void object_members_base::
object (semantics::class_& c)
{
inherits (c);
@@ -38,7 +46,7 @@ object (semantics::class_& c)
void object_members_base::
traverse_composite (semantics::data_member& m, semantics::class_& c)
{
- composite (&m, c);
+ composite_wrapper (&m, c, 0);
}
void object_members_base::
@@ -88,7 +96,7 @@ traverse (semantics::class_& c)
if (obj)
object (c);
else
- composite (0, c);
+ composite_wrapper (0, c, 0);
}
if (obj)
@@ -108,7 +116,7 @@ traverse (semantics::data_member& m)
semantics::type& t (m.type ());
- if (semantics::class_* comp = context::comp_value (t))
+ if (semantics::class_* comp = context::comp_value_wrapper (t))
{
string old_prefix, old_table_prefix;
@@ -153,7 +161,7 @@ traverse (semantics::data_member& m)
om_.table_prefix_.level++;
}
- om_.composite (&m, *comp);
+ om_.composite_wrapper (&m, *comp, (wrapper (t) ? &t : 0));
if (om_.build_table_prefix_)
{
@@ -275,7 +283,7 @@ traverse (semantics::data_member& m)
semantics::type& t (m.type ());
- if (semantics::class_* comp = comp_value (t))
+ if (semantics::class_* comp = comp_value_wrapper (t))
{
string old_prefix (prefix_);
diff --git a/odb/common.hxx b/odb/common.hxx
index 548e2a2..86a39c7 100644
--- a/odb/common.hxx
+++ b/odb/common.hxx
@@ -30,6 +30,17 @@ struct object_members_base: traversal::class_, virtual context
virtual void
composite (semantics::data_member*, semantics::class_&);
+ // More general version of the above function that allows detection
+ // of wrapped composite value. By default this function calls
+ // composite (m, comp) ignoring the wrapper type. Note that this
+ // function is called for all composite value (wrapped or not).
+ // If it is not wrapped, the wrapper argument will be NULL.
+ //
+ virtual void
+ composite_wrapper (semantics::data_member*,
+ semantics::class_& comp,
+ semantics::type* wrapper);
+
// If you override this function, you can call the base to traverse
// bases and members.
//
diff --git a/odb/context.hxx b/odb/context.hxx
index 69c5d48..3a09805 100644
--- a/odb/context.hxx
+++ b/odb/context.hxx
@@ -78,6 +78,17 @@ public:
//
public:
+ // Check whether the type is a wrapper. Return the wrapped type if
+ // it is a wrapper and NULL otherwise.
+ //
+ static semantics::type*
+ wrapper (semantics::type& t)
+ {
+ return t.count ("wrapper") && t.get<bool> ("wrapper")
+ ? t.get<semantics::type*> ("wrapper-type")
+ : 0;
+ }
+
// Composite value type is a class type that was explicitly marked
// as value type and there was no database type mapping provided for
// it by the user (specifying the database type makes the value type
@@ -102,6 +113,19 @@ public:
return c != 0 && comp_value (*c) ? c : 0;
}
+ // As above but also "sees through" wrappers.
+ //
+ static semantics::class_*
+ comp_value_wrapper (semantics::type& t)
+ {
+ if (semantics::class_* c = comp_value (t))
+ return c;
+ else if (semantics::type* wt = wrapper (t))
+ return comp_value (*wt);
+ else
+ return 0;
+ }
+
static bool
container (semantics::type& t)
{
diff --git a/odb/relational/header.hxx b/odb/relational/header.hxx
index 49de640..fb18598 100644
--- a/odb/relational/header.hxx
+++ b/odb/relational/header.hxx
@@ -296,7 +296,7 @@ namespace relational
//
size_t n;
- if (class_* kc = comp_value (*kt))
+ if (class_* kc = comp_value_wrapper (*kt))
n = in_column_count (*kc);
else
n = 1;
@@ -316,7 +316,7 @@ namespace relational
//
// Value is also a key.
//
- //if (class_* vc = comp_value (vt))
+ //if (class_* vc = comp_value_wrapper (vt))
// cond_columns += in_column_count (*vc);
//else
// cond_columns++;
@@ -325,7 +325,7 @@ namespace relational
}
}
- if (class_* vc = comp_value (vt))
+ if (class_* vc = comp_value_wrapper (vt))
data_columns += in_column_count (*vc);
else
data_columns++;
diff --git a/odb/relational/mysql/common.cxx b/odb/relational/mysql/common.cxx
index 5ddd27d..f9028d7 100644
--- a/odb/relational/mysql/common.cxx
+++ b/odb/relational/mysql/common.cxx
@@ -35,9 +35,13 @@ namespace relational
semantics::type& t (type_override_ != 0 ? *type_override_ : m.type ());
- if (comp_value (t))
+ if (semantics::class_* comp = comp_value_wrapper (t))
{
- member_info mi (m, t, var, fq_type_override_);
+ // 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_);
if (pre (mi))
{
traverse_composite (mi);
@@ -46,7 +50,7 @@ namespace relational
}
else if (container (t))
{
- member_info mi (m, t, var, fq_type_override_);
+ member_info mi (m, t, 0, var, fq_type_override_);
if (pre (mi))
{
traverse_container (mi);
@@ -59,7 +63,8 @@ namespace relational
if (semantics::class_* c = object_pointer (t))
{
- member_info mi (m, id_member (*c)->type (), var, fq_type_override_);
+ member_info mi (
+ m, id_member (*c)->type (), 0, var, fq_type_override_);
mi.st = &st;
if (pre (mi))
{
@@ -69,7 +74,7 @@ namespace relational
}
else
{
- member_info mi (m, t, var, fq_type_override_);
+ member_info mi (m, t, 0, var, fq_type_override_);
mi.st = &st;
if (pre (mi))
{
diff --git a/odb/relational/mysql/common.hxx b/odb/relational/mysql/common.hxx
index dae7774..69ee515 100644
--- a/odb/relational/mysql/common.hxx
+++ b/odb/relational/mysql/common.hxx
@@ -30,14 +30,21 @@ namespace relational
{
semantics::data_member& m; // Member.
semantics::type& t; // Member C++ type (m.type () may != t).
+ semantics::type* wrapper; // Wrapper type if member is a wrapper.
+ // In this case t is the wrapped type.
sql_type const* st; // Member SQL type (only simple values).
string& var; // Member variable name with trailing '_'.
// C++ type fq-name.
//
string
- fq_type () const
+ 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 original type from 'm' instead of 't' since the hint
// may be invalid for a different type. Plus, if a type is
// overriden, then the fq_type must be as well.
@@ -51,9 +58,15 @@ namespace relational
member_info (semantics::data_member& m_,
semantics::type& t_,
+ semantics::type* wrapper_,
string& var_,
string const& fq_type)
- : m (m_), t (t_), st (0), var (var_), fq_type_ (fq_type)
+ : m (m_),
+ t (t_),
+ wrapper (wrapper_),
+ st (0),
+ var (var_),
+ fq_type_ (fq_type)
{
}
};
diff --git a/odb/relational/mysql/source.cxx b/odb/relational/mysql/source.cxx
index 451a44d..190ca93 100644
--- a/odb/relational/mysql/source.cxx
+++ b/odb/relational/mysql/source.cxx
@@ -506,6 +506,18 @@ namespace relational
<< "//" << endl;
}
+ // If this is a wrapped composite value, then we need to
+ // "unwrap" it. For simple values this is taken care of
+ // by the value_traits specializations.
+ //
+ if (mi.wrapper != 0 && comp_value (mi.t))
+ {
+ // Here we need the wrapper type, not the wrapped type.
+ //
+ member = "wrapper_traits< " + mi.fq_type (false) + " >::" +
+ "get_ref (" + member + ")";
+ }
+
if (comp_value (mi.t))
traits = "composite_value_traits< " + mi.fq_type () + " >";
else
@@ -601,8 +613,9 @@ namespace relational
virtual void
traverse_composite (member_info& mi)
{
- os << "if (" << traits << "::init (i." << mi.var << "value, " <<
- member << "))"
+ os << "if (" << traits << "::init (" << endl
+ << "i." << mi.var << "value," << endl
+ << member << "))"
<< "{"
<< "grew = true;"
<< "}";
@@ -762,6 +775,18 @@ namespace relational
<< "//" << endl;
}
+ // If this is a wrapped composite value, then we need to
+ // "unwrap" it. For simple values this is taken care of
+ // by the value_traits specializations.
+ //
+ if (mi.wrapper != 0 && comp_value (mi.t))
+ {
+ // Here we need the wrapper type, not the wrapped type.
+ //
+ member = "wrapper_traits< " + mi.fq_type (false) + " >::" +
+ "set_ref (" + member + ")";
+ }
+
if (comp_value (mi.t))
traits = "composite_value_traits< " + mi.fq_type () + " >";
else
@@ -846,8 +871,10 @@ namespace relational
virtual void
traverse_composite (member_info& mi)
{
- os << traits << "::init (" << member << ", i." <<
- mi.var << "value, db);"
+ os << traits << "::init (" << endl
+ << member << "," << endl
+ << "i." << mi.var << "value," << endl
+ << "db);"
<< endl;
}
diff --git a/odb/relational/pgsql/common.cxx b/odb/relational/pgsql/common.cxx
index c5e3c9f..d6ef9c3 100644
--- a/odb/relational/pgsql/common.cxx
+++ b/odb/relational/pgsql/common.cxx
@@ -35,9 +35,13 @@ namespace relational
semantics::type& t (type_override_ != 0 ? *type_override_ : m.type ());
- if (comp_value (t))
+ if (semantics::class_* comp = comp_value_wrapper (t))
{
- member_info mi (m, t, var, fq_type_override_);
+ // 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_);
if (pre (mi))
{
traverse_composite (mi);
@@ -46,7 +50,7 @@ namespace relational
}
else if (container (t))
{
- member_info mi (m, t, var, fq_type_override_);
+ member_info mi (m, t, 0, var, fq_type_override_);
if (pre (mi))
{
traverse_container (mi);
@@ -59,7 +63,8 @@ namespace relational
if (semantics::class_* c = object_pointer (t))
{
- member_info mi (m, id_member (*c)->type (), var, fq_type_override_);
+ member_info mi (
+ m, id_member (*c)->type (), 0, var, fq_type_override_);
mi.st = &st;
if (pre (mi))
{
@@ -69,7 +74,7 @@ namespace relational
}
else
{
- member_info mi (m, t, var, fq_type_override_);
+ member_info mi (m, t, 0, var, fq_type_override_);
mi.st = &st;
if (pre (mi))
{
diff --git a/odb/relational/pgsql/common.hxx b/odb/relational/pgsql/common.hxx
index 52fcd2d..f41ca8c 100644
--- a/odb/relational/pgsql/common.hxx
+++ b/odb/relational/pgsql/common.hxx
@@ -30,14 +30,21 @@ namespace relational
{
semantics::data_member& m; // Member.
semantics::type& t; // Member C++ type (m.type () may != t).
+ semantics::type* wrapper; // Wrapper type if member is a wrapper.
+ // In this case t is the wrapped type.
sql_type const* st; // Member SQL type (only simple values).
string& var; // Member variable name with trailing '_'.
// C++ type fq-name.
//
string
- fq_type () const
+ 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 original type from 'm' instead of 't' since the hint
// may be invalid for a different type. Plus, if a type is
// overriden, then the fq_type must be as well.
@@ -51,9 +58,15 @@ namespace relational
member_info (semantics::data_member& m_,
semantics::type& t_,
+ semantics::type* wrapper_,
string& var_,
string const& fq_type)
- : m (m_), t (t_), st (0), var (var_), fq_type_ (fq_type)
+ : m (m_),
+ t (t_),
+ wrapper (wrapper_),
+ st (0),
+ var (var_),
+ fq_type_ (fq_type)
{
}
};
diff --git a/odb/relational/pgsql/schema.cxx b/odb/relational/pgsql/schema.cxx
index 191d522..5bfbc71 100644
--- a/odb/relational/pgsql/schema.cxx
+++ b/odb/relational/pgsql/schema.cxx
@@ -214,7 +214,7 @@ namespace relational
// value
//
- if (semantics::class_* cvt = comp_value (vt))
+ if (semantics::class_* cvt = comp_value_wrapper (vt))
{
object_columns_references ocr (e_, os_, name);
ocr.traverse_composite (m, *cvt, "value", "value");
diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx
index bfc26ba..1bba68a 100644
--- a/odb/relational/pgsql/source.cxx
+++ b/odb/relational/pgsql/source.cxx
@@ -420,6 +420,18 @@ namespace relational
<< "//" << endl;
}
+ // If this is a wrapped composite value, then we need to
+ // "unwrap" it. For simple values this is taken care of
+ // by the value_traits specializations.
+ //
+ if (mi.wrapper != 0 && comp_value (mi.t))
+ {
+ // Here we need the wrapper type, not the wrapped type.
+ //
+ member = "wrapper_traits< " + mi.fq_type (false) + " >::" +
+ "get_ref (" + member + ")";
+ }
+
if (comp_value (mi.t))
traits = "composite_value_traits< " + mi.fq_type () + " >";
else
@@ -515,8 +527,9 @@ namespace relational
virtual void
traverse_composite (member_info& mi)
{
- os << "if (" << traits << "::init (i." << mi.var << "value, " <<
- member << "))"
+ os << "if (" << traits << "::init (" << endl
+ << "i." << mi.var << "value," << endl
+ << member << "))"
<< "{"
<< "grew = true;"
<< "}";
@@ -650,6 +663,18 @@ namespace relational
<< "//" << endl;
}
+ // If this is a wrapped composite value, then we need to
+ // "unwrap" it. For simple values this is taken care of
+ // by the value_traits specializations.
+ //
+ if (mi.wrapper != 0 && comp_value (mi.t))
+ {
+ // Here we need the wrapper type, not the wrapped type.
+ //
+ member = "wrapper_traits< " + mi.fq_type (false) + " >::" +
+ "set_ref (" + member + ")";
+ }
+
if (comp_value (mi.t))
traits = "composite_value_traits< " + mi.fq_type () + " >";
else
@@ -734,8 +759,10 @@ namespace relational
virtual void
traverse_composite (member_info& mi)
{
- os << traits << "::init (" << member << ", i." <<
- mi.var << "value, db);"
+ os << traits << "::init (" << endl
+ << member << "," << endl
+ << "i." << mi.var << "value," << endl
+ << "db);"
<< endl;
}
@@ -1065,7 +1092,8 @@ namespace relational
case ck_map:
case ck_multimap:
{
- if (semantics::class_* ktc = comp_value (container_kt (mt)))
+ if (semantics::class_* ktc =
+ comp_value_wrapper (container_kt (mt)))
{
instance<statement_oids> st;
st->traverse_composite (m, *ktc, "key", "key");
@@ -1083,7 +1111,7 @@ namespace relational
}
}
- if (semantics::class_* vtc = comp_value (vt))
+ if (semantics::class_* vtc = comp_value_wrapper (vt))
{
instance <statement_oids> st;
st->traverse_composite (m, *vtc, "value", "value");
diff --git a/odb/relational/schema.hxx b/odb/relational/schema.hxx
index 24f5c54..5f253c4 100644
--- a/odb/relational/schema.hxx
+++ b/odb/relational/schema.hxx
@@ -423,7 +423,7 @@ namespace relational
os << "," << endl;
- if (semantics::class_* ckt = comp_value (kt))
+ if (semantics::class_* ckt = comp_value_wrapper (kt))
{
instance<object_columns> oc;
oc->traverse_composite (m, *ckt, "key", "key");
@@ -441,7 +441,7 @@ namespace relational
{
os << "," << endl;
- if (semantics::class_* cvt = comp_value (vt))
+ if (semantics::class_* cvt = comp_value_wrapper (vt))
{
instance<object_columns> oc;
oc->traverse_composite (m, *cvt, "value", "value");
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx
index 6546670..7d0c079 100644
--- a/odb/relational/source.hxx
+++ b/odb/relational/source.hxx
@@ -773,7 +773,7 @@ namespace relational
{
instance<object_columns> t (table, false, false);
- if (semantics::class_* ckt = comp_value (*kt))
+ if (semantics::class_* ckt = comp_value_wrapper (*kt))
t->traverse_composite (m, *ckt, "key", "key");
else
{
@@ -792,7 +792,7 @@ namespace relational
instance<object_columns> t (table, false);
- if (semantics::class_* cvt = comp_value (vt))
+ if (semantics::class_* cvt = comp_value_wrapper (vt))
t->traverse_composite (m, *cvt, "value", "value");
else
{
@@ -849,7 +849,7 @@ namespace relational
{
instance<object_columns> t (false, false);
- if (semantics::class_* ckt = comp_value (*kt))
+ if (semantics::class_* ckt = comp_value_wrapper (*kt))
t->traverse_composite (m, *ckt, "key", "key");
else
{
@@ -867,7 +867,7 @@ namespace relational
instance<object_columns> t (false);
- if (semantics::class_* cvt = comp_value (vt))
+ if (semantics::class_* cvt = comp_value_wrapper (vt))
t->traverse_composite (m, *cvt, "value", "value");
else
{
@@ -1025,7 +1025,7 @@ namespace relational
instance<bind_member> bm ("key_", "d", *kt, "key_type", "key");
bm->traverse (m);
- if (semantics::class_* c = comp_value (*kt))
+ if (semantics::class_* c = comp_value_wrapper (*kt))
os << "n += " << in_column_count (*c) << "UL;"
<< endl;
else
@@ -1689,12 +1689,16 @@ namespace relational
};
container_calls (call_type call)
- : object_members_base (true, false), call_ (call)
+ : object_members_base (true, false),
+ call_ (call),
+ obj_prefix_ ("obj.")
{
}
virtual void
- composite (semantics::data_member* m, semantics::class_& c)
+ composite_wrapper (semantics::data_member* m,
+ semantics::class_& c,
+ semantics::type* w)
{
if (m == 0)
{
@@ -1704,7 +1708,25 @@ namespace relational
string old (obj_prefix_);
obj_prefix_ += m->name ();
+
+ // If this is a wrapped composite value, then we need to
+ // "unwrap" it.
+ //
+ if (w != 0)
+ {
+ // Because we cannot have nested containers, m.type () should
+ // be the same as w.
+ //
+ assert (m != 0 && &m->type () == w);
+ string const& type (m->type ().fq_name (m->belongs ().hint ()));
+
+ obj_prefix_ = "wrapper_traits< " + type + " >::" +
+ (call_ == load_call ? "set_ref" : "get_ref") +
+ " (" + obj_prefix_ + ")";
+ }
+
obj_prefix_ += '.';
+
object_members_base::composite (m, c);
obj_prefix_ = old;
}
@@ -1727,7 +1749,7 @@ namespace relational
{
if (!inverse)
os << traits << "::persist (" << endl
- << "obj." << obj_name << "," << endl
+ << obj_name << "," << endl
<< "idb," << endl
<< "sts.container_statment_cache ()." << sts_name << ");"
<< endl;
@@ -1736,7 +1758,7 @@ namespace relational
case load_call:
{
os << traits << "::load (" << endl
- << "obj." << obj_name << "," << endl
+ << obj_name << "," << endl
<< "idb," << endl
<< "sts.container_statment_cache ()." << sts_name << ");"
<< endl;
@@ -1746,7 +1768,7 @@ namespace relational
{
if (!inverse)
os << traits << "::update (" << endl
- << "obj." << obj_name << "," << endl
+ << obj_name << "," << endl
<< "idb," << endl
<< "sts.container_statment_cache ()." << sts_name << ");"
<< endl;
diff --git a/odb/relational/sqlite/common.cxx b/odb/relational/sqlite/common.cxx
index 010e267..d9f79b0 100644
--- a/odb/relational/sqlite/common.cxx
+++ b/odb/relational/sqlite/common.cxx
@@ -35,9 +35,13 @@ namespace relational
semantics::type& t (type_override_ != 0 ? *type_override_ : m.type ());
- if (comp_value (t))
+ if (semantics::class_* comp = comp_value_wrapper (t))
{
- member_info mi (m, t, var, fq_type_override_);
+ // 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_);
if (pre (mi))
{
traverse_composite (mi);
@@ -46,7 +50,7 @@ namespace relational
}
else if (container (t))
{
- member_info mi (m, t, var, fq_type_override_);
+ member_info mi (m, t, 0, var, fq_type_override_);
if (pre (mi))
{
traverse_container (mi);
@@ -59,7 +63,8 @@ namespace relational
if (semantics::class_* c = object_pointer (t))
{
- member_info mi (m, id_member (*c)->type (), var, fq_type_override_);
+ member_info mi (
+ m, id_member (*c)->type (), 0, var, fq_type_override_);
mi.st = &st;
if (pre (mi))
{
@@ -69,7 +74,7 @@ namespace relational
}
else
{
- member_info mi (m, t, var, fq_type_override_);
+ member_info mi (m, t, 0, var, fq_type_override_);
mi.st = &st;
if (pre (mi))
{
diff --git a/odb/relational/sqlite/common.hxx b/odb/relational/sqlite/common.hxx
index 0c9aae0..e3f81a5 100644
--- a/odb/relational/sqlite/common.hxx
+++ b/odb/relational/sqlite/common.hxx
@@ -30,14 +30,21 @@ namespace relational
{
semantics::data_member& m; // Member.
semantics::type& t; // Member C++ type (m.type () may != t).
+ semantics::type* wrapper; // Wrapper type if member is a wrapper.
+ // In this case t is the wrapped type.
sql_type const* st; // Member SQL type (only simple values).
string& var; // Member variable name with trailing '_'.
// C++ type fq-name.
//
string
- fq_type () const
+ 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 original type from 'm' instead of 't' since the hint
// may be invalid for a different type. Plus, if a type is
// overriden, then the fq_type must be as well.
@@ -51,9 +58,15 @@ namespace relational
member_info (semantics::data_member& m_,
semantics::type& t_,
+ semantics::type* wrapper_,
string& var_,
string const& fq_type)
- : m (m_), t (t_), st (0), var (var_), fq_type_ (fq_type)
+ : m (m_),
+ t (t_),
+ wrapper (wrapper_),
+ st (0),
+ var (var_),
+ fq_type_ (fq_type)
{
}
};
diff --git a/odb/relational/sqlite/source.cxx b/odb/relational/sqlite/source.cxx
index 6a99fc8..a482184 100644
--- a/odb/relational/sqlite/source.cxx
+++ b/odb/relational/sqlite/source.cxx
@@ -239,6 +239,18 @@ namespace relational
<< "//" << endl;
}
+ // If this is a wrapped composite value, then we need to
+ // "unwrap" it. For simple values this is taken care of
+ // by the value_traits specializations.
+ //
+ if (mi.wrapper != 0 && comp_value (mi.t))
+ {
+ // Here we need the wrapper type, not the wrapped type.
+ //
+ member = "wrapper_traits< " + mi.fq_type (false) + " >::" +
+ "get_ref (" + member + ")";
+ }
+
if (comp_value (mi.t))
traits = "composite_value_traits< " + mi.fq_type () + " >";
else
@@ -333,8 +345,9 @@ namespace relational
virtual void
traverse_composite (member_info& mi)
{
- os << "if (" << traits << "::init (i." << mi.var << "value, " <<
- member << "))"
+ os << "if (" << traits << "::init (" << endl
+ << "i." << mi.var << "value," << endl
+ << member << "))"
<< "{"
<< "grew = true;"
<< "}";
@@ -413,6 +426,18 @@ namespace relational
<< "//" << endl;
}
+ // If this is a wrapped composite value, then we need to
+ // "unwrap" it. For simple values this is taken care of
+ // by the value_traits specializations.
+ //
+ if (mi.wrapper != 0 && comp_value (mi.t))
+ {
+ // Here we need the wrapper type, not the wrapped type.
+ //
+ member = "wrapper_traits< " + mi.fq_type (false) + " >::" +
+ "set_ref (" + member + ")";
+ }
+
if (comp_value (mi.t))
traits = "composite_value_traits< " + mi.fq_type () + " >";
else
@@ -497,8 +522,10 @@ namespace relational
virtual void
traverse_composite (member_info& mi)
{
- os << traits << "::init (" << member << ", i." <<
- mi.var << "value, db);"
+ os << traits << "::init (" << endl
+ << member << "," << endl
+ << "i." << mi.var << "value," << endl
+ << "db);"
<< endl;
}
diff --git a/odb/relational/type-processor.cxx b/odb/relational/type-processor.cxx
index 5aa8830..24a7325 100644
--- a/odb/relational/type-processor.cxx
+++ b/odb/relational/type-processor.cxx
@@ -127,7 +127,7 @@ namespace relational
// Nothing to do if this is a composite value type.
//
- if (comp_value (t))
+ if (comp_value_wrapper (t))
return;
string type, ref_type;
@@ -228,7 +228,7 @@ namespace relational
wh = t.get<semantics::names*> ("wrapper-hint");
}
- if (comp_value (t))
+ if (comp_value_wrapper (t))
return;
string type;