Exemple #1
0
        private IColumn GetExtractionIdentifierFrom(Catalogue catalogue, ChooseWhichExtractionIdentifierToUseFromManyHandler resolveMultipleExtractionIdentifiers)
        {
            //the aggregate they are cloning does not have an extraction identifier but the dataset might still have one
            var catalogueCandidates = catalogue.GetAllExtractionInformation(ExtractionCategory.Any).Where(e => e.IsExtractionIdentifier).ToArray();

            //if there are multiple IsExtractionInformation columns
            if (catalogueCandidates.Count() != 1)
            {
                if (resolveMultipleExtractionIdentifiers == null)//no delegate has been provided for resolving this
                {
                    throw new NotSupportedException("Cannot create AggregateConfiguration because the Catalogue " + catalogue + " has " + catalogueCandidates.Length + " IsExtractionIdentifier ExtractionInformations");
                }
                else
                {
                    //there is a delegate to resolve this, invoke it
                    var answer = resolveMultipleExtractionIdentifiers(catalogue, catalogueCandidates);

                    //the delegate returned null
                    if (answer == null)
                    {
                        throw new Exception("User did not pick a candidate ExtractionInformation column from those we offered");
                    }
                    else
                    {
                        return(answer);//the delegate picked one
                    }
                }
            }

            return(catalogueCandidates[0]);
        }
Exemple #2
0
        /// <summary>
        /// returns an underlying ExtractionInformation which IsExtractionIdentifier (e.g. a chi column).  The first pass approach is to look for a suitable AggregateDimension which
        /// has an underlying  ExtractionInformation which IsExtractionIdentifier but if it doesn't find one then it will look in the Catalogue for one instead.  The reason this is
        /// complex is because you can have datasets with multiple IsExtractionIdentifier columns e.g. SMR02 (birth records) where there is both MotherCHI and BabyCHI which are both
        /// IsExtractionIdentifier - in this case the AggregateConfiguration would need a Dimension of one or the other (but not both!) - if it had neither then the method would throw
        /// when it checked Catalogue and found both.
        /// </summary>
        /// <param name="toClone"></param>
        /// <param name="underlyingExtractionInformation"></param>
        /// <param name="resolveMultipleExtractionIdentifiers"></param>
        /// <returns></returns>
        private IColumn GetExtractionIdentifierFrom(AggregateConfiguration toClone, out ExtractionInformation underlyingExtractionInformation, ChooseWhichExtractionIdentifierToUseFromManyHandler resolveMultipleExtractionIdentifiers)
        {
            //make sure it can be cloned before starting

            //Aggregates have AggregateDimensions which are a subset of the Catalogues ExtractionInformations.  Most likely there won't be an AggregateDimension which IsExtractionIdentifier
            //because why would the user have graphs of chi numbers?

            var     existingExtractionIdentifierDimensions = toClone.AggregateDimensions.Where(d => d.IsExtractionIdentifier).ToArray();
            IColumn extractionIdentifier = null;

            //very unexpected, he had multiple IsExtractionIdentifier Dimensions all configured for simultaneous use on this Aggregate, it is very freaky and we definetly don't want to let him import it for cohort identification
            if (existingExtractionIdentifierDimensions.Count() > 1)
            {
                throw new NotSupportedException("Cannot clone the AggregateConfiguration " + toClone + " because it has multiple IsExtractionIdentifier dimensions (must be 0 or 1)");
            }

            //It has 1... maybe it's already being used in cohort identification from another project or he just likes to graph chi numbers for some reason
            if (existingExtractionIdentifierDimensions.Count() == 1)
            {
                extractionIdentifier            = existingExtractionIdentifierDimensions[0];
                underlyingExtractionInformation = existingExtractionIdentifierDimensions[0].ExtractionInformation;
            }
            else
            {
                //As expected the user isn't graphing chis or otherwise configured any Dimensions on this aggregate.  It is probably just a normal aggregate e.g. 'Prescriptions of Morphine over time between 2005-2001' where the only dimension is 'date prescribed'
                //now when we import this for cohort identification we want to keep the cool filters and stuff but we can junk all the dimensions.  BUT we do need to add the IsExtractionIdentifier column from the dataset (and if there are for some reason multiple
                //e.g. babychi, motherchi then we can invoke the delegate to let the user pick one.

                //get the unique IsExtractionIdentifier from the cloned configurations parent catalogue
                underlyingExtractionInformation =
                    (ExtractionInformation)GetExtractionIdentifierFrom(
                        toClone.Catalogue, resolveMultipleExtractionIdentifiers);

                return(underlyingExtractionInformation);
            }

            return(extractionIdentifier);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        /// <summary>
        /// Creates a new cohort set <see cref="AggregateConfiguration"/> which initially matches any patient appearing in the dataset (<see cref="Catalogue"/>).
        /// <para>IMPORTANT: It must be possible to select a single column from which to harvest the patient identifiers from <paramref name="resolveMultipleExtractionIdentifiers"/></para>
        /// </summary>
        /// <param name="catalogue">The catalogue to import as a patient identification set (you can import the same Catalogue multiple times e.g.
        /// 'People ever prescribed morphine' EXCEPT 'People ever prescribed percoset'</param>
        /// <param name="resolveMultipleExtractionIdentifiers">What to do if there are multiple <see cref="ExtractionInformation"/>
        ///  marked IsExtractionIdentifier</param>
        /// <param name="importMandatoryFilters"></param>
        /// <returns></returns>
        public AggregateConfiguration CreateNewEmptyConfigurationForCatalogue(Catalogue catalogue, ChooseWhichExtractionIdentifierToUseFromManyHandler resolveMultipleExtractionIdentifiers, bool importMandatoryFilters = true)
        {
            var extractionIdentifier = (ExtractionInformation)GetExtractionIdentifierFrom(catalogue, resolveMultipleExtractionIdentifiers);

            var cataRepo = (ICatalogueRepository)Repository;

            AggregateConfiguration configuration = new AggregateConfiguration(cataRepo, catalogue, "People in " + catalogue);

            EnsureNamingConvention(configuration);

            //make the extraction identifier column into the sole dimension on the new configuration
            new AggregateDimension(cataRepo, extractionIdentifier, configuration);

            //no count sql
            configuration.CountSQL = null;
            configuration.SaveToDatabase();

            if (importMandatoryFilters)
            {
                ImportMandatoryFilters(catalogue, configuration, GetAllParameters());
            }

            return(configuration);
        }
Exemple #5
0
        /// <summary>
        /// Creates an adjusted copy of the <paramref name="toClone"/> to be used as a cohort identification <see cref="AggregateConfiguration"/>.  This could be
        /// an <see cref="AggregateConfiguration"/> graph or one that is acting as a patient index table / cohort set for another <see cref="CohortIdentificationConfiguration"/>.
        /// <para>IMPORTANT: It must be possible to select a single column from which to harvest the patient identifiers from <paramref name="resolveMultipleExtractionIdentifiers"/></para>
        /// </summary>
        /// <param name="toClone">The aggregate to import</param>
        /// <param name="resolveMultipleExtractionIdentifiers">What to do if there are multiple <see cref="ExtractionInformation"/>/<see cref="AggregateDimension"/>
        ///  marked IsExtractionIdentifier</param>
        /// <param name="useTransaction">True to run the import in a transaction</param>
        /// <returns></returns>
        public AggregateConfiguration ImportAggregateConfigurationAsIdentifierList(AggregateConfiguration toClone, ChooseWhichExtractionIdentifierToUseFromManyHandler resolveMultipleExtractionIdentifiers, bool useTransaction = true)
        {
            if (!useTransaction)
            {
                return(CreateCloneOfAggregateConfigurationPrivate(toClone, resolveMultipleExtractionIdentifiers));
            }

            var cataRepo = (CatalogueRepository)Repository;


            using (cataRepo.BeginNewTransactedConnection())
            {
                try
                {
                    var toReturn = CreateCloneOfAggregateConfigurationPrivate(toClone, resolveMultipleExtractionIdentifiers);
                    cataRepo.EndTransactedConnection(true);
                    return(toReturn);
                }
                catch (Exception)
                {
                    cataRepo.EndTransactedConnection(false);//abandon
                    throw;
                }
            }
        }