summaryrefslogtreecommitdiff
path: root/odb/relational
diff options
context:
space:
mode:
Diffstat (limited to 'odb/relational')
-rw-r--r--odb/relational/common.txx6
-rw-r--r--odb/relational/header.cxx10
-rw-r--r--odb/relational/inline.hxx8
-rw-r--r--odb/relational/model.hxx8
-rw-r--r--odb/relational/mssql/source.cxx14
-rw-r--r--odb/relational/oracle/source.cxx6
-rw-r--r--odb/relational/pgsql/header.cxx2
-rw-r--r--odb/relational/pgsql/source.cxx10
-rw-r--r--odb/relational/processor.cxx12
-rw-r--r--odb/relational/source.cxx76
-rw-r--r--odb/relational/source.hxx24
-rw-r--r--odb/relational/validator.cxx16
12 files changed, 111 insertions, 81 deletions
diff --git a/odb/relational/common.txx b/odb/relational/common.txx
index 5e5c5ac..116cfc2 100644
--- a/odb/relational/common.txx
+++ b/odb/relational/common.txx
@@ -36,9 +36,9 @@ namespace relational
{
// A pointer in view might point to an object without id.
//
- semantics::data_member* idm (id_member (*c));
- semantics::type& t (utype (idm != 0 ? *idm : m, &ct));
- semantics::class_* comp (idm != 0 ? composite_wrapper (t) : 0);
+ data_member_path* id (id_member (*c));
+ semantics::type& t (id != 0 ? utype (*id, &ct) : utype (m, &ct));
+ semantics::class_* comp (id != 0 ? composite_wrapper (t) : 0);
member_info mi (m,
(comp != 0 ? *comp : t),
diff --git a/odb/relational/header.cxx b/odb/relational/header.cxx
index 4b8b193..b64ab2a 100644
--- a/odb/relational/header.cxx
+++ b/odb/relational/header.cxx
@@ -12,9 +12,11 @@ traverse_object (type& c)
{
using semantics::data_member;
- data_member* id (id_member (c));
+ data_member_path* id (id_member (c));
+ data_member* idf (id ? id->front () : 0);
+ data_member* idb (id ? id->back () : 0);
bool auto_id (id && auto_ (*id));
- bool base_id (id && &id->scope () != &c); // Comes from base.
+ bool base_id (id && &idf->scope () != &c); // Comes from base.
data_member* opt (context::optimistic (c));
@@ -120,7 +122,7 @@ traverse_object (type& c)
else
{
semantics::class_& b (
- dynamic_cast<semantics::class_&> (id->scope ()));
+ dynamic_cast<semantics::class_&> (idf->scope ()));
os << "typedef object_traits_impl< " << class_fq_name (b) << ", " <<
"id_" << db << " >::id_image_type id_image_type;"
@@ -132,7 +134,7 @@ traverse_object (type& c)
os << "struct id_image_type"
<< "{";
- id_image_member_->traverse (*id);
+ id_image_member_->traverse (*idb);
if (opt != 0)
version_image_member_->traverse (*opt);
diff --git a/odb/relational/inline.hxx b/odb/relational/inline.hxx
index 090779f..583cb13 100644
--- a/odb/relational/inline.hxx
+++ b/odb/relational/inline.hxx
@@ -214,16 +214,16 @@ namespace relational
{
using semantics::data_member;
- data_member* id (id_member (c));
+ data_member_path* id (id_member (c));
+ data_member* idf (id ? id->front () : 0);
bool auto_id (id && auto_ (*id));
- bool base_id (id && &id->scope () != &c); // Comes from base.
+ bool base_id (id && &idf->scope () != &c); // Comes from base.
data_member* optimistic (context::optimistic (c));
// Base class that contains the object id and version for optimistic
// concurrency.
//
- type* base (
- id != 0 && base_id ? dynamic_cast<type*> (&id->scope ()) : 0);
+ type* base (base_id ? dynamic_cast<type*> (&idf->scope ()) : 0);
type* poly_root (context::polymorphic (c));
bool poly (poly_root != 0);
diff --git a/odb/relational/model.hxx b/odb/relational/model.hxx
index 00b3b46..13c67d7 100644
--- a/odb/relational/model.hxx
+++ b/odb/relational/model.hxx
@@ -342,10 +342,10 @@ namespace relational
// Get referenced columns.
//
{
- semantics::data_member& idm (*id_member (c));
+ data_member_path& id (*id_member (c));
instance<object_columns_list> ocl;
- ocl->traverse (idm);
+ ocl->traverse (id);
for (object_columns_list::iterator i (ocl->begin ());
i != ocl->end (); ++i)
@@ -634,10 +634,10 @@ namespace relational
// Get referenced columns.
//
{
- data_member& idm (*id_member (*context::top_object));
+ data_member_path& id (*id_member (*context::top_object));
instance<object_columns_list> ocl;
- ocl->traverse (idm);
+ ocl->traverse (id);
for (object_columns_list::iterator i (ocl->begin ());
i != ocl->end (); ++i)
diff --git a/odb/relational/mssql/source.cxx b/odb/relational/mssql/source.cxx
index 89b5702..42c29a7 100644
--- a/odb/relational/mssql/source.cxx
+++ b/odb/relational/mssql/source.cxx
@@ -44,10 +44,9 @@ namespace relational
string const& column)
{
// Don't add a column for auto id in the INSERT statement.
+ // Only simple, direct id can be auto.
//
- if (sk_ == statement_insert &&
- key_prefix_.empty () &&
- context::id (m) && auto_(m)) // Only simple id can be auto.
+ if (sk_ == statement_insert && key_prefix_.empty () && auto_ (m))
return false;
// Don't update the ROWVERSION column explicitly.
@@ -987,7 +986,7 @@ namespace relational
// See if we have auto id or ROWVERSION version.
//
- semantics::data_member* id (id_member (c));
+ data_member_path* id (id_member (c));
semantics::data_member* ver (optimistic (c));
if (id != 0 && !auto_ (*id))
@@ -1047,7 +1046,8 @@ namespace relational
throw operation_failed ();
}
- r = "; SELECT " + convert_from ("SCOPE_IDENTITY()", *id);
+ r = "; SELECT " +
+ convert_from ("SCOPE_IDENTITY()", *id->back ());
}
return r;
@@ -1061,8 +1061,8 @@ namespace relational
// Top-level auto id column.
//
if (id != 0)
- r += "INSERTED." + convert_from (
- column_qname (*id, column_prefix ()), *id);
+ r += "INSERTED." +
+ convert_from (column_qname (*id), *id->back ());
// Top-level version column.
//
diff --git a/odb/relational/oracle/source.cxx b/odb/relational/oracle/source.cxx
index 310eac6..802bc99 100644
--- a/odb/relational/oracle/source.cxx
+++ b/odb/relational/oracle/source.cxx
@@ -604,16 +604,16 @@ namespace relational
if (p == persist_after_values)
{
- semantics::data_member* id (id_member (c));
+ data_member_path* id (id_member (c));
type* poly_root (polymorphic (c));
bool poly_derived (poly_root != 0 && poly_root != &c);
// Top-level auto id.
//
- if (id != 0 && !poly_derived && id->count ("auto"))
+ if (id != 0 && !poly_derived && auto_ (*id))
r = "RETURNING " +
- convert_from (column_qname (*id, column_prefix ()), *id) +
+ convert_from (column_qname (*id), *id->back ()) +
" INTO " + qp.next ();
}
diff --git a/odb/relational/pgsql/header.cxx b/odb/relational/pgsql/header.cxx
index 19fa573..b3566d8 100644
--- a/odb/relational/pgsql/header.cxx
+++ b/odb/relational/pgsql/header.cxx
@@ -31,7 +31,7 @@ namespace relational
if (abst && !poly)
return;
- semantics::data_member* id (id_member (c));
+ data_member_path* id (id_member (c));
semantics::data_member* optimistic (context::optimistic (c));
column_count_type const& cc (column_count (c));
diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx
index 2bbe232..b8270ac 100644
--- a/odb/relational/pgsql/source.cxx
+++ b/odb/relational/pgsql/source.cxx
@@ -583,16 +583,16 @@ namespace relational
if (p == persist_after_values)
{
- semantics::data_member* id (id_member (c));
+ data_member_path* id (id_member (c));
type* poly_root (polymorphic (c));
bool poly_derived (poly_root != 0 && poly_root != &c);
// Top-level auto id.
//
- if (id != 0 && !poly_derived && id->count ("auto"))
+ if (id != 0 && !poly_derived && auto_ (*id))
r = "RETURNING " +
- convert_from (column_qname (*id, column_prefix ()), *id);
+ convert_from (column_qname (*id), *id->back ());
}
return r;
@@ -610,7 +610,7 @@ namespace relational
if (abst && !poly)
return;
- semantics::data_member* id (id_member (c));
+ data_member_path* id (id_member (c));
semantics::data_member* optimistic (context::optimistic (c));
column_count_type const& cc (column_count (c));
@@ -706,7 +706,7 @@ namespace relational
statement_oids st (statement_insert);
st.traverse (c);
- // Empty array are not portable. So add a dummy member if we
+ // Empty array is not portable. So add a dummy member if we
// are not sending anything with the insert statement.
//
if (cc.total == cc.inverse + cc.optimistic_managed +
diff --git a/odb/relational/processor.cxx b/odb/relational/processor.cxx
index 2979a34..48ddba4 100644
--- a/odb/relational/processor.cxx
+++ b/odb/relational/processor.cxx
@@ -27,8 +27,8 @@ namespace relational
id_column_type ()
{
context& c (context::current ());
- semantics::data_member& id (*context::id_member (*c.top_object));
- return id.get<string> ("column-type");
+ data_member_path& id (*context::id_member (*c.top_object));
+ return id.back ()->get<string> ("column-id-type");
}
struct data_member: traversal::data_member, context
@@ -85,7 +85,7 @@ namespace relational
// This is an object pointer. The column type is the pointed-to
// object id type.
//
- semantics::data_member& id (*id_member (*c));
+ semantics::data_member& id (*id_member (*c)->back ());
semantics::names* idhint;
semantics::type& idt (utype (id, idhint));
@@ -220,7 +220,7 @@ namespace relational
//
{
semantics::class_& r (*object_pointer (t));
- semantics::data_member& id (*id_member (r));
+ semantics::data_member& id (*id_member (r)->front ());
if (id.count ("column"))
m.set ("column", id.get<table_column> ("column"));
@@ -306,7 +306,7 @@ namespace relational
// This is an object pointer. The column type is the pointed-to
// object id type.
//
- semantics::data_member& id (*id_member (*c));
+ semantics::data_member& id (*id_member (*c)->back ());
semantics::names* idhint;
semantics::type& idt (utype (id, idhint));
@@ -824,7 +824,7 @@ namespace relational
m.set ("column-type", src_m->get<string> ("column-type"));
else if (semantics::class_* c = object_pointer (utype (*src_m)))
{
- semantics::data_member& id (*id_member (*c));
+ semantics::data_member& id (*id_member (*c)->back ());
if (id.count ("type"))
m.set ("column-type", id.get<string> ("column-type"));
diff --git a/odb/relational/source.cxx b/odb/relational/source.cxx
index 83e3c40..3b96ab5 100644
--- a/odb/relational/source.cxx
+++ b/odb/relational/source.cxx
@@ -19,9 +19,11 @@ traverse_object (type& c)
{
using semantics::data_member;
- data_member* id (id_member (c));
+ data_member_path* id (id_member (c));
+ data_member* idf (id ? id->front () : 0);
+ data_member* idb (id ? id->back () : 0);
bool auto_id (id && auto_ (*id));
- bool base_id (id && &id->scope () != &c); // Comes from base.
+ bool base_id (id && &idf->scope () != &c); // Comes from base.
data_member* opt (optimistic (c));
@@ -42,7 +44,7 @@ traverse_object (type& c)
if (generate_grow)
{
grow = context::grow (c);
- grow_id = (id ? context::grow (*id) : false) ||
+ grow_id = (id ? context::grow (*idb) : false) ||
(opt ? context::grow (*opt) : false);
}
@@ -188,7 +190,7 @@ traverse_object (type& c)
<< "ODB_POTENTIALLY_UNUSED (db);"
<< endl
<< "id_type id;";
- init_id_value_member_id_image_->traverse (*id);
+ init_id_value_member_id_image_->traverse (*idb);
os << "return id;"
<< "}";
}
@@ -205,7 +207,35 @@ traverse_object (type& c)
<< "ODB_POTENTIALLY_UNUSED (db);"
<< endl
<< "id_type id;";
- init_id_value_member_->traverse (*id);
+
+ // Handle nested id.
+ //
+ if (id->size () > 1)
+ {
+ string var;
+
+ for (data_member_path::const_iterator i (id->begin ());
+ i != id->end ();
+ ++i)
+ {
+ // The same logic as in member_base.
+ //
+ if (!var.empty ())
+ var += "value."; // Composite.
+
+ string const& name ((*i)->name ());
+ var += name;
+
+ if (name[name.size () - 1] != '_')
+ var += '_';
+ }
+
+ instance<init_value_member> t ("id", var);
+ t->traverse (*idb);
+ }
+ else
+ init_id_value_member_->traverse (*idb);
+
os << "return id;"
<< "}";
}
@@ -339,7 +369,7 @@ traverse_object (type& c)
{
// The id reference comes first in the insert statement.
//
- os << "// " << id->name () << endl
+ os << "// " << idf->name () << endl
<< "//" << endl
<< "if (sk == statement_insert)"
<< "{"
@@ -358,7 +388,7 @@ traverse_object (type& c)
// The id reference comes last in the update statement.
//
if (!readonly)
- os << "// " << id->name () << endl
+ os << "// " << idf->name () << endl
<< "//" << endl
<< "if (sk == statement_update)"
<< "{"
@@ -398,7 +428,7 @@ traverse_object (type& c)
if (composite_wrapper (utype (*id)))
os << db << "::statement_kind sk (" << db << "::statement_select);";
- bind_id_member_->traverse (*id);
+ bind_id_member_->traverse (*idb);
if (opt != 0)
{
@@ -516,7 +546,7 @@ traverse_object (type& c)
if (composite_wrapper (utype (*id)))
os << db << "::statement_kind sk (" << db << "::statement_select);";
- init_id_image_member_->traverse (*id);
+ init_id_image_member_->traverse (*idb);
if (opt != 0)
{
@@ -1222,9 +1252,9 @@ traverse_object (type& c)
if (!poly_derived && auto_id && insert_send_auto_id)
{
- string const& n (id->name ());
+ string const& n (idf->name ());
string var ("im." + n + (n[n.size () - 1] == '_' ? "" : "_"));
- init_auto_id (*id, var);
+ init_auto_id (*idf, var); // idf == idb, since auto
os << endl;
}
@@ -1278,9 +1308,9 @@ traverse_object (type& c)
<< "throw object_already_persistent ();"
<< endl;
- if (!poly_derived && auto_id)
+ if (!poly_derived && auto_id) // idf == idb since auto
{
- set_member (*id, "obj", "id (sts.id_image ())", "db", "id_type");
+ set_member (*idf, "obj", "id (sts.id_image ())", "db", "id_type");
os << endl;
}
@@ -1486,9 +1516,9 @@ traverse_object (type& c)
// Extract auto id.
//
- if (auto_id)
+ if (auto_id) // idb == idf, since auto
{
- set_member (*id, "obj", "id (sts.id_image (i))", "db", "id_type");
+ set_member (*idf, "obj", "id (sts.id_image (i))", "db", "id_type");
os << endl;
}
@@ -4867,7 +4897,7 @@ traverse_view (type& c)
{
// container.value = pointer.id
//
- semantics::data_member& id (*id_member (*e.vo->obj));
+ data_member_path& id (*id_member (*e.vo->obj));
c_cols->traverse (imb, utype (id), "value", "value");
o_cols->traverse (id);
@@ -4877,7 +4907,7 @@ traverse_view (type& c)
{
// container.id = pointed-to.id
//
- semantics::data_member& id (*id_member (*vo->obj));
+ data_member_path& id (*id_member (*vo->obj));
c_cols->traverse (imb, utype (id), "id", "object_id", vo->obj);
o_cols->traverse (id);
@@ -4890,7 +4920,7 @@ traverse_view (type& c)
{
// container.id = pointer.id
//
- semantics::data_member& id (*id_member (*e.vo->obj));
+ data_member_path& id (*id_member (*e.vo->obj));
c_cols->traverse (
m, utype (id), "id", "object_id", e.vo->obj);
@@ -4901,7 +4931,7 @@ traverse_view (type& c)
{
// container.value = pointed-to.id
//
- semantics::data_member& id (*id_member (*vo->obj));
+ data_member_path& id (*id_member (*vo->obj));
c_cols->traverse (m, utype (id), "value", "value");
o_cols->traverse (id);
@@ -4961,7 +4991,7 @@ traverse_view (type& c)
{
// container.id = pointed-to.id
//
- semantics::data_member& id (*id_member (*vo->obj));
+ data_member_path& id (*id_member (*vo->obj));
c_cols->traverse (imb, utype (id), "id", "object_id", vo->obj);
o_cols->traverse (id);
@@ -4971,7 +5001,7 @@ traverse_view (type& c)
{
// container.value = pointer.id
//
- semantics::data_member& id (*id_member (*e.vo->obj));
+ data_member_path& id (*id_member (*e.vo->obj));
c_cols->traverse (imb, utype (id), "value", "value");
o_cols->traverse (id);
@@ -4984,7 +5014,7 @@ traverse_view (type& c)
{
// container.value = pointed-to.id
//
- semantics::data_member& id (*id_member (*vo->obj));
+ data_member_path& id (*id_member (*vo->obj));
c_cols->traverse (m, utype (id), "value", "value");
o_cols->traverse (id);
@@ -4994,7 +5024,7 @@ traverse_view (type& c)
{
// container.id = pointer.id
//
- semantics::data_member& id (*id_member (*e.vo->obj));
+ data_member_path& id (*id_member (*e.vo->obj));
c_cols->traverse (m, utype (id), "id", "object_id", e.vo->obj);
o_cols->traverse (id);
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx
index e67931f..f495cef 100644
--- a/odb/relational/source.hxx
+++ b/odb/relational/source.hxx
@@ -211,7 +211,7 @@ namespace relational
semantics::class_& imc (
poly ? dynamic_cast<semantics::class_&> (imf.scope ()) : c);
- semantics::data_member& id (*id_member (imc));
+ data_member_path& id (*id_member (imc));
semantics::type& idt (utype (id));
if (container (imb))
@@ -484,7 +484,7 @@ namespace relational
instance<object_columns_list> l_cols; // Our id columns.
instance<object_columns_list> r_cols; // Other side id columns.
- semantics::data_member& id (*id_member (*us.obj));
+ data_member_path& id (*id_member (*us.obj));
l_cols->traverse (id);
@@ -1018,7 +1018,7 @@ namespace relational
dt = quote_id (table);
da = quote_id (poly ? alias + "_" + table.uname () : alias);
- semantics::data_member& id (*id_member (c));
+ data_member_path& id (*id_member (c));
instance<object_columns_list> oid_cols, cid_cols;
oid_cols->traverse (id);
@@ -1171,7 +1171,7 @@ namespace relational
bool query_;
size_t depth_;
string table_;
- semantics::data_member& id_;
+ data_member_path& id_;
instance<object_columns_list> id_cols_;
};
@@ -1391,7 +1391,7 @@ namespace relational
// Order of these tests is important.
//
- if (!insert_send_auto_id && id (mi.m) && auto_ (mi.m))
+ if (!insert_send_auto_id && auto_ (mi.m))
os << "if (sk != statement_insert && sk != statement_update)"
<< "{";
else if (section_ == 0 && separate_load (mi.m))
@@ -1567,7 +1567,7 @@ namespace relational
// The same logic as in pre().
//
- if (!insert_send_auto_id && id (mi.m) && auto_ (mi.m))
+ if (!insert_send_auto_id && auto_ (mi.m))
block = true;
else if (section_ == 0 && separate_load (mi.m))
block = true;
@@ -1673,7 +1673,7 @@ namespace relational
size_t insert (cc.total - cc.inverse - cc.optimistic_managed);
size_t update (insert - cc.id - cc.readonly - cc.separate_update);
- semantics::data_member* id;
+ data_member_path* id;
if (!insert_send_auto_id && (id = id_member (c)) != 0 && auto_ (*id))
insert -= cc.id;
@@ -2041,7 +2041,7 @@ namespace relational
// If we don't send auto id in INSERT statement, ignore this
// member altogether (we never send auto id in UPDATE).
//
- if (!insert_send_auto_id && id (mi.m) && auto_ (mi.m))
+ if (!insert_send_auto_id && auto_ (mi.m))
return false;
os << "// " << mi.m.name () << endl
@@ -2985,7 +2985,7 @@ namespace relational
bool poly_derived (poly && poly_root != &c);
size_t poly_depth (poly_derived ? polymorphic_depth (c) : 1);
- semantics::data_member* idm (id_member (poly ? *poly_root : c));
+ data_member_path* idm (id_member (poly ? *poly_root : c));
os << "// " << mi.m.name () << (pre_ ? " pre" : " post") << endl
<< "//" << endl;
@@ -3084,7 +3084,7 @@ namespace relational
for (size_t i (0); i < poly_depth - 1; ++i)
id_im += (i == 0 ? ".base" : "->base");
- string const& n (idm->name ());
+ string const& n (idm->front ()->name ());
id_var = id_im + (poly_derived ? "->" : ".") + n +
(n[n.size () - 1] == '_' ? "" : "_");
@@ -3563,7 +3563,7 @@ namespace relational
if (polymorphic (*c))
c = &dynamic_cast<semantics::class_&> (imf.scope ());
- semantics::data_member& inv_id (*id_member (*c));
+ data_member_path& inv_id (*id_member (*c));
qname inv_table; // Other table name.
string inv_qtable;
@@ -6456,7 +6456,7 @@ namespace relational
if (version (m))
p = version_value (m);
- else if (context::id (m) && auto_ (m)) // Only simple id can be auto.
+ else if (auto_ (m)) // Only simple, direct id can be auto.
p = qp_.auto_id ();
else
p = qp_.next ();
diff --git a/odb/relational/validator.cxx b/odb/relational/validator.cxx
index 5dea25f..f78c145 100644
--- a/odb/relational/validator.cxx
+++ b/odb/relational/validator.cxx
@@ -325,20 +325,20 @@ namespace relational
virtual void
traverse_object (type& c)
{
- semantics::data_member* id (id_member (c));
+ data_member_path* id (id_member (c));
if (id != 0)
{
if (semantics::class_* cm = composite_wrapper (utype (*id)))
{
+ location idl (id->front ()->location ());
+
// Composite id cannot be auto.
//
if (auto_ (*id))
{
- os << id->file () << ":" << id->line () << ":" << id->column ()
- << ": error: composite id cannot be automatically assigned"
- << endl;
-
+ error (idl) << "composite id cannot be automatically assigned"
+ << endl;
valid_ = false;
}
@@ -350,8 +350,7 @@ namespace relational
composite_id_members_.traverse (*cm);
if (!valid_)
- os << id->file () << ":" << id->line () << ":" << id->column ()
- << ": info: composite id is defined here" << endl;
+ info (idl) << "composite id is defined here" << endl;
}
// Check that the composite value type is default-constructible.
@@ -366,8 +365,7 @@ namespace relational
<< ": info: provide default constructor for this value type"
<< endl;
- os << id->file () << ":" << id->line () << ":" << id->column ()
- << ": info: composite id is defined here" << endl;
+ info (idl) << "composite id is defined here" << endl;
valid_ = false;
}