summaryrefslogtreecommitdiff
path: root/odb/relational/mssql/schema.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'odb/relational/mssql/schema.cxx')
-rw-r--r--odb/relational/mssql/schema.cxx652
1 files changed, 0 insertions, 652 deletions
diff --git a/odb/relational/mssql/schema.cxx b/odb/relational/mssql/schema.cxx
deleted file mode 100644
index 77a6271..0000000
--- a/odb/relational/mssql/schema.cxx
+++ /dev/null
@@ -1,652 +0,0 @@
-// file : odb/relational/mssql/schema.cxx
-// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <odb/relational/schema.hxx>
-
-#include <odb/relational/mssql/common.hxx>
-#include <odb/relational/mssql/context.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace mssql
- {
- namespace schema
- {
- namespace relational = relational::schema;
- using relational::table_set;
-
- struct sql_emitter: relational::sql_emitter
- {
- sql_emitter (const base& x): base (x) {}
-
- virtual void
- post ()
- {
- if (!first_) // Ignore empty statements.
- {
- os << ';' << endl
- << "GO" << endl
- << endl;
- }
- }
- };
- entry<sql_emitter> sql_emitter_;
-
- //
- // File.
- //
-
- struct sql_file: relational::sql_file, context
- {
- sql_file (const base& x): base (x) {}
-
- virtual void
- prologue ()
- {
- // Suppress the (x rows affected) messages from sqlcmd for DML
- // statements. We only use DML for schema version management.
- //
- if ((model == 0 || model->version () != 0) &&
- !options.suppress_schema_version ())
- os << "SET NOCOUNT ON;" << endl
- << endl;
- }
- };
- entry<sql_file> sql_file_;
-
- //
- // Drop.
- //
-
- struct drop_column: relational::drop_column, context
- {
- drop_column (base const& x): base (x) {}
-
- virtual void
- traverse (sema_rel::drop_column& dc)
- {
- if (first_)
- first_ = false;
- else
- os << "," << endl
- << " ";
-
- os << quote_id (dc.name ());
- }
- };
- entry<drop_column> drop_column_;
-
- struct drop_foreign_key: relational::drop_foreign_key, context
- {
- drop_foreign_key (base const& x): base (x) {}
-
- virtual void
- drop (sema_rel::table& t, sema_rel::foreign_key& fk)
- {
- bool migration (dropped_ == 0);
-
- if (migration)
- {
- if (fk.not_deferrable ())
- pre_statement ();
- else
- {
- if (format_ != schema_format::sql)
- return;
-
- os << "/*" << endl;
- }
- }
- else
- {
- // Here we drop potentially deferrable keys and also need to
- // test if the key exists.
- //
- pre_statement ();
-
- os << "IF OBJECT_ID(" << quote_string (fk.name ()) << ", " <<
- quote_string ("F") << ") IS NOT NULL" << endl
- << " ";
- }
-
- os << "ALTER TABLE " << quote_id (t.name ()) << endl
- << (migration ? " " : " ") << "DROP CONSTRAINT " <<
- quote_id (fk.name ()) << endl;
-
-
- if (!migration || fk.not_deferrable ())
- post_statement ();
- else
- os << "*/" << endl
- << endl;
- }
-
- virtual void
- traverse (sema_rel::drop_foreign_key& dfk)
- {
- // Find the foreign key we are dropping in the base model.
- //
- sema_rel::foreign_key& fk (find<sema_rel::foreign_key> (dfk));
-
- bool c (!fk.not_deferrable () && !in_comment);
-
- if (c && format_ != schema_format::sql)
- return;
-
- if (!first_)
- os << (c ? "" : ",") << endl
- << " ";
-
- if (c)
- os << "/* ";
-
- os << quote_id (fk.name ());
-
- if (c)
- os << " */";
-
- if (first_)
- {
- if (c)
- // There has to be a real name otherwise the whole statement
- // would have been commented out.
- //
- os << endl
- << " ";
- else
- first_ = false;
- }
- }
- };
- entry<drop_foreign_key> drop_foreign_key_;
-
- struct drop_index: relational::drop_index, context
- {
- drop_index (base const& x): base (x) {}
-
- virtual void
- drop (sema_rel::index& in)
- {
- sema_rel::table& t (static_cast<sema_rel::table&> (in.scope ()));
-
- os << "DROP INDEX " << name (in) << " ON " <<
- quote_id (t.name ()) << endl;
- }
- };
- entry<drop_index> drop_index_;
-
- struct drop_table: relational::drop_table, context
- {
- drop_table (base const& x): base (x) {}
-
- virtual void
- drop (sema_rel::table& t, bool migration)
- {
- // SQL Server has no IF EXISTS conditional for dropping tables.
- // The following approach appears to be the recommended way to
- // drop a table if it exists.
- //
- sema_rel::qname const& name (t.name ());
-
- pre_statement ();
-
- if (!migration)
- os << "IF OBJECT_ID(" << quote_string (name.string ()) <<
- ", " << quote_string ("U") << ") IS NOT NULL" << endl
- << " ";
-
- os << "DROP TABLE " << quote_id (name) << endl;
-
- post_statement ();
- }
- };
- entry<drop_table> drop_table_;
-
- //
- // Create.
- //
-
- struct create_column: relational::create_column, context
- {
- create_column (base const& x): base (x) {}
-
- virtual void
- traverse (sema_rel::add_column& ac)
- {
- if (first_)
- first_ = false;
- else
- os << "," << endl
- << " ";
-
- create (ac);
- }
-
- virtual void
- auto_ (sema_rel::primary_key&)
- {
- os << " IDENTITY";
- }
- };
- entry<create_column> create_column_;
-
- struct create_foreign_key: relational::create_foreign_key, context
- {
- create_foreign_key (base const& x): base (x) {}
-
- void
- diagnose (sema_rel::foreign_key& fk)
- {
- if (fk.on_delete () != sema_rel::foreign_key::no_action)
- {
- cerr << "warning: foreign key '" << fk.name () << "' has " <<
- "ON DELETE clause but is disabled in SQL Server due to lack "
- "of deferrable constraint support" << endl;
-
- cerr << "info: consider using non-deferrable foreign keys (" <<
- "--fkeys-deferrable-mode)" << endl;
- }
- }
-
- virtual void
- traverse_create (sema_rel::foreign_key& fk)
- {
- // SQL Server 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::traverse_create (fk);
- else
- {
- diagnose (fk);
-
- // Don't bloat C++ code with comment strings if we are
- // generating embedded schema.
- //
- if (format_ != schema_format::sql)
- return;
-
- os << endl
- << " /*" << endl
- << " CONSTRAINT ";
- create (fk);
- os << endl
- << " */";
- }
- }
-
- virtual void
- traverse_add (sema_rel::foreign_key& fk)
- {
- bool c (!fk.not_deferrable () && !in_comment);
-
- if (c)
- diagnose (fk);
-
- if (c && format_ != schema_format::sql)
- return;
-
- if (!first_)
- os << (c ? "" : ",") << endl
- << " ";
-
- if (c)
- os << "/*" << endl
- << " ";
-
- os << "CONSTRAINT ";
- create (fk);
-
- if (c)
- os << endl
- << " */";
-
- if (first_)
- {
- if (c)
- // There has to be a real key otherwise the whole statement
- // would have been commented out.
- //
- os << endl
- << " ";
- else
- first_ = false;
- }
- }
-
- virtual void
- deferrable (sema_rel::deferrable)
- {
- // This will still be called to output the comment.
- }
- };
- entry<create_foreign_key> create_foreign_key_;
-
- struct create_table: relational::create_table, context
- {
- create_table (base const& x): base (x) {}
-
- // See if there are any undefined foreign keys that are not
- // deferrable.
- //
- bool
- check_undefined_fk_deferrable_only (sema_rel::table& t)
- {
- for (sema_rel::table::names_iterator i (t.names_begin ());
- i != t.names_end (); ++i)
- {
- using sema_rel::foreign_key;
-
- if (foreign_key* fk = dynamic_cast<foreign_key*> (&i->nameable ()))
- {
- if (!fk->count ("mssql-fk-defined") &&
- fk->not_deferrable ())
- return false;
- }
- }
- return true;
- }
-
- 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 ()) << endl
- << " ADD ";
-
- 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 ();
- }
- }
- }
- }
- };
- entry<create_table> create_table_;
-
- //
- // Alter.
- //
-
- struct alter_column: relational::alter_column, context
- {
- alter_column (base const& x): base (x) {}
-
- virtual void
- traverse (sema_rel::column& c)
- {
- // Relax (NULL) in pre and tighten (NOT NULL) in post.
- //
- if (pre_ != c.null ())
- return;
-
- using sema_rel::table;
- table& at (static_cast<table&> (c.scope ()));
-
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ()) << endl
- << " ALTER COLUMN ";
- alter (c);
- os << endl;
-
- post_statement ();
- }
- };
- entry<alter_column> alter_column_;
-
- struct alter_table_pre: relational::alter_table_pre, context
- {
- alter_table_pre (base const& x): base (x) {}
-
- // Check if we are only dropping deferrable foreign keys.
- //
- bool
- check_drop_deferrable_only (sema_rel::alter_table& at)
- {
- for (sema_rel::alter_table::names_iterator i (at.names_begin ());
- i != at.names_end (); ++i)
- {
- using sema_rel::foreign_key;
- using sema_rel::drop_foreign_key;
-
- if (drop_foreign_key* dfk =
- dynamic_cast<drop_foreign_key*> (&i->nameable ()))
- {
- foreign_key& fk (find<foreign_key> (*dfk));
-
- if (fk.not_deferrable ())
- return false;
- }
- }
- return true;
- }
-
- virtual void
- alter (sema_rel::alter_table& at)
- {
- // SQL Server can only alter one kind of thing at a time.
- //
- if (check<sema_rel::drop_foreign_key> (at))
- {
- bool deferrable (check_drop_deferrable_only (at));
-
- if (!deferrable || format_ == schema_format::sql)
- {
- if (deferrable)
- {
- os << "/*" << endl;
- in_comment = true;
- }
- else
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ()) << endl
- << " DROP CONSTRAINT ";
-
- instance<drop_foreign_key> dfc (*this);
- trav_rel::unames n (*dfc);
- names (at, n);
- os << endl;
-
- if (deferrable)
- {
- in_comment = false;
- os << "*/" << endl
- << endl;
- }
- else
- post_statement ();
- }
- }
-
- if (check<sema_rel::add_column> (at))
- {
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ()) << endl
- << " ADD ";
-
- instance<create_column> cc (*this);
- trav_rel::unames n (*cc);
- names (at, n);
- os << endl;
-
- post_statement ();
- }
-
- // For ALTER COLUMN, SQL Server can only have one per ALTER TABLE.
- //
- {
- bool tl (true); // (Im)perfect forwarding.
- instance<alter_column> ac (*this, tl);
- trav_rel::unames n (*ac);
- names (at, n);
- }
- }
- };
- entry<alter_table_pre> alter_table_pre_;
-
- struct alter_table_post: relational::alter_table_post, context
- {
- alter_table_post (base const& x): base (x) {}
-
- // Check if we are only adding deferrable foreign keys.
- //
- bool
- check_add_deferrable_only (sema_rel::alter_table& at)
- {
- for (sema_rel::alter_table::names_iterator i (at.names_begin ());
- i != at.names_end (); ++i)
- {
- using sema_rel::add_foreign_key;
-
- if (add_foreign_key* afk =
- dynamic_cast<add_foreign_key*> (&i->nameable ()))
- {
- if (afk->not_deferrable ())
- return false;
- }
- }
- return true;
- }
-
- virtual void
- alter (sema_rel::alter_table& at)
- {
- // SQL Server can only alter one kind of thing at a time.
- //
- if (check<sema_rel::drop_column> (at))
- {
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ()) << endl
- << " DROP COLUMN ";
-
- instance<drop_column> dc (*this);
- trav_rel::unames n (*dc);
- names (at, n);
- os << endl;
-
- post_statement ();
- }
-
- // For ALTER COLUMN, SQL Server can only have one per ALTER TABLE.
- //
- {
- bool fl (false); // (Im)perfect forwarding.
- instance<alter_column> ac (*this, fl);
- trav_rel::unames n (*ac);
- names (at, n);
- }
-
- if (check<sema_rel::add_foreign_key> (at))
- {
- bool deferrable (check_add_deferrable_only (at));
-
- if (!deferrable || format_ == schema_format::sql)
- {
- if (deferrable)
- {
- os << "/*" << endl;
- in_comment = true;
- }
- else
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ()) << endl
- << " ADD ";
-
- instance<create_foreign_key> cfc (*this);
- trav_rel::unames n (*cfc);
- names (at, n);
- os << endl;
-
- if (deferrable)
- {
- in_comment = false;
- os << "*/" << endl
- << endl;
- }
- else
- post_statement ();
- }
- }
- }
- };
- entry<alter_table_post> alter_table_post_;
-
- //
- // Schema version table.
- //
-
- struct version_table: relational::version_table, context
- {
- version_table (base const& x): base (x) {}
-
- virtual void
- create_table ()
- {
- pre_statement ();
-
- os << "IF OBJECT_ID(" << quote_string (table_.string ()) <<
- ", " << quote_string ("U") << ") IS NULL" << endl
- << " CREATE TABLE " << qt_ << " (" << endl
- << " " << qn_ << " VARCHAR(256) NOT NULL PRIMARY KEY," << endl
- << " " << qv_ << " BIGINT NOT NULL," << endl
- << " " << qm_ << " BIT NOT NULL)" << endl;
-
- post_statement ();
- }
-
- virtual void
- create (sema_rel::version v)
- {
- pre_statement ();
-
- os << "IF NOT EXISTS (SELECT 1 FROM " << qt_ << " WHERE " << qn_ <<
- " = " << qs_ << ")" << endl
- << " INSERT INTO " << qt_ << " (" << endl
- << " " << qn_ << ", " << qv_ << ", " << qm_ << ")" << endl
- << " VALUES (" << qs_ << ", " << v << ", 0)" << endl;
-
- post_statement ();
- }
- };
- entry<version_table> version_table_;
- }
- }
-}