Exemple #1
0
        /// <inheritdoc cref="WhenIHaveA{T}()"/>
        protected ANOTable WhenIHaveA <T>(out ExternalDatabaseServer server) where T : ANOTable
        {
            server = new ExternalDatabaseServer(Repository, "ANO Server", new ANOStorePatcher());
            var anoTable = new ANOTable(Repository, server, "ANOFish", "F");

            return(anoTable);
        }
        public void Synchronize(ICheckNotifier notifier)
        {
            IdentifierDumper dumper = new IdentifierDumper(_tableToSync);

            dumper.Check(notifier);

            CheckForDuplicateANOVsRegularNames();

            var columnInfosWithANOTransforms = _tableToSync.ColumnInfos.Where(c => c.ANOTable_ID != null).ToArray();

            if (!columnInfosWithANOTransforms.Any())
            {
                notifier.OnCheckPerformed(
                    new CheckEventArgs(
                        "There are no ANOTables configured for this table so skipping ANOTable checking",
                        CheckResult.Success));
            }

            foreach (ColumnInfo columnInfoWithANOTransform in columnInfosWithANOTransforms)
            {
                ANOTable anoTable = columnInfoWithANOTransform.ANOTable;
                anoTable.Check(new ThrowImmediatelyCheckNotifier());

                if (!anoTable.GetRuntimeDataType(LoadStage.PostLoad).Equals(columnInfoWithANOTransform.Data_type))
                {
                    throw new ANOConfigurationException("Mismatch between anoTable.GetRuntimeDataType(LoadStage.PostLoad) = " + anoTable.GetRuntimeDataType(LoadStage.PostLoad) + " and column " + columnInfoWithANOTransform + " datatype = " + columnInfoWithANOTransform.Data_type);
                }

                notifier.OnCheckPerformed(
                    new CheckEventArgs(
                        "ANOTable " + anoTable + " has shared compatible datatype " + columnInfoWithANOTransform.Data_type + " with ColumnInfo " +
                        columnInfoWithANOTransform, CheckResult.Success));
            }
        }
Exemple #3
0
        private void ddANOTables_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (ddANOTables.SelectedItem == null)
            {
                return;
            }

            //get ANOTable input datatype
            var anoTable = (ANOTable)ddANOTables.SelectedItem;

            //if table is already on the ANO server
            if (anoTable.IsTablePushed())
            {
                string anoDatatype = anoTable.GetRuntimeDataType(LoadStage.AdjustRaw);
                string colDatatype = _columnInfo.GetRuntimeDataType(LoadStage.PostLoad);

                if (!anoDatatype.Equals(colDatatype))
                {
                    checksUI1.OnCheckPerformed(
                        new CheckEventArgs(
                            "ANOTable  " + anoTable + " cannot be used because it's input datatype is " + anoDatatype + " but the data in " +
                            _columnInfo + " is of datatype " + colDatatype, CheckResult.Fail));
                    ddANOTables.SelectedItem = null;
                    return;
                }
            }

            //either it is not pushed or it is pushed and the datatypes are compatible.
            ANOTable = anoTable;

            gbANOTable.Enabled = true;
            gbSelectExistingANOTable.Enabled = false;
            gbCreateNewANOTable.Enabled      = false;
        }
Exemple #4
0
        public override void SetDatabaseObject(IActivateItems activator, ANOTable databaseObject)
        {
            _anoTable = databaseObject;
            base.SetDatabaseObject(activator, databaseObject);

            llServer.Text = _anoTable.Server.Name;

            CommonFunctionality.AddChecks(databaseObject);
            CommonFunctionality.StartChecking();

            SetEnabledness();

            CommonFunctionality.AddHelp(tbSuffix, "ANOTable.Suffix");
            CommonFunctionality.AddHelp(llServer, "ANOTable.Server_ID");
            CommonFunctionality.AddHelpString(tbInputDataType, "DataType", "Datatype for private identifiers being mapped e.g. varchar(100)");
            CommonFunctionality.AddHelp(nIntegers, "ANOTable.NumberOfIntegersToUseInAnonymousRepresentation");
            CommonFunctionality.AddHelp(nCharacters, "ANOTable.NumberOfCharactersToUseInAnonymousRepresentation");

            if (!_anoTable.Server.WasCreatedBy(new ANOStorePatcher()))
            {
                _serverErrorProvider.SetError(llServer, "Server is not an ANO server");
            }
            else
            {
                _serverErrorProvider.Clear();
            }
        }
Exemple #5
0
        /// <summary>
        /// Gets the DataType adjusted for the stage at which the ColumnInfo is at, this is almost always the same as Data_type.  The only
        /// time it is different is when there is an ANOTable involved e.g. ANOLocation could be a varchar(6) like 'AB10_L' after anonymisation
        /// but if the LoadStage is AdjustRaw then it would have a value like 'NH10' (varchar(4) - the unanonymised state).
        /// </summary>
        /// <param name="loadStage"></param>
        /// <returns></returns>
        public string GetRuntimeDataType(LoadStage loadStage)
        {
            if (loadStage <= LoadStage.AdjustRaw)
            {
                //if it has an ANO transform
                if (ANOTable_ID != null)
                {
                    return(ANOTable.GetRuntimeDataType(loadStage));    //get the datatype from the ANOTable because ColumnInfo is of mutable type depending on whether it has been anonymised yet
                }
                //it doesn't have an ANOtransform but it might be the subject of dilution
                var discard = TableInfo.PreLoadDiscardedColumns.SingleOrDefault(c => c.GetRuntimeName().Equals(GetRuntimeName(), StringComparison.InvariantCultureIgnoreCase));

                //The column exists both in the live database and in the identifier dump.  This is because it goes through horrendous bitcrushing operations e.g. Load RAW with full
                //postcode varchar(8) and ship postcode off to identifier dump but also let it go through to live but only as the first 4 letters varchar(4).  so the datatype of the column
                //in RAW is varchar(8) but in Live is varchar(4)
                if (discard != null)
                {
                    return(discard.Data_type);
                }

                return(Data_type);
            }

            //The user is asking about a stage other than RAW so tell them about the final column type state
            return(Data_type);
        }
Exemple #6
0
        private void btnCreateNewANOTable_Click(object sender, EventArgs e)
        {
            try
            {
                var server = ddExternalDatabaseServer.SelectedItem as ExternalDatabaseServer;

                var a = new ANOTable(Activator.RepositoryLocator.CatalogueRepository, server, tbANOTableName.Text, tbSuffix.Text);

                //if we know the type is e.g. varchar(5)
                var length = ColumnInfo.Discover(DataAccessContext.InternalDataProcessing).DataType.GetLengthIfString();

                if (length > 0)
                {
                    a.NumberOfIntegersToUseInAnonymousRepresentation   = 0;
                    a.NumberOfCharactersToUseInAnonymousRepresentation = length;//give it a sensible maximal that will work
                    a.SaveToDatabase();
                }

                ANOTable = a;//and set the property to it to populate the rest of the form

                gbANOTable.Enabled = true;
                gbSelectExistingANOTable.Enabled = false;
                gbCreateNewANOTable.Enabled      = false;
            }
            catch (Exception exception)
            {
                checksUI1.OnCheckPerformed(new CheckEventArgs("Could not create ANOTable", CheckResult.Fail, exception));
            }
        }
Exemple #7
0
        public override void Execute()
        {
            base.Execute();

            var name = new TypeTextOrCancelDialog("ANO Concept Name", "Name", 500, "ANOConceptName");

            if (name.ShowDialog() == DialogResult.OK)
            {
                var suffix = new TypeTextOrCancelDialog("Type Concept Suffix", "Suffix", 5, "_X");
                if (suffix.ShowDialog() == DialogResult.OK)
                {
                    var n = name.ResultText;

                    if (!n.StartsWith("ANO"))
                    {
                        n = "ANO" + n;
                    }

                    var s = suffix.ResultText.Trim('_');

                    var anoTable = new ANOTable(Activator.RepositoryLocator.CatalogueRepository, (ExternalDatabaseServer)_anoStoreServer, n, s);
                    Publish(anoTable);
                    Activate(anoTable);
                }
            }
        }
Exemple #8
0
        public GatheredObject GatherDependencies(ANOTable anoTable)
        {
            var root = new GatheredObject(anoTable.Server);

            root.Children.Add(new GatheredObject(anoTable));

            return(root);
        }
Exemple #9
0
        public ANOTransformer(ANOTable anoTable, IDataLoadEventListener listener = null)
        {
            _externalDatabaseServer = anoTable.Server;

            _server = DataAccessPortal.GetInstance().ExpectServer(_externalDatabaseServer, DataAccessContext.DataLoad);

            _anoTable = anoTable;
            _listener = listener;
        }
Exemple #10
0
        protected override void SetBindings(BinderWithErrorProviderFactory rules, ANOTable databaseObject)
        {
            base.SetBindings(rules, databaseObject);

            Bind(tbID, "Text", "ID", a => a.ID);
            Bind(nIntegers, "Value", "NumberOfIntegersToUseInAnonymousRepresentation", a => a.NumberOfIntegersToUseInAnonymousRepresentation);
            Bind(nCharacters, "Value", "NumberOfCharactersToUseInAnonymousRepresentation", a => a.NumberOfCharactersToUseInAnonymousRepresentation);
            Bind(tbName, "Text", "TableName", a => a.TableName);
            Bind(tbSuffix, "Text", "Suffix", a => a.Suffix);
        }
Exemple #11
0
        protected void TruncateANOTable(ANOTable anoTable)
        {
            Console.WriteLine("Truncating table " + anoTable.TableName + " on server " + ANOStore_ExternalDatabaseServer);

            var server = ANOStore_Database.Server;

            using (var con = server.GetConnection())
            {
                con.Open();
                var cmdDelete = server.GetCommand("if exists (select top 1 * from sys.tables where name ='" + anoTable.TableName + "') TRUNCATE TABLE " + anoTable.TableName, con);
                cmdDelete.ExecuteNonQuery();
                con.Close();
            }
        }
Exemple #12
0
        public string GetEndpointDataType()
        {
            var sourceTypeTranslater = _querySyntaxHelper.TypeTranslater;

            //if we have picked a destination
            ITypeTranslater destinationTypeTranslater;

            if (_planManager.TargetDatabase != null)
            {
                destinationTypeTranslater = _planManager.TargetDatabase.Server.GetQuerySyntaxHelper().TypeTranslater;//ensure we handle type translation between the two platforms
            }
            else
            {
                destinationTypeTranslater = sourceTypeTranslater;//otherwise (we haven't picked a destination yet)
            }
            switch (Plan)
            {
            case Plan.Drop:
                return(null);

            case Plan.ANO:
                if (ANOTable == null)
                {
                    return("Unknown");
                }

                return(sourceTypeTranslater.TranslateSQLDBType(ANOTable.GetRuntimeDataType(LoadStage.PostLoad), destinationTypeTranslater));

            case Plan.Dilute:
                if (Dilution == null)
                {
                    return("Unknown");
                }

                return(destinationTypeTranslater.GetSQLDBTypeForCSharpType(Dilution.ExpectedDestinationType));

            case Plan.PassThroughUnchanged:

                //if they have an identity column then we substitute it for int in the destination
                if (ColumnInfo.IsAutoIncrement)
                {
                    return(destinationTypeTranslater.GetSQLDBTypeForCSharpType(new DatabaseTypeRequest(typeof(int))));
                }

                return(sourceTypeTranslater.TranslateSQLDBType(ColumnInfo.Data_type, destinationTypeTranslater));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemple #13
0
        public void CreateAnANOTable_IntCountNegative()
        {
            ANOTable anoTable = GetANOTable();

            try
            {
                anoTable.NumberOfIntegersToUseInAnonymousRepresentation = -500;
                var ex = Assert.Throws <Exception>(anoTable.SaveToDatabase);
                Assert.AreEqual("NumberOfIntegersToUseInAnonymousRepresentation cannot be negative", ex.Message);
            }
            finally
            {
                anoTable.DeleteInDatabase();
            }
        }
        public override void Execute()
        {
            base.Execute();

            if (TypeText("ANO Concept Name", "Name", 500, null, out string name))
            {
                if (TypeText("Type Concept Suffix", "Suffix", 5, null, out string suffix))
                {
                    if (!name.StartsWith("ANO"))
                    {
                        name = "ANO" + name;
                    }

                    var s = suffix.Trim('_');

                    var anoTable = new ANOTable(BasicActivator.RepositoryLocator.CatalogueRepository, (ExternalDatabaseServer)_anoStoreServer, name, s);
                    Publish(anoTable);
                    Activate(anoTable);
                }
            }
        }
Exemple #15
0
        private void CreateMigrationRules(ForwardEngineerANOCataloguePlanManager planManager, BulkTestsData bulk)
        {
            var chi = bulk.GetColumnInfo("chi");

            var anoChi = new ANOTable(CatalogueRepository, ANOStore_ExternalDatabaseServer, "ANOCHI", "C");

            anoChi.NumberOfIntegersToUseInAnonymousRepresentation   = 9;
            anoChi.NumberOfCharactersToUseInAnonymousRepresentation = 1;
            anoChi.SaveToDatabase();
            anoChi.PushToANOServerAsNewTable(chi.Data_type, new ThrowImmediatelyCheckNotifier());

            planManager.GetPlanForColumnInfo(chi).Plan     = Plan.ANO;
            planManager.GetPlanForColumnInfo(chi).ANOTable = anoChi;

            var dob = bulk.GetColumnInfo("date_of_birth");

            planManager.GetPlanForColumnInfo(dob).Plan     = Plan.Dilute;
            planManager.GetPlanForColumnInfo(dob).Dilution = new RoundDateToMiddleOfQuarter();

            var postcode = bulk.GetColumnInfo("current_postcode");

            planManager.GetPlanForColumnInfo(postcode).Plan     = Plan.Dilute;
            planManager.GetPlanForColumnInfo(postcode).Dilution = new ExcludeRight3OfUKPostcodes();
        }
 public ColumnInfoToANOTableConverter(ColumnInfo colToNuke, ANOTable toConformTo)
 {
     _tableInfo   = colToNuke.TableInfo;
     _colToNuke   = colToNuke;
     _toConformTo = toConformTo;
 }
Exemple #17
0
        protected override void SetUp()
        {
            base.SetUp();

            var db = GetCleanedServer(FAnsi.DatabaseType.MicrosoftSQLServer);

            BlitzMainDataTables();

            DeleteANOEndpoint();

            ANOTable remnantANO = CatalogueRepository.GetAllObjects <ANOTable>().SingleOrDefault(a => a.TableName.Equals("ANOCondition"));

            if (remnantANO != null)
            {
                remnantANO.DeleteInDatabase();
            }

            //cleanup
            foreach (var remnant in CatalogueRepository.GetAllObjects <TableInfo>().Where(t => t.GetRuntimeName().Equals(TableName)))
            {
                remnant.DeleteInDatabase();
            }

            const string sql = @"
CREATE TABLE [ANOMigration](
	[AdmissionDate] [datetime] NOT NULL,
	[DischargeDate] [datetime] NOT NULL,
	[Condition1] [varchar](4) NOT NULL,
	[Condition2] [varchar](4) NULL,
	[Condition3] [varchar](4) NULL,
	[Condition4] [varchar](4) NULL,
	[CHI] [varchar](10) NOT NULL
 CONSTRAINT [PK_ANOMigration] PRIMARY KEY CLUSTERED 
(
	[AdmissionDate] ASC,
	[Condition1] ASC,
	[CHI] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

INSERT [ANOMigration] ([AdmissionDate], [DischargeDate], [Condition1], [Condition2], [Condition3], [Condition4], [CHI]) VALUES (CAST(0x000001B300000000 AS DateTime), CAST(0x000001B600000000 AS DateTime), N'Z61', N'Z29', NULL, N'Z11', N'0809003082')
INSERT [ANOMigration] ([AdmissionDate], [DischargeDate], [Condition1], [Condition2], [Condition3], [Condition4], [CHI]) VALUES (CAST(0x0000021D00000000 AS DateTime), CAST(0x0000022600000000 AS DateTime), N'P024', N'Q230', NULL,N'Z11', N'1610007810')
INSERT [ANOMigration] ([AdmissionDate], [DischargeDate], [Condition1], [Condition2], [Condition3], [Condition4], [CHI]) VALUES (CAST(0x0000032900000000 AS DateTime), CAST(0x0000032A00000000 AS DateTime), N'L73', NULL, NULL, NULL, N'2407011022')
INSERT [ANOMigration] ([AdmissionDate], [DischargeDate], [Condition1], [Condition2], [Condition3], [Condition4], [CHI]) VALUES (CAST(0x000004EA00000000 AS DateTime), CAST(0x000004EA00000000 AS DateTime), N'Y523', N'Z29', NULL, NULL, N'1104015472')
INSERT [ANOMigration] ([AdmissionDate], [DischargeDate], [Condition1], [Condition2], [Condition3], [Condition4], [CHI]) VALUES (CAST(0x0000060300000000 AS DateTime), CAST(0x0000060800000000 AS DateTime), N'F721', N'B871', NULL, NULL, N'0203025927')
INSERT [ANOMigration] ([AdmissionDate], [DischargeDate], [Condition1], [Condition2], [Condition3], [Condition4], [CHI]) VALUES (CAST(0x0000065300000000 AS DateTime), CAST(0x0000065700000000 AS DateTime), N'Z914', N'J398', NULL, NULL, N'2702024715')
INSERT [ANOMigration] ([AdmissionDate], [DischargeDate], [Condition1], [Condition2], [Condition3], [Condition4], [CHI]) VALUES (CAST(0x0000070100000000 AS DateTime), CAST(0x0000070800000000 AS DateTime), N'N009', N'V698', NULL, NULL, N'1610007810')
INSERT [ANOMigration] ([AdmissionDate], [DischargeDate], [Condition1], [Condition2], [Condition3], [Condition4], [CHI]) VALUES (CAST(0x0000077000000000 AS DateTime), CAST(0x0000077200000000 AS DateTime), N'E44', N'J050', N'Q560', NULL, N'1610007810')
INSERT [ANOMigration] ([AdmissionDate], [DischargeDate], [Condition1], [Condition2], [Condition3], [Condition4], [CHI]) VALUES (CAST(0x000007E800000000 AS DateTime), CAST(0x000007EA00000000 AS DateTime), N'Q824', NULL, NULL, NULL, N'1110029231')
INSERT [ANOMigration] ([AdmissionDate], [DischargeDate], [Condition1], [Condition2], [Condition3], [Condition4], [CHI]) VALUES (CAST(0x0000087700000000 AS DateTime), CAST(0x0000087F00000000 AS DateTime), N'T020', NULL, NULL, NULL, N'2110021261')
INSERT [ANOMigration] ([AdmissionDate], [DischargeDate], [Condition1], [Condition2], [Condition3], [Condition4], [CHI]) VALUES (CAST(0x0000088A00000000 AS DateTime), CAST(0x0000089300000000 AS DateTime), N'G009', NULL, NULL, NULL, N'0706013071')
INSERT [ANOMigration] ([AdmissionDate], [DischargeDate], [Condition1], [Condition2], [Condition3], [Condition4], [CHI]) VALUES (CAST(0x000008CA00000000 AS DateTime), CAST(0x000008D100000000 AS DateTime), N'T47', N'H311', N'O037', NULL, N'1204057592')";

            var server = db.Server;

            using (var con = server.GetConnection())
            {
                con.Open();
                server.GetCommand(sql, con).ExecuteNonQuery();
            }

            var table = db.ExpectTable(TableName);
            TableInfoImporter importer = new TableInfoImporter(CatalogueRepository, table);

            importer.DoImport(out _tableInfo, out _columnInfos);

            //Configure the structure of the ANO transform we want - identifiers should have 3 characters and 2 ints and end with _C
            _anoConditionTable = new ANOTable(CatalogueRepository, ANOStore_ExternalDatabaseServer, "ANOCondition", "C");
            _anoConditionTable.NumberOfCharactersToUseInAnonymousRepresentation = 3;
            _anoConditionTable.NumberOfIntegersToUseInAnonymousRepresentation   = 2;
            _anoConditionTable.SaveToDatabase();
            _anoConditionTable.PushToANOServerAsNewTable("varchar(4)", new ThrowImmediatelyCheckNotifier());
        }
        protected override void SetUp()
        {
            base.SetUp();

            string sql =
                @"CREATE TABLE [dbo].[Tests](
	[chi] [varchar](10) NULL,
	[Date] [datetime] NULL,
	[hb_extract] [varchar](1) NULL,
	[TestId] [int] NOT NULL,
 CONSTRAINT [PK_Tests] PRIMARY KEY CLUSTERED 
(
	[TestId] ASC
)
) 

GO

CREATE TABLE [dbo].[Results](
	[TestId] [int] NOT NULL,
	[Measure] [varchar](10) NOT NULL,
	[Value] [int] NULL,
 CONSTRAINT [PK_Results] PRIMARY KEY CLUSTERED 
(
	[TestId] ASC,
	[Measure] ASC
)
)

GO

ALTER TABLE [dbo].[Results]  WITH CHECK ADD  CONSTRAINT [FK_Results_Tests] FOREIGN KEY([TestId])
REFERENCES [dbo].[Tests] ([TestId])
GO";

            var server = From.Server;

            using (var con = server.GetConnection())
            {
                con.Open();
                UsefulStuff.ExecuteBatchNonQuery(sql, con);
            }

            var importer1 = new TableInfoImporter(CatalogueRepository, From.ExpectTable("Tests"));
            var importer2 = new TableInfoImporter(CatalogueRepository, From.ExpectTable("Results"));

            importer1.DoImport(out t1, out c1);

            importer2.DoImport(out t2, out c2);

            var engineer1 = new ForwardEngineerCatalogue(t1, c1, true);
            var engineer2 = new ForwardEngineerCatalogue(t2, c2, true);

            engineer1.ExecuteForwardEngineering(out cata1, out cataItems1, out eis1);
            engineer2.ExecuteForwardEngineering(out cata2, out cataItems2, out eis2);

            new JoinInfo(CatalogueRepository,
                         c1.Single(e => e.GetRuntimeName().Equals("TestId")),
                         c2.Single(e => e.GetRuntimeName().Equals("TestId")),
                         ExtractionJoinType.Left, null);

            _anoTable = new ANOTable(CatalogueRepository, ANOStore_ExternalDatabaseServer, "ANOTes", "T");
            _anoTable.NumberOfCharactersToUseInAnonymousRepresentation = 10;
            _anoTable.SaveToDatabase();
            _anoTable.PushToANOServerAsNewTable("int", new ThrowImmediatelyCheckNotifier());

            _comboCata = new Catalogue(CatalogueRepository, "Combo Catalogue");

            //pk
            var ciTestId  = new CatalogueItem(CatalogueRepository, _comboCata, "TestId");
            var colTestId = c1.Single(c => c.GetRuntimeName().Equals("TestId"));

            ciTestId.ColumnInfo_ID = colTestId.ID;
            ciTestId.SaveToDatabase();
            var eiTestId = new ExtractionInformation(CatalogueRepository, ciTestId, colTestId, colTestId.Name);

            //Measure
            var ciMeasure  = new CatalogueItem(CatalogueRepository, _comboCata, "Measuree");
            var colMeasure = c2.Single(c => c.GetRuntimeName().Equals("Measure"));

            ciMeasure.ColumnInfo_ID = colMeasure.ID;
            ciMeasure.SaveToDatabase();
            var eiMeasure = new ExtractionInformation(CatalogueRepository, ciMeasure, colMeasure, colMeasure.Name);

            //Date
            var ciDate = new CatalogueItem(CatalogueRepository, _comboCata, "Dat");

            var colDate = c1.Single(c => c.GetRuntimeName().Equals("Date"));

            ciDate.ColumnInfo_ID = colDate.ID;
            ciDate.SaveToDatabase();
            var eiDate = new ExtractionInformation(CatalogueRepository, ciDate, colDate, colDate.Name);

            _destinationDatabase = To;
        }
Exemple #19
0
        public void CreateANOVersion_TestSkippingTables(bool tableInfoAlreadyExistsForSkippedTable, bool putPlanThroughSerialization)
        {
            var dbFrom = DiscoveredServerICanCreateRandomDatabasesAndTablesOn.ExpectDatabase(TestDatabaseNames.GetConsistentName("CreateANOVersion_TestSkippingTables_From"));
            var dbTo   = DiscoveredServerICanCreateRandomDatabasesAndTablesOn.ExpectDatabase(TestDatabaseNames.GetConsistentName("CreateANOVersion_TestSkippingTables_To"));

            dbFrom.Create(true);
            dbTo.Create(true);

            try
            {
                var tblFromHeads = dbFrom.CreateTable("Heads", new[]
                {
                    new DatabaseColumnRequest("SkullColor", "varchar(10)"),
                    new DatabaseColumnRequest("Vertebrae", "varchar(25)")
                });

                var cols = new[]
                {
                    new DatabaseColumnRequest("SpineColor", "varchar(10)"),
                    new DatabaseColumnRequest("Vertebrae", "varchar(25)")
                };

                var tblFromNeck = dbFrom.CreateTable("Necks", cols);

                //Necks table already exists in the destination so will be skipped for migration but still needs to be imported
                var tblToNeck = dbTo.CreateTable("Necks", cols);


                TableInfo    fromHeadsTableInfo;
                ColumnInfo[] fromHeadsColumnInfo;
                TableInfo    fromNeckTableInfo;
                ColumnInfo[] fromNeckColumnInfo;
                TableInfo    toNecksTableInfo  = null;
                ColumnInfo[] toNecksColumnInfo = null;

                TableInfoImporter i1 = new TableInfoImporter(CatalogueRepository, tblFromHeads);
                i1.DoImport(out fromHeadsTableInfo, out fromHeadsColumnInfo);

                TableInfoImporter i2 = new TableInfoImporter(CatalogueRepository, tblFromNeck);
                i2.DoImport(out fromNeckTableInfo, out fromNeckColumnInfo);

                //Table already exists but does the in Catalogue reference exist?
                if (tableInfoAlreadyExistsForSkippedTable)
                {
                    TableInfoImporter i3 = new TableInfoImporter(CatalogueRepository, tblToNeck);
                    i3.DoImport(out toNecksTableInfo, out toNecksColumnInfo);
                }

                //Create a JoinInfo so the query builder knows how to connect the tables
                new JoinInfo(CatalogueRepository,
                             fromHeadsColumnInfo.Single(c => c.GetRuntimeName().Equals("Vertebrae")),
                             fromNeckColumnInfo.Single(c => c.GetRuntimeName().Equals("Vertebrae")), ExtractionJoinType.Inner, null
                             );

                var                     cataEngineer = new ForwardEngineerCatalogue(fromHeadsTableInfo, fromHeadsColumnInfo, true);
                Catalogue               cata;
                CatalogueItem[]         cataItems;
                ExtractionInformation[] extractionInformations;
                cataEngineer.ExecuteForwardEngineering(out cata, out cataItems, out extractionInformations);

                var cataEngineer2 = new ForwardEngineerCatalogue(fromNeckTableInfo, fromNeckColumnInfo, true);
                cataEngineer2.ExecuteForwardEngineering(cata);

                //4 extraction informations in from Catalogue (2 from Heads and 2 from Necks)
                Assert.AreEqual(cata.GetAllExtractionInformation(ExtractionCategory.Any).Count(), 4);

                //setup ANOTable on head
                var anoTable = new ANOTable(CatalogueRepository, ANOStore_ExternalDatabaseServer, "ANOSkullColor", "C");
                anoTable.NumberOfCharactersToUseInAnonymousRepresentation = 10;
                anoTable.SaveToDatabase();
                anoTable.PushToANOServerAsNewTable("varchar(10)", new ThrowImmediatelyCheckNotifier());

                //////////////////The actual test!/////////////////
                var planManager = new ForwardEngineerANOCataloguePlanManager(RepositoryLocator, cata);

                //ano the table SkullColor
                var scPlan = planManager.GetPlanForColumnInfo(fromHeadsColumnInfo.Single(col => col.GetRuntimeName().Equals("SkullColor")));
                scPlan.ANOTable = anoTable;
                scPlan.Plan     = Plan.ANO;

                if (putPlanThroughSerialization)
                {
                    var asString = JsonConvertExtensions.SerializeObject(planManager, RepositoryLocator);

                    planManager = (ForwardEngineerANOCataloguePlanManager)JsonConvertExtensions.DeserializeObject(asString, typeof(ForwardEngineerANOCataloguePlanManager), RepositoryLocator);
                }

                //not part of serialization
                planManager.TargetDatabase = dbTo;
                planManager.SkippedTables.Add(fromNeckTableInfo);//skip the necks table because it already exists (ColumnInfos may or may not exist but physical table definetly does)

                var engine = new ForwardEngineerANOCatalogueEngine(RepositoryLocator, planManager);

                if (!tableInfoAlreadyExistsForSkippedTable)
                {
                    var ex = Assert.Throws <Exception>(engine.Execute);
                    Assert.IsTrue(Regex.IsMatch(ex.InnerException.Message, "Found '0' ColumnInfos called"));
                    Assert.IsTrue(Regex.IsMatch(ex.InnerException.Message, "[Necks].[SpineColor]"));

                    return;
                }
                else
                {
                    engine.Execute();
                }

                var newCata = CatalogueRepository.GetAllObjects <Catalogue>().Single(c => c.Name.Equals("ANOHeads"));
                Assert.IsTrue(newCata.Exists());

                var newCataItems = newCata.CatalogueItems;
                Assert.AreEqual(newCataItems.Count(), 4);

                //should be extraction informations
                //all extraction informations should point to the new table location
                Assert.IsTrue(newCataItems.All(ci => ci.ExtractionInformation.SelectSQL.Contains(dbTo.GetRuntimeName())));

                //these columns should all exist
                Assert.IsTrue(newCataItems.Any(ci => ci.ExtractionInformation.SelectSQL.Contains("SkullColor")));
                Assert.IsTrue(newCataItems.Any(ci => ci.ExtractionInformation.SelectSQL.Contains("SpineColor")));
                Assert.IsTrue(newCataItems.Any(ci => ci.ExtractionInformation.SelectSQL.Contains("Vertebrae"))); //actually there will be 2 copies of this one from Necks one from Heads

                //new ColumnInfo should have a reference to the anotable
                Assert.IsTrue(newCataItems.Single(ci => ci.Name.Equals("ANOSkullColor")).ColumnInfo.ANOTable_ID == anoTable.ID);


                var newSpineColorColumnInfo = newCataItems.Single(ci => ci.Name.Equals("ANOSkullColor")).ColumnInfo;

                //table info already existed, make sure the new CatalogueItems point to the same columninfos / table infos
                Assert.IsTrue(newCataItems.Select(ci => ci.ColumnInfo).Contains(newSpineColorColumnInfo));
            }
            finally
            {
                dbFrom.Drop();
                dbTo.Drop();
            }
        }
Exemple #20
0
        public void GatherAndShare_ANOTable_Test(bool goViaJson)
        {
            var anoserver = new ExternalDatabaseServer(CatalogueRepository, "MyGatherAndShareTestANOServer", new ANOStorePatcher());
            var anoTable  = new ANOTable(CatalogueRepository, anoserver, "ANOMagad", "N");

            Assert.AreEqual(anoTable.Server_ID, anoserver.ID);

            Gatherer g = new Gatherer(RepositoryLocator);

            Assert.IsTrue(g.CanGatherDependencies(anoTable));

            var gObj = g.GatherDependencies(anoTable);

            //root should be the server
            Assert.AreEqual(gObj.Object, anoserver);
            Assert.AreEqual(gObj.Children.Single().Object, anoTable);

            //get the sharing definitions
            var             shareManager = new ShareManager(RepositoryLocator);
            ShareDefinition defParent    = gObj.ToShareDefinition(shareManager, new List <ShareDefinition>());
            ShareDefinition defChild     = gObj.Children.Single().ToShareDefinition(shareManager, new List <ShareDefinition>(new [] { defParent }));

            //make it look like we never had it in the first place
            shareManager.GetNewOrExistingExportFor(anoserver).DeleteInDatabase();
            shareManager.GetNewOrExistingExportFor(anoTable).DeleteInDatabase();
            anoTable.DeleteInDatabase();
            anoserver.DeleteInDatabase();

            if (goViaJson)
            {
                var sParent = JsonConvertExtensions.SerializeObject(defParent, RepositoryLocator);
                var sChild  = JsonConvertExtensions.SerializeObject(defChild, RepositoryLocator);

                defParent = (ShareDefinition)JsonConvertExtensions.DeserializeObject(sParent, typeof(ShareDefinition), RepositoryLocator);
                defChild  = (ShareDefinition)JsonConvertExtensions.DeserializeObject(sChild, typeof(ShareDefinition), RepositoryLocator);
            }

            var anoserverAfter = new ExternalDatabaseServer(shareManager, defParent);

            Assert.IsTrue(anoserverAfter.Exists());

            //new instance
            Assert.AreNotEqual(anoserverAfter.ID, anoserver.ID);

            //same properties
            Assert.AreEqual(anoserverAfter.Name, anoserver.Name);
            Assert.AreEqual(anoserverAfter.CreatedByAssembly, anoserver.CreatedByAssembly);
            Assert.AreEqual(anoserverAfter.Database, anoserver.Database);
            Assert.AreEqual(anoserverAfter.DatabaseType, anoserver.DatabaseType);
            Assert.AreEqual(anoserverAfter.Username, anoserver.Username);
            Assert.AreEqual(anoserverAfter.Password, anoserver.Password);

            var anoTableAfter = new ANOTable(shareManager, defChild);

            //new instance
            Assert.AreNotEqual(anoTableAfter.ID, anoTable.ID);
            Assert.AreNotEqual(anoTableAfter.Server_ID, anoTable.Server_ID);

            //same properties
            Assert.AreEqual(anoTableAfter.NumberOfCharactersToUseInAnonymousRepresentation, anoTable.NumberOfCharactersToUseInAnonymousRepresentation);
            Assert.AreEqual(anoTableAfter.Suffix, anoTable.Suffix);

            //change a property and save it
            anoTableAfter.Suffix = "CAMMELS!";
            CatalogueRepository.SaveToDatabase(anoTableAfter);
            //anoTableAfter.SaveToDatabase(); <- this decides to go check the ANOTable exists on the server refernced which is immaginary btw >< thats why we have the above line instead

            //reimport (this time it should be an update, we import the share definitions and it overrdies our database copy (sharing is UPSERT)
            var anoTableAfter2 = new ANOTable(shareManager, defChild);

            Assert.AreEqual(anoTableAfter.ID, anoTableAfter2.ID);
            Assert.AreEqual("N", anoTableAfter2.Suffix);
            Assert.AreEqual(ChangeDescription.DatabaseCopyDifferent, anoTableAfter.HasLocalChanges().Evaluation);

            anoTableAfter.DeleteInDatabase();
            anoserverAfter.DeleteInDatabase();

            foreach (ObjectImport o in RepositoryLocator.CatalogueRepository.GetAllObjects <ObjectImport>())
            {
                o.DeleteInDatabase();
            }
        }