public void PlanManagementTest() { var dbName = TestDatabaseNames.GetConsistentName("PlanManagementTests"); var db = DiscoveredServerICanCreateRandomDatabasesAndTablesOn.ExpectDatabase(dbName); db.Create(true); BulkTestsData bulk = new BulkTestsData(CatalogueRepository, DiscoveredDatabaseICanCreateRandomTablesIn, 100); bulk.SetupTestData(); bulk.ImportAsCatalogue(); var planManager = new ForwardEngineerANOCataloguePlanManager(RepositoryLocator, bulk.catalogue); planManager.TargetDatabase = db; //no operations are as yet configured Assert.DoesNotThrow(() => planManager.Check(new ThrowImmediatelyCheckNotifier())); //create a table with the same name in the endpoint database to confirm that that's a problem db.CreateTable(bulk.tableInfo.GetRuntimeName(), new DatabaseColumnRequest[] { new DatabaseColumnRequest("fish", "varchar(100)") }); //throws because table already exists Assert.Throws <Exception>(() => planManager.Check(new ThrowImmediatelyCheckNotifier())); db.ExpectTable(bulk.tableInfo.GetRuntimeName()).Drop(); //back to being fine again Assert.DoesNotThrow(() => planManager.Check(new ThrowImmediatelyCheckNotifier())); //setup test rules for migrator CreateMigrationRules(planManager, bulk); //rules should pass Assert.DoesNotThrow(() => planManager.Check(new ThrowImmediatelyCheckNotifier())); var chi = bulk.GetColumnInfo("chi"); Assert.Throws <Exception>(() => { planManager.GetPlanForColumnInfo(chi).Plan = Plan.Drop; planManager.GetPlanForColumnInfo(chi).Check(new ThrowImmediatelyCheckNotifier()); } , "Should not be able to drop primary key column"); db.Drop(); }
private object MigrationPlanAspectGetter(object rowobject) { var col = rowobject as ColumnInfo; var table = rowobject as TableInfo; if (col != null) { return(_planManager.GetPlanForColumnInfo(col).Plan); } if (_planManager.SkippedTables.Contains(table)) { return("Already Exists"); } return(null); }
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 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(); } }
public void TestAnonymisingJoinKey() { //Create a plan for the first Catlogue (Tests) - single Table dataset var plan1 = new ForwardEngineerANOCataloguePlanManager(RepositoryLocator, cata1); var testIdHeadPlan = plan1.GetPlanForColumnInfo(c1.Single(c => c.GetRuntimeName().Equals("TestId"))); plan1.TargetDatabase = _destinationDatabase; //the plan is that the column TestId should be anonymised - where it's name will become ANOTestId testIdHeadPlan.Plan = Plan.ANO; testIdHeadPlan.ANOTable = _anoTable; plan1.Check(new ThrowImmediatelyCheckNotifier()); var engine1 = new ForwardEngineerANOCatalogueEngine(RepositoryLocator, plan1); engine1.Execute(); var plan1ExtractionInformationsAtDestination = engine1.NewCatalogue.GetAllExtractionInformation(ExtractionCategory.Any); var ei1 = plan1ExtractionInformationsAtDestination.Single(e => e.GetRuntimeName().Equals("ANOTestId")); Assert.IsTrue(ei1.Exists()); //Now create a plan for the combo Catalogue which contains references to both tables (Tests and Results). Remember Tests has already been migrated as part of plan1 var plan2 = new ForwardEngineerANOCataloguePlanManager(RepositoryLocator, _comboCata); //tell it to skip table 1 (Tests) and only anonymise Results plan2.SkippedTables.Add(t1); plan2.TargetDatabase = _destinationDatabase; plan2.Check(new ThrowImmediatelyCheckNotifier()); //Run the anonymisation var engine2 = new ForwardEngineerANOCatalogueEngine(RepositoryLocator, plan2); engine2.Execute(); //Did it succesfully pick SetUp the correct ANO column var plan2ExtractionInformationsAtDestination = engine2.NewCatalogue.GetAllExtractionInformation(ExtractionCategory.Any); var ei2 = plan2ExtractionInformationsAtDestination.Single(e => e.GetRuntimeName().Equals("ANOTestId")); Assert.IsTrue(ei2.Exists()); //and can the query be executed succesfully var qb = new QueryBuilder(null, null); qb.AddColumnRange(plan2ExtractionInformationsAtDestination); using (var con = _destinationDatabase.Server.GetConnection()) { con.Open(); var cmd = _destinationDatabase.Server.GetCommand(qb.SQL, con); Assert.DoesNotThrow(() => cmd.ExecuteNonQuery()); } Console.WriteLine("Final migrated combo dataset SQL was:" + qb.SQL); Assert.IsTrue(_comboCata.CatalogueItems.Any(ci => ci.Name.Equals("Measuree"))); Assert.IsTrue(engine2.NewCatalogue.CatalogueItems.Any(ci => ci.Name.Equals("Measuree")), "ANO Catalogue did not respect the original CatalogueItem Name"); }