Пример #1
0
        private string BuildSql(CohortQueryBuilderDependency dependency, ParameterManager parameterManager)
        {
            //if we are fully cached on everything
            if (dependency.SqlFullyCached != null)
            {
                SetTargetServer(GetCacheServer(), " dependency is cached"); //run on the cache server
                CountOfCachedSubQueries++;                                  //it is cached
                return(dependency.SqlFullyCached.Use(parameterManager));    //run the fully cached sql
            }

            switch (CacheUsageDecision)
            {
            case CacheUsage.MustUse:
                throw new QueryBuildingException("Could not build final SQL because " + dependency + " is not fully cached and CacheUsageDecision is " + CacheUsageDecision);

            case CacheUsage.Opportunistic:

                //The cache and dataset are on the same server so run it
                SetTargetServer(DependenciesSingleServer.GetDistinctServer(), "data and cache are on the same server");
                return(dependency.SqlPartiallyCached?.Use(parameterManager) ?? dependency.SqlCacheless.Use(parameterManager));

            case CacheUsage.AllOrNothing:

                //It's not fully cached so we have to run it entirely uncached
                SetTargetServer(DependenciesSingleServer.GetDistinctServer(), "cache and data are on seperate servers / access credentials and not all datasets are in the cache");
                return(dependency.SqlCacheless.Use(parameterManager));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Пример #2
0
        private CohortQueryBuilderDependency AddDependency(AggregateConfiguration cohortSet)
        {
            if (cohortSet.Catalogue.IsApiCall())
            {
                if (CacheManager == null)
                {
                    throw new Exception($"Caching must be enabled to execute API call '{cohortSet}'");
                }

                if (!PluginCohortCompilers.Any(c => c.ShouldRun(cohortSet)))
                {
                    throw new Exception($"No PluginCohortCompilers claimed to support '{cohortSet}' in their ShouldRun method");
                }
            }

            var join = ChildProvider.AllJoinUses.Where(j => j.AggregateConfiguration_ID == cohortSet.ID).ToArray();

            if (join.Length > 1)
            {
                throw new NotSupportedException($"There are {join.Length} joins configured to AggregateConfiguration {cohortSet}");
            }

            var d = new CohortQueryBuilderDependency(cohortSet, join.SingleOrDefault(), ChildProvider, PluginCohortCompilers);

            _dependencies.Add(d);

            return(d);
        }
Пример #3
0
        private void HandleDependency(CohortQueryBuilderDependency dependency, bool isPatientIndexTable, ITableInfo dependantTable)
        {
            _log.AppendLine($"Found dependant table '{dependantTable}' (Server:{dependantTable.Server} DatabaseType:{dependantTable.DatabaseType})");

            //if dependencies are on different servers / access credentials
            if (DependenciesSingleServer != null)
            {
                if (!DependenciesSingleServer.TryAdd(dependantTable))
                {
                    //we can no longer establish a consistent connection to all the dependencies
                    _log.AppendLine($"Found problematic dependant table '{dependantTable}'");

                    //if there's no cache server that's a problem!
                    if (CacheServer == null)
                    {
                        throw new QueryBuildingException($"Table {dependantTable} is on a different server (or uses different access credentials) from previously seen dependencies and no QueryCache is configured");
                    }

                    //there is a cache server, perhaps we can dodge 'dependantTable' by going to cache instead
                    bool canUseCacheForDependantTable =
                        (isPatientIndexTable ? dependency.SqlJoinableCached : dependency.SqlFullyCached)
                        != null;

                    //can we go to the cache server instead?
                    if (canUseCacheForDependantTable && DependenciesSingleServer.TryAdd(CacheServer))
                    {
                        _log.AppendLine($"Avoided problematic dependant table '{dependantTable}' by using the cache");
                    }
                    else
                    {
                        DependenciesSingleServer = null;

                        //there IS a cache so we now Must use it
                        if (CacheUsageDecision != CacheUsage.MustUse)
                        {
                            SetCacheUsage(CacheUsage.MustUse, $"Table {dependantTable} is on a different server (or uses different access credentials) from previously seen dependencies.  Therefore the QueryCache MUST be used for all dependencies");
                        }
                    }
                }
            }

            if (DependenciesSingleServer != null &&
                CacheServer != null &&
                CacheUsageDecision == CacheUsage.Opportunistic)
            {
                //We can only do opportunistic joins if the Cache and Data server are on the same server
                bool canCombine = DependenciesSingleServer.AddWouldBePossible(CacheServer);

                if (!canCombine)
                {
                    SetCacheUsage(CacheUsage.AllOrNothing, "All datasets are on one server/access credentials while Cache is on a separate one");
                }
            }
        }
Пример #4
0
        private CohortQueryBuilderDependency AddDependency(AggregateConfiguration cohortSet)
        {
            var join = ChildProvider.AllJoinUses.Where(j => j.AggregateConfiguration_ID == cohortSet.ID).ToArray();

            if (join.Length > 1)
            {
                throw new NotSupportedException($"There are {join.Length} joins configured to AggregateConfiguration {cohortSet}");
            }

            var d = new CohortQueryBuilderDependency(cohortSet, join.SingleOrDefault(), ChildProvider);

            _dependencies.Add(d);

            return(d);
        }