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); }
/// <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); } } }
private void RecreateHelpers(QueryBuilderCustomArgs customizations) { helper = new CohortQueryBuilderHelper(); Results = new CohortQueryBuilderResult(CacheServer, _childProvider, helper, customizations); }
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); }