From 2aa3cabf1b737e225178230882ee9aadfd817ce0 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 28 Mar 2013 16:04:48 +0200 Subject: Add changelog support for add/drop index/foreign key Also diagnose changes to primary keys and establish the 'alters' association. --- odb/semantics/relational/changelog.cxx | 84 ++++++++++++++++++++++++---- odb/semantics/relational/changeset.cxx | 10 ++-- odb/semantics/relational/changeset.hxx | 4 +- odb/semantics/relational/column.cxx | 29 ++++++---- odb/semantics/relational/column.hxx | 58 ++++++++++++------- odb/semantics/relational/elements.cxx | 38 +++++++++++-- odb/semantics/relational/elements.hxx | 95 ++++++++++++++++++++++++++++++-- odb/semantics/relational/elements.txx | 39 +++++++++++-- odb/semantics/relational/foreign-key.cxx | 81 +++++++++++++++++++++++++-- odb/semantics/relational/foreign-key.hxx | 48 ++++++++++++++++ odb/semantics/relational/index.cxx | 75 ++++++++++++++++++++++++- odb/semantics/relational/index.hxx | 48 ++++++++++++++-- odb/semantics/relational/key.cxx | 4 +- odb/semantics/relational/key.hxx | 14 ++++- odb/semantics/relational/model.cxx | 4 +- odb/semantics/relational/name.hxx | 12 ++++ odb/semantics/relational/table.cxx | 33 +++++------ odb/semantics/relational/table.hxx | 18 +++--- 18 files changed, 582 insertions(+), 112 deletions(-) (limited to 'odb/semantics/relational') diff --git a/odb/semantics/relational/changelog.cxx b/odb/semantics/relational/changelog.cxx index cd94494..fb304ca 100644 --- a/odb/semantics/relational/changelog.cxx +++ b/odb/semantics/relational/changelog.cxx @@ -3,6 +3,7 @@ // license : GNU GPL v3; see accompanying LICENSE file #include +#include #include @@ -10,6 +11,8 @@ #include #include +using namespace std; + namespace semantics { namespace relational @@ -26,10 +29,12 @@ namespace semantics if (p.attribute ("version") != 1) throw parsing (p, "unsupported changelog format version"); - // Get the changesets. Because they are stored in the reverse order, - // first save them to the temporary vector. + // Because things are stored in the reverse order, first save the + // changesets as XML chunks and then re-parse them in the reverse + // order. We have to do it this way so that we can do lookups along + // the alters edges. // - typedef std::vector changesets; + typedef vector changesets; changesets cs; for (parser::event_type e (p.peek ()); @@ -39,22 +44,79 @@ namespace semantics if (p.qname () != xml::qname (xmlns, "changeset")) break; // Not our elements. - p.next (); - cs.push_back (&new_node (p, *this)); - p.next_expect (parser::end_element); - } + ostringstream os; + os.exceptions (ios_base::badbit | ios_base::failbit); + serializer s (os, "changeset", 0); // No pretty-printing. + size_t depth (0); - for (changesets::reverse_iterator i (cs.rbegin ()); i != cs.rend (); ++i) - new_edge (*this, **i); + do + { + switch (p.next ()) + { + case parser::start_element: + { + s.start_element (p.qname ()); + + if (depth == 0) + s.namespace_decl (xmlns, ""); + + typedef parser::attribute_map_type attr_map; + attr_map const& am (p.attribute_map ()); + + for (attr_map::const_iterator i (am.begin ()); + i != am.end (); ++i) + s.attribute (i->first, i->second.value); + + depth++; + break; + } + case parser::end_element: + { + depth--; + s.end_element (); + break; + } + case parser::characters: + { + s.characters (p.value ()); + break; + } + default: + { + depth = 0; + break; + } + } + } while (depth != 0); + + cs.push_back (os.str ()); + } // Get the model. // p.next_expect (parser::start_element, xmlns, "model"); - model_type& m (new_node (p, *this)); new_edge (*this, m); - p.next_expect (parser::end_element); + + // Re-parse the changesets in reverse order. + // + qscope* base (&m); + for (changesets::reverse_iterator i (cs.rbegin ()); i != cs.rend (); ++i) + { + istringstream is (*i); + is.exceptions (ios_base::badbit | ios_base::failbit); + parser ip (is, p.input_name ()); + + ip.next_expect (parser::start_element, xmlns, "changeset"); + + changeset& c (new_node (ip, *base, *this)); + new_edge (*this, c); + base = &c; + + ip.next_expect (parser::end_element); + } + p.next_expect (parser::end_element); } diff --git a/odb/semantics/relational/changeset.cxx b/odb/semantics/relational/changeset.cxx index 8004844..fd5a17f 100644 --- a/odb/semantics/relational/changeset.cxx +++ b/odb/semantics/relational/changeset.cxx @@ -11,15 +11,15 @@ namespace semantics namespace relational { changeset:: - changeset (changeset const& c, graph& g) - : qscope (c, g), - version_ (c.version_) + changeset (changeset const& c, qscope& b, graph& g) + : qscope (c, &b, g), + version_ (c.version_) { } changeset:: - changeset (xml::parser& p, graph& g) - : qscope (p, g), + changeset (xml::parser& p, qscope& b, graph& g) + : qscope (p, &b, g), version_ (p.attribute ("version")) { } diff --git a/odb/semantics/relational/changeset.hxx b/odb/semantics/relational/changeset.hxx index 575eb7b..76fd683 100644 --- a/odb/semantics/relational/changeset.hxx +++ b/odb/semantics/relational/changeset.hxx @@ -21,8 +21,8 @@ namespace semantics public: changeset (version_type v): version_ (v) {} - changeset (changeset const&, graph&); - changeset (xml::parser&, graph&); + changeset (changeset const&, qscope& base, graph&); + changeset (xml::parser&, qscope& base, graph&); virtual string kind () const {return "changeset";} diff --git a/odb/semantics/relational/column.cxx b/odb/semantics/relational/column.cxx index f90b94e..1a47ef7 100644 --- a/odb/semantics/relational/column.cxx +++ b/odb/semantics/relational/column.cxx @@ -104,20 +104,26 @@ namespace semantics // alter_column // alter_column:: - alter_column (alter_column const& ac, uscope&, graph& g) - : unameable (ac, g), - null_altered_ (ac.null_altered_), - null_ (ac.null_) + alter_column (alter_column const& ac, uscope& s, graph& g) + : column (ac, s, g), + alters_ (0), + null_altered_ (ac.null_altered_) { + column* b (s.lookup (ac.name ())); + assert (b != 0); + g.new_edge (*this, *b); } alter_column:: - alter_column (xml::parser& p, uscope&, graph& g) - : unameable (p, g), - null_altered_ (p.attribute_present ("null")), - null_ (null_altered_ ? p.attribute ("null") : false) + alter_column (xml::parser& p, uscope& s, graph& g) + : column (p, s, g), + alters_ (0), + null_altered_ (p.attribute_present ("null")) { - p.content (xml::parser::empty); + name_type n (p.attribute ("name")); + column* b (s.lookup (n)); + assert (b != 0); + g.new_edge (*this, *b); } alter_column& alter_column:: @@ -130,6 +136,9 @@ namespace semantics serialize (xml::serializer& s) const { s.start_element (xmlns, "alter-column"); + + // Here we override the standard column logic. + // unameable::serialize_attributes (s); if (null_altered_) @@ -183,7 +192,7 @@ namespace semantics // { type_info ti (typeid (alter_column)); - ti.add_base (typeid (unameable)); + ti.add_base (typeid (column)); insert (ti); } } diff --git a/odb/semantics/relational/column.hxx b/odb/semantics/relational/column.hxx index 7702a13..11a76e0 100644 --- a/odb/semantics/relational/column.hxx +++ b/odb/semantics/relational/column.hxx @@ -19,35 +19,32 @@ namespace semantics typedef std::vector contained_list; public: - string const& + virtual string const& type () const {return type_;} - bool + virtual bool null () const {return null_;} - void + virtual void null (bool n) {null_ = n;} - string const& + virtual string const& default_ () const {return default__;} - void + virtual void default_ (string const& d) {default__ = d;} - string const& + virtual string const& options () const {return options_;} - void + virtual void options (string const& o) {options_ = o;} public: typedef relational::table table_type; table_type& - table () const - { - return dynamic_cast (scope ()); - } + table () const {return dynamic_cast (scope ());} // Key containment. // @@ -95,12 +92,13 @@ namespace semantics void serialize_attributes (xml::serializer&) const; - private: + protected: string type_; bool null_; string default__; string options_; + private: contained_list contained_; }; @@ -140,24 +138,34 @@ namespace semantics serialize (xml::serializer&) const; }; - class alter_column: public unameable + class alter_column: public column { public: + virtual string const& + type () const {return base ().type ();} + bool null_altered () const {return null_altered_;} - bool - null () const {return null_;} + virtual bool + null () const {return null_altered_ ? null_ : base ().null ();} - void + virtual void null (bool n) {null_ = n; null_altered_ = true;} + virtual string const& + default_ () const {return base ().default_ ();} + + virtual string const& + options () const {return base ().options ();} + public: - alter_column (string const& id) - : unameable (id), null_altered_ (false) - { - } + column& + base () const {return dynamic_cast (alters_->base ());} + public: + alter_column (string const& id) + : column (id, "", false), alters_ (0), null_altered_ (false) {} alter_column (alter_column const&, uscope&, graph&); alter_column (xml::parser&, uscope&, graph&); @@ -173,9 +181,17 @@ namespace semantics virtual void serialize (xml::serializer&) const; + virtual void + add_edge_left (alters& a) + { + assert (alters_ == 0); + alters_ = &a; + } + private: + alters* alters_; + bool null_altered_; - bool null_; }; } } diff --git a/odb/semantics/relational/elements.cxx b/odb/semantics/relational/elements.cxx index e14bc00..d83bff7 100644 --- a/odb/semantics/relational/elements.cxx +++ b/odb/semantics/relational/elements.cxx @@ -45,23 +45,36 @@ namespace semantics { typename names_list::iterator i; - // We want the order to be columns first, then the primary key, - // and then the foreign keys. + // We want the order to be add/alter columns first, then the + // primary key, then other keys, and finnally drop columns. // - if (n.is_a ()) + if (n.is_a () || + n.is_a () || + n.is_a ()) + { i = names_.insert (first_key_, &e); - else + } + else if (!n.is_a ()) { if (n.is_a ()) - first_key_ = i = names_.insert (first_key_, &e); + first_key_ = i = names_.insert ( + first_key_ != names_.end () ? first_key_ : first_drop_column_, + &e); else { - i = names_.insert (names_.end (), &e); + i = names_.insert (first_drop_column_, &e); if (first_key_ == names_.end ()) first_key_ = i; } } + else + { + i = names_.insert (names_.end (), &e); + + if (first_drop_column_ == names_.end ()) + first_drop_column_ = i; + } names_map_[name] = i; iterator_map_[&e] = i; @@ -83,6 +96,11 @@ namespace semantics if (first_key_ == i->second) first_key_++; + // The same for the first drop column. + // + if (first_drop_column_ == i->second) + first_drop_column_++; + names_.erase (i->second); names_map_.erase (e.name ()); iterator_map_.erase (i); @@ -106,6 +124,14 @@ namespace semantics // insert (type_info (typeid (edge))); + // alters + // + { + type_info ti (typeid (alters)); + ti.add_base (typeid (edge)); + insert (ti); + } + // names // { diff --git a/odb/semantics/relational/elements.hxx b/odb/semantics/relational/elements.hxx index 381d7a8..11e7ea8 100644 --- a/odb/semantics/relational/elements.hxx +++ b/odb/semantics/relational/elements.hxx @@ -93,9 +93,57 @@ namespace semantics // public: void - add_edge_right (edge&) + add_edge_right (edge&) {} + + void + remove_edge_right (edge&) {} + }; + + // + // + class alters: public edge + { + public: + node& + base () const {return *base_;} + + node& + modifier () const {return *modifier_;} + + public: + alters () : base_ (0), modifier_ (0) {} + + void + set_left_node (node& m) + { + assert (modifier_ == 0); + modifier_ = &m; + } + + void + set_right_node (node& b) { + assert (base_ == 0); + base_ = &b; } + + void + clear_left_node (node& m) + { + assert (modifier_ == &m); + modifier_ = 0; + } + + void + clear_right_node (node& b) + { + assert (base_ == &b); + base_ = 0; + } + + protected: + node* base_; + node* modifier_; }; // @@ -224,6 +272,7 @@ namespace semantics } using node::add_edge_right; + using node::remove_edge_right; protected: nameable (nameable const&, graph& g); @@ -319,7 +368,7 @@ namespace semantics return names_.empty (); } - // Find. + // Find (this scope only). // template T* @@ -337,30 +386,64 @@ namespace semantics names_const_iterator find (names_type const&) const; + // Lookup in this and all altered scopes until we find what we are + // looking for or hit a stop node of type S (e.g., drop_*). + // + template + T* + lookup (name_type const&); + + public: + scope* + base () const + { + return alters_ != 0 ? &dynamic_cast (alters_->base ()) : 0; + } + public: - scope (): first_key_ (names_.end ()) {} + scope () + : first_key_ (names_.end ()), + first_drop_column_ (names_.end ()), + alters_ (0) {} // Virtual because we call it via scope interface (e.g., in copy). // virtual void + add_edge_left (alters& a) + { + assert (alters_ == 0); + alters_ = &a; + } + + virtual void + remove_edge_left (alters& a) + { + assert (alters_ == &a); + alters_ = 0; + } + + virtual void add_edge_left (names_type&); virtual void remove_edge_left (names_type&); protected: - scope (scope const&, graph&); - scope (xml::parser&, graph&); + scope (scope const&, scope* base, graph&); + scope (xml::parser&, scope* base, graph&); void serialize_content (xml::serializer&) const; - private: + protected: names_list names_; names_map names_map_; names_iterator_map iterator_map_; typename names_list::iterator first_key_; + typename names_list::iterator first_drop_column_; + + alters* alters_; }; template <> diff --git a/odb/semantics/relational/elements.txx b/odb/semantics/relational/elements.txx index e1fd6d5..725fc3f 100644 --- a/odb/semantics/relational/elements.txx +++ b/odb/semantics/relational/elements.txx @@ -54,6 +54,23 @@ namespace semantics // template + template + T* scope:: + lookup (name_type const& name) + { + if (T* r = find (name)) + return r; + + if (scope* b = base ()) + { + if (find (name) == 0) + return b->lookup (name); + } + + return 0; + } + + template template T* scope:: find (name_type const& name) @@ -106,9 +123,16 @@ namespace semantics template scope:: - scope (scope const& s, graph& g) - : first_key_ (names_.end ()) + scope (scope const& s, scope* base, graph& g) + : first_key_ (names_.end ()), + first_drop_column_ (names_.end ()), + alters_ (0) { + // Set the alters edge for lookup. + // + if (base != 0) + g.new_edge (*this, *base); + for (names_const_iterator i (s.names_begin ()); i != s.names_end (); ++i) { @@ -119,9 +143,16 @@ namespace semantics template scope:: - scope (xml::parser& p, graph& g) - : first_key_ (names_.end ()) + scope (xml::parser& p, scope* base, graph& g) + : first_key_ (names_.end ()), + first_drop_column_ (names_.end ()), + alters_ (0) { + // Set the alters edge for lookup. + // + if (base != 0) + g.new_edge (*this, *base); + using namespace xml; p.content (parser::complex); diff --git a/odb/semantics/relational/foreign-key.cxx b/odb/semantics/relational/foreign-key.cxx index 7ef88a6..0407858 100644 --- a/odb/semantics/relational/foreign-key.cxx +++ b/odb/semantics/relational/foreign-key.cxx @@ -89,11 +89,9 @@ namespace semantics return g.new_node (*this, s, g); } - void foreign_key:: - serialize (xml::serializer& s) const + serialize_attributes (xml::serializer& s) const { - s.start_element (xmlns, "foreign-key"); key::serialize_attributes (s); if (deferred ()) @@ -101,7 +99,11 @@ namespace semantics if (on_delete () != no_action) s.attribute ("on-delete", on_delete ()); + } + void foreign_key:: + serialize_content (xml::serializer& s) const + { key::serialize_content (s); // Referenced columns. @@ -118,9 +120,57 @@ namespace semantics } s.end_element (); // references + } + + void foreign_key:: + serialize (xml::serializer& s) const + { + s.start_element (xmlns, "foreign-key"); + serialize_attributes (s); + serialize_content (s); s.end_element (); // foreign-key } + // add_foreign_key + // + add_foreign_key& add_foreign_key:: + clone (uscope& s, graph& g) const + { + return g.new_node (*this, s, g); + } + + void add_foreign_key:: + serialize (xml::serializer& s) const + { + s.start_element (xmlns, "add-foreign-key"); + foreign_key::serialize_attributes (s); + foreign_key::serialize_content (s); + s.end_element (); + } + + // drop_foreign_key + // + drop_foreign_key:: + drop_foreign_key (xml::parser& p, uscope&, graph& g) + : unameable (p, g) + { + p.content (xml::parser::empty); + } + + drop_foreign_key& drop_foreign_key:: + clone (uscope& s, graph& g) const + { + return g.new_node (*this, s, g); + } + + void drop_foreign_key:: + serialize (xml::serializer& s) const + { + s.start_element (xmlns, "drop-foreign-key"); + unameable::serialize_attributes (s); + s.end_element (); + } + // type info // namespace @@ -129,16 +179,37 @@ namespace semantics { init () { - unameable::parser_map_["foreign-key"] = - &unameable::parser_impl; + unameable::parser_map& m (unameable::parser_map_); + + m["foreign-key"] = &unameable::parser_impl; + m["add-foreign-key"] = &unameable::parser_impl; + m["drop-foreign-key"] = &unameable::parser_impl; using compiler::type_info; + // foreign_key + // { type_info ti (typeid (foreign_key)); ti.add_base (typeid (key)); insert (ti); } + + // add_foreign_key + // + { + type_info ti (typeid (add_foreign_key)); + ti.add_base (typeid (foreign_key)); + insert (ti); + } + + // drop_foreign_key + // + { + type_info ti (typeid (drop_foreign_key)); + ti.add_base (typeid (unameable)); + insert (ti); + } } } init_; } diff --git a/odb/semantics/relational/foreign-key.hxx b/odb/semantics/relational/foreign-key.hxx index 5d551fe..50a3fae 100644 --- a/odb/semantics/relational/foreign-key.hxx +++ b/odb/semantics/relational/foreign-key.hxx @@ -83,6 +83,13 @@ namespace semantics virtual void serialize (xml::serializer&) const; + protected: + void + serialize_attributes (xml::serializer&) const; + + void + serialize_content (xml::serializer&) const; + private: qname referenced_table_; columns referenced_columns_; @@ -95,6 +102,47 @@ namespace semantics std::istream& operator>> (std::istream&, foreign_key::action_type&); + + class add_foreign_key: public foreign_key + { + public: + add_foreign_key (string const& id, + qname const& rt, + bool d, + action_type od = no_action) + : foreign_key (id, rt, d, od) {} + add_foreign_key (foreign_key const& fk, uscope& s, graph& g) + : foreign_key (fk, s, g) {} + add_foreign_key (xml::parser& p, uscope& s, graph& g) + : foreign_key (p, s, g) {} + + virtual add_foreign_key& + clone (uscope&, graph&) const; + + virtual string + kind () const {return "add foreign key";} + + virtual void + serialize (xml::serializer&) const; + }; + + class drop_foreign_key: public unameable + { + public: + drop_foreign_key (string const& id): unameable (id) {} + drop_foreign_key (drop_foreign_key const& dfk, uscope&, graph& g) + : unameable (dfk, g) {} + drop_foreign_key (xml::parser&, uscope&, graph&); + + virtual drop_foreign_key& + clone (uscope&, graph&) const; + + virtual string + kind () const {return "drop foreign key";} + + virtual void + serialize (xml::serializer&) const; + }; } } diff --git a/odb/semantics/relational/index.cxx b/odb/semantics/relational/index.cxx index 5ff1a26..b38c6e4 100644 --- a/odb/semantics/relational/index.cxx +++ b/odb/semantics/relational/index.cxx @@ -10,6 +10,8 @@ namespace semantics { namespace relational { + // index + // index:: index (index const& i, uscope& s, graph& g) : key (i, s, g), @@ -35,9 +37,8 @@ namespace semantics } void index:: - serialize (xml::serializer& s) const + serialize_attributes (xml::serializer& s) const { - s.start_element (xmlns, "index"); key::serialize_attributes (s); if (!type ().empty ()) @@ -48,11 +49,57 @@ namespace semantics if (!options ().empty ()) s.attribute ("options", options ()); + } + void index:: + serialize (xml::serializer& s) const + { + s.start_element (xmlns, "index"); + serialize_attributes (s); key::serialize_content (s); s.end_element (); } + // add_index + // + add_index& add_index:: + clone (uscope& s, graph& g) const + { + return g.new_node (*this, s, g); + } + + void add_index:: + serialize (xml::serializer& s) const + { + s.start_element (xmlns, "add-index"); + index::serialize_attributes (s); + index::serialize_content (s); + s.end_element (); + } + + // drop_index + // + drop_index:: + drop_index (xml::parser& p, uscope&, graph& g) + : unameable (p, g) + { + p.content (xml::parser::empty); + } + + drop_index& drop_index:: + clone (uscope& s, graph& g) const + { + return g.new_node (*this, s, g); + } + + void drop_index:: + serialize (xml::serializer& s) const + { + s.start_element (xmlns, "drop-index"); + unameable::serialize_attributes (s); + s.end_element (); + } + // type info // namespace @@ -61,15 +108,37 @@ namespace semantics { init () { - unameable::parser_map_["index"] = &unameable::parser_impl; + unameable::parser_map& m (unameable::parser_map_); + + m["index"] = &unameable::parser_impl; + m["add-index"] = &unameable::parser_impl; + m["drop-index"] = &unameable::parser_impl; using compiler::type_info; + // index + // { type_info ti (typeid (index)); ti.add_base (typeid (key)); insert (ti); } + + // add_index + // + { + type_info ti (typeid (add_index)); + ti.add_base (typeid (index)); + insert (ti); + } + + // drop_index + // + { + type_info ti (typeid (drop_index)); + ti.add_base (typeid (unameable)); + insert (ti); + } } } init_; } diff --git a/odb/semantics/relational/index.hxx b/odb/semantics/relational/index.hxx index 621f36a..500c341 100644 --- a/odb/semantics/relational/index.hxx +++ b/odb/semantics/relational/index.hxx @@ -31,10 +31,7 @@ namespace semantics string const& t = string (), string const& m = string (), string const& o = string ()) - : key (id), type_ (t), method_ (m), options_ (o) - { - } - + : key (id), type_ (t), method_ (m), options_ (o) {} index (index const&, uscope&, graph&); index (xml::parser&, uscope&, graph&); @@ -50,11 +47,54 @@ namespace semantics virtual void serialize (xml::serializer&) const; + protected: + void + serialize_attributes (xml::serializer&) const; + private: string type_; // E.g., "UNIQUE", etc. string method_; // E.g., "BTREE", etc. string options_; // Database-specific index options. }; + + class add_index: public index + { + public: + add_index (string const& id, + string const& t = string (), + string const& m = string (), + string const& o = string ()) + : index (id, t, m, o) {} + add_index (index const& i, uscope& s, graph& g): index (i, s, g) {} + add_index (xml::parser& p, uscope& s, graph& g): index (p, s, g) {} + + virtual add_index& + clone (uscope&, graph&) const; + + virtual string + kind () const {return "add index";} + + virtual void + serialize (xml::serializer&) const; + }; + + class drop_index: public unameable + { + public: + drop_index (string const& id): unameable (id) {} + drop_index (drop_index const& di, uscope&, graph& g) + : unameable (di, g) {} + drop_index (xml::parser&, uscope&, graph&); + + virtual drop_index& + clone (uscope&, graph&) const; + + virtual string + kind () const {return "drop index";} + + virtual void + serialize (xml::serializer&) const; + }; } } diff --git a/odb/semantics/relational/key.cxx b/odb/semantics/relational/key.cxx index e27253c..dc0fbe0 100644 --- a/odb/semantics/relational/key.cxx +++ b/odb/semantics/relational/key.cxx @@ -18,7 +18,7 @@ namespace semantics for (contains_iterator i (k.contains_begin ()); i != k.contains_end (); ++i) { - column* c (s.find (i->column ().name ())); + column* c (s.lookup (i->column ().name ())); assert (c != 0); g.new_edge (*this, *c, i->options ()); } @@ -42,7 +42,7 @@ namespace semantics p.content (parser::empty); uname n (p.attribute ("name")); - column* c (s.find (n)); + column* c (s.lookup (n)); if (c == 0) throw parsing (p, "invalid column name in the 'name' attribute"); diff --git a/odb/semantics/relational/key.hxx b/odb/semantics/relational/key.hxx index 8d64993..184433e 100644 --- a/odb/semantics/relational/key.hxx +++ b/odb/semantics/relational/key.hxx @@ -6,6 +6,7 @@ #define ODB_SEMANTICS_RELATIONAL_KEY_HXX #include +#include namespace semantics { @@ -55,6 +56,8 @@ namespace semantics typedef std::vector contains_list; public: + typedef contains_list::size_type contains_size_type; + typedef pointer_iterator contains_iterator; @@ -65,9 +68,18 @@ namespace semantics contains_iterator contains_end () const {return contains_.end ();} - contains_list::size_type + contains_size_type contains_size () const {return contains_.size ();} + contains& + contains_at (contains_size_type i) const {return *contains_[i];} + + public: + typedef relational::table table_type; + + table_type& + table () const {return dynamic_cast (scope ());} + public: key (std::string const& id): unameable (id) {} diff --git a/odb/semantics/relational/model.cxx b/odb/semantics/relational/model.cxx index 6515591..678debe 100644 --- a/odb/semantics/relational/model.cxx +++ b/odb/semantics/relational/model.cxx @@ -12,14 +12,14 @@ namespace semantics { model:: model (model const& m, graph& g) - : qscope (m, g), + : qscope (m, 0, g), version_ (m.version_) { } model:: model (xml::parser& p, graph& g) - : qscope (p, g), + : qscope (p, 0, g), version_ (p.attribute ("version")) { } diff --git a/odb/semantics/relational/name.hxx b/odb/semantics/relational/name.hxx index 18c7509..06794be 100644 --- a/odb/semantics/relational/name.hxx +++ b/odb/semantics/relational/name.hxx @@ -125,6 +125,18 @@ namespace semantics public: friend bool + operator== (qname const& x, qname const& y) + { + return x.components_ == y.components_; + } + + friend bool + operator!= (qname const& x, qname const& y) + { + return x.components_ != y.components_; + } + + friend bool operator< (qname const& x, qname const& y) { return x.components_ < y.components_; diff --git a/odb/semantics/relational/table.cxx b/odb/semantics/relational/table.cxx index 682196c..17265bd 100644 --- a/odb/semantics/relational/table.cxx +++ b/odb/semantics/relational/table.cxx @@ -13,14 +13,20 @@ namespace semantics // table // table:: - table (table const& t, qscope&, graph& g) - : qnameable (t, g), uscope (t, g) + table (table const& t, qscope& s, graph& g, bool b) + : qnameable (t, g), + uscope (t, (b ? s.lookup (t.name ()) : 0), g) { } table:: - table (xml::parser& p, qscope&, graph& g) - : qnameable (p, g), uscope (p, g) + table (xml::parser& p, qscope& s, graph& g, bool b) + : qnameable (p, g), + uscope ( + p, + (b ? s.lookup ( + p.attribute ("name")) : 0), + g) { } @@ -81,18 +87,6 @@ namespace semantics // alter_table // - alter_table:: - alter_table (alter_table const& t, qscope&, graph& g) - : qnameable (t, g), uscope (t, g) - { - } - - alter_table:: - alter_table (xml::parser& p, qscope&, graph& g) - : qnameable (p, g), uscope (p, g) - { - } - alter_table& alter_table:: clone (qscope& s, graph& g) const { @@ -103,8 +97,8 @@ namespace semantics serialize (xml::serializer& s) const { s.start_element (xmlns, "alter-table"); - qnameable::serialize_attributes (s); - uscope::serialize_content (s); + table::serialize_attributes (s); + table::serialize_content (s); s.end_element (); } @@ -154,8 +148,7 @@ namespace semantics // { type_info ti (typeid (alter_table)); - ti.add_base (typeid (qnameable)); - ti.add_base (typeid (uscope)); + ti.add_base (typeid (table)); insert (ti); } } diff --git a/odb/semantics/relational/table.hxx b/odb/semantics/relational/table.hxx index effd552..ae4c96c 100644 --- a/odb/semantics/relational/table.hxx +++ b/odb/semantics/relational/table.hxx @@ -15,8 +15,8 @@ namespace semantics { public: table (string const& id): qnameable (id) {} - table (table const&, qscope&, graph&); - table (xml::parser&, qscope&, graph&); + table (table const&, qscope&, graph&, bool base = false); + table (xml::parser&, qscope&, graph&, bool base = false); virtual table& clone (qscope&, graph&) const; @@ -66,12 +66,14 @@ namespace semantics serialize (xml::serializer&) const; }; - class alter_table: public qnameable, public uscope + class alter_table: public table { public: - alter_table (string const& id): qnameable (id) {} - alter_table (alter_table const&, qscope&, graph&); - alter_table (xml::parser&, qscope&, graph&); + alter_table (string const& id): table (id) {} + alter_table (alter_table const& at, qscope& s, graph& g) + : table (at, s, g, true) {} + alter_table (xml::parser& p, qscope& s, graph& g) + : table (p, s, g, true) {} virtual alter_table& clone (qscope&, graph&) const; @@ -81,10 +83,6 @@ namespace semantics virtual void serialize (xml::serializer&) const; - - // Resolve ambiguity. - // - using qnameable::scope; }; } } -- cgit v1.1