/// <summary> /// Creates a entirely new copy of the <see cref="CohortIdentificationConfiguration"/> with all new IDs on the root and all child objects. This includes /// filters, patient index tables, parameters, set containers etc. /// <para>This is done in a transaction so that if it fails halfway through you won't end up with half a clone configuration</para> /// </summary> /// <param name="notifier">Event listener for reporting cloning progress and any problems</param> /// <returns></returns> public CohortIdentificationConfiguration CreateClone(ICheckNotifier notifier) { //todo this would be nice if it was ICatalogueRepository but transaction is super SQLy var cataRepo = ((CatalogueRepository)Repository); //start a new super transaction using (cataRepo.BeginNewTransactedConnection()) { try { notifier.OnCheckPerformed(new CheckEventArgs("Super Transaction started on Catalogue Repository", CheckResult.Success)); var clone = new CohortIdentificationConfiguration(cataRepo, Name + " (Clone)"); notifier.OnCheckPerformed(new CheckEventArgs("Created clone configuration '" + clone.Name + "' with ID " + clone.ID + " called " + clone, CheckResult.Success)); //clone the global parameters foreach (var p in GetAllParameters()) { notifier.OnCheckPerformed(new CheckEventArgs("Cloning global parameter " + p.ParameterName, CheckResult.Success)); var cloneP = new AnyTableSqlParameter(cataRepo, clone, p.ParameterSQL); cloneP.Comment = p.Comment; cloneP.Value = p.Value; cloneP.SaveToDatabase(); } //key is the original, value is the clone var parentToCloneJoinablesDictionary = new Dictionary <JoinableCohortAggregateConfiguration, JoinableCohortAggregateConfiguration>(); //clone the joinables foreach (var joinable in GetAllJoinables()) { //clone the aggregate which has permission to be joinable var cloneJoinableAggregate = joinable.AggregateConfiguration.CreateClone(); //clone the join permission var cloneJoinable = new JoinableCohortAggregateConfiguration(cataRepo, clone, cloneJoinableAggregate); parentToCloneJoinablesDictionary.Add(joinable, cloneJoinable); } clone.ClonedFrom_ID = ID; clone.RootCohortAggregateContainer_ID = RootCohortAggregateContainer.CloneEntireTreeRecursively(notifier, this, clone, parentToCloneJoinablesDictionary).ID; clone.SaveToDatabase(); notifier.OnCheckPerformed(new CheckEventArgs("Clone creation successful, about to commit Super Transaction", CheckResult.Success)); cataRepo.EndTransactedConnection(true); notifier.OnCheckPerformed(new CheckEventArgs("Super Transaction committed successfully", CheckResult.Success)); return(clone); } catch (Exception e) { cataRepo.EndTransactedConnection(false); notifier.OnCheckPerformed(new CheckEventArgs("Cloning failed, See Exception for details, the Super Transaction was rolled back successfully though", CheckResult.Fail, e)); } } return(null); }
private AggregateConfiguration CreateCloneOfAggregateConfigurationPrivate(AggregateConfiguration toClone, ChooseWhichExtractionIdentifierToUseFromManyHandler resolveMultipleExtractionIdentifiers) { var cataRepo = CatalogueRepository; //two cases here either the import has a custom freaky CHI column (dimension) or it doesn't reference CHI at all if it is freaky we want to preserve it's freakyness ExtractionInformation underlyingExtractionInformation; IColumn extractionIdentifier = GetExtractionIdentifierFrom(toClone, out underlyingExtractionInformation, resolveMultipleExtractionIdentifiers); //clone will not have axis or pivot or dimensions other than extraction identifier var newConfiguration = toClone.ShallowClone(); //make it's name follow the naming convention e.g. cic_105_LINK103_MyAggregate EnsureNamingConvention(newConfiguration); //now clear it's pivot dimension, make it not extratcable and make it's countSQL basic/sane newConfiguration.PivotOnDimensionID = null; newConfiguration.IsExtractable = false; newConfiguration.CountSQL = null;//clear the count sql //clone parameters foreach (AnyTableSqlParameter toCloneParameter in toClone.Parameters) { var newParam = new AnyTableSqlParameter((ICatalogueRepository)newConfiguration.Repository, newConfiguration, toCloneParameter.ParameterSQL); newParam.Value = toCloneParameter.Value; newParam.Comment = toCloneParameter.Comment; newParam.SaveToDatabase(); } //now clone it's AggregateForcedJoins foreach (var t in cataRepo.AggregateForcedJoinManager.GetAllForcedJoinsFor(toClone)) { cataRepo.AggregateForcedJoinManager.CreateLinkBetween(newConfiguration, t); } //now give it 1 dimension which is the only IsExtractionIdentifier column var newDimension = new AggregateDimension(cataRepo, underlyingExtractionInformation, newConfiguration); //the thing we were cloning had a freaky CHI column (probably had a collate or something involved in it or a masterchi) if (extractionIdentifier is AggregateDimension) { //preserve it's freakyness newDimension.Alias = extractionIdentifier.Alias; newDimension.SelectSQL = extractionIdentifier.SelectSQL; newDimension.Order = extractionIdentifier.Order; newDimension.SaveToDatabase(); } //now rewire all it's filters if (toClone.RootFilterContainer_ID != null) //if it has any filters { //get the tree AggregateFilterContainer oldRootContainer = toClone.RootFilterContainer; //clone the tree var newRootContainer = oldRootContainer.DeepCloneEntireTreeRecursivelyIncludingFilters(); newConfiguration.RootFilterContainer_ID = newRootContainer.ID; } newConfiguration.SaveToDatabase(); return(newConfiguration); }