/// <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> /// Returns all unique <see cref="TableInfo"/> required for building all of the <see cref="AggregateConfiguration"/>s in the /// <see cref="AggregateConfiguration.RootFilterContainer_ID"/> or any subcontainers. /// </summary> /// <returns></returns> public TableInfo[] GetDistinctTableInfos() { return (RootCohortAggregateContainer.GetAllAggregateConfigurationsRecursively() //get all the aggregate sets .SelectMany(a => a.AggregateDimensions //get all the Dimensions (should really be 1 per aggregate which is the IsExtractionIdentifier column but who are we to check) .Select(d => d.ColumnInfo)) //get the underlying Column for the dimension .Select(c => c.TableInfo) //get the TableInfo from the column .Distinct() //return distinct array of them .ToArray()); }
/// <inheritdoc/> public IHasDependencies[] GetObjectsThisDependsOn() { List <IHasDependencies> dependencies = new List <IHasDependencies>(); dependencies.AddRange(GetAllParameters().Cast <AnyTableSqlParameter>()); if (RootCohortAggregateContainer_ID != null) { dependencies.AddRange(RootCohortAggregateContainer.GetAllAggregateConfigurationsRecursively()); } return(dependencies.ToArray()); }
/// <summary> /// Deletes the root container and consequently the entire <see cref="CohortIdentificationConfiguration"/> /// </summary> public override void DeleteInDatabase() { //container is the parent class even though this is a 1 to 1 and there is a CASCADE which will actually nuke ourselves when we delete the root container! if (RootCohortAggregateContainer_ID != null) { RootCohortAggregateContainer.DeleteInDatabase(); } //shouldnt ever happen but double check anyway incase somebody removes the CASCADE if (Exists()) { base.DeleteInDatabase(); } else { //make sure to do the obscure cross server/database cascade activities too //if the repository has obscure dependencies if (CatalogueRepository.ObscureDependencyFinder != null) { CatalogueRepository.ObscureDependencyFinder.HandleCascadeDeletesForDeletedObject(this); } } }