public void MustRecreateDependentConceptWhereBaseIsCreatedAndDeletedWithSameKey()
        {
            var oldSimple = new SimpleConcept("S", "sqlS");
            var newSimple = new SimpleConcept("S", "sqlS"); // S is not changed, but its implementation type will be changes later.

            var oldReferenceUnchanged = new ReferenceConcept("R", oldSimple, "sqlR");
            var newReferenceUnchanged = new ReferenceConcept("R", newSimple, "sqlR"); // R is not changed.

            Assert.AreEqual(oldReferenceUnchanged.Name, newReferenceUnchanged.Name);
            Assert.AreEqual(oldReferenceUnchanged.Sql, newReferenceUnchanged.Sql);
            var oldApplications = CreateConceptApplications(oldSimple, oldReferenceUnchanged);
            var newApplications = CreateConceptApplications(newSimple, newReferenceUnchanged);

            // Changing ConceptImplementationTypeName will affect ConceptApplication's key (see GetConceptApplicationKey), and result with dropping and creating it in database.
            // This behavior might change in future if some optimizations are implemented in DatabaseGenerator.
            oldApplications.Find <SimpleConcept>().ConceptImplementationTypeName = typeof(SimpleImplementation).AssemblyQualifiedName.Replace(nameof(SimpleImplementation), "OldImplementationThatNoLongerExists");

            var dbUpdate = DatabaseGeneratorUpdateDatabase(oldApplications, newApplications);

            string expected = "drop-sqlR, del ReferenceConcept R, drop-sqlS, del SimpleConcept S, sqlS, ins SimpleConcept S, sqlR, ins ReferenceConcept R";

            Assert.AreEqual(expected, dbUpdate.Report);

            var removedSimple     = dbUpdate.RemovedConcepts.Find <SimpleConcept>();
            var removedReference  = dbUpdate.RemovedConcepts.Find <ReferenceConcept>();
            var insertedSimple    = dbUpdate.InsertedConcepts.Find <SimpleConcept>();
            var insertedReference = dbUpdate.InsertedConcepts.Find <ReferenceConcept>();

            Assert.AreNotSame(removedSimple, insertedSimple);
            Assert.AreSame(removedSimple, removedReference.DependsOn.Single(), "Removed reference should point to old version of changed concept.");
            Assert.AreEqual(insertedSimple, insertedReference.DependsOn.Single(), "Inserted reference should point to new version of changed concept.");
        }
        public void MustRecreateDependentConcept()
        {
            var oldSimple = new SimpleConcept("S", "sqlS1");
            var newSimple = new SimpleConcept("S", "sqlS2");

            var oldReferenceUnchanged = new ReferenceConcept("R", oldSimple, "sqlR");
            var newReferenceUnchanged = new ReferenceConcept("R", newSimple, "sqlR"); // Reference is not changed.

            Assert.AreEqual(oldReferenceUnchanged.Name, newReferenceUnchanged.Name);
            Assert.AreEqual(oldReferenceUnchanged.Sql, newReferenceUnchanged.Sql);
            var oldApplications = CreateConceptApplications(oldSimple, oldReferenceUnchanged);
            var newApplications = CreateConceptApplications(newSimple, newReferenceUnchanged);

            string expected = "drop-sqlR, del ReferenceConcept R, drop-sqlS1, del SimpleConcept S, sqlS2, ins SimpleConcept S, sqlR, ins ReferenceConcept R";

            var dbUpdate = DatabaseGeneratorUpdateDatabase(oldApplications, newApplications);

            Assert.AreEqual(expected, dbUpdate.Report);
        }
        public void RecreatedDependentConceptReferencesNewVersion()
        {
            var oldSimple = new SimpleConcept("S", "sqlS1");
            var newSimple = new SimpleConcept("S", "sqlS2");

            var oldReferenceUnchanged = new ReferenceConcept("R", oldSimple, "sqlR");
            var newReferenceUnchanged = new ReferenceConcept("R", newSimple, "sqlR"); // Reference is not changed.

            Assert.AreEqual(oldReferenceUnchanged.Name, newReferenceUnchanged.Name);
            Assert.AreEqual(oldReferenceUnchanged.Sql, newReferenceUnchanged.Sql);
            var oldApplications = CreateConceptApplications(oldSimple, oldReferenceUnchanged);
            var newApplications = CreateConceptApplications(newSimple, newReferenceUnchanged);

            var dbUpdate = DatabaseGeneratorUpdateDatabase(oldApplications, newApplications);

            Assert.AreEqual("sqlS1", dbUpdate.RemovedConcepts.Find <ReferenceConcept>().DependsOn.Single().CreateQuery,
                            "Removed reference should point to old version of changed concept.");
            Assert.AreEqual("sqlS2", dbUpdate.InsertedConcepts.Find <ReferenceConcept>().DependsOn.Single().CreateQuery,
                            "Inserted reference should point to new version of changed concept.");
        }
        public void UnchangedMiddleReferenceWithoutDatabaseGenerator()
        {
            // A <- B <- C;
            var oldA = new SimpleConcept("A", "sqlA1");
            var newA = new SimpleConcept("A", "sqlA2"); // Changed.

            var oldB = new NoImplementationConcept("B", oldA);
            var newB = new NoImplementationConcept("B", newA); // A and C have database generator implementations, but B doesn't.

            var oldC = new ReferenceConcept("C", oldB, "sqlC1");
            var newC = new ReferenceConcept("C", newB, "sqlC2"); // Second-level reference is changed.

            var oldApplications = CreateConceptApplications(oldA, oldB, oldC);
            var newApplications = CreateConceptApplications(newA, newB, newC);

            var dbUpdate = DatabaseGeneratorUpdateDatabase(oldApplications, newApplications);

            string expected = "drop-sqlC1, del ReferenceConcept C, del NoImplementationConcept B, drop-sqlA1, del SimpleConcept A,"
                              + " sqlA2, ins SimpleConcept A, ins NoImplementationConcept B, sqlC2, ins ReferenceConcept C";

            Assert.AreEqual(expected, dbUpdate.Report);
        }
        public void MustRecreateDependentConceptInCorrectOrder()
        {
            // A <- B <- C;
            var oldA = new SimpleConcept("A", "sqlA1");
            var newA = new SimpleConcept("A", "sqlA2"); // Changed.

            var oldB = new ReferenceConcept("B", oldA, "sqlB");
            var newB = new ReferenceConcept("B", newA, "sqlB"); // Reference is not changed.

            var oldC = new ReferenceReferenceConcept("C", oldB, "sqlC1");
            var newC = new ReferenceReferenceConcept("C", newB, "sqlC2"); // Second-level reference is changed.

            var oldApplications = CreateConceptApplications(oldA, oldB, oldC);
            var newApplications = CreateConceptApplications(newA, newB, newC);

            var dbUpdate = DatabaseGeneratorUpdateDatabase(oldApplications, newApplications);

            string expected = "drop-sqlC1, del ReferenceReferenceConcept C, drop-sqlB, del ReferenceConcept B, drop-sqlA1, del SimpleConcept A,"
                              + " sqlA2, ins SimpleConcept A, sqlB, ins ReferenceConcept B, sqlC2, ins ReferenceReferenceConcept C";

            Assert.AreEqual(expected, dbUpdate.Report);
        }
 public ReferenceReferenceConcept(string name, ReferenceConcept parent, string sql)
 {
     Name   = name;
     Parent = parent;
     Sql    = sql;
 }