diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2013-04-03 11:22:42 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2013-04-10 18:46:44 +0200 |
commit | b0391e168b489811708ca7ba5f71a0eb67b46ffe (patch) | |
tree | ce15fb5ce0998ec27696152054609bb5dd4f45c3 /odb/relational/oracle | |
parent | e356a9112750e836197a8545bcf6cedad0c1ebe1 (diff) |
Generate add/drop table migration statements
Diffstat (limited to 'odb/relational/oracle')
-rw-r--r-- | odb/relational/oracle/schema.cxx | 82 |
1 files changed, 54 insertions, 28 deletions
diff --git a/odb/relational/oracle/schema.cxx b/odb/relational/oracle/schema.cxx index 28fd4fd..bd0acda 100644 --- a/odb/relational/oracle/schema.cxx +++ b/odb/relational/oracle/schema.cxx @@ -93,49 +93,72 @@ namespace relational drop_table (base const& x): base (x) {} virtual void - traverse (sema_rel::table& t) + traverse (sema_rel::table& t, bool migration) { if (pass_ != 1) return; - qname const& table (t.name ()); - - // Oracle has no IF EXISTS conditional for dropping objects. The - // PL/SQL approach below seems to be the least error-prone and the - // most widely used of the alternatives. - // - pre_statement (); - os << "BEGIN" << endl - << " BEGIN" << endl - << " EXECUTE IMMEDIATE 'DROP TABLE " << quote_id (table) << - " CASCADE CONSTRAINTS';" << endl - << " EXCEPTION" << endl - << " WHEN OTHERS THEN" << endl - << " IF SQLCODE != -942 THEN RAISE; END IF;" << endl - << " END;" << endl; - - // Drop the sequence if we have auto primary key. - // using sema_rel::primary_key; + qname const& table (t.name ()); + sema_rel::table::names_iterator i (t.find ("")); // Special name. primary_key* pk (i != t.names_end () ? &dynamic_cast<primary_key&> (i->nameable ()) : 0); - if (pk != 0 && pk->auto_ ()) + string qt (quote_id (table)); + string qs (pk != 0 && pk->auto_ () + ? quote_id (sequence_name (table)) + : ""); + + if (migration) + { + pre_statement (); + os << "DROP TABLE " << qt << " CASCADE CONSTRAINTS" << endl; + post_statement (); + + // Drop the sequence if we have auto primary key. + // + if (!qs.empty ()) + { + pre_statement (); + os << "DROP SEQUENCE " << qs << endl; + post_statement (); + } + } + else { - os << " BEGIN" << endl - << " EXECUTE IMMEDIATE 'DROP SEQUENCE " << - quote_id (sequence_name (table)) << "';" << endl + // Oracle has no IF EXISTS conditional for dropping objects. The + // PL/SQL approach below seems to be the least error-prone and the + // most widely used of the alternatives. + // + pre_statement (); + os << "BEGIN" << endl + << " BEGIN" << endl + << " EXECUTE IMMEDIATE 'DROP TABLE " << qt << " CASCADE " << + "CONSTRAINTS';" << endl << " EXCEPTION" << endl << " WHEN OTHERS THEN" << endl - << " IF SQLCODE != -2289 THEN RAISE; END IF;" << endl + << " IF SQLCODE != -942 THEN RAISE; END IF;" << endl << " END;" << endl; - } - os << "END;" << endl; - post_statement (); + // Drop the sequence if we have auto primary key. + // + if (!qs.empty ()) + { + os << " BEGIN" << endl + << " EXECUTE IMMEDIATE 'DROP SEQUENCE " << qs << + "';" << endl + << " EXCEPTION" << endl + << " WHEN OTHERS THEN" << endl + << " IF SQLCODE != -2289 THEN RAISE; END IF;" << endl + << " END;" << endl; + } + + os << "END;" << endl; + post_statement (); + } } }; entry<drop_table> drop_table_; @@ -217,7 +240,10 @@ namespace relational { if (pass_ == 1) { - tables_.insert (t.name ()); // Add it before to cover self-refs. + // In migration we always add foreign keys on pass 2. + // + if (!t.is_a<sema_rel::add_table> ()) + tables_.insert (t.name ()); // Add it before to cover self-refs. base::traverse (t); // Create the sequence if we have auto primary key. |