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 void TestScript() { var person = new Table("dbo", "Person"); person.Columns.Add(new Column("id", "int", false, null)); person.Columns.Add(new Column("name", "varchar", 50, false, null)); person.Columns.Find("id").Identity = new Identity(1, 1); person.AddConstraint(new Constraint("PK_Person", "PRIMARY KEY", "id")); var address = new Table("dbo", "Address"); address.Columns.Add(new Column("id", "int", false, null)); address.Columns.Add(new Column("personId", "int", false, null)); address.Columns.Add(new Column("street", "varchar", 50, false, null)); address.Columns.Add(new Column("city", "varchar", 50, false, null)); address.Columns.Add(new Column("state", "char", 2, false, null)); address.Columns.Add(new Column("zip", "varchar", 5, false, null)); address.Columns.Find("id").Identity = new Identity(1, 1); address.AddConstraint(new Constraint("PK_Address", "PRIMARY KEY", "id")); var fk = new ForeignKey(address, "FK_Address_Person", "personId", person, "id", "", "CASCADE"); TestHelper.ExecSql(person.ScriptCreate(), ""); TestHelper.ExecSql(address.ScriptCreate(), ""); TestHelper.ExecSql(fk.ScriptCreate(), ""); TestHelper.ExecSql("drop table Address", ""); TestHelper.ExecSql("drop table Person", ""); }
public ForeignKey(Table table, string name, string columns, Table refTable, string refColumns, string onUpdate, string onDelete) { Table = table; Name = name; Columns = new List<string>(columns.Split(',')); RefTable = refTable; RefColumns = new List<string>(refColumns.Split(',')); OnUpdate = onUpdate; OnDelete = onDelete; }
public void CompareConstraints() { var t1 = new Table("dbo", "Test"); var t2 = new Table("dbo", "Test"); var diff = default(TableDiff); //test equal t1.Columns.Add(new Column("first", "varchar", 30, false, null)); t2.Columns.Add(new Column("first", "varchar", 30, false, null)); t1.AddConstraint(Constraint.CreateCheckedConstraint("IsTomorrow", true, "fnTomorrow()")); t2.AddConstraint(Constraint.CreateCheckedConstraint("IsTomorrow", false, "Tomorrow <> 1")); diff = t1.Compare(t2); Assert.AreEqual(1, diff.ConstraintsChanged.Count); Assert.IsNotNull(diff); Assert.IsTrue(diff.IsDiff); }
public void TestCompare() { var t1 = new Table("dbo", "Test"); var t2 = new Table("dbo", "Test"); var diff = default(TableDiff); //test equal t1.Columns.Add(new Column("first", "varchar", 30, false, null)); t2.Columns.Add(new Column("first", "varchar", 30, false, null)); t1.AddConstraint(new Constraint("PK_Test", "PRIMARY KEY", "first")); t2.AddConstraint(new Constraint("PK_Test", "PRIMARY KEY", "first")); diff = t1.Compare(t2); Assert.IsNotNull(diff); Assert.IsFalse(diff.IsDiff); //test add t1.Columns.Add(new Column("second", "varchar", 30, false, null)); diff = t1.Compare(t2); Assert.IsTrue(diff.IsDiff); Assert.AreEqual(1, diff.ColumnsAdded.Count); //test delete diff = t2.Compare(t1); Assert.IsTrue(diff.IsDiff); Assert.AreEqual(1, diff.ColumnsDropped.Count); //test diff t1.Columns.Items[0].Length = 20; diff = t1.Compare(t2); Assert.IsTrue(diff.IsDiff); Assert.AreEqual(1, diff.ColumnsDiff.Count); Console.WriteLine("--- create ----"); Console.Write(t1.ScriptCreate()); Console.WriteLine("--- migrate up ---"); Console.Write(t1.Compare(t2).Script()); Console.WriteLine("--- migrate down ---"); Console.Write(t2.Compare(t1).Script()); }
public void TestScript() { var t = new Table("dbo", "Address"); t.Columns.Add(new Column("id", "int", false, null)); t.Columns.Add(new Column("street", "varchar", 50, false, null)); t.Columns.Add(new Column("city", "varchar", 50, false, null)); t.Columns.Add(new Column("state", "char", 2, false, null)); t.Columns.Add(new Column("zip", "char", 5, false, null)); t.AddConstraint(new Constraint("PK_Address", "PRIMARY KEY", "id")); var getAddress = new Routine("dbo", "GetAddress", null); getAddress.Text = @" CREATE PROCEDURE [dbo].[GetAddress] @id int AS select * from Address where id = @id "; TestHelper.ExecSql(t.ScriptCreate(), ""); TestHelper.ExecBatchSql(getAddress.ScriptCreate() + "\nGO", ""); TestHelper.ExecSql("drop table [dbo].[Address]", ""); TestHelper.ExecSql("drop procedure [dbo].[GetAddress]", ""); }
public TableDiff Compare(Table t) { var diff = new TableDiff(); diff.Owner = t.Owner; diff.Name = t.Name; //get additions and compare mutual columns foreach (var c in Columns.Items) { var c2 = t.Columns.Find(c.Name); if (c2 == null) { diff.ColumnsAdded.Add(c); } else { //compare mutual columns var cDiff = c.Compare(c2); if (cDiff.IsDiff) { diff.ColumnsDiff.Add(cDiff); } } } //get deletions foreach (var c in t.Columns.Items.Where(c => Columns.Find(c.Name) == null)) { diff.ColumnsDropped.Add(c); } if (!t.IsType) { //get added and compare mutual constraints foreach (var c in Constraints) { var c2 = t.FindConstraint(c.Name); if (c2 == null) { diff.ConstraintsAdded.Add(c); } else { if (c.ScriptCreate() != c2.ScriptCreate()) { diff.ConstraintsChanged.Add(c); } } } //get deleted constraints foreach (var c in t.Constraints.Where(c => FindConstraint(c.Name) == null)){ diff.ConstraintsDeleted.Add(c); } } else { // compare constraints on table types, which can't be named in the script, but have names in the DB var dest = Constraints.ToList(); var src = t.Constraints.ToList(); var j = from c1 in dest join c2 in src on c1.ScriptCreate() equals c2.ScriptCreate() into match //new { c1.Type, c1.Unique, c1.Clustered, Columns = string.Join(",", c1.Columns.ToArray()), IncludedColumns = string.Join(",", c1.IncludedColumns.ToArray()) } equals new { c2.Type, c2.Unique, c2.Clustered, Columns = string.Join(",", c2.Columns.ToArray()), IncludedColumns = string.Join(",", c2.IncludedColumns.ToArray()) } into match from m in match.DefaultIfEmpty() select new { c1, m }; foreach (var c in j) { if (c.m == null) { diff.ConstraintsAdded.Add(c.c1); } else { src.Remove(c.m); } } foreach (var c in src) { diff.ConstraintsDeleted.Add(c); } } return diff; }
public ForeignKey(Table table, string name, string columns, Table refTable, string refColumns) : this(table, name, columns, refTable, refColumns, "", "") { }
public void TestExportData() { var t = new Table("dbo", "Status"); t.Columns.Add(new Column("id", "int", false, null)); t.Columns.Add(new Column("code", "char", 1, false, null)); t.Columns.Add(new Column("description", "varchar", 20, false, null)); t.Columns.Find("id").Identity = new Identity(1, 1); t.AddConstraint(new Constraint("PK_Status", "PRIMARY KEY", "id")); var conn = TestHelper.GetConnString("TESTDB"); DBHelper.DropDb(conn); DBHelper.CreateDb(conn); SqlConnection.ClearAllPools(); DBHelper.ExecBatchSql(conn, t.ScriptCreate()); var dataIn = @"1 R Ready 2 P Processing 3 F Frozen "; var filename = Path.GetTempFileName(); var writer = File.AppendText(filename); writer.Write(dataIn); writer.Flush(); writer.Close(); t.ImportData(conn, filename); var sw = new StringWriter(); t.ExportData(conn, sw); Assert.AreEqual(dataIn, sw.ToString()); File.Delete(filename); }
public void TestScriptNonSupportedColumn() { var t = new Table("dbo", "bla"); t.Columns.Add(new Column("a", "madeuptype", true, null)); t.ScriptCreate(); }
public void TestScript() { //create a table with all known types, script it, and execute the script var t = new Table("dbo", "AllTypesTest"); t.Columns.Add(new Column("a", "bigint", false, null)); t.Columns.Add(new Column("b", "binary", 50, false, null)); t.Columns.Add(new Column("c", "bit", false, null)); t.Columns.Add(new Column("d", "char", 10, false, null)); t.Columns.Add(new Column("e", "datetime", false, null)); t.Columns.Add(new Column("f", "decimal", 18, 0, false, null)); t.Columns.Add(new Column("g", "float", false, null)); t.Columns.Add(new Column("h", "image", false, null)); t.Columns.Add(new Column("i", "int", false, null)); t.Columns.Add(new Column("j", "money", false, null)); t.Columns.Add(new Column("k", "nchar", 10, false, null)); t.Columns.Add(new Column("l", "ntext", false, null)); t.Columns.Add(new Column("m", "numeric", 18, 0, false, null)); t.Columns.Add(new Column("n", "nvarchar", 50, false, null)); t.Columns.Add(new Column("o", "nvarchar", -1, false, null)); t.Columns.Add(new Column("p", "real", false, null)); t.Columns.Add(new Column("q", "smalldatetime", false, null)); t.Columns.Add(new Column("r", "smallint", false, null)); t.Columns.Add(new Column("s", "smallmoney", false, null)); t.Columns.Add(new Column("t", "sql_variant", false, null)); t.Columns.Add(new Column("u", "text", false, null)); t.Columns.Add(new Column("v", "timestamp", false, null)); t.Columns.Add(new Column("w", "tinyint", false, null)); t.Columns.Add(new Column("x", "uniqueidentifier", false, null)); t.Columns.Add(new Column("y", "varbinary", 50, false, null)); t.Columns.Add(new Column("z", "varbinary", -1, false, null)); t.Columns.Add(new Column("aa", "varchar", 50, true, new Default("DF_AllTypesTest_aa", "'asdf'"))); t.Columns.Add(new Column("bb", "varchar", -1, true, null)); t.Columns.Add(new Column("cc", "xml", true, null)); t.Columns.Add(new Column("dd", "hierarchyid", false, null)); Console.WriteLine(t.ScriptCreate()); TestHelper.ExecSql(t.ScriptCreate(), ""); TestHelper.ExecSql("drop table [dbo].[AllTypesTest]", ""); }
public void TestLargeAmountOfRowsImportAndExport() { var t = new Table("dbo", "TestData"); t.Columns.Add(new Column("test_field", "int", false, null)); t.AddConstraint(new Constraint("PK_TestData", "PRIMARY KEY", "test_field")); t.AddConstraint(new Constraint("IX_TestData_PK", "INDEX", "test_field") { Clustered = true, Table = t, Unique = true }); // clustered index is required to ensure the row order is the same as what we import var conn = TestHelper.GetConnString("TESTDB"); DBHelper.DropDb(conn); DBHelper.CreateDb(conn); SqlConnection.ClearAllPools(); DBHelper.ExecBatchSql(conn, t.ScriptCreate()); var filename = Path.GetTempFileName(); var writer = File.CreateText(filename); StringBuilder sb = new StringBuilder(); for (var i = 0; i < Table.rowsInBatch * 4.2; i++) { sb.AppendLine(i.ToString()); writer.WriteLine(i.ToString()); } writer.Flush(); writer.Close(); var dataIn = sb.ToString(); Assert.AreEqual(dataIn, File.ReadAllText(filename)); // just prove that the file and the string are the same, to make the next assertion meaningful! try { t.ImportData(conn, filename); var sw = new StringWriter(); t.ExportData(conn, sw); Assert.AreEqual(dataIn, sw.ToString()); } finally { File.Delete(filename); } }
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.Columns.Add(new Column("category", "int", false, null) { Position = 4 }); 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 }); formType.AddConstraint(Constraint.CreateCheckedConstraint("CK_FormType", false, "([code]<(5))")); var categoryType = new Table("dbo", "CategoryType"); categoryType.Columns.Add(new Column("id", "int", false, null) { Position = 1 }); categoryType.Columns.Add(new Column("Category", "varchar", 10, false, null) { Position = 2 }); categoryType.AddConstraint(new Constraint("PK_CategoryType", "PRIMARY KEY", "id") { Clustered = true, Unique = true }); var emptyTable = new Table("dbo", "EmptyTable"); emptyTable.Columns.Add(new Column("code", "tinyint", false, null) {Position = 1}); emptyTable.AddConstraint(new Constraint("PK_EmptyTable", "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 fk_location_category = new ForeignKey("FK_Location_category"); fk_location_category.Table = loc; fk_location_category.Columns.Add("category"); fk_location_category.RefTable = categoryType; fk_location_category.RefColumns.Add("id"); fk_location_category.OnUpdate = "NO ACTION"; fk_location_category.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(categoryType); db.Tables.Add(emptyTable); db.Tables.Add(loc); db.TableTypes.Add(tt_codedesc); db.ForeignKeys.Add(fk_policy_formType); db.ForeignKeys.Add(fk_location_policy); db.ForeignKeys.Add(fk_location_category); 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.DataTables.Add(emptyTable); 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) { if (t.Name == "EmptyTable") { Assert.IsFalse(File.Exists(db.Name + "\\data\\" + t.Name + ".tsv")); } else { Assert.IsTrue(File.Exists(db.Name + "\\data\\" + t.Name + ".tsv")); } } foreach (var t in db.Tables) { var tblFile = db.Name + "\\tables\\" + t.Name + ".sql"; Assert.IsTrue(File.Exists(tblFile)); // Test that the constraints are ordered in the file string script = File.ReadAllText(tblFile); int cindex = -1; foreach (var ckobject in t.Constraints.OrderBy(x => x.Name)) { var thisindex = script.IndexOf(ckobject.ScriptCreate()); Assert.Greater(thisindex, cindex, "Constraints are not ordered."); cindex = thisindex; } } 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); } // Test that the foreign keys are ordered in the file foreach (var t in db.Tables) { var fksFile = db.Name + "\\foreign_keys\\" + t.Name + ".sql"; if (File.Exists(fksFile)) { string script = File.ReadAllText(fksFile); int fkindex = -1; foreach (var fkobject in db.ForeignKeys.Where(x => x.Table == t).OrderBy(x => x.Name)) { var thisindex = script.IndexOf(fkobject.ScriptCreate()); Assert.Greater(thisindex, fkindex, "Foreign keys are not ordered."); fkindex = thisindex; } } } 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); } }