summaryrefslogtreecommitdiff
path: root/odb/relational/pgsql
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/relational/pgsql
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/relational/pgsql')
-rw-r--r--odb/relational/pgsql/common.cxx101
-rw-r--r--odb/relational/pgsql/common.hxx118
-rw-r--r--odb/relational/pgsql/context.cxx17
-rw-r--r--odb/relational/pgsql/context.hxx8
-rw-r--r--odb/relational/pgsql/model.cxx2
-rw-r--r--odb/relational/pgsql/source.cxx436
6 files changed, 111 insertions, 571 deletions
diff --git a/odb/relational/pgsql/common.cxx b/odb/relational/pgsql/common.cxx
index 0ec9f7c..3d7e01e 100644
--- a/odb/relational/pgsql/common.cxx
+++ b/odb/relational/pgsql/common.cxx
@@ -16,91 +16,10 @@ namespace relational
// member_base
//
- void member_base::
- traverse (semantics::data_member& m)
+ sql_type const& member_base::
+ member_sql_type (semantics::data_member& m)
{
- if (transient (m))
- return;
-
- string var;
-
- if (!var_override_.empty ())
- var = var_override_;
- else
- {
- string const& name (m.name ());
- var = name + (name[name.size () - 1] == '_' ? "" : "_");
- }
-
- bool cq (type_override_ != 0 ? false : const_type (m.type ()));
- semantics::type& t (type_override_ != 0 ? *type_override_ : utype (m));
-
- semantics::type* cont;
- if (semantics::class_* c = composite_wrapper (t))
- {
- // If t is a wrapper, pass the wrapped type. Also pass the
- // original, wrapper type.
- //
- member_info mi (m,
- *c,
- (wrapper (t) ? &t : 0),
- cq,
- var,
- fq_type_override_);
- if (pre (mi))
- {
- traverse_composite (mi);
- post (mi);
- }
- }
- // This cannot be a container if we have a type override.
- //
- else if (type_override_ == 0 && (cont = context::container (m)))
- {
- // The same unwrapping logic as for composite values.
- //
- member_info mi (m,
- *cont,
- (wrapper (t) ? &t : 0),
- cq,
- var,
- fq_type_override_);
- if (pre (mi))
- {
- traverse_container (mi);
- post (mi);
- }
- }
- else
- {
- sql_type const& st (column_sql_type (m, key_prefix_));
-
- if (semantics::class_* c = object_pointer (t))
- {
- member_info mi (m,
- utype (*id_member (*c)),
- 0,
- cq,
- var,
- fq_type_override_);
- mi.st = &st;
- if (pre (mi))
- {
- traverse_object_pointer (mi);
- post (mi);
- }
- }
- else
- {
- member_info mi (m, t, 0, cq, var, fq_type_override_);
- mi.st = &st;
- if (pre (mi))
- {
- traverse_simple (mi);
- post (mi);
- }
- }
- }
+ return parse_sql_type (column_type (m, key_prefix_), m);
}
void member_base::
@@ -310,13 +229,21 @@ namespace relational
"id_string", // TEXT,
"id_bytea" // BYTEA
};
- }
+ }
+
+ member_database_type_id::
+ member_database_type_id (base const& x)
+ : member_base::base (x), // virtual base
+ base (x)
+ {
+ }
member_database_type_id::
member_database_type_id (semantics::type* type,
string const& fq_type,
string const& key_prefix)
- : relational::member_base (type, fq_type, key_prefix)
+ : member_base::base (type, fq_type, key_prefix), // virtual base
+ base (type, fq_type, key_prefix)
{
}
@@ -386,6 +313,8 @@ namespace relational
type_id_ = "pgsql::id_uuid";
}
+ entry<member_database_type_id> member_database_type_id_;
+
//
// query_columns
//
diff --git a/odb/relational/pgsql/common.hxx b/odb/relational/pgsql/common.hxx
index 4f3ee4d..4b9bbd5 100644
--- a/odb/relational/pgsql/common.hxx
+++ b/odb/relational/pgsql/common.hxx
@@ -12,118 +12,18 @@ namespace relational
{
namespace pgsql
{
- struct member_base: virtual relational::member_base, context
+ struct member_base: virtual relational::member_base_impl<sql_type>, context
{
- member_base (base const& x): base (x) {}
+ member_base (base const& x): base (x), base_impl (x) {}
// This c-tor is for the direct use inside the pgsql namespace.
// If you do use this c-tor, you should also explicitly call
- // relational::member_base.
+ // relational::member_base (aka base).
//
member_base () {}
- virtual void
- traverse (semantics::data_member& m);
-
- struct member_info
- {
- semantics::data_member& m; // Member.
- semantics::type& t; // Cvr-unqualified member C++ type, note
- // that m.type () may not be the same as t.
- semantics::type* wrapper; // Wrapper type if member is a composite or
- // container wrapper, also cvr-unqualified.
- // In this case t is the wrapped type.
- bool cq; // True if the original (wrapper) type
- // is const-qualified.
- sql_type const* st; // Member SQL type (only simple values).
- string& var; // Member variable name with trailing '_'.
-
- // C++ type fq-name.
- //
- string
- fq_type (bool unwrap = true) const
- {
- semantics::names* hint;
-
- if (wrapper != 0 && unwrap)
- {
- // Use the hint from the wrapper unless the wrapped type
- // is qualified.
- //
- hint = wrapper->get<semantics::names*> ("wrapper-hint");
- utype (*context::wrapper (*wrapper), hint);
- return t.fq_name (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
- // overriden, then the fq_type must be as well.
- //
- if (fq_type_.empty ())
- {
- semantics::type& t (utype (m, hint));
- return t.fq_name (hint);
- }
- else
- return fq_type_;
- }
-
- string const& fq_type_;
-
- member_info (semantics::data_member& m_,
- semantics::type& t_,
- semantics::type* wrapper_,
- bool cq_,
- string& var_,
- string const& fq_type)
- : m (m_),
- t (t_),
- wrapper (wrapper_),
- cq (cq_),
- st (0),
- var (var_),
- fq_type_ (fq_type)
- {
- }
- };
-
- bool
- container (member_info& mi)
- {
- // This cannot be a container if we have a type override.
- //
- return type_override_ == 0 && context::container (mi.m);
- }
-
- // The false return value indicates that no further callbacks
- // should be called for this member.
- //
- virtual bool
- pre (member_info&)
- {
- return true;
- }
-
- virtual void
- post (member_info&)
- {
- }
-
- virtual void
- traverse_composite (member_info&)
- {
- }
-
- virtual void
- traverse_container (member_info&)
- {
- }
-
- virtual void
- traverse_object_pointer (member_info& mi)
- {
- traverse_simple (mi);
- }
+ virtual sql_type const&
+ member_sql_type (semantics::data_member&);
virtual void
traverse_simple (member_info&);
@@ -208,12 +108,16 @@ namespace relational
string type_;
};
- struct member_database_type_id: member_base
+ struct member_database_type_id: relational::member_database_type_id,
+ member_base
{
+ member_database_type_id (base const&);
+
member_database_type_id (semantics::type* type = 0,
string const& fq_type = string (),
string const& key_prefix = string ());
- string
+
+ virtual string
database_type_id (type&);
virtual void
diff --git a/odb/relational/pgsql/context.cxx b/odb/relational/pgsql/context.cxx
index 8cc4eca..17ceaaa 100644
--- a/odb/relational/pgsql/context.cxx
+++ b/odb/relational/pgsql/context.cxx
@@ -236,17 +236,20 @@ namespace relational
//
sql_type const& context::
- column_sql_type (semantics::data_member& m, string const& kp)
+ parse_sql_type (string const& t, semantics::data_member& m)
{
- string key (kp.empty ()
- ? string ("pgsql-column-sql-type")
- : "pgsql-" + kp + "-column-sql-type");
+ // If this proves to be too expensive, we can maintain a
+ // cache of parsed types.
+ //
+ data::sql_type_cache::iterator i (data_->sql_type_cache_.find (t));
- if (!m.count (key))
+ if (i != data_->sql_type_cache_.end ())
+ return i->second;
+ else
{
try
{
- m.set (key, parse_sql_type (column_type (m, kp)));
+ return (data_->sql_type_cache_[t] = parse_sql_type (t));
}
catch (invalid_sql_type const& e)
{
@@ -256,8 +259,6 @@ namespace relational
throw operation_failed ();
}
}
-
- return m.get<sql_type> (key);
}
sql_type context::
diff --git a/odb/relational/pgsql/context.hxx b/odb/relational/pgsql/context.hxx
index a79cceb..1da353a 100644
--- a/odb/relational/pgsql/context.hxx
+++ b/odb/relational/pgsql/context.hxx
@@ -5,6 +5,8 @@
#ifndef ODB_RELATIONAL_PGSQL_CONTEXT_HXX
#define ODB_RELATIONAL_PGSQL_CONTEXT_HXX
+#include <map>
+
#include <odb/relational/context.hxx>
namespace relational
@@ -69,8 +71,7 @@ namespace relational
{
public:
sql_type const&
- column_sql_type (semantics::data_member&,
- string const& key_prefix = string ());
+ parse_sql_type (string const&, semantics::data_member&);
public:
struct invalid_sql_type
@@ -124,6 +125,9 @@ namespace relational
struct data: base_context::data
{
data (std::ostream& os): base_context::data (os) {}
+
+ typedef std::map<string, sql_type> sql_type_cache;
+ sql_type_cache sql_type_cache_;
};
data* data_;
};
diff --git a/odb/relational/pgsql/model.cxx b/odb/relational/pgsql/model.cxx
index ebd04af..06a7dde 100644
--- a/odb/relational/pgsql/model.cxx
+++ b/odb/relational/pgsql/model.cxx
@@ -34,7 +34,7 @@ namespace relational
{
// Make sure the column is mapped to an integer type.
//
- switch (column_sql_type (m).type)
+ switch (parse_sql_type (column_type (), m).type)
{
case sql_type::SMALLINT:
case sql_type::INTEGER:
diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx
index ceb7dbd..ae19e05 100644
--- a/odb/relational/pgsql/source.cxx
+++ b/odb/relational/pgsql/source.cxx
@@ -103,7 +103,21 @@ namespace relational
struct statement_oids: object_columns_base, context
{
- statement_oids (statement_kind sk): sk_ (sk) {}
+ statement_oids (statement_kind sk, bool first = true)
+ : object_columns_base (first), sk_ (sk)
+ {
+ }
+
+ virtual void
+ traverse_pointer (semantics::data_member& m, semantics::class_& c)
+ {
+ // Ignore certain columns depending on what kind statement we are
+ // generating. See object_columns in common source generator for
+ // details.
+ //
+ if (!(inverse (m, key_prefix_) && sk_ != statement_select))
+ object_columns_base::traverse_pointer (m, c);
+ }
virtual bool
traverse_column (semantics::data_member& m,
@@ -114,10 +128,7 @@ namespace relational
// generating. See object_columns in common source generator for
// details.
//
- if (inverse (m) && sk_ != statement_select)
- return false;
-
- if ((id (m) || readonly (member_path_, member_scope_)) &&
+ if ((id () || readonly (member_path_, member_scope_)) &&
sk_ == statement_update)
return false;
@@ -128,7 +139,7 @@ namespace relational
if (!first)
os << ',' << endl;
- os << oids[column_sql_type (m).type];
+ os << oids[parse_sql_type (column_type (), m).type];
return true;
}
@@ -471,188 +482,37 @@ namespace relational
// init image
//
- struct init_image_member: relational::init_image_member, member_base
+ struct init_image_member: relational::init_image_member_impl<sql_type>,
+ member_base
{
init_image_member (base const& x)
- : member_base::base (x), // virtual base
- base (x),
- member_base (x),
- member_database_type_id_ (base::type_override_,
- base::fq_type_override_,
- base::key_prefix_)
- {
- }
-
- virtual bool
- pre (member_info& mi)
- {
- // Ignore containers (they get their own table) and inverse
- // object pointers (they are not present in this binding).
- //
- if (container (mi) || inverse (mi.m, key_prefix_))
- return false;
-
- if (!member_override_.empty ())
- member = member_override_;
- else
- {
- // If we are generating standard init() and this member
- // contains version, ignore it.
- //
- if (version (mi.m))
- return false;
-
- string const& name (mi.m.name ());
- member = "o." + name;
-
- os << "// " << name << endl
- << "//" << endl;
-
- // If the whole class is readonly, then we will never be
- // called with sk == statement_update.
- //
- if (!readonly (*context::top_object))
- {
- semantics::class_* c;
-
- if (id (mi.m) ||
- readonly (mi.m) ||
- ((c = composite (mi.t)) && readonly (*c)))
- os << "if (sk == statement_insert)";
- }
- }
-
- // 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 && composite (mi.t))
- {
- // Here we need the wrapper type, not the wrapped type.
- //
- member = "wrapper_traits< " + mi.fq_type (false) + " >::" +
- "get_ref (" + member + ")";
- }
-
- if (composite (mi.t))
- {
- os << "{";
- traits = "composite_value_traits< " + mi.fq_type () + " >";
- }
- else
- {
- // When handling a pointer, mi.t is the id type of the referenced
- // object.
- //
- semantics::type& mt (member_utype (mi.m, key_prefix_));
-
- if (semantics::class_* c = object_pointer (mt))
- {
- type = "obj_traits::id_type";
- db_type_id = member_database_type_id_.database_type_id (mi.m);
-
- // Handle NULL pointers and extract the id.
- //
- os << "{"
- << "typedef object_traits< " << class_fq_name (*c) <<
- " > obj_traits;";
-
- if (weak_pointer (mt))
- {
- os << "typedef pointer_traits< " << mi.fq_type () <<
- " > wptr_traits;"
- << "typedef pointer_traits< wptr_traits::" <<
- "strong_pointer_type > ptr_traits;"
- << endl
- << "wptr_traits::strong_pointer_type sp (" <<
- "wptr_traits::lock (" << member << "));";
-
- member = "sp";
- }
- else
- os << "typedef pointer_traits< " << mi.fq_type () <<
- " > ptr_traits;"
- << endl;
-
- os << "bool is_null (ptr_traits::null_ptr (" << member << "));"
- << "if (!is_null)"
- << "{"
- << "const " << type << "& id (" << endl;
-
- if (lazy_pointer (mt))
- os << "ptr_traits::object_id< ptr_traits::element_type > (" <<
- member << ")";
- else
- os << "obj_traits::id (ptr_traits::get_ref (" << member << "))";
-
- os << ");"
- << endl;
-
- member = "id";
- }
- else
- {
- type = mi.fq_type ();
- db_type_id = member_database_type_id_.database_type_id (mi.m);
-
- os << "{"
- << "bool is_null;";
- }
-
- traits = "pgsql::value_traits<\n "
- + type + ",\n "
- + db_type_id + " >";
- }
-
- return true;
- }
-
- virtual void
- post (member_info& mi)
+ : member_base::base (x), // virtual base
+ member_base::base_impl (x), // virtual base
+ base_impl (x),
+ member_base (x)
{
- if (composite (mi.t))
- os << "}";
- else
- {
- // When handling a pointer, mi.t is the id type of the referenced
- // object.
- //
- if (object_pointer (member_utype (mi.m, key_prefix_)))
- {
- os << "}";
-
- if (!null (mi.m, key_prefix_))
- os << "else" << endl
- << "throw null_pointer ();";
- }
-
- os << "i." << mi.var << "null = is_null;"
- << "}";
- }
}
virtual void
- traverse_composite (member_info& mi)
+ set_null (member_info& mi)
{
- os << "if (" << traits << "::init (" << endl
- << "i." << mi.var << "value," << endl
- << member << "," << endl
- << "sk))" << endl
- << "grew = true;";
+ os << "i." << mi.var << "null = true;";
}
virtual void
traverse_integer (member_info& mi)
{
os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");";
+ << "i." << mi.var << "value, is_null, " << member << ");"
+ << "i." << mi.var << "null = is_null;";
}
virtual void
traverse_float (member_info& mi)
{
os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");";
+ << "i." << mi.var << "value, is_null, " << member << ");"
+ << "i." << mi.var << "null = is_null;";
}
virtual void
@@ -667,6 +527,7 @@ namespace relational
<< "size," << endl
<< "is_null," << endl
<< member << ");"
+ << "i." << mi.var << "null = is_null;"
<< "i." << mi.var << "size = size;"
<< "grew = grew || (cap != i." << mi.var << "value.capacity ());";
}
@@ -675,7 +536,8 @@ namespace relational
traverse_date_time (member_info& mi)
{
os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");";
+ << "i." << mi.var << "value, is_null, " << member << ");"
+ << "i." << mi.var << "null = is_null;";
}
virtual void
@@ -688,6 +550,7 @@ namespace relational
<< "size," << endl
<< "is_null," << endl
<< member << ");"
+ << "i." << mi.var << "null = is_null;"
<< "i." << mi.var << "size = size;"
<< "grew = grew || (cap != i." << mi.var << "value.capacity ());";
}
@@ -702,6 +565,7 @@ namespace relational
<< "size," << endl
<< "is_null," << endl
<< member << ");"
+ << "i." << mi.var << "null = is_null;"
<< "i." << mi.var << "size = size;";
}
@@ -715,6 +579,7 @@ namespace relational
<< "size," << endl
<< "is_null," << endl
<< member << ");"
+ << "i." << mi.var << "null = is_null;"
<< "i." << mi.var << "size = size;"
<< "grew = grew || (cap != i." << mi.var << "value.capacity ());";
}
@@ -723,16 +588,9 @@ namespace relational
traverse_uuid (member_info& mi)
{
os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");";
+ << "i." << mi.var << "value, is_null, " << member << ");"
+ << "i." << mi.var << "null = is_null;";
}
-
- private:
- string type;
- string db_type_id;
- string member;
- string traits;
-
- member_database_type_id member_database_type_id_;
};
entry<init_image_member> init_image_member_;
@@ -740,147 +598,21 @@ namespace relational
// init value
//
- struct init_value_member: relational::init_value_member, member_base
+ struct init_value_member: relational::init_value_member_impl<sql_type>,
+ member_base
{
init_value_member (base const& x)
- : member_base::base (x), // virtual base
- base (x),
- member_base (x),
- member_database_type_id_ (base::type_override_,
- base::fq_type_override_,
- base::key_prefix_)
- {
- }
-
- virtual bool
- pre (member_info& mi)
- {
- if (container (mi))
- return false;
-
- if (!member_override_.empty ())
- member = member_override_;
- else
- {
- string const& name (mi.m.name ());
- member = "o." + name;
-
- if (mi.cq)
- member = "const_cast< " + mi.fq_type (false) + "& > (" +
- member + ")";
-
- os << "// " << name << endl
- << "//" << 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 && composite (mi.t))
- {
- // Here we need the wrapper type, not the wrapped type.
- //
- member = "wrapper_traits< " + mi.fq_type (false) + " >::" +
- "set_ref (\n" + member + ")";
- }
-
- if (composite (mi.t))
- traits = "composite_value_traits< " + mi.fq_type () + " >";
- else
- {
- // When handling a pointer, mi.t is the id type of the referenced
- // object.
- //
- semantics::type& mt (member_utype (mi.m, key_prefix_));
-
- if (semantics::class_* c = object_pointer (mt))
- {
- type = "obj_traits::id_type";
- db_type_id = member_database_type_id_.database_type_id (mi.m);
-
- // Handle NULL pointers and extract the id.
- //
- os << "{"
- << "typedef object_traits< " << class_fq_name (*c) <<
- " > obj_traits;"
- << "typedef pointer_traits< " << mi.fq_type () <<
- " > ptr_traits;"
- << endl
- << "if (i." << mi.var << "null)" << endl;
-
- if (null (mi.m, key_prefix_))
- os << member << " = ptr_traits::pointer_type ();";
- else
- os << "throw null_pointer ();";
-
- os << "else"
- << "{"
- << type << " id;";
-
- member = "id";
- }
- else
- {
- type = mi.fq_type ();
- db_type_id = member_database_type_id_.database_type_id (mi.m);
- }
-
- traits = "pgsql::value_traits<\n "
- + type + ",\n "
- + db_type_id + " >";
- }
-
- return true;
- }
-
- virtual void
- post (member_info& mi)
+ : member_base::base (x), // virtual base
+ member_base::base_impl (x), // virtual base
+ base_impl (x),
+ member_base (x)
{
- if (composite (mi.t))
- return;
-
- // When handling a pointer, mi.t is the id type of the referenced
- // object.
- //
- semantics::type& mt (member_utype (mi.m, key_prefix_));
-
- if (object_pointer (mt))
- {
- if (!member_override_.empty ())
- member = member_override_;
- else
- {
- member = "o." + mi.m.name ();
-
- if (mi.cq)
- member = "const_cast< " + mi.fq_type (false) + "& > (" +
- member + ")";
- }
-
- if (lazy_pointer (mt))
- os << member << " = ptr_traits::pointer_type (db, id);";
- else
- os << "// If a compiler error points to the line below, then" << endl
- << "// it most likely means that a pointer used in a member" << endl
- << "// cannot be initialized from an object pointer." << endl
- << "//" << endl
- << member << " = ptr_traits::pointer_type (" << endl
- << "db.load< obj_traits::object_type > (id));";
-
- os << "}"
- << "}";
- }
}
virtual void
- traverse_composite (member_info& mi)
+ get_null (member_info& mi)
{
- os << traits << "::init (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "db);"
- << endl;
+ os << "i." << mi.var << "null";
}
virtual void
@@ -970,14 +702,6 @@ namespace relational
<< "i." << mi.var << "null);"
<< endl;
}
-
- private:
- string type;
- string db_type_id;
- string traits;
- string member;
-
- member_database_type_id member_database_type_id_;
};
entry<init_value_member> init_value_member_;
@@ -1090,7 +814,7 @@ namespace relational
<< "{";
instance<statement_oids> st (statement_select);
- st->traverse_column (*id, "", true);
+ st->traverse (*id);
os << "};";
}
@@ -1111,16 +835,11 @@ namespace relational
bool first (cc.total == cc.id + cc.inverse + cc.readonly +
cc.optimistic_managed);
- {
- instance<statement_oids> st (statement_where);
- st->traverse_column (*id, "", first);
- }
+ instance<statement_oids> st (statement_where, first);
+ st->traverse (*id);
if (optimistic != 0)
- {
- instance<statement_oids> st (statement_where);
- st->traverse_column (*optimistic, "", false);
- }
+ st->traverse (*optimistic);
os << "};";
}
@@ -1134,7 +853,7 @@ namespace relational
<< "{";
instance<statement_oids> st (statement_where);
- st->traverse_column (*id, "", true);
+ st->traverse (*id);
os << "};";
}
@@ -1145,15 +864,9 @@ namespace relational
<< "optimistic_erase_statement_types[] ="
<< "{";
- {
- instance<statement_oids> st (statement_where);
- st->traverse_column (*id, "", true);
- }
-
- {
- instance<statement_oids> st (statement_where);
- st->traverse_column (*optimistic, "", false);
- }
+ instance<statement_oids> st (statement_where);
+ st->traverse (*id);
+ st->traverse (*optimistic);
os << "};";
}
@@ -1258,8 +971,7 @@ namespace relational
bool inv (inv_m != 0);
semantics::type& vt (container_vt (t));
-
- string id_oid (oids[column_sql_type (m, "id").type]);
+ semantics::type& idt (container_idt (m));
// select_all statement types.
//
@@ -1268,20 +980,22 @@ namespace relational
<< "select_all_types[] ="
<< "{";
+ instance<statement_oids> so (statement_where);
+
if (inv)
{
// many(i)-to-many
//
if (container (*inv_m))
- os << oids[column_sql_type (*inv_m, "value").type];
+ so->traverse (*inv_m, idt, "value", "value");
// many(i)-to-one
//
else
- os << oids[column_sql_type (*inv_m).type];
+ so->traverse (*inv_m);
}
else
- os << id_oid;
+ so->traverse (m, idt, "id", "object_id");
os << "};";
}
@@ -1295,30 +1009,22 @@ namespace relational
if (!inv)
{
- os << id_oid << ",";
+ instance<statement_oids> so (statement_insert);
+
+ so->traverse (m, idt, "id", "object_id");
switch (container_kind (t))
{
case ck_ordered:
{
if (!unordered (m))
- os << oids[column_sql_type (m, "index").type] << ",";
-
+ so->traverse (m, container_it (t), "index", "index");
break;
}
case ck_map:
case ck_multimap:
{
- if (semantics::class_* ktc =
- composite_wrapper (container_kt (t)))
- {
- instance<statement_oids> st (statement_insert);
- st->traverse (m, *ktc, "key", "key");
- os << ",";
- }
- else
- os << oids[column_sql_type (m, "key").type] << ",";
-
+ so->traverse (m, container_kt (t), "key", "key");
break;
}
case ck_set:
@@ -1328,14 +1034,7 @@ namespace relational
}
}
- if (semantics::class_* vtc = composite_wrapper (vt))
- {
- instance <statement_oids> st (statement_insert);
- st->traverse (m, *vtc, "value", "value");
- }
- else
- os << oids[column_sql_type (m, "value").type];
-
+ so->traverse (m, vt, "value", "value");
}
else
// MSVC does not allow zero length arrays or uninitialized
@@ -1354,7 +1053,10 @@ namespace relational
<< "{";
if (!inv)
- os << id_oid;
+ {
+ instance<statement_oids> so (statement_where);
+ so->traverse (m, idt, "id", "object_id");
+ }
else
os << "0";