public LoadableTable(DataContext context, SchemaMapping mapping) { Mapping = mapping; Synchronizer = new TableSynchronizer(CreateTable(), Mapping, sqlProvider); context.Tables.AddTable(Synchronizer.Table); }
public void NullValuesTest() { using (var connection = SqlProvider.OpenConnection()) connection.ExecuteNonQuery(@" CREATE TABLE [NullableTest]( [ID] UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL PRIMARY KEY DEFAULT(newid()), [Integer] INTEGER NULL, [String] NVARCHAR(1024) NULL, [RowVersion] RowVersion );"); var schema = new TableSchema("NullableTest"); schema.PrimaryKey = schema.Columns.AddValueColumn("ID", typeof(Guid), null); schema.Columns.AddValueColumn("Integer", typeof(int?), null); schema.Columns.AddValueColumn("String", typeof(string), null); var mapping = new SchemaMapping(schema); var table = new Table(schema); var syncer = new TableSynchronizer(table, mapping, SqlProvider); table.Rows.AddFromValues(Guid.NewGuid()); table.Rows.AddFromValues(Guid.NewGuid(), 4, null); table.Rows.AddFromValues(Guid.NewGuid(), null, "4"); table.Rows.AddFromValues(Guid.NewGuid(), 4, "4"); syncer.WriteData(); var newTable = new Table(schema); var newSyncer = new TableSynchronizer(newTable, mapping, SqlProvider); newSyncer.ReadData(); AssertTablesEqual(table, newTable); table.Rows[0]["Integer"] = 5; table.Rows[0]["String"] = "5"; table.Rows[3]["Integer"] = null; table.Rows[3]["String"] = null; syncer.WriteData(); newTable = new Table(schema); newSyncer = new TableSynchronizer(newTable, mapping, SqlProvider); newSyncer.ReadData(); AssertTablesEqual(table, newTable); syncer.ReadData(); AssertTablesEqual(newTable, table); }
public void ConflictsTest() { using (var connection = SqlProvider.OpenConnection()) connection.ExecuteNonQuery(@" CREATE TABLE [ConflictsTest]( [ID] UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL PRIMARY KEY DEFAULT(newid()), [Key] INTEGER NOT NULL UNIQUE, [Value] INTEGER NULL, [RowVersion] RowVersion );"); try { var schema = new TableSchema("ConflictsTest"); schema.PrimaryKey = schema.Columns.AddValueColumn("ID", typeof(Guid), null); schema.Columns.AddValueColumn("Key", typeof(int), null).Unique = true; schema.Columns.AddValueColumn("Value", typeof(int?), null); var mapping = new SchemaMapping(schema); var table1 = new Table(schema); var syncer1 = new TableSynchronizer(table1, mapping, SqlProvider); var table2 = new Table(schema); var syncer2 = new TableSynchronizer(table2, mapping, SqlProvider); Func<Table, int, Row> GetRow = (t, key) => t.Rows.SingleOrDefault(r => r.Field<int>("Key") == key); Func<int, Row> R1 = k => GetRow(table1, k), R2 = k => GetRow(table2, k); table1.Rows.AddFromValues(Guid.NewGuid(), 2, 67); table2.Rows.AddFromValues(Guid.NewGuid(), 1, null); table2.Rows.AddFromValues(Guid.NewGuid(), 2, 43); syncer1.WriteData(); try { syncer2.WriteData(); Assert.Fail("Conflict succeeded"); } catch (RowException ex) { Assert.IsNotNull(ex.InnerException); Assert.AreEqual(R2(2), ex.Row); } table2.Rows.Clear(); syncer2.ReadData(); AssertTablesEqual(table1, table2); table1.Rows.AddFromValues(Guid.NewGuid(), 1, null); syncer1.WriteData(); syncer2.ReadData(); R1(1)["Value"] = 100; R2(1)["Value"] = 200; syncer1.WriteData(); try { syncer2.WriteData(); Assert.Fail("Conflict succeeded - Update / Update"); } catch (RowModifiedException ex) { Assert.IsNull(ex.InnerException); Assert.AreEqual(R2(1), ex.Row); Assert.AreEqual(R1(1)["Key"], ex.DatabaseValues[schema.Columns["Key"]]); Assert.AreEqual(R1(1)["Value"], ex.DatabaseValues[schema.Columns["Value"]]); } syncer2.ReadData(); AssertTablesEqual(table1, table2); R1(1)["Value"] = 123; R2(1).RemoveRow(); syncer1.WriteData(); try { syncer2.WriteData(); Assert.Fail("Conflict succeeded - Update / Delete"); } catch (RowModifiedException ex) { Assert.IsNull(ex.InnerException); Assert.AreEqual(1, ex.Row["Key"]); Assert.AreEqual(R1(1)["Value"], ex.DatabaseValues[schema.Columns["Value"]]); } syncer2.ReadData(); AssertTablesEqual(table1, table2); R1(1).RemoveRow(); R2(1)["Value"] = -1; syncer1.WriteData(); try { syncer2.WriteData(); Assert.Fail("Conflict succeeded - Delete / Update"); } catch (RowDeletedException ex) { Assert.IsNull(ex.InnerException); Assert.AreEqual(R2(1), ex.Row); } syncer2.ReadData(); AssertTablesEqual(table1, table2); R1(2).RemoveRow(); R2(2).RemoveRow(); syncer1.WriteData(); syncer2.WriteData(); //Delete / Delete - should not throw syncer1.ReadData(); Assert.AreEqual(0, table1.Rows.Count); } finally { using (var connection = SqlProvider.OpenConnection()) connection.ExecuteNonQuery(@"DROP TABLE ConflictsTest;"); } }
public void SimpleTableTest() { using (var connection = SqlProvider.OpenConnection()) connection.ExecuteNonQuery(@" CREATE TABLE [Numbers]( [ID] UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL PRIMARY KEY DEFAULT(newid()), [Value] INTEGER NOT NULL, [IsEven] BIT NOT NULL, [String] NVARCHAR(1024) NOT NULL, [RowVersion] RowVersion );"); try { var schema = new TableSchema("Numbers"); schema.PrimaryKey = schema.Columns.AddValueColumn("ID", typeof(Guid), null); schema.Columns.AddValueColumn("Value", typeof(int), 2); schema.Columns.AddValueColumn("IsEven", typeof(bool), false); schema.Columns.AddValueColumn("String", typeof(string), null).AllowNulls = false; var mapping = new SchemaMapping(schema); var table = new Table(schema); var syncer = new TableSynchronizer(table, mapping, SqlProvider); table.Rows.AddFromValues(Guid.NewGuid(), 2, true, "2"); syncer.ReadData(); Assert.AreEqual(0, table.Rows.Count); for (int i = 0; i < 10; i++) { var row = table.Rows.AddFromValues(Guid.NewGuid(), i, i % 2 == 0, "t"); row["String"] = i.ToString(); } Assert.IsTrue(syncer.Changes.All(c => c.ChangeType == RowChangeType.Added)); Assert.AreEqual(10, syncer.Changes.Count); Assert.IsTrue(syncer.Changes.Select(c => c.Row).SequenceEqual(table.Rows)); syncer.WriteData(); foreach (var row in table.Rows.Where(r => r.Field<bool>("IsEven"))) { row["String"] += "E"; } Assert.IsTrue(syncer.Changes.All(c => c.ChangeType == RowChangeType.Changed)); Assert.AreEqual(5, syncer.Changes.Count); syncer.WriteData(); var newTable = new Table(schema); var newSyncer = new TableSynchronizer(newTable, mapping, SqlProvider); newSyncer.ReadData(); AssertTablesEqual(table, newTable); table.Rows[4].RemoveRow(); table.Rows[7].RemoveRow(); table.Rows[2].RemoveRow(); syncer.WriteData(); newSyncer.ReadData(); AssertTablesEqual(table, newTable); newTable = new Table(schema); newSyncer = new TableSynchronizer(newTable, mapping, SqlProvider); newSyncer.ReadData(); AssertTablesEqual(table, newTable); syncer.ReadData(); AssertTablesEqual(newTable, table); } finally { using (var connection = SqlProvider.OpenConnection()) connection.ExecuteNonQuery(@"DROP TABLE Numbers;"); } }
public void SimpleTableTest() { using (var connection = SqlProvider.OpenConnection()) connection.ExecuteNonQuery(@" CREATE TABLE [Numbers]( [ID] UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL PRIMARY KEY DEFAULT(newid()), [Value] INTEGER NOT NULL, [IsEven] BIT NOT NULL, [String] NVARCHAR(1024) NOT NULL, [RowVersion] RowVersion );"); try { var schema = new TableSchema("Numbers"); schema.PrimaryKey = schema.Columns.AddValueColumn("ID", typeof(Guid), null); schema.Columns.AddValueColumn("Value", typeof(int), 2); schema.Columns.AddValueColumn("IsEven", typeof(bool), false); schema.Columns.AddValueColumn("String", typeof(string), null).AllowNulls = false; var mapping = new SchemaMapping(schema); var table = new Table(schema); var syncer = new TableSynchronizer(table, mapping, SqlProvider); table.Rows.AddFromValues(Guid.NewGuid(), 2, true, "2"); syncer.ReadData(); Assert.AreEqual(0, table.Rows.Count); for (int i = 0; i < 10; i++) { var row = table.Rows.AddFromValues(Guid.NewGuid(), i, i % 2 == 0, "t"); row["String"] = i.ToString(); } Assert.IsTrue(syncer.Changes.All(c => c.ChangeType == RowChangeType.Added)); Assert.AreEqual(10, syncer.Changes.Count); Assert.IsTrue(syncer.Changes.Select(c => c.Row).SequenceEqual(table.Rows)); syncer.WriteData(); foreach (var row in table.Rows.Where(r => r.Field <bool>("IsEven"))) { row["String"] += "E"; } Assert.IsTrue(syncer.Changes.All(c => c.ChangeType == RowChangeType.Changed)); Assert.AreEqual(5, syncer.Changes.Count); syncer.WriteData(); var newTable = new Table(schema); var newSyncer = new TableSynchronizer(newTable, mapping, SqlProvider); newSyncer.ReadData(); AssertTablesEqual(table, newTable); table.Rows[4].RemoveRow(); table.Rows[7].RemoveRow(); table.Rows[2].RemoveRow(); syncer.WriteData(); newSyncer.ReadData(); AssertTablesEqual(table, newTable); newTable = new Table(schema); newSyncer = new TableSynchronizer(newTable, mapping, SqlProvider); newSyncer.ReadData(); AssertTablesEqual(table, newTable); syncer.ReadData(); AssertTablesEqual(newTable, table); } finally { using (var connection = SqlProvider.OpenConnection()) connection.ExecuteNonQuery(@"DROP TABLE Numbers;"); } }
public void ConflictsTest() { using (var connection = SqlProvider.OpenConnection()) connection.ExecuteNonQuery(@" CREATE TABLE [ConflictsTest]( [ID] UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL PRIMARY KEY DEFAULT(newid()), [Key] INTEGER NOT NULL UNIQUE, [Value] INTEGER NULL, [RowVersion] RowVersion );"); try { var schema = new TableSchema("ConflictsTest"); schema.PrimaryKey = schema.Columns.AddValueColumn("ID", typeof(Guid), null); schema.Columns.AddValueColumn("Key", typeof(int), null).Unique = true; schema.Columns.AddValueColumn("Value", typeof(int?), null); var mapping = new SchemaMapping(schema); var table1 = new Table(schema); var syncer1 = new TableSynchronizer(table1, mapping, SqlProvider); var table2 = new Table(schema); var syncer2 = new TableSynchronizer(table2, mapping, SqlProvider); Func <Table, int, Row> GetRow = (t, key) => t.Rows.SingleOrDefault(r => r.Field <int>("Key") == key); Func <int, Row> R1 = k => GetRow(table1, k), R2 = k => GetRow(table2, k); table1.Rows.AddFromValues(Guid.NewGuid(), 2, 67); table2.Rows.AddFromValues(Guid.NewGuid(), 1, null); table2.Rows.AddFromValues(Guid.NewGuid(), 2, 43); syncer1.WriteData(); try { syncer2.WriteData(); Assert.Fail("Conflict succeeded"); } catch (RowException ex) { Assert.IsNotNull(ex.InnerException); Assert.AreEqual(R2(2), ex.Row); } table2.Rows.Clear(); syncer2.ReadData(); AssertTablesEqual(table1, table2); table1.Rows.AddFromValues(Guid.NewGuid(), 1, null); syncer1.WriteData(); syncer2.ReadData(); R1(1)["Value"] = 100; R2(1)["Value"] = 200; syncer1.WriteData(); try { syncer2.WriteData(); Assert.Fail("Conflict succeeded - Update / Update"); } catch (RowModifiedException ex) { Assert.IsNull(ex.InnerException); Assert.AreEqual(R2(1), ex.Row); Assert.AreEqual(R1(1)["Key"], ex.DatabaseValues[schema.Columns["Key"]]); Assert.AreEqual(R1(1)["Value"], ex.DatabaseValues[schema.Columns["Value"]]); } syncer2.ReadData(); AssertTablesEqual(table1, table2); R1(1)["Value"] = 123; R2(1).RemoveRow(); syncer1.WriteData(); try { syncer2.WriteData(); Assert.Fail("Conflict succeeded - Update / Delete"); } catch (RowModifiedException ex) { Assert.IsNull(ex.InnerException); Assert.AreEqual(1, ex.Row["Key"]); Assert.AreEqual(R1(1)["Value"], ex.DatabaseValues[schema.Columns["Value"]]); } syncer2.ReadData(); AssertTablesEqual(table1, table2); R1(1).RemoveRow(); R2(1)["Value"] = -1; syncer1.WriteData(); try { syncer2.WriteData(); Assert.Fail("Conflict succeeded - Delete / Update"); } catch (RowDeletedException ex) { Assert.IsNull(ex.InnerException); Assert.AreEqual(R2(1), ex.Row); } syncer2.ReadData(); AssertTablesEqual(table1, table2); R1(2).RemoveRow(); R2(2).RemoveRow(); syncer1.WriteData(); syncer2.WriteData(); //Delete / Delete - should not throw syncer1.ReadData(); Assert.AreEqual(0, table1.Rows.Count); } finally { using (var connection = SqlProvider.OpenConnection()) connection.ExecuteNonQuery(@"DROP TABLE ConflictsTest;"); } }