private AggregateBuilder GetAdjustedForRecordsIn(IFilter singleFilterOnly = null)
        {
            if (_cohort == null)
            {
                throw new NotSupportedException("This method only works when there is a cohort aggregate, it does not work for CohortAggregateContainers");
            }

            var memoryRepository = new MemoryCatalogueRepository();

            //Get a builder for creating the basic aggregate graph
            var summaryBuilder = _summary.GetQueryBuilder();

            //Find it's root container if it has one
            var summaryRootContainer = summaryBuilder.RootFilterContainer;

            //work out a filter SQL that will restrict the graph generated only to the cohort
            IContainer cohortRootContainer = _cohort.RootFilterContainer;

            //if we are only graphing a single filter from the Cohort
            if (singleFilterOnly != null)
            {
                cohortRootContainer = new SpontaneouslyInventedFilterContainer(memoryRepository, null, new [] { singleFilterOnly }, FilterContainerOperation.AND);
            }

            //so hacky, we pass in the summary builder (a blatant lie!) and tell the CohortQueryBuilderHelper it belongs to AggregateConfiguration _cohort (when it doesn't).  This
            //will result in any PatientIndex tables associated with _cohort being propagated into the _summary builder
            var cohortHelper = new CohortQueryBuilderHelper(_globals, new ParameterManager(_globals), _cohort.GetCohortIdentificationConfigurationIfAny().QueryCachingServer);

            cohortHelper.AddJoinablesToBuilder(summaryBuilder, _cohort, 1);

            //if the cohort has no WHERE SQL
            if (cohortRootContainer == null)
            {
                return(summaryBuilder); //summary can be run verbatim
            }
            //the summary has no WHERE SQL
            if (summaryRootContainer == null)
            {
                summaryBuilder.RootFilterContainer = cohortRootContainer;//hijack the cohorts root container
            }
            else
            {
                //they both have WHERE SQL

                //Create a new spontaneous container (virtual memory only container) that contains both subtrees
                var spontContainer = new SpontaneouslyInventedFilterContainer(memoryRepository, new[] { cohortRootContainer, summaryRootContainer }, null, FilterContainerOperation.AND);
                summaryBuilder.RootFilterContainer = spontContainer;
            }

            //better import the globals because WHERE logic from the cohort has been inherited... only problem will be if there are conflicting globals in users aggregate but that's just tough luck
            foreach (ISqlParameter p in _globals)
            {
                summaryBuilder.ParameterManager.AddGlobalParameter(p);
            }

            return(summaryBuilder);
        }
Beispiel #2
0
        /// <summary>
        /// Creates a new result for a single <see cref="AggregateConfiguration"/> or <see cref="CohortAggregateContainer"/>
        /// </summary>
        /// <param name="cacheServer"></param>
        /// <param name="childProvider"></param>
        /// <param name="helper"></param>
        /// <param name="customise"></param>
        public CohortQueryBuilderResult(ExternalDatabaseServer cacheServer, ICoreChildProvider childProvider, CohortQueryBuilderHelper helper, QueryBuilderCustomArgs customise)
        {
            CacheServer   = cacheServer;
            ChildProvider = childProvider;
            Helper        = helper;
            Customise     = customise;

            if (cacheServer != null)
            {
                CacheManager = new CachedAggregateConfigurationResultsManager(CacheServer);
            }
        }
        /// <summary>
        /// Creates a new result for a single <see cref="AggregateConfiguration"/> or <see cref="CohortAggregateContainer"/>
        /// </summary>
        /// <param name="cacheServer"></param>
        /// <param name="childProvider"></param>
        /// <param name="helper"></param>
        /// <param name="customise"></param>
        /// <param name="cancellationToken"></param>
        public CohortQueryBuilderResult(ExternalDatabaseServer cacheServer, ICoreChildProvider childProvider, CohortQueryBuilderHelper helper, QueryBuilderCustomArgs customise, CancellationToken cancellationToken)
        {
            CacheServer       = cacheServer;
            ChildProvider     = childProvider;
            Helper            = helper;
            Customise         = customise;
            CancellationToken = cancellationToken;

            if (cacheServer != null)
            {
                CacheManager = new CachedAggregateConfigurationResultsManager(CacheServer);

                try
                {
                    PluginCohortCompilers = new PluginCohortCompilerFactory(cacheServer.CatalogueRepository.MEF).CreateAll();
                }
                catch (Exception ex)
                {
                    throw new Exception("Failed to build list of IPluginCohortCompilers", ex);
                }
            }
        }
Beispiel #4
0
 private void RecreateHelpers(QueryBuilderCustomArgs customizations)
 {
     helper  = new CohortQueryBuilderHelper();
     Results = new CohortQueryBuilderResult(CacheServer, _childProvider, helper, customizations);
 }
Beispiel #5
0
 private void RecreateHelper()
 {
     helper = new CohortQueryBuilderHelper(_globals, ParameterManager, CacheServer);
 }
        private AggregateBuilder GetAdjustedForRecordsIn(IFilter singleFilterOnly = null)
        {
            if (_cohort == null)
            {
                throw new NotSupportedException("This method only works when there is a cohort aggregate, it does not work for CohortAggregateContainers");
            }

            var memoryRepository = new MemoryCatalogueRepository();

            //Get a builder for creating the basic aggregate graph
            var summaryBuilder = _summary.GetQueryBuilder();

            //Find it's root container if it has one
            var summaryRootContainer = summaryBuilder.RootFilterContainer;

            //work out a filter SQL that will restrict the graph generated only to the cohort
            IContainer cohortRootContainer = _cohort.RootFilterContainer;

            //if we are only graphing a single filter from the Cohort
            if (singleFilterOnly != null)
            {
                cohortRootContainer = new SpontaneouslyInventedFilterContainer(memoryRepository, null, new [] { singleFilterOnly }, FilterContainerOperation.AND);
            }

            var joinUse = _cohort.PatientIndexJoinablesUsed.SingleOrDefault();
            var joinTo  = joinUse?.JoinableCohortAggregateConfiguration?.AggregateConfiguration;

            //if there is a patient index table we must join to it
            if (joinUse != null)
            {
                //get sql for the join table
                var builder     = new CohortQueryBuilder(joinTo, _globals, null);
                var joinableSql = new CohortQueryBuilderDependencySql(builder.SQL, builder.ParameterManager);

                var helper = new CohortQueryBuilderHelper();

                var extractionIdentifierColumn = _summary.Catalogue.GetAllExtractionInformation(ExtractionCategory.Any)
                                                 .Where(ei => ei.IsExtractionIdentifier).ToArray();

                if (extractionIdentifierColumn.Length != 1)
                {
                    throw new Exception($"Catalogue behind {_summary} must have exactly 1 IsExtractionIdentifier column but it had " + extractionIdentifierColumn.Length);
                }

                helper.AddJoinToBuilder(_summary, extractionIdentifierColumn[0], summaryBuilder, new QueryBuilderArgs(joinUse, joinTo, joinableSql, null, _globals));
            }

            //if the cohort has no WHERE SQL
            if (cohortRootContainer == null)
            {
                return(summaryBuilder); //summary can be run verbatim
            }
            //the summary has no WHERE SQL
            if (summaryRootContainer == null)
            {
                summaryBuilder.RootFilterContainer = cohortRootContainer;//hijack the cohorts root container
            }
            else
            {
                //they both have WHERE SQL

                //Create a new spontaneous container (virtual memory only container) that contains both subtrees
                var spontContainer = new SpontaneouslyInventedFilterContainer(memoryRepository, new[] { cohortRootContainer, summaryRootContainer }, null, FilterContainerOperation.AND);
                summaryBuilder.RootFilterContainer = spontContainer;
            }

            //better import the globals because WHERE logic from the cohort has been inherited... only problem will be if there are conflicting globals in users aggregate but that's just tough luck
            foreach (ISqlParameter p in _globals)
            {
                summaryBuilder.ParameterManager.AddGlobalParameter(p);
            }

            return(summaryBuilder);
        }