public void CopyForeignKeyColumns_Test()
        {
            // Arrange

            var target = new ManualKeyForeignTable();

            var recordReference = new RecordReference<ManualKeyForeignTable>(Helpers.GetTypeGeneratorMock(target).Object, this.attributeDecorator);
            recordReference.Populate();

            this.insertRecordService = new InsertRecordService(recordReference, this.attributeDecorator, InsertRecordServiceTest.IsKeyReferenceCheckEnforced);

            var columns = new[]
            {
                new Column { Name = "ForeignKey1", Value = "ABCD" },
                new Column { Name = "Two", Value = new Variable(null) },
                new Column { Name = "ForeignKey2", Value = 3 },
            };

            // Act

            this.insertRecordService.CopyPrimaryToForeignKeyColumns(columns);

            // Assert

            Assert.AreEqual(columns[0].Value, target.ForeignKey1);
            Assert.AreEqual(columns[2].Value, target.ForeignKey2);
        }
        public void ForeignKeyCopiedFromAutoPrimaryKey_InCorrectOrder_Test()
        {
            // Arrange

            var primaryTable = new PrimaryTable();
            var primaryRecordReference = new RecordReference<PrimaryTable>(Helpers.GetTypeGeneratorMock(primaryTable).Object, this.attributeDecorator);
            primaryRecordReference.Populate();

            var foreignTable = new ForeignTable();
            var foreignRecordReference = new RecordReference<ForeignTable>(Helpers.GetTypeGeneratorMock(foreignTable).Object, this.attributeDecorator);
            foreignRecordReference.Populate();

            foreignRecordReference.AddPrimaryRecordReference(primaryRecordReference);

            var expected = new object[] {"Key", 1, "Guid",  Guid.NewGuid(), "Key", 2};

            this.writePrimitivesMock.Setup(m => m.Execute()).Returns(expected);

            // Act

            // Note the foreign key record is being passed in before the primary key record.
            // This is to test that the primary key record that wrote first gets the first return
            // data element and the foreign key record gets the subsequent one.

            this.persistence.Persist(new RecordReference[] { foreignRecordReference, primaryRecordReference });

            // Assert

            Assert.AreEqual(expected[1], primaryTable.Key);
            Assert.AreEqual(expected[5], foreignTable.Key);
        }
        public void Persists_KeyMapping_Test()
        {
            // Arrange

            var primaryTable = new ManualKeyPrimaryTable { Key1 = "ABCD", Key2 = 5 };
            var primaryReference = new RecordReference<ManualKeyPrimaryTable>(Helpers.GetTypeGeneratorMock(primaryTable).Object, this.attributeDecorator);

            var foreignTable = new ManualKeyForeignTable();
            var foreignReference =
                new RecordReference<ManualKeyForeignTable>(Helpers.GetTypeGeneratorMock(foreignTable).Object, this.attributeDecorator);

            foreignReference.AddPrimaryRecordReference(primaryReference);

            var deferredValueGeneratorMock = new Mock<IDeferredValueGenerator<LargeInteger>>();
            var persistence = new MemoryPersistence(deferredValueGeneratorMock.Object, this.attributeDecorator);

            // Act

            primaryReference.Populate();
            foreignReference.Populate();
            persistence.Persist(new RecordReference[] { primaryReference, foreignReference});

            // Assert

            Assert.AreEqual(primaryTable.Key1, foreignTable.ForeignKey1);
            Assert.AreEqual(primaryTable.Key2, foreignTable.ForeignKey2);
        }
        public void DeferredValueGenerator_Test()
        {
            // Arrange

            var typeGeneratorMock = new Mock<ITypeGenerator>();

            typeGeneratorMock.Setup(
                m => m.GetObject<PrimaryTable>(It.IsAny<ConcurrentDictionary<PropertyInfo, Action<PrimaryTable>>>()))
                .Returns(new PrimaryTable());

            typeGeneratorMock.Setup(
                m => m.GetObject<ForeignTable>(It.IsAny<ConcurrentDictionary<PropertyInfo, Action<ForeignTable>>>()))
                .Returns(new ForeignTable());

            var recordObject1 = new RecordReference<PrimaryTable>(typeGeneratorMock.Object, this.attributeDecorator);
            var recordObject2 = new RecordReference<ForeignTable>(typeGeneratorMock.Object, this.attributeDecorator);

            var dataSource = new Mock<IPropertyDataGenerator<LargeInteger>>();
            var generator = new StandardDeferredValueGenerator<LargeInteger>(dataSource.Object);

            // Act

            recordObject1.Populate();
            recordObject2.Populate();

            generator.AddDelegate(recordObject1.RecordType.GetProperty("Text"), ul => "A");
            generator.AddDelegate(recordObject1.RecordType.GetProperty("Integer"), ul => 1);
            generator.AddDelegate(recordObject2.RecordType.GetProperty("Text"), ul => "B");
            generator.AddDelegate(recordObject2.RecordType.GetProperty("Integer"), ul => 2);

            generator.Execute(new RecordReference[] {recordObject2, recordObject1});

            // Assert

            Assert.AreEqual("A", recordObject1.RecordObject.Text);
            Assert.AreEqual(1, recordObject1.RecordObject.Integer);
            Assert.AreEqual("B", recordObject2.RecordObject.Text);
            Assert.AreEqual(2, recordObject2.RecordObject.Integer);
        }
        public void CopyForeignKeyColumns_UnknownColumnThrows_Test()
        {
            // Arrange

            var target = new ManualKeyForeignTable();

            var recordReference = new RecordReference<ManualKeyForeignTable>(Helpers.GetTypeGeneratorMock(target).Object, this.attributeDecorator);
            recordReference.Populate();

            this.insertRecordService = new InsertRecordService(recordReference, this.attributeDecorator, InsertRecordServiceTest.IsKeyReferenceCheckEnforced);

            var columns = new[]
            {
                new Column { Name = "ForeignKey1", Value = "ABCD" },
                new Column { Name = "Two", Value = new object() },
            };

            // Act
            // Assert

            Helpers.ExceptionTest(
                () => this.insertRecordService.CopyPrimaryToForeignKeyColumns(columns),
                typeof(InvalidOperationException),
                "Sequence contains no matching element");
        }
        public void GetRegularColumns_WriteGuid_Test()
        {
            // Arrange

            var table = new ClassWithGuidKeys();

            Mock<ITypeGenerator> typeGeneratorMock = Helpers.GetTypeGeneratorMock(table);

            var recordReference = new RecordReference<ClassWithGuidKeys>(typeGeneratorMock.Object, this.attributeDecorator);
            recordReference.Populate();

            var insertRecordService = new InsertRecordService(recordReference, this.attributeDecorator, InsertRecordServiceTest.IsKeyReferenceCheckEnforced);

            Variable v1, v2, v3;
            this.writerMock.Setup(m => m.WriteGuid("Key1")).Returns(v1 = new Variable("x"));
            this.writerMock.Setup(m => m.WriteGuid("Key3")).Returns(v2 = new Variable("y"));
            this.writerMock.Setup(m => m.WriteGuid("Key4")).Returns(v3 = new Variable("z"));

            // Act

            List<Column> regularColumns = insertRecordService.GetRegularColumns(this.writerMock.Object).ToList();

            // Assert

            this.writerMock.Verify(m => m.WriteGuid(It.IsAny<string>()), Times.Exactly(3));

            Column key1 = regularColumns.First(c => c.Name == "Key1");
            Column key3 = regularColumns.First(c => c.Name == "Key3");
            Column key4 = regularColumns.First(c => c.Name == "Key4");

            Assert.AreEqual(v1, key1.Value);
            Assert.AreEqual(v2, key3.Value);
            Assert.AreEqual(v3, key4.Value);
        }
        public void GetRegularColumns_NonAutoPrimaryKey_Test()
        {
            // Arrange

            var table = new ManualKeyPrimaryTable {Key1 = "ABCD", Key2 = 7};

            var typeGeneratorMock = Helpers.GetTypeGeneratorMock(table);
            var recordReference = new RecordReference<ManualKeyPrimaryTable>(typeGeneratorMock.Object, this.attributeDecorator);
            recordReference.Populate();
            var insertRecordService = new InsertRecordService(recordReference, this.attributeDecorator, InsertRecordServiceTest.IsKeyReferenceCheckEnforced);

            // Act

            List<Column> regularColumns = insertRecordService.GetRegularColumns(null).ToList();

            // Assert

            Assert.AreEqual(2, regularColumns.Count);

            Column stringKey = regularColumns.First(c => c.Name == "Key1");
            Column intKey = regularColumns.First(c => c.Name == "Key2");

            Assert.AreEqual(table.Key1, stringKey.Value);
            Assert.AreEqual(table.Key2, intKey.Value);
        }
        public void GetRegularColumns_ExplicitlySetGuid_Test()
        {
            // Arrange

            var table = new ClassWithGuidKeys {Key1 = Guid.NewGuid(), Key3 = Guid.NewGuid(), Key4 = null};

            Mock<ITypeGenerator> typeGeneratorMock = Helpers.GetTypeGeneratorMock(table);
            var recordReference = new RecordReference<ClassWithGuidKeys>(typeGeneratorMock.Object, this.attributeDecorator);

            recordReference.Set(r => r.Key1, Guid.Empty).Set(r => r.Key3, Guid.Empty).Set(r => r.Key4, Guid.Empty);
            recordReference.Populate();

            var insertRecordService = new InsertRecordService(recordReference, this.attributeDecorator, InsertRecordServiceTest.IsKeyReferenceCheckEnforced);

            // Act

            List<Column> regularColumns = insertRecordService.GetRegularColumns(null).ToList();

            // Assert

            Column key1 = regularColumns.First(c => c.Name == "Key1");
            Column key3 = regularColumns.First(c => c.Name == "Key3");
            Column key4 = regularColumns.First(c => c.Name == "Key4");

            Assert.AreEqual(table.Key1, key1.Value);
            Assert.AreEqual(table.Key3, key3.Value);
            Assert.AreEqual(null, key4.Value);
        }
        public void ForeignKeysCopiedFromManualPrimaryKeys_Test()
        {
            // Arrange

            var primaryTable = new ManualKeyPrimaryTable {Key1 = "A", Key2 = 7};
            var foreignTable = new ManualKeyForeignTable();

            var primaryRecordReference = new RecordReference<ManualKeyPrimaryTable>(Helpers.GetTypeGeneratorMock(primaryTable).Object, this.attributeDecorator);
            primaryRecordReference.Populate();

            var foreignRecordReference = new RecordReference<ManualKeyForeignTable>(Helpers.GetTypeGeneratorMock(foreignTable).Object, this.attributeDecorator);
            foreignRecordReference.Populate();

            foreignRecordReference.AddPrimaryRecordReference(primaryRecordReference);
            const string catalogueName = "catABC";
            const string schema = "schemaABC";
            const string tableName = "ABCD";

            var columns = new List<List<Column>>();

            this.writePrimitivesMock.Setup(m => m.Insert(catalogueName, schema, tableName, It.IsAny<IEnumerable<Column>>()))
                .Callback<string, string, string, IEnumerable<Column>>((cat, s, t, col) => columns.Add(col.ToList()));

            // Act

            this.persistence.Persist(new RecordReference[] { foreignRecordReference, primaryRecordReference });

            // Assert

            Assert.AreEqual(primaryTable.Key1, foreignTable.ForeignKey1);
            Assert.AreEqual(primaryTable.Key2, foreignTable.ForeignKey2);
        }
        public void Insert_Test()
        {
            // Arrange

            var primaryTable = new PrimaryTable { Integer = 5, Text = "Text"};

            var primaryRecordReference = new RecordReference<PrimaryTable>(Helpers.GetTypeGeneratorMock(primaryTable).Object, this.attributeDecorator);
            primaryRecordReference.Populate();

            string tableName = typeof(PrimaryTable).Name;

            List<Column> primaryTableColumns = null;

            this.writePrimitivesMock.Setup(m => m.Insert(null, It.IsAny<string>(), tableName, It.IsAny<IEnumerable<Column>>()))
                .Callback<string, string, string, IEnumerable<Column>>((cat, s, t, col) => primaryTableColumns = col.ToList());

            this.writePrimitivesMock.Setup(m => m.Execute()).Returns(new object[] {"Key", 0, "Guid", Guid.NewGuid()});

            // Act

            var recordReferenceArray = new RecordReference[] {primaryRecordReference};

            this.persistence.Persist(recordReferenceArray);

            // Assert

            this.writePrimitivesMock.Verify(m => m.Insert(null, It.IsAny<string>(), tableName, It.IsAny<IEnumerable<Column>>()), Times.Once());

            this.deferredValueGeneratorMock.Verify(
                m => m.Execute(It.Is<IEnumerable<RecordReference>>(e => e.First() == recordReferenceArray[0])),
                Times.Once);

            Assert.IsNotNull(primaryTableColumns);
            Assert.AreEqual(4, primaryTableColumns.Count);

            Assert.AreEqual("Text", primaryTableColumns[0].Name);
            Assert.AreEqual(primaryTable.Text, primaryTableColumns[0].Value);

            Assert.AreEqual("Integer", primaryTableColumns[1].Name);
            Assert.AreEqual(primaryTable.Integer, primaryTableColumns[1].Value);
        }
        public void InsertsInProperOrder_Test()
        {
            // Arrange

            var primaryTable = new PrimaryTable { Integer = 1};
            var primaryRecordReference = new RecordReference<PrimaryTable>(Helpers.GetTypeGeneratorMock(primaryTable).Object, this.attributeDecorator);
            primaryRecordReference.Populate();

            var foreignTable = new ForeignTable {Integer = 1};
            var foreignRecordReference = new RecordReference<ForeignTable>(Helpers.GetTypeGeneratorMock(foreignTable).Object, this.attributeDecorator);
            foreignRecordReference.Populate();

            foreignRecordReference.AddPrimaryRecordReference(primaryRecordReference);

            var columns = new List<List<Column>>();

            this.writePrimitivesMock.Setup(m => m.Insert(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IEnumerable<Column>>()))
                .Callback<string, string, string, IEnumerable<Column>>((cat, s, t, col) => columns.Add(col.ToList()));

            this.writePrimitivesMock.Setup(m => m.SelectIdentity(It.IsAny<string>())).Returns(new Variable(null));

            this.writePrimitivesMock.Setup(m => m.Execute()).Returns(new object[] {"Key", 0, "Guid", Guid.NewGuid(), "Key", 0});

            // Act

            // Note the foreign key record is being passed in before the primary key record
            // to test that the primary key record writes first regardless which insert operation's
            // Write method is called.

            this.persistence.Persist(new RecordReference[] { foreignRecordReference, primaryRecordReference});

            // Assert

            Assert.AreEqual(primaryTable.Integer, columns[0].First(c => c.Name == "Integer").Value);
            Assert.AreEqual(foreignTable.Integer, columns[1].First(c => c.Name == "Integer").Value);
        }