Beispiel #1
0
        private void CheckTriggerIntact(DiscoveredTable table, ICheckNotifier notifier, out bool runSynchronizationAgain)
        {
            TriggerChecks checker = new TriggerChecks(table);

            checker.Check(notifier);

            runSynchronizationAgain = checker.TriggerCreated;
        }
Beispiel #2
0
 private void CheckUpdateTriggers(IEnumerable <ITableInfo> allTableInfos)
 {
     // Check that the update triggers are present/enabled
     foreach (var tableInfo in allTableInfos)
     {
         TriggerChecks checker = new TriggerChecks(_databaseConfiguration.DeployInfo[LoadBubble.Live].ExpectTable(tableInfo.GetRuntimeName(), tableInfo.Schema));
         checker.Check(_notifier);
     }
 }
Beispiel #3
0
        public void Check(ICheckNotifier notifier)
        {
            var columnsToDump = TableInfo.PreLoadDiscardedColumns;
            var duplicates    = columnsToDump.GroupBy(k => k.GetRuntimeName()).Where(c => c.Count() > 1).ToArray();

            foreach (var duplicate in duplicates)
            {
                notifier.OnCheckPerformed(
                    new CheckEventArgs(
                        "There are " + duplicate.Count() + " PreLoadDiscardedColumns called '" + duplicate.Key + "' for TableInfo '" +
                        TableInfo + "'", CheckResult.Fail));
            }

            //columns that exist in live but are supposedly dropped during load
            var liveColumns = TableInfo.ColumnInfos.ToArray();


            foreach (var preLoadDiscardedColumn in columnsToDump)
            {
                var match = liveColumns.FirstOrDefault(c => c.GetRuntimeName().Equals(preLoadDiscardedColumn.GetRuntimeName()));

                if (match != null)
                {
                    if (preLoadDiscardedColumn.Destination != DiscardedColumnDestination.Dilute)
                    {
                        notifier.OnCheckPerformed(new CheckEventArgs("TableInfo " + TableInfo + " declares both a PreLoadDiscardedColumn '" + preLoadDiscardedColumn + "' and a ColumnInfo with the same name", CheckResult.Fail));
                        return;
                    }

                    if (match.IsPrimaryKey && preLoadDiscardedColumn.Destination == DiscardedColumnDestination.Dilute)
                    {
                        notifier.OnCheckPerformed(new CheckEventArgs("TableInfo " + TableInfo + " declares a PreLoadDiscardedColumn '" + preLoadDiscardedColumn + "' but there is a matching ColumnInfo of the same name which IsPrimaryKey", CheckResult.Fail));
                        return;
                    }
                }
            }

            if (!HasAtLeastOneColumnToStoreInDump)
            {
                notifier.OnCheckPerformed(new CheckEventArgs("No columns require dumping from TableInfo " + _tableInfo + " so checking is not needed", CheckResult.Success, null));
                return;
            }

            var tables = _dumpDatabase.DiscoverTables(false);

            bool stagingTableFound = tables.Any(t => t.GetRuntimeName().Equals(GetStagingRuntimeName()));

            ConfirmDependencies(_dumpDatabase, notifier);

            //detect ongoing loads/dirty cleanup
            if (stagingTableFound)
            {
                bool shouldDrop = notifier.OnCheckPerformed(new CheckEventArgs("STAGING table found " + GetStagingRuntimeName() + " in ANO database",
                                                                               CheckResult.Fail, null, "Drop table " + GetStagingRuntimeName()));

                if (shouldDrop)
                {
                    DropStaging();
                }
            }
            else
            {
                notifier.OnCheckPerformed(new CheckEventArgs("Confirmed absence of Table  " + GetStagingRuntimeName() + "(this will be created during load)", CheckResult.Success, null));
            }

            //confirm that there is a ColumnInfo for every Dilute column
            var columnInfos = _tableInfo.ColumnInfos.ToArray();

            foreach (var dilutedColumn in ColumnsToRouteToSomewhereElse.Where(c => c.Destination == DiscardedColumnDestination.Dilute))
            {
                if (!columnInfos.Any(c => c.GetRuntimeName().Equals(dilutedColumn.RuntimeColumnName)))
                {
                    notifier.OnCheckPerformed(new CheckEventArgs("PreLoadDiscardedColumn called " + dilutedColumn.GetRuntimeName() +
                                                                 " is marked for Dilution but does not appear in the TableInfo object's ColumnInfo collection.  Diluted columns must appear both in the LIVE database (in diluted state) and in IdentifierDump (in pristene state) which means that for every PreLoadDiscardedColumn which has the destination Dilution, there must be a ColumnInfo with the same name in LIVE", CheckResult.Fail, null));
                }
            }

            //if there are any columns due to be stored in the Identifier dump
            if (ColumnsToRouteToSomewhereElse.Any(c => c.GoesIntoIdentifierDump()))
            {
                //see if table exists
                IdentifierDumperSynchronizer synchronizer = new IdentifierDumperSynchronizer(this, _externalDatabaseServer);
                synchronizer.Synchronize(notifier);

                //make sure there is a backup trigger enabled on the Identifier dump so that we version updates
                TriggerChecks triggerChecker = new TriggerChecks(_dumpDatabase.ExpectTable(GetRuntimeName()));  // primary keys - ignoring transforms for ANO
                triggerChecker.Check(notifier);
            }
        }
Beispiel #4
0
        public void TriggerImplementationTest(DatabaseType type)
        {
            var db  = GetCleanedServer(type);
            var tbl = db.CreateTable("MyTable", new[]
            {
                new DatabaseColumnRequest("name", new DatabaseTypeRequest(typeof(string), 30), false),
                new DatabaseColumnRequest("bubbles", new DatabaseTypeRequest(typeof(int)))
            });

            var factory     = new TriggerImplementerFactory(type);
            var implementer = factory.Create(tbl);

            Assert.AreEqual(TriggerStatus.Missing, implementer.GetTriggerStatus());

            Assert.AreEqual(2, tbl.DiscoverColumns().Length);

            implementer = factory.Create(tbl);

            //no primary keys
            Assert.Throws <TriggerException>(() => implementer.CreateTrigger(new ThrowImmediatelyCheckNotifier()));

            tbl.CreatePrimaryKey(tbl.DiscoverColumn("name"));

            implementer = factory.Create(tbl);

            implementer.CreateTrigger(new ThrowImmediatelyCheckNotifier());

            Assert.AreEqual(4, tbl.DiscoverColumns().Length);

            var archiveTable = tbl.Database.ExpectTable(tbl.GetRuntimeName() + "_Archive");

            Assert.IsTrue(archiveTable.Exists());

            Assert.AreEqual(7, archiveTable.DiscoverColumns().Count());

            Assert.AreEqual(1, archiveTable.DiscoverColumns().Count(c => c.GetRuntimeName().Equals("name")));
            Assert.AreEqual(1, archiveTable.DiscoverColumns().Count(c => c.GetRuntimeName().Equals("bubbles")));
            Assert.AreEqual(1, archiveTable.DiscoverColumns().Count(c => c.GetRuntimeName().Equals("hic_dataLoadrunID", StringComparison.CurrentCultureIgnoreCase)));
            Assert.AreEqual(1, archiveTable.DiscoverColumns().Count(c => c.GetRuntimeName().Equals("hic_validFrom", StringComparison.CurrentCultureIgnoreCase)));
            Assert.AreEqual(1, archiveTable.DiscoverColumns().Count(c => c.GetRuntimeName().Equals("hic_validTo", StringComparison.CurrentCultureIgnoreCase)));
            Assert.AreEqual(1, archiveTable.DiscoverColumns().Count(c => c.GetRuntimeName().Equals("hic_userID", StringComparison.CurrentCultureIgnoreCase)));
            Assert.AreEqual(1, archiveTable.DiscoverColumns().Count(c => c.GetRuntimeName().Equals("hic_status")));

            //is the trigger now existing
            Assert.AreEqual(TriggerStatus.Enabled, implementer.GetTriggerStatus());

            //does it function as expected
            using (var con = tbl.Database.Server.GetConnection())
            {
                con.Open();
                var cmd = tbl.Database.Server.GetCommand(string.Format("INSERT INTO {0}(name,bubbles) VALUES('bob',1)", tbl.GetRuntimeName()), con);
                cmd.ExecuteNonQuery();

                Assert.AreEqual(1, tbl.GetRowCount());
                Assert.AreEqual(0, archiveTable.GetRowCount());

                cmd = tbl.Database.Server.GetCommand(string.Format("UPDATE {0} set bubbles=2", tbl.GetRuntimeName()), con);
                cmd.ExecuteNonQuery();

                Assert.AreEqual(1, tbl.GetRowCount());
                Assert.AreEqual(1, archiveTable.GetRowCount());

                var archive = archiveTable.GetDataTable();
                var dr      = archive.Rows.Cast <DataRow>().Single();

                Assert.AreEqual(((DateTime)dr["hic_validTo"]).Date, DateTime.Now.Date);
            }

            //do the strict check too
            Assert.IsTrue(implementer.CheckUpdateTriggerIsEnabledAndHasExpectedBody());

            tbl.AddColumn("amagad", new DatabaseTypeRequest(typeof(float), null, new DecimalSize(2, 2)), true, 30);
            implementer = factory.Create(tbl);

            Assert.Throws <IrreconcilableColumnDifferencesInArchiveException>(() => implementer.CheckUpdateTriggerIsEnabledAndHasExpectedBody());

            archiveTable.AddColumn("amagad", new DatabaseTypeRequest(typeof(float), null, new DecimalSize(2, 2)), true, 30);

            var checks = new TriggerChecks(tbl);

            checks.Check(new AcceptAllCheckNotifier());

            Assert.IsTrue(implementer.CheckUpdateTriggerIsEnabledAndHasExpectedBody());


            //does it function as expected
            using (var con = tbl.Database.Server.GetConnection())
            {
                con.Open();

                Assert.AreEqual(1, tbl.GetRowCount());
                Assert.AreEqual(1, archiveTable.GetRowCount());

                var cmd = tbl.Database.Server.GetCommand(string.Format("UPDATE {0} set amagad=1.0", tbl.GetRuntimeName()), con);
                cmd.ExecuteNonQuery();

                cmd = tbl.Database.Server.GetCommand(string.Format("UPDATE {0} set amagad=.09", tbl.GetRuntimeName()), con);
                cmd.ExecuteNonQuery();

                Assert.AreEqual(1, tbl.GetRowCount());
                Assert.AreEqual(3, archiveTable.GetRowCount());

                var archive = archiveTable.GetDataTable();
                Assert.AreEqual(1, archive.Rows.Cast <DataRow>().Count(r => Equals(r["amagad"], (decimal)1.00)));
                Assert.AreEqual(2, archive.Rows.Cast <DataRow>().Count(r => r["amagad"] == DBNull.Value));
            }

            string problems;
            string worked;

            implementer.DropTrigger(out problems, out worked);

            Assert.IsTrue(string.IsNullOrEmpty(problems));

            Assert.AreEqual(TriggerStatus.Missing, implementer.GetTriggerStatus());
        }