diff options
Diffstat (limited to 'odb/relational')
-rw-r--r-- | odb/relational/common.txx | 6 | ||||
-rw-r--r-- | odb/relational/header.cxx | 10 | ||||
-rw-r--r-- | odb/relational/inline.hxx | 8 | ||||
-rw-r--r-- | odb/relational/model.hxx | 8 | ||||
-rw-r--r-- | odb/relational/mssql/source.cxx | 14 | ||||
-rw-r--r-- | odb/relational/oracle/source.cxx | 6 | ||||
-rw-r--r-- | odb/relational/pgsql/header.cxx | 2 | ||||
-rw-r--r-- | odb/relational/pgsql/source.cxx | 10 | ||||
-rw-r--r-- | odb/relational/processor.cxx | 12 | ||||
-rw-r--r-- | odb/relational/source.cxx | 76 | ||||
-rw-r--r-- | odb/relational/source.hxx | 24 | ||||
-rw-r--r-- | odb/relational/validator.cxx | 16 |
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; } |