From b0391e168b489811708ca7ba5f71a0eb67b46ffe Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 3 Apr 2013 11:22:42 +0200 Subject: Generate add/drop table migration statements --- odb/relational/schema.hxx | 159 +++++++++++++++++++++++++++++++--------------- 1 file changed, 108 insertions(+), 51 deletions(-) (limited to 'odb/relational/schema.hxx') diff --git a/odb/relational/schema.hxx b/odb/relational/schema.hxx index 86b7419..8ce9f59 100644 --- a/odb/relational/schema.hxx +++ b/odb/relational/schema.hxx @@ -58,84 +58,69 @@ namespace relational // Drop. // - struct drop_index: trav_rel::index, common + struct drop_table: trav_rel::table, + trav_rel::drop_table, + trav_rel::add_table, // override + trav_rel::alter_table, // override + common { - typedef drop_index base; + typedef drop_table base; - drop_index (emitter_type& e, ostream& os, schema_format f) + drop_table (emitter_type& e, ostream& os, schema_format f) : common (e, os), format_ (f) { } - virtual string - name (sema_rel::index& in) - { - return quote_id (in.name ()); - } - - virtual string - table_name (sema_rel::index& in) + virtual void + drop (sema_rel::qname const& table, bool migration) { - return quote_id (static_cast (in.scope ()).name ()); + os << "DROP TABLE " << (migration ? "" : "IF EXISTS ") << + quote_id (table) << endl; } virtual void - drop (string const& /*name*/, string const& /*table*/) + traverse (sema_rel::table& t, bool migration) { - // Most database systems drop indexes together with the table. + // By default we do everything in a single pass. But some + // databases may require the second pass. // - // os << "DROP INDEX IF EXISTS " << quote_id (name) << " ON " << - // table << endl; - } + if (pass_ > 1) + return; - virtual void - traverse (sema_rel::index& in) - { pre_statement (); - drop (name (in), table_name (in)); + drop (t.name (), migration); post_statement (); } - protected: - schema_format format_; - }; - - struct drop_table: trav_rel::table, common - { - typedef drop_table base; - - drop_table (emitter_type& e, ostream& os, schema_format f) - : common (e, os), format_ (f) + virtual void + traverse (sema_rel::table& t) { + traverse (t, false); } virtual void - drop (sema_rel::qname const& table) + traverse (sema_rel::drop_table& dt) { - os << "DROP TABLE IF EXISTS " << quote_id (table) << endl; + using sema_rel::model; + using sema_rel::changeset; + using sema_rel::table; + + // Find the table we are dropping in the base model. + // + changeset& cs (dynamic_cast (dt.scope ())); + model& bm (cs.base_model ()); + table* t (bm.find (dt.name ())); + assert (t != 0); + traverse (*t, true); } virtual void - traverse (sema_rel::table& t) - { - // By default we do everything in a single pass. But some - // databases may require the second pass. - // - if (pass_ > 1) - return; + traverse (sema_rel::add_table&) {} - // Drop indexes. - // - { - instance in (emitter (), stream (), format_); - trav_rel::unames n (*in); - names (t, n); - } + virtual void + traverse (sema_rel::alter_table&) {} - pre_statement (); - drop (t.name ()); - post_statement (); - } + using table::names; void pass (unsigned short p) @@ -646,6 +631,78 @@ namespace relational unsigned short pass_; }; + struct migrate_pre_changeset: trav_rel::changeset, common + { + typedef migrate_pre_changeset base; + + migrate_pre_changeset (emitter_type& e, ostream& os, schema_format f) + : common (e, os), format_ (f) + { + } + + // This version is only called for file migration. + // + virtual void + traverse (sema_rel::changeset& m) + { + traverse (m.names_begin (), m.names_end ()); + } + + virtual void + traverse (sema_rel::changeset::names_iterator begin, + sema_rel::changeset::names_iterator end) + { + for (; begin != end; ++begin) + dispatch (*begin); + } + + void + pass (unsigned short p) + { + pass_ = p; + } + + protected: + schema_format format_; + unsigned short pass_; + }; + + struct migrate_post_changeset: trav_rel::changeset, common + { + typedef migrate_post_changeset base; + + migrate_post_changeset (emitter_type& e, ostream& os, schema_format f) + : common (e, os), format_ (f) + { + } + + // This version is only called for file migration. + // + virtual void + traverse (sema_rel::changeset& m) + { + traverse (m.names_begin (), m.names_end ()); + } + + virtual void + traverse (sema_rel::changeset::names_iterator begin, + sema_rel::changeset::names_iterator end) + { + for (; begin != end; ++begin) + dispatch (*begin); + } + + void + pass (unsigned short p) + { + pass_ = p; + } + + protected: + schema_format format_; + unsigned short pass_; + }; + // // SQL output. // -- cgit v1.1