diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2013-04-08 14:22:00 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2013-04-10 18:46:44 +0200 |
commit | a9da959e71ce02b7e8b0457edcae303043b2799a (patch) | |
tree | 6ad504022ce8b6e841891b40820519d1c1311205 /odb/relational/mysql | |
parent | 104cdccab69dd0b68a756f5d54126a6b74914408 (diff) |
Use single ALTER TABLE to add foreign keys on pass 2
Diffstat (limited to 'odb/relational/mysql')
-rw-r--r-- | odb/relational/mysql/schema.cxx | 96 |
1 files changed, 66 insertions, 30 deletions
diff --git a/odb/relational/mysql/schema.cxx b/odb/relational/mysql/schema.cxx index be058ce..d1721fa 100644 --- a/odb/relational/mysql/schema.cxx +++ b/odb/relational/mysql/schema.cxx @@ -130,14 +130,14 @@ namespace relational create_foreign_key (base const& x): base (x) {} virtual void - generate (sema_rel::foreign_key& fk) + traverse_create (sema_rel::foreign_key& fk) { // MySQL does not support deferrable constraint checking. Output // such foreign keys as comments, for documentation, unless we // are generating embedded schema. // if (fk.not_deferrable ()) - base::generate (fk); + base::traverse_create (fk); else { // Don't bloat C++ code with comment strings if we are @@ -149,17 +149,17 @@ namespace relational os << endl << " /*" << endl << " CONSTRAINT "; - base::create (fk); + create (fk); os << endl << " */"; } } virtual void - traverse (sema_rel::add_foreign_key& afk) + traverse_add (sema_rel::foreign_key& fk) { - if (afk.not_deferrable () || in_comment) - base::traverse (afk); + if (fk.not_deferrable () || in_comment) + base::traverse_add (fk); else { if (format_ != schema_format::sql) @@ -169,7 +169,7 @@ namespace relational << " /*" << endl; - add (afk); + add (fk); os << endl << " */"; @@ -184,37 +184,73 @@ namespace relational }; entry<create_foreign_key> create_foreign_key_; - struct add_foreign_key: relational::add_foreign_key, context + struct create_table: relational::create_table, context { - add_foreign_key (base const& x): base (x) {} + create_table (base const& x): base (x) {} - virtual void - generate (sema_rel::table& t, sema_rel::foreign_key& fk) + // See if there are any undefined foreign keys that are not + // deferrable. + // + bool + check_undefined_fk_deferrable_only (sema_rel::table& t) { - // MySQL has no deferrable constraints. - // - if (fk.not_deferrable ()) - base::generate (t, fk); - else + for (sema_rel::table::names_iterator i (t.names_begin ()); + i != t.names_end (); ++i) { - if (format_ != schema_format::sql) - return; + using sema_rel::foreign_key; - os << "/*" << endl; - os << "ALTER TABLE " << quote_id (t.name ()) << endl - << " ADD CONSTRAINT "; - def_->create (fk); - os << endl - << "*/" << endl - << endl; + if (foreign_key* fk = dynamic_cast<foreign_key*> (&i->nameable ())) + { + if (!fk->count ("mysql-fk-defined") && + fk->not_deferrable ()) + return false; + } } + return true; } - }; - entry<add_foreign_key> add_foreign_key_; - struct create_table: relational::create_table, context - { - create_table (base const& x): base (x) {} + virtual void + traverse (sema_rel::table& t) + { + if (pass_ == 1) + base::traverse (t); + else + { + // Add undefined foreign keys. + // + if (check_undefined_fk (t)) + { + bool deferrable (check_undefined_fk_deferrable_only (t)); + + if (!deferrable || format_ == schema_format::sql) + { + if (deferrable) + { + os << "/*" << endl; + in_comment = true; + } + else + pre_statement (); + + os << "ALTER TABLE " << quote_id (t.name ()); + + instance<create_foreign_key> cfk (*this); + trav_rel::unames n (*cfk); + names (t, n); + os << endl; + + if (deferrable) + { + in_comment = false; + os << "*/" << endl + << endl; + } + else + post_statement (); + } + } + } + } virtual void create_post () |