/// <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); }
/// <summary> /// Splits the root container of a <see cref="CohortIdentificationConfiguration"/> into multiple new cic. /// </summary> /// <param name="rootContainer"></param> /// <returns>All new configurations unmerged out of the <paramref name="rootContainer"/></returns> public CohortIdentificationConfiguration[] UnMerge(CohortAggregateContainer rootContainer) { if (!rootContainer.IsRootContainer()) { throw new ArgumentException("Container must be a root container to be unmerged", nameof(rootContainer)); } if (rootContainer.GetAggregateConfigurations().Any()) { throw new ArgumentException("Container must contain only sub-containers (i.e. no aggregates)", nameof(rootContainer)); } if (rootContainer.GetSubContainers().Length <= 1) { throw new ArgumentException("Container must contain 2+ sub-containers to be unmerged", nameof(rootContainer)); } var cic = rootContainer.GetCohortIdentificationConfiguration(); var toReturn = new List <CohortIdentificationConfiguration>(); try { // clone the input cic cic = cic.CreateClone(new ThrowImmediatelyCheckNotifier()); // grab the new clone root container rootContainer = cic.RootCohortAggregateContainer; } catch (Exception ex) { throw new Exception("Error during pre merge cloning stage, no UnMerge will be attempted", ex); } using (_repository.BeginNewTransactedConnection()) { // For each of these foreach (var subContainer in rootContainer.GetSubContainers().OrderBy(c => c.Order)) { // create a new config var newCic = new CohortIdentificationConfiguration(_repository, $"Un Merged { subContainer.Name } ({subContainer.ID }) "); //take the container we are splitting out subContainer.MakeIntoAnOrphan(); //make it the root container of the new cic newCic.RootCohortAggregateContainer_ID = subContainer.ID; newCic.SaveToDatabase(); // Make the new name of all the AggregateConfigurations match the new cic foreach (var child in subContainer.GetAllAggregateConfigurationsRecursively()) { EnsureNamingConvention(newCic, child); } toReturn.Add(newCic); } //Now delete the original clone that we unmerged the containers out of cic.DeleteInDatabase(); //finish transaction _repository.EndTransactedConnection(true); } return(toReturn.ToArray()); }