Example #1
0
        /// <summary>
        /// Provide a count of patients in the specified query.
        /// Converts the query into a local validation context.
        /// Validates the resulting context to ensure sensible construction.
        /// Obtains the cohort of unique patient IDs.
        /// Caches those patient IDs.
        /// </summary>
        /// <returns><see cref="CohortCount">The count of patients in the cohort.</see></returns>
        /// <param name="queryDTO">Abstract query representation.</param>
        /// <param name="token">Cancellation token.</param>
        /// <exception cref="OperationCanceledException"/>
        /// <exception cref="InvalidOperationException"/>
        /// <exception cref="ArgumentNullException"/>
        /// <exception cref="LeafDbException"/>
        public async Task <Result> Count(IPatientCountQueryDTO queryDTO, CancellationToken token)
        {
            Ensure.NotNull(queryDTO, nameof(queryDTO));

            var ctx = await converter.GetPanelsAsync(queryDTO, token);

            if (!ctx.PreflightPassed)
            {
                return(new Result
                {
                    ValidationContext = ctx
                });
            }

            var query  = validator.Validate(ctx);
            var cohort = await counter.GetPatientCohortAsync(query, token);

            token.ThrowIfCancellationRequested();

            log.LogInformation("Caching unsaved cohort.");
            var qid = await cohortCache.CreateUnsavedQueryAsync(cohort, user);

            log.LogInformation("Cached unsaved cohort. QueryId:{QueryId}", qid);

            return(new Result
            {
                ValidationContext = ctx,
                Count = new PatientCount
                {
                    QueryId = qid,
                    Value = cohort.Count,
                    SqlStatements = cohort.SqlStatements
                }
            });
        }
Example #2
0
        /// <summary>
        /// Provide an zero count of patients in the specified query.
        /// Converts the query into a local validation context.
        /// Validates the resulting context to ensure sensible construction.
        /// Creates a queryId and empty cohort.
        /// </summary>
        /// <returns><see cref="Result">The count of patients in the cohort.</see></returns>
        /// <param name="queryDTO">Abstract query representation.</param>
        /// <param name="token">Cancellation token.</param>
        /// <exception cref="OperationCanceledException"/>
        /// <exception cref="LeafCompilerException"/>
        /// <exception cref="ArgumentNullException"/>
        /// <exception cref="LeafRPCException"/>
        /// <exception cref="System.Data.Common.DbException"/>
        async Task <Result> GatewayCount(IPatientCountQueryDTO queryDTO, CancellationToken token)
        {
            log.LogInformation("GatewayCount starting. DTO:{@DTO}", queryDTO);
            Ensure.NotNull(queryDTO, nameof(queryDTO));

            var ctx = await converter.GetPanelsAsync(queryDTO, token);

            log.LogInformation("GatewayCount panel validation context. Context:{@Context}", ctx);

            if (!ctx.PreflightPassed)
            {
                return(new Result
                {
                    ValidationContext = ctx
                });
            }

            validator.Validate(ctx);

            token.ThrowIfCancellationRequested();

            var cohort = new PatientCohort();
            var qid    = await CacheCohort(cohort);

            return(new Result
            {
                ValidationContext = ctx,
                Count = new PatientCount
                {
                    QueryId = qid,
                    Value = cohort.Count,
                    SqlStatements = cohort.SqlStatements
                }
            });
        }
Example #3
0
        /// <summary>
        /// Converts stub AST query definition into local, fully hydrated AST.
        /// The returned AST is unvalidated, and has a QueryId property set if the incoming query has one.
        /// </summary>
        /// <returns>The panels async.</returns>
        /// <param name="query">Stub AST query definition.</param>
        /// <param name="token">Cancellation token.</param>
        public async Task <PanelValidationContext> GetPanelsAsync(IPatientCountQueryDTO query, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();
            var validationContext = await GetPanelsAsync(query);

            validationContext.SetQueryId(query.QueryId);
            return(validationContext);
        }
Example #4
0
        /// <summary>
        /// Provide a count of patients in the specified query.
        /// </summary>
        /// <returns><see cref="Result">The count of patients in the cohort.</see></returns>
        /// <param name="queryDTO">Abstract query representation.</param>
        /// <param name="token">Cancellation token.</param>
        /// <exception cref="OperationCanceledException"/>
        /// <exception cref="LeafCompilerException"/>
        /// <exception cref="ArgumentNullException"/>
        /// <exception cref="LeafRPCException"/>
        /// <exception cref="System.Data.Common.DbException"/>
        public async Task <Result> Count(IPatientCountQueryDTO queryDTO, CancellationToken token)
        {
            switch (runtime)
            {
            case RuntimeMode.Gateway:
                return(await GatewayCount(queryDTO, token));

            default:
                return(await FullCount(queryDTO, token));
            }
        }
Example #5
0
        /// <summary>
        /// Provide a count of patients in the specified query.
        /// Converts the query into a local validation context.
        /// Validates the resulting context to ensure sensible construction.
        /// Obtains the cohort of unique patient IDs.
        /// Caches those patient IDs.
        /// </summary>
        /// <returns><see cref="Result">The count of patients in the cohort.</see></returns>
        /// <param name="queryDTO">Abstract query representation.</param>
        /// <param name="token">Cancellation token.</param>
        /// <exception cref="OperationCanceledException"/>
        /// <exception cref="LeafCompilerException"/>
        /// <exception cref="ArgumentNullException"/>
        /// <exception cref="LeafRPCException"/>
        /// <exception cref="System.Data.Common.DbException"/>
        async Task <Result> FullCount(IPatientCountQueryDTO queryDTO, CancellationToken token)
        {
            log.LogInformation("FullCount starting. DTO:{@DTO}", queryDTO);
            Ensure.NotNull(queryDTO, nameof(queryDTO));

            var ctx = await converter.GetPanelsAsync(queryDTO, token);

            log.LogInformation("FullCount panel validation context. Context:{@Context}", ctx);

            if (!ctx.PreflightPassed)
            {
                return(new Result
                {
                    ValidationContext = ctx
                });
            }

            var query = validator.Validate(ctx);

            log.LogInformation("FullCount cohort started.");
            var cohort = await counter.GetPatientCohortAsync(query, token);

            log.LogInformation("FullCount cohort retrieved. Cohort:{@Cohort}", new { cohort.Count, cohort.SqlStatements });

            token.ThrowIfCancellationRequested();

            var qid = await CacheCohort(cohort);

            var result = new Result
            {
                ValidationContext = ctx,
                Count             = new PatientCount
                {
                    QueryId       = qid,
                    Value         = cohort.Count,
                    SqlStatements = cohort.SqlStatements
                }
            };

            if (deidentOpts.ObfuscateCohort)
            {
                var count = result.Count;
                obfuscator.Obfuscate(ref count, result.ValidationContext, deidentOpts);
                log.LogInformation("FullCount results obfuscated. Obfuscated:{@Result}", result);
            }

            return(result);
        }