public static void TestCopySchema(string pathToSchemaScript) { TestHelper.DropDb("TEST_SOURCE"); TestHelper.DropDb("TEST_COPY"); //create the db from sql script TestHelper.ExecSql("CREATE DATABASE TEST_SOURCE", ""); TestHelper.ExecBatchSql(File.ReadAllText(pathToSchemaScript), "TEST_SOURCE"); SqlConnection.ClearAllPools(); //load the model from newly created db and create a copy var copy = new Database("TEST_COPY"); copy.Connection = TestHelper.GetConnString("TEST_SOURCE"); copy.Load(); SqlConnection.ClearAllPools(); var scripted = copy.ScriptCreate(); TestHelper.ExecBatchSql(scripted, "master"); //compare the dbs to make sure they are the same var source = new Database("TEST_SOURCE"); source.Connection = TestHelper.GetConnString("TEST_SOURCE"); source.Load(); copy.Load(); TestCompare(source, copy); }
public string ScriptAssignDefaultSchema(Database db) { if (!string.IsNullOrEmpty(DefaultSchema)) { return string.Format("ALTER USER {0} WITH DEFAULT_SCHEMA = {1}", Name, DefaultSchema); } return string.Empty; }
public void TestMultiColumnKey() { var t1 = new Table("dbo", "t1"); t1.Columns.Add(new Column("c2", "varchar", 10, false, null)); t1.Columns.Add(new Column("c1", "int", false, null)); t1.AddConstraint(new Constraint("pk_t1", "PRIMARY KEY", "c1,c2")); var t2 = new Table("dbo", "t2"); t2.Columns.Add(new Column("c1", "int", false, null)); t2.Columns.Add(new Column("c2", "varchar", 10, false, null)); t2.Columns.Add(new Column("c3", "int", false, null)); var fk = new ForeignKey(t2, "fk_test", "c3,c2", t1, "c1,c2"); var db = new Database("TESTDB"); db.Tables.Add(t1); db.Tables.Add(t2); db.ForeignKeys.Add(fk); db.Connection = TestHelper.GetConnString("TESTDB"); db.ExecCreate(true); db.Load(); Assert.AreEqual("c3", db.FindForeignKey("fk_test", "dbo").Columns[0]); Assert.AreEqual("c2", db.FindForeignKey("fk_test", "dbo").Columns[1]); Assert.AreEqual("c1", db.FindForeignKey("fk_test", "dbo").RefColumns[0]); Assert.AreEqual("c2", db.FindForeignKey("fk_test", "dbo").RefColumns[1]); db.ExecCreate(true); }
public override int Run(string[] remainingArguments) { var sourceDb = new Database(); var targetDb = new Database(); sourceDb.Connection = _source; targetDb.Connection = _target; sourceDb.Load(); targetDb.Load(); var diff = sourceDb.Compare(targetDb); if (diff.IsDiff) { Console.WriteLine("Databases are different."); Console.WriteLine(diff.SummarizeChanges(_verbose)); if (!string.IsNullOrEmpty(_outDiff)) { Console.WriteLine(); if (!_overwrite && File.Exists(_outDiff)) { if (!ConsoleQuestion.AskYN(string.Format("{0} already exists - do you want to replace it", _outDiff))) { return 1; } } File.WriteAllText(_outDiff, diff.Script()); Console.WriteLine("Script to make the databases identical has been created at {0}", Path.GetFullPath(_outDiff)); } return 1; } Console.WriteLine("Databases are identical."); return 0; }
public string ScriptAlter(Database db) { bool replaced = false; string alter = null; if (RoutineType != RoutineKind.XmlSchemaCollection) { IList<ParseError> errors; TSqlFragment script = new TSql120Parser(initialQuotedIdentifiers: QuotedId).Parse(new StringReader(Text), out errors); alter = ScriptBase(db, string.Join(string.Empty, script.ScriptTokenStream.Select(t => { if (t.TokenType == TSqlTokenType.Create && !replaced) { replaced = true; return "ALTER"; } else { return t.Text; } }))); } if (replaced) return alter; else throw new Exception(string.Format("Unable to script routine {0} {1}.{2} as ALTER", RoutineType, Schema, Name)); }
public string ScriptCreate(Database db) { IEnumerable<string> commands = Files.Select( (kvp, index) => string.Format("{0} ASSEMBLY [{1}]\r\n{2}FROM {3}\r\n{4}", index == 0 ? "CREATE" : "ALTER", Name, index == 0 ? string.Empty : "ADD FILE ", "0x" + new SoapHexBinary(kvp.Value).ToString(), index == 0 ? "WITH PERMISSION_SET = " + PermissionSet : string.Format("AS N'{0}'", kvp.Key))); string script = string.Join("\r\nGO\r\n", commands.ToArray()); return script; }
public string ScriptAlter(Database db) { if (RoutineType != RoutineKind.XmlSchemaCollection) { var regex = new Regex(SqlCreateRegex, RegexOptions.IgnoreCase); var match = regex.Match(Text); var group = match.Groups[1]; if (group.Success) { return ScriptBase(db, Text.Substring(0, group.Index) + "ALTER" + Text.Substring(group.Index + group.Length)); } } throw new Exception(string.Format("Unable to script routine {0} {1}.{2} as ALTER", RoutineType, Schema, Name)); }
public string ScriptCreate(Database db) { string login = PasswordHash == null ? string.Empty : string.Format(@"IF SUSER_ID('{0}') IS NULL BEGIN CREATE LOGIN {0} WITH PASSWORD = {1} HASHED END ", Name, "0x" + new SoapHexBinary(PasswordHash)); return login + string.Format("CREATE USER {0} {1}", Name, PasswordHash == null ? "WITHOUT LOGIN" : "FOR LOGIN " + Name) + "\r\n" + string.Join("\r\n", DatabaseRoles.Select( r => string.Format("/*ALTER ROLE {0} ADD MEMBER {1}*/ exec sp_addrolemember '{0}', '{1}'", r, Name)) .ToArray()); }
public void TestCollate() { var pathToSchema = ConfigHelper.TestSchemaDir + "/SANDBOX3_GBL.SQL"; TestHelper.DropDb("TEST_SOURCE"); //create the db from sql script TestHelper.ExecSql("CREATE DATABASE TEST_SOURCE", ""); TestHelper.ExecBatchSql(File.ReadAllText(pathToSchema), "TEST_SOURCE"); //load the model from newly created db and check collation var copy = new Database("TEST_COPY"); copy.Connection = TestHelper.GetConnString("TEST_SOURCE"); copy.Load(); Assert.AreEqual("SQL_Latin1_General_CP1_CI_AS", copy.FindProp("COLLATE").Value); }
private string ScriptBase(Database db, string definition) { var before = ScriptQuotedIdAndAnsiNulls(db, false); var after = ScriptQuotedIdAndAnsiNulls(db, true); if (!string.IsNullOrEmpty(after)) after = Environment.NewLine + "GO" + Environment.NewLine + after; if (RoutineType == RoutineKind.Trigger) after += string.Format("{0} TRIGGER [{1}].[{2}] ON [{3}].[{4}]", Disabled ? "DISABLE" : "ENABLE", Owner, Name, RelatedTableSchema, RelatedTableName) + Environment.NewLine + "GO" + Environment.NewLine; if (string.IsNullOrEmpty(definition)) definition = string.Format("/* missing definition for {0} [{1}].[{2}] */", RoutineType, Owner, Name); return before + definition + after; }
public void TestCreateTableParser() { var t = new Table("dbo", "Status"); t.Columns.Add(new Column("id", "int", false, null){Position = 1}); t.Columns.Add(new Column("code", "char", 1, false, null){Position = 2}); t.Columns.Add(new Column("description", "varchar", 20, false, null){Position = 3}); t.Columns.Find("id").Identity = new Identity(1, 1); t.Constraints.Add(new Constraint("PK_Status", "PRIMARY KEY", "id")); var db = new Database(); var script = t.ScriptCreate(); db.ParseSql(script); var t2 = db.FindTable("Status", "dbo"); var diff = t2.Compare(t); Assert.IsFalse(diff.IsDiff); }
private static void HandleDataTables(Database db, string tableNames) { foreach (var value in tableNames.Split(',')) { var schema = "dbo"; var name = value; if (value.Contains(".")) { schema = value.Split('.')[0]; name = value.Split('.')[1]; } var t = db.FindTable(name, schema); if (t == null) { Console.WriteLine( "warning: could not find data table {0}.{1}", schema, name); } if (db.DataTables.Contains(t)) continue; db.DataTables.Add(t); } }
private string ScriptQuotedIdAndAnsiNulls(Database db, bool databaseDefaults) { var script = ""; var defaultQuotedId = !QuotedId; if (db != null && db.FindProp("QUOTED_IDENTIFIER") != null) { defaultQuotedId = db.FindProp("QUOTED_IDENTIFIER").Value == "ON"; } if (defaultQuotedId != QuotedId) { script += string.Format(@"SET QUOTED_IDENTIFIER {0} {1}GO{1}", ((databaseDefaults ? defaultQuotedId : QuotedId) ? "ON" : "OFF"), Environment.NewLine); } var defaultAnsiNulls = !AnsiNull; if (db != null && db.FindProp("ANSI_NULLS") != null) { defaultAnsiNulls = db.FindProp("ANSI_NULLS").Value == "ON"; } if (defaultAnsiNulls != AnsiNull) { script += string.Format(@"SET ANSI_NULLS {0} {1}GO{1}", ((databaseDefaults ? defaultAnsiNulls : AnsiNull) ? "ON" : "OFF"), Environment.NewLine); } return script; }
private static void TestCompare(Database source, Database copy) { //compare the dbs to make sure they are the same Assert.IsFalse(source.Compare(copy).IsDiff); // get a second opinion // if you ever find your license key /* var cmd = string.Format("/c {0}\\SQLDBDiffConsole.exe {1} {2} {0}\\{3}", ConfigHelper.SqlDbDiffPath, "localhost\\SQLEXPRESS " + copy.Name + " NULL NULL Y", "localhost\\SQLEXPRESS " + source.Name + " NULL NULL Y", "SqlDbDiff.XML CompareResult.txt null"); Console.WriteLine(cmd); var proc = new Process(); proc.StartInfo.FileName = "cmd.exe"; proc.StartInfo.Arguments = cmd; proc.StartInfo.WindowStyle = ProcessWindowStyle.Normal; proc.Start(); proc.WaitForExit(); Assert.AreEqual("no difference", File.ReadAllLines("CompareResult.txt")[0]); */ }
public void TestScriptDeletedProc() { var source = new Database(); source.Routines.Add(new Routine("dbo", "test", null)); source.FindRoutine("test", "dbo").RoutineType = Routine.RoutineKind.Procedure; source.FindRoutine("test", "dbo").Text = @" create procedure [dbo].[test] as select * from Table1 "; var target = new Database(); var scriptUp = target.Compare(source).Script(); var scriptDown = source.Compare(target).Script(); Assert.IsTrue(scriptUp.ToLower().Contains("drop procedure [dbo].[test]")); Assert.IsTrue(scriptDown.ToLower().Contains("create procedure [dbo].[test]")); }
public void TestScriptViewInsteadOfTrigger() { var setupSQL1 = @" CREATE TABLE [dbo].[t1] ( a INT NOT NULL, CONSTRAINT [PK] PRIMARY KEY (a) ) "; var setupSQL2 = @" CREATE VIEW [dbo].[v1] AS SELECT * FROM t1 "; var setupSQL3 = @" CREATE TRIGGER [dbo].[TR_v1] ON [dbo].[v1] INSTEAD OF DELETE AS DELETE FROM [dbo].[t1] FROM [dbo].[t1] INNER JOIN DELETED ON DELETED.a = [dbo].[t1].a "; var db = new Database("TestScriptViewInsteadOfTrigger"); db.Connection = ConfigHelper.TestDB.Replace("database=TESTDB", "database=" + db.Name); db.ExecCreate(true); DBHelper.ExecSql(db.Connection, setupSQL1); DBHelper.ExecSql(db.Connection, setupSQL2); DBHelper.ExecSql(db.Connection, setupSQL3); db.Dir = db.Name; db.Load(); // Required in order to expose the exception db.ScriptToDir(); var triggers = db.Routines.Where(x => x.RoutineType == Routine.RoutineKind.Trigger).ToList(); Assert.AreEqual(1, triggers.Count()); Assert.AreEqual("TR_v1", triggers[0].Name); Assert.IsTrue(File.Exists(db.Name + "\\triggers\\TR_v1.sql")); }
public void TestScriptFKSameName() { var setupSQL = @" CREATE SCHEMA [s2] AUTHORIZATION [dbo] CREATE TABLE [dbo].[t1a] ( a INT NOT NULL, CONSTRAINT [PK_1a] PRIMARY KEY (a) ) CREATE TABLE [dbo].[t1b] ( a INT NOT NULL, CONSTRAINT [FKName] FOREIGN KEY ([a]) REFERENCES [dbo].[t1a] ([a]) ) CREATE TABLE [s2].[t2a] ( a INT NOT NULL, CONSTRAINT [PK_2a] PRIMARY KEY (a) ) CREATE TABLE [s2].[t2b] ( a INT NOT NULL, CONSTRAINT [FKName] FOREIGN KEY ([a]) REFERENCES [s2].[t2a] ([a]) ) "; var db = new Database("TestScriptFKSameName"); db.Connection = ConfigHelper.TestDB.Replace("database=TESTDB", "database=" + db.Name); db.ExecCreate(true); DBHelper.ExecSql(db.Connection, setupSQL); db.Dir = db.Name; db.Load(); // Required in order to expose the exception db.ScriptToDir(); Assert.AreEqual(2, db.ForeignKeys.Count()); Assert.AreEqual(db.ForeignKeys[0].Name, db.ForeignKeys[1].Name); Assert.AreNotEqual(db.ForeignKeys[0].Table.Owner, db.ForeignKeys[1].Table.Owner); }
public void TestFindTableRegEx() { var db = new Database(); db.Tables.Add(new Table("dbo", "cmicDeductible")); db.Tables.Add(new Table("dbo", "cmicZipCode")); db.Tables.Add(new Table("dbo", "cmicState")); db.Tables.Add(new Table("dbo", "Policy")); db.Tables.Add(new Table("dbo", "Location")); db.Tables.Add(new Table("dbo", "Rate")); Assert.AreEqual(3, db.FindTablesRegEx("^cmic").Count); Assert.AreEqual(1, db.FindTablesRegEx("Location").Count); }
public void TestDescIndex() { TestHelper.DropDb("test"); TestHelper.ExecSql("create database test", ""); TestHelper.ExecSql(@"create table MyTable (Id int)", "test"); TestHelper.ExecSql(@"create nonclustered index MyIndex on MyTable (Id desc)", "test"); var db = new Database("test") { Connection = TestHelper.GetConnString("test") }; db.Load(); var result = db.ScriptCreate(); Assert.That(result, Is.StringContaining("CREATE NONCLUSTERED INDEX [MyIndex] ON [dbo].[MyTable] ([Id] DESC)")); TestHelper.DropDb("test"); }
public Routine(string owner, string name, Database db) { Owner = owner; Name = name; Db = db; }
private string ScriptBase(Database db, string definition) { var before = ScriptQuotedIdAndAnsiNulls(db, false); var after = ScriptQuotedIdAndAnsiNulls(db, true); if (after != string.Empty) after = Environment.NewLine + "GO" + Environment.NewLine + after; return before + definition + after; }
public string ScriptCreate(Database db) { return ScriptBase(db, Text); }
public void TestScriptToDir() { var policy = new Table("dbo", "Policy"); policy.Columns.Add(new Column("id", "int", false, null) {Position = 1}); policy.Columns.Add(new Column("form", "tinyint", false, null) {Position = 2}); policy.AddConstraint(new Constraint("PK_Policy", "PRIMARY KEY", "id") { Clustered = true, Unique = true }); policy.Columns.Items[0].Identity = new Identity(1, 1); var loc = new Table("dbo", "Location"); loc.Columns.Add(new Column("id", "int", false, null) {Position = 1}); loc.Columns.Add(new Column("policyId", "int", false, null) {Position = 2}); loc.Columns.Add(new Column("storage", "bit", false, null) {Position = 3}); loc.AddConstraint(new Constraint("PK_Location", "PRIMARY KEY", "id") { Clustered = true, Unique = true }); loc.Columns.Items[0].Identity = new Identity(1, 1); var formType = new Table("dbo", "FormType"); formType.Columns.Add(new Column("code", "tinyint", false, null) {Position = 1}); formType.Columns.Add(new Column("desc", "varchar", 10, false, null) {Position = 2}); formType.AddConstraint(new Constraint("PK_FormType", "PRIMARY KEY", "code") { Clustered = true, Unique = true }); var fk_policy_formType = new ForeignKey("FK_Policy_FormType"); fk_policy_formType.Table = policy; fk_policy_formType.Columns.Add("form"); fk_policy_formType.RefTable = formType; fk_policy_formType.RefColumns.Add("code"); fk_policy_formType.OnUpdate = "NO ACTION"; fk_policy_formType.OnDelete = "NO ACTION"; var fk_location_policy = new ForeignKey("FK_Location_Policy"); fk_location_policy.Table = loc; fk_location_policy.Columns.Add("policyId"); fk_location_policy.RefTable = policy; fk_location_policy.RefColumns.Add("id"); fk_location_policy.OnUpdate = "NO ACTION"; fk_location_policy.OnDelete = "CASCADE"; var tt_codedesc = new Table("dbo", "CodeDesc"); tt_codedesc.IsType = true; tt_codedesc.Columns.Add(new Column("code", "tinyint", false, null) { Position = 1 }); tt_codedesc.Columns.Add(new Column("desc", "varchar", 10, false, null) { Position = 2 }); tt_codedesc.AddConstraint(new Constraint("PK_CodeDesc", "PRIMARY KEY", "code")); var db = new Database("ScriptToDirTest"); db.Tables.Add(policy); db.Tables.Add(formType); db.Tables.Add(loc); db.TableTypes.Add(tt_codedesc); db.ForeignKeys.Add(fk_policy_formType); db.ForeignKeys.Add(fk_location_policy); db.FindProp("COMPATIBILITY_LEVEL").Value = "110"; db.FindProp("COLLATE").Value = "SQL_Latin1_General_CP1_CI_AS"; db.FindProp("AUTO_CLOSE").Value = "OFF"; db.FindProp("AUTO_SHRINK").Value = "ON"; db.FindProp("ALLOW_SNAPSHOT_ISOLATION").Value = "ON"; db.FindProp("READ_COMMITTED_SNAPSHOT").Value = "OFF"; db.FindProp("RECOVERY").Value = "SIMPLE"; db.FindProp("PAGE_VERIFY").Value = "CHECKSUM"; db.FindProp("AUTO_CREATE_STATISTICS").Value = "ON"; db.FindProp("AUTO_UPDATE_STATISTICS").Value = "ON"; db.FindProp("AUTO_UPDATE_STATISTICS_ASYNC").Value = "ON"; db.FindProp("ANSI_NULL_DEFAULT").Value = "ON"; db.FindProp("ANSI_NULLS").Value = "ON"; db.FindProp("ANSI_PADDING").Value = "ON"; db.FindProp("ANSI_WARNINGS").Value = "ON"; db.FindProp("ARITHABORT").Value = "ON"; db.FindProp("CONCAT_NULL_YIELDS_NULL").Value = "ON"; db.FindProp("NUMERIC_ROUNDABORT").Value = "ON"; db.FindProp("QUOTED_IDENTIFIER").Value = "ON"; db.FindProp("RECURSIVE_TRIGGERS").Value = "ON"; db.FindProp("CURSOR_CLOSE_ON_COMMIT").Value = "ON"; db.FindProp("CURSOR_DEFAULT").Value = "LOCAL"; db.FindProp("TRUSTWORTHY").Value = "ON"; db.FindProp("DB_CHAINING").Value = "ON"; db.FindProp("PARAMETERIZATION").Value = "FORCED"; db.FindProp("DATE_CORRELATION_OPTIMIZATION").Value = "ON"; db.Connection = ConfigHelper.TestDB.Replace("database=TESTDB", "database=" + db.Name); db.ExecCreate(true); DBHelper.ExecSql(db.Connection, " insert into formType ([code], [desc]) values (1, 'DP-1')\n" + "insert into formType ([code], [desc]) values (2, 'DP-2')\n" + "insert into formType ([code], [desc]) values (3, 'DP-3')"); db.DataTables.Add(formType); db.Dir = db.Name; if (Directory.Exists(db.Dir)) Directory.Delete(db.Dir, true); db.ScriptToDir(); Assert.IsTrue(Directory.Exists(db.Name)); Assert.IsTrue(Directory.Exists(db.Name + "\\data")); Assert.IsTrue(Directory.Exists(db.Name + "\\tables")); Assert.IsTrue(Directory.Exists(db.Name + "\\foreign_keys")); foreach (var t in db.DataTables) { Assert.IsTrue(File.Exists(db.Name + "\\data\\" + t.Name + ".tsv")); } foreach (var t in db.Tables) { Assert.IsTrue(File.Exists(db.Name + "\\tables\\" + t.Name + ".sql")); } foreach (var t in db.TableTypes) { Assert.IsTrue(File.Exists(db.Name + "\\table_types\\TYPE_" + t.Name + ".sql")); } foreach (var expected in db.ForeignKeys.Select(fk => db.Name + "\\foreign_keys\\" + fk.Table.Name + ".sql")) { Assert.IsTrue(File.Exists(expected), "File does not exist" + expected); } var copy = new Database("ScriptToDirTestCopy"); copy.Dir = db.Dir; copy.Connection = ConfigHelper.TestDB.Replace("database=TESTDB", "database=" + copy.Name); copy.CreateFromDir(true); copy.Load(); TestCompare(db, copy); }
public void TestScript() { var db = new Database("TEST_TEMP"); var t1 = new Table("dbo", "t1"); t1.Columns.Add(new Column("col1", "int", false, null) {Position = 1}); t1.Columns.Add(new Column("col2", "int", false, null) {Position = 2}); t1.AddConstraint(new Constraint("pk_t1", "PRIMARY KEY", "col1,col2")); t1.FindConstraint("pk_t1").Clustered = true; var t2 = new Table("dbo", "t2"); t2.Columns.Add(new Column("col1", "int", false, null) {Position = 1}); t2.Columns.Add(new Column("col2", "int", false, null) {Position = 2}); t2.Columns.Add(new Column("col3", "int", false, null) {Position = 3}); t2.AddConstraint(new Constraint("pk_t2", "PRIMARY KEY", "col1")); t2.FindConstraint("pk_t2").Clustered = true; t2.AddConstraint(new Constraint("IX_col3", "UNIQUE", "col3")); db.ForeignKeys.Add(new ForeignKey(t2, "fk_t2_t1", "col2,col3", t1, "col1,col2")); db.Tables.Add(t1); db.Tables.Add(t2); TestHelper.DropDb("TEST_TEMP"); SqlConnection.ClearAllPools(); TestHelper.ExecBatchSql(db.ScriptCreate(), "master"); var db2 = new Database(); db2.Connection = TestHelper.GetConnString("TEST_TEMP"); db2.Load(); TestHelper.DropDb("TEST_TEMP"); foreach (var t in db.Tables) { Assert.IsNotNull(db2.FindTable(t.Name, t.Owner)); Assert.IsFalse(db2.FindTable(t.Name, t.Owner).Compare(t).IsDiff); } }
public void TestScriptToDirOnlyCreatesNecessaryFolders() { var db = new Database("TestEmptyDB"); db.Connection = ConfigHelper.TestDB.Replace("database=TESTDB", "database=" + db.Name); db.ExecCreate(true); db.Dir = db.Name; db.Load(); if (Directory.Exists(db.Dir)) // if the directory exists, delete it to make it a fair test { Directory.Delete(db.Dir, true); } db.ScriptToDir(); Assert.AreEqual(0, db.Assemblies.Count); Assert.AreEqual(0, db.DataTables.Count); Assert.AreEqual(0, db.ForeignKeys.Count); Assert.AreEqual(0, db.Routines.Count); Assert.AreEqual(0, db.Schemas.Count); Assert.AreEqual(0, db.Synonyms.Count); Assert.AreEqual(0, db.Tables.Count); Assert.AreEqual(0, db.TableTypes.Count); Assert.AreEqual(0, db.Users.Count); Assert.AreEqual(0, db.ViewIndexes.Count); Assert.IsTrue(Directory.Exists(db.Name)); Assert.IsTrue(File.Exists(db.Name + "\\props.sql")); //Assert.IsFalse(File.Exists(db.Name + "\\schemas.sql")); Assert.IsFalse(Directory.Exists(db.Name + "\\assemblies")); Assert.IsFalse(Directory.Exists(db.Name + "\\data")); Assert.IsFalse(Directory.Exists(db.Name + "\\foreign_keys")); foreach (var routineType in Enum.GetNames(typeof(Routine.RoutineKind))) { var dir = routineType.ToLower() + "s"; Assert.IsFalse(Directory.Exists(db.Name + "\\" + dir)); } Assert.IsFalse(Directory.Exists(db.Name + "\\synonyms")); Assert.IsFalse(Directory.Exists(db.Name + "\\tables")); Assert.IsFalse(Directory.Exists(db.Name + "\\table_types")); Assert.IsFalse(Directory.Exists(db.Name + "\\users")); }
public void TestScriptTableType() { var setupSQL1 = @" CREATE TYPE [dbo].[MyTableType] AS TABLE( [ID] [nvarchar](250) NULL, [Value] [numeric](5, 1) NULL ) "; var db = new Database("TestScriptTableType"); db.Connection = ConfigHelper.TestDB.Replace("database=TESTDB", "database=" + db.Name); db.ExecCreate(true); DBHelper.ExecSql(db.Connection, setupSQL1); db.Dir = db.Name; db.Load(); db.ScriptToDir(); Assert.AreEqual(1, db.TableTypes.Count()); Assert.AreEqual(250, db.TableTypes[0].Columns.Items[0].Length); Assert.AreEqual(1, db.TableTypes[0].Columns.Items[1].Scale); Assert.AreEqual(5, db.TableTypes[0].Columns.Items[1].Precision); Assert.AreEqual("MyTableType", db.TableTypes[0].Name); Assert.IsTrue(File.Exists(db.Name + "\\table_types\\TYPE_MyTableType.sql")); }
public void TestDiffScript() { TestHelper.DropDb("TEST_SOURCE"); TestHelper.DropDb("TEST_COPY"); //create the dbs from sql script var script = File.ReadAllText(ConfigHelper.TestSchemaDir + "\\BOP_QUOTE.sql"); TestHelper.ExecSql("CREATE DATABASE TEST_SOURCE", ""); TestHelper.ExecBatchSql(script, "TEST_SOURCE"); script = File.ReadAllText(ConfigHelper.TestSchemaDir + "\\BOP_QUOTE_2.sql"); TestHelper.ExecSql("CREATE DATABASE TEST_COPY", ""); TestHelper.ExecBatchSql(script, "TEST_COPY"); var source = new Database("TEST_SOURCE"); source.Connection = TestHelper.GetConnString("TEST_SOURCE"); source.Load(); var copy = new Database("TEST_COPY"); copy.Connection = TestHelper.GetConnString("TEST_COPY"); copy.Load(); //execute migration script to make SOURCE the same as COPY var diff = copy.Compare(source); TestHelper.ExecBatchSql(diff.Script(), "TEST_SOURCE"); //compare the dbs to make sure they are the same var cmd = string.Format("/c {0}\\SQLDBDiffConsole.exe {1} {2} {0}\\{3}", ConfigHelper.SqlDbDiffPath, "localhost\\SQLEXPRESS TEST_COPY NULL NULL Y", "localhost\\SQLEXPRESS TEST_SOURCE NULL NULL Y", "SqlDbDiff.XML CompareResult.txt null"); var proc = new Process(); proc.StartInfo.FileName = "cmd.exe"; proc.StartInfo.Arguments = cmd; proc.StartInfo.WindowStyle = ProcessWindowStyle.Normal; proc.Start(); proc.WaitForExit(); Assert.AreEqual("no difference", File.ReadAllLines("CompareResult.txt")[0]); }
public void TestScriptTableTypePrimaryKey() { var setupSQL1 = @" CREATE TYPE [dbo].[MyTableType] AS TABLE( [ID] [int] NOT NULL, [Value] [varchar](50) NOT NULL, PRIMARY KEY CLUSTERED ( [ID] ASC ) ) "; var db = new Database("TestScriptTableTypePrimaryKey"); db.Connection = ConfigHelper.TestDB.Replace("database=TESTDB", "database=" + db.Name); db.ExecCreate(true); DBHelper.ExecSql(db.Connection, setupSQL1); db.Dir = db.Name; db.Load(); db.ScriptToDir(); Assert.AreEqual(1, db.TableTypes.Count()); Assert.AreEqual(1, db.TableTypes[0].PrimaryKey.Columns.Count); Assert.AreEqual("ID", db.TableTypes[0].PrimaryKey.Columns[0]); Assert.AreEqual(50, db.TableTypes[0].Columns.Items[1].Length); Assert.AreEqual("MyTableType", db.TableTypes[0].Name); Assert.IsTrue(File.Exists(db.Name + "\\table_types\\TYPE_MyTableType.sql")); Assert.IsTrue(File.ReadAllText(db.Name + "\\table_types\\TYPE_MyTableType.sql").Contains("PRIMARY KEY")); }
public DatabaseDiff Compare(Database db) { var diff = new DatabaseDiff(); diff.Db = db; //compare database properties foreach (var p in from p in Props let p2 = db.FindProp(p.Name) where p.Script() != p2.Script() select p) { diff.PropsChanged.Add(p); } //get tables added and changed foreach (var tables in new[] {Tables, TableTypes}) { foreach (var t in tables) { var t2 = db.FindTable(t.Name, t.Owner, t.IsType); if (t2 == null) { diff.TablesAdded.Add(t); } else { //compare mutual tables var tDiff = t.Compare(t2); if (tDiff.IsDiff) { if (t.IsType) { // types cannot be altered... diff.TableTypesDiff.Add(t); } else { diff.TablesDiff.Add(tDiff); } } } } } //get deleted tables foreach (var t in db.Tables.Concat(db.TableTypes).Where(t => FindTable(t.Name, t.Owner, t.IsType) == null)) { diff.TablesDeleted.Add(t); } //get procs added and changed foreach (var r in Routines) { var r2 = db.FindRoutine(r.Name, r.Owner); if (r2 == null) { diff.RoutinesAdded.Add(r); } else { //compare mutual procs if (r.Text.Trim() != r2.Text.Trim()) { diff.RoutinesDiff.Add(r); } } } //get procs deleted foreach (var r in db.Routines.Where(r => FindRoutine(r.Name, r.Owner) == null)) { diff.RoutinesDeleted.Add(r); } //get added and compare mutual foreign keys foreach (var fk in ForeignKeys) { var fk2 = db.FindForeignKey(fk.Name, fk.Table.Owner); if (fk2 == null) { diff.ForeignKeysAdded.Add(fk); } else { if (fk.ScriptCreate() != fk2.ScriptCreate()) { diff.ForeignKeysDiff.Add(fk); } } } //get deleted foreign keys foreach (var fk in db.ForeignKeys.Where(fk => FindForeignKey(fk.Name, fk.Table.Owner) == null)) { diff.ForeignKeysDeleted.Add(fk); } //get added and compare mutual assemblies foreach (var a in Assemblies) { var a2 = db.FindAssembly(a.Name); if (a2 == null) { diff.AssembliesAdded.Add(a); } else { if (a.ScriptCreate() != a2.ScriptCreate()) { diff.AssembliesDiff.Add(a); } } } //get deleted assemblies foreach (var a in db.Assemblies.Where(a => FindAssembly(a.Name) == null)) { diff.AssembliesDeleted.Add(a); } //get added and compare mutual users foreach (var u in Users) { var u2 = db.FindUser(u.Name); if (u2 == null) { diff.UsersAdded.Add(u); } else { if (u.ScriptCreate() != u2.ScriptCreate()) { diff.UsersDiff.Add(u); } } } //get deleted users foreach (var u in db.Users.Where(u => FindUser(u.Name) == null)) { diff.UsersDeleted.Add(u); } //get added and compare view indexes foreach (var c in ViewIndexes) { var c2 = db.FindViewIndex(c.Name); if (c2 == null) { diff.ViewIndexesAdded.Add(c); } else { if (c.ScriptCreate() != c2.ScriptCreate()) { diff.ViewIndexesDiff.Add(c); } } } //get deleted view indexes foreach (var c in db.ViewIndexes.Where(c => FindViewIndex(c.Name) == null)) { diff.ViewIndexesDeleted.Add(c); } //get added and compare synonyms foreach (var s in Synonyms) { var s2 = db.FindSynonym(s.Name, s.Owner); if (s2 == null) { diff.SynonymsAdded.Add(s); } else { if (s.BaseObjectName != s2.BaseObjectName) { diff.SynonymsDiff.Add(s); } } } //get deleted synonyms foreach (var s in db.Synonyms.Where(s => FindSynonym(s.Name, s.Owner) == null)) { diff.SynonymsDeleted.Add(s); } return diff; }
private string ScriptBase(Database db, string definition) { var before = ScriptQuotedIdAndAnsiNulls(db, false); var after = ScriptQuotedIdAndAnsiNulls(db, true); if (after != string.Empty) after = Environment.NewLine + "GO" + Environment.NewLine + after; #if FixRoutineNames // correct the name if it is incorrect var identifierEnd = new[] {TSqlTokenType.As, TSqlTokenType.On, TSqlTokenType.Variable, TSqlTokenType.LeftParenthesis}; var identifier = new[] {TSqlTokenType.Identifier, TSqlTokenType.QuotedIdentifier, TSqlTokenType.Dot}; var commentOrWhitespace = new[] {TSqlTokenType.MultilineComment, TSqlTokenType.SingleLineComment,TSqlTokenType.WhiteSpace}; IList<ParseError> errors; TSqlFragment script = new TSql120Parser(initialQuotedIdentifiers: QuotedId).Parse(new StringReader(definition), out errors); var id = script.ScriptTokenStream.SkipWhile(t => !identifier.Contains(t.TokenType)) .TakeWhile(t => identifier.Contains(t.TokenType) || commentOrWhitespace.Contains(t.TokenType)) .Where(t => identifier.Contains(t.TokenType)).ToArray(); var replaced = false; definition = string.Join(string.Empty, script.ScriptTokenStream.Select(t => { if (id.Contains(t)) { if (replaced) return string.Empty; else { replaced = true; return string.Format("[{0}].[{1}]", Schema, Name); } } else { return t.Text; } })); #endif return before + definition + after; }