diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2013-04-05 10:16:48 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2013-04-10 18:46:44 +0200 |
commit | 853d76b58e96aab4e6182cc1234652dfcdd74c14 (patch) | |
tree | 612e54f542dd3d6a11d8a8299f2c82f35e9e714e /odb/relational/schema.hxx | |
parent | c9dbc099d74d92b17724a24823aafe1fcc8ca7e7 (diff) |
Generate alter column migration statements
Diffstat (limited to 'odb/relational/schema.hxx')
-rw-r--r-- | odb/relational/schema.hxx | 160 |
1 files changed, 148 insertions, 12 deletions
diff --git a/odb/relational/schema.hxx b/odb/relational/schema.hxx index b0d70df..69e8089 100644 --- a/odb/relational/schema.hxx +++ b/odb/relational/schema.hxx @@ -64,8 +64,24 @@ namespace relational { typedef drop_column base; - drop_column (emitter_type& e, ostream& os, schema_format f) - : common (e, os), format_ (f), first_ (true) + drop_column (emitter_type& e, + ostream& os, + schema_format f, + bool* first = 0) + : common (e, os), + format_ (f), + first_ (first != 0 ? *first : first_data_), + first_data_ (true) + { + } + + drop_column (drop_column const& c) + : root_context (), // @@ -Wextra + context (), + common (c), + format_ (c.format_), + first_ (&c.first_ != &c.first_data_ ? c.first_ : first_data_), + first_data_ (c.first_data_) { } @@ -92,7 +108,8 @@ namespace relational protected: schema_format format_; - bool first_; + bool& first_; + bool first_data_; }; // Currently only used in migration. @@ -292,8 +309,24 @@ namespace relational { typedef create_column base; - create_column (emitter_type& e, ostream& os, schema_format f) - : common (e, os), format_ (f), first_ (true) + create_column (emitter_type& e, + ostream& os, + schema_format f, + bool* first = 0) + : common (e, os), + format_ (f), + first_ (first != 0 ? *first : first_data_), + first_data_ (true) + { + } + + create_column (create_column const& c) + : root_context (), // @@ -Wextra + context (), + common (c), + format_ (c.format_), + first_ (&c.first_ != &c.first_data_ ? c.first_ : first_data_), + first_data_ (c.first_data_) { } @@ -394,7 +427,8 @@ namespace relational protected: schema_format format_; - bool first_; + bool& first_; + bool first_data_; }; struct create_primary_key: trav_rel::primary_key, virtual context @@ -775,6 +809,78 @@ namespace relational // Migration. // + struct alter_column: trav_rel::alter_column, common + { + typedef alter_column base; + + alter_column (emitter_type& e, + ostream& os, + schema_format f, + bool pre, + bool* first = 0) + : common (e, os), + format_ (f), + pre_ (pre), + first_ (first != 0 ? *first : first_data_), + first_data_ (true), + def_ (e, os, f) + { + } + + alter_column (alter_column const& c) + : root_context (), // @@ -Wextra + context (), + common (c), + format_ (c.format_), + pre_ (c.pre_), + first_ (&c.first_ != &c.first_data_ ? c.first_ : first_data_), + first_data_ (c.first_data_), + def_ (common::e_, common::os_, c.format_) + { + } + + virtual void + alter_header () + { + os << "ALTER COLUMN "; + } + + virtual void + alter (sema_rel::alter_column& ac) + { + // By default use the whole definition. + // + def_->create (ac); + } + + virtual void + traverse (sema_rel::alter_column& ac) + { + assert (ac.null_altered ()); + + // Relax (NULL) in pre and tighten (NOT NULL) in post. + // + if (pre_ != ac.null ()) + return; + + if (first_) + first_ = false; + else + os << "," << endl; + + os << " "; + alter_header (); + alter (ac); + } + + protected: + schema_format format_; + bool pre_; + bool& first_; + bool first_data_; + instance<create_column> def_; + }; + struct alter_table_common: trav_rel::alter_table, common { alter_table_common (emitter_type& e, ostream& os, schema_format f) @@ -796,6 +902,24 @@ namespace relational return 0; } + sema_rel::alter_column* + check_alter_null (sema_rel::alter_table& at, bool v) + { + using sema_rel::alter_column; + + for (sema_rel::alter_table::names_iterator i (at.names_begin ()); + i != at.names_end (); ++i) + { + if (alter_column* ac = dynamic_cast<alter_column*> (&i->nameable ())) + { + if (ac->null_altered () && ac->null () == v) + return ac; + } + } + + return 0; + } + virtual void alter_header (sema_rel::qname const& table) { @@ -829,7 +953,8 @@ namespace relational virtual bool check (sema_rel::alter_table& at) { - return check<sema_rel::add_column> (at); + return check<sema_rel::add_column> (at) || + check_alter_null (at, true); } virtual void @@ -841,9 +966,14 @@ namespace relational pre_statement (); alter_header (at.name ()); - instance<create_column> c (emitter (), stream (), format_); + bool f (true); // Shared first flag. + bool* pf (&f); // (Im)perfect forwarding. + bool tl (true); // (Im)perfect forwarding. + instance<create_column> cc (emitter (), stream (), format_, pf); + instance<alter_column> ac (emitter (), stream (), format_, tl, pf); trav_rel::unames n; - n >> c; + n >> cc; + n >> ac; names (at, n); os << endl; @@ -933,7 +1063,8 @@ namespace relational virtual bool check (sema_rel::alter_table& at) { - return check<sema_rel::drop_column> (at); + return check<sema_rel::drop_column> (at) || + check_alter_null (at, false); } virtual void @@ -945,9 +1076,14 @@ namespace relational pre_statement (); alter_header (at.name ()); - instance<drop_column> c (emitter (), stream (), format_); + bool f (true); // Shared first flag. + bool* pf (&f); // (Im)perfect forwarding. + bool fl (false); // (Im)perfect forwarding. + instance<drop_column> dc (emitter (), stream (), format_, pf); + instance<alter_column> ac (emitter (), stream (), format_, fl, pf); trav_rel::unames n; - n >> c; + n >> dc; + n >> ac; names (at, n); os << endl; |