Ejemplo n.º 1
0
        private void ParseHasParameter(KeyValuePair <string, StringValues> Item)
        {
            //GET [base]/Patient?_has:Observation:patient:code=1234-5
            //or
            //GET [base]/Patient?_has:Observation:patient:_has:AuditEvent:entity:user=MyUserId
            if (Item.Key.StartsWith($"{TermHas}{TermSearchModifierDelimiter}"))
            {
                this.QueryItemProcessed = true;
                var HasSplit = Item.Key.Split(TermHas);
                FhirSearchQuery.HasParameter?RootHasParameter     = null;
                FhirSearchQuery.HasParameter?PreviousHasParameter = null;
                for (int i = 1; i < HasSplit.Length; i++)
                {
                    var ModifierSplit = HasSplit[i].Split(TermSearchModifierDelimiter);
                    if (ModifierSplit.Length == 4 && RootHasParameter is null)
                    {
                        if (ModifierSplit[3] == string.Empty)
                        {
                            RootHasParameter = new HasParameter(ModifierSplit[1], ModifierSplit[2]);
                            RootHasParameter.RawHasParameter = $"{Item.Key}={ Item.Value}";
                            PreviousHasParameter             = RootHasParameter;
                        }
                        else
                        {
                            RootHasParameter                 = new HasParameter(ModifierSplit[1], ModifierSplit[2]);
                            RootHasParameter.SearchQuery     = new KeyValuePair <string, StringValues>(ModifierSplit[3], Item.Value);
                            RootHasParameter.RawHasParameter = $"{Item.Key}={ Item.Value}";
                            PreviousHasParameter             = RootHasParameter;
                        }
                    }
                    else if (ModifierSplit.Length == 4 && RootHasParameter is object)
                    {
                        if (ModifierSplit[3] == string.Empty)
                        {
                            PreviousHasParameter !.ChildHasParameter = new HasParameter(ModifierSplit[1], ModifierSplit[2]);
                            PreviousHasParameter = PreviousHasParameter !.ChildHasParameter;
                        }
                        else
                        {
                            PreviousHasParameter !.ChildHasParameter             = new HasParameter(ModifierSplit[1], ModifierSplit[2]);
                            PreviousHasParameter !.ChildHasParameter.SearchQuery = new KeyValuePair <string, StringValues>(ModifierSplit[3], Item.Value);
                            PreviousHasParameter = PreviousHasParameter !.ChildHasParameter;
                        }
                    }
                    else
                    {
                        this.InvalidParameterList.Add(new InvalidSearchQueryParameter(Item.Key, Item.Value, $"The {TermHas} query must contain a resource name followed by a reference search parameter name followed by another {TermHas} parameter or a search parameter and value where each is separated by a colon {TermSearchModifierDelimiter}. For instance: _has:Observation:patient:code=1234-5 or _has:Observation:patient:_has:AuditEvent:entity:user=MyUserId. The {TermHas} qery found was : {Item.Key}={Item.Value} "));
                    }
                }

                if (RootHasParameter is object)
                {
                    this.Has.Add(RootHasParameter);
                }
            }
        }
Ejemplo n.º 2
0
        private async Task <SearchQueryHas?> ProccessHas(HasParameter Has, string RawHasParameter)
        {
            var Result = new SearchQueryHas();

            ResourceType?TargetResourceForSearchQuery = IResourceTypeSupport.GetTypeFromName(Has.TargetResourceForSearchQuery);

            if (TargetResourceForSearchQuery.HasValue && IKnownResource.IsKnownResource(this.FhirVersion, Has.TargetResourceForSearchQuery))
            {
                Result.TargetResourceForSearchQuery = TargetResourceForSearchQuery.Value;
            }
            else
            {
                Outcome !.InvalidSearchQueryList.Add(new InvalidSearchQueryParameter(RawHasParameter, $"The resource type name of: {Has.TargetResourceForSearchQuery} in a {FhirSearchQuery.TermHas} parameter could not be resolved to a resource type supported by this server for FHIR version {this.FhirVersion.GetCode()}."));
                return(null);
            }

            List <Bug.Logic.DomainModel.SearchParameter> SearchParameterList = await ISearchParameterCache.GetForIndexingAsync(this.FhirVersion, Result.TargetResourceForSearchQuery);

            Bug.Logic.DomainModel.SearchParameter BackReferenceSearchParameter = SearchParameterList.SingleOrDefault(x => x.Name == Has.BackReferenceSearchParameterName);
            if (BackReferenceSearchParameter is object && BackReferenceSearchParameter.SearchParamTypeId == SearchParamType.Reference)
            {
                Result.BackReferenceSearchParameter = BackReferenceSearchParameter;
            }
            else
            {
                if (BackReferenceSearchParameter is null)
                {
                    string Message = $"The reference search parameter back to the target resource type of: {Has.BackReferenceSearchParameterName} is not a supported search parameter for the resource type {this.ResourceContext.GetCode()} for FHIR version {this.FhirVersion.GetCode()} within this server.";
                    Outcome !.InvalidSearchQueryList.Add(new InvalidSearchQueryParameter(RawHasParameter, Message));
                    return(null);
                }
            }

            if (Has.ChildHasParameter is object)
            {
                Result.ChildSearchQueryHas = await ProccessHas(Has.ChildHasParameter, RawHasParameter);

                return(Result);
            }
            else
            {
                if (Has.SearchQuery.HasValue)
                {
                    SearchParameterList = await ISearchParameterCache.GetForIndexingAsync(this.FhirVersion, Result.TargetResourceForSearchQuery);

                    Bug.Logic.DomainModel.SearchParameter SearchParameter = SearchParameterList.SingleOrDefault(x => x.Name == Has.SearchQuery.Value.Key);
                    if (SearchParameter is object)
                    {
                        IList <ISearchQueryBase> SearchQueryBaseList = await ISearchQueryFactory.Create(this.ResourceContext, SearchParameter, Has.SearchQuery.Value);

                        if (SearchQueryBaseList.Count == 1)
                        {
                            if (SearchQueryBaseList[0].IsValid)
                            {
                                Result.SearchQuery = SearchQueryBaseList[0];
                                return(Result);
                            }
                            else
                            {
                                string Message = $"Error parsing the search parameter found at the end of a {FhirSearchQuery.TermHas} query. The search parameter name was : {Has.SearchQuery.Value.Key} with the value of {Has.SearchQuery.Value.Value}. " +
                                                 $"Additional information: {SearchQueryBaseList[0].InvalidMessage}";
                                Outcome !.InvalidSearchQueryList.Add(new InvalidSearchQueryParameter(RawHasParameter, Message));
                                return(null);
                            }
                        }
                        else
                        {
                            throw new ApplicationException($"The {FhirSearchQuery.TermHas} parameter seems to end with more then one search parameter, this should not be possible.");
                        }
                    }
                    else
                    {
                        string Message = $"The {FhirSearchQuery.TermHas} query finish with a search parameter: {Has.SearchQuery.Value.Key} for the resource type of: {Result.TargetResourceForSearchQuery.GetCode()}. " +
                                         $"However, the search parameter: {Has.SearchQuery.Value.Key} is not a supported search parameter for this resource type in this server for FHIR version {this.FhirVersion.GetCode()}.";
                        Outcome !.InvalidSearchQueryList.Add(new InvalidSearchQueryParameter(RawHasParameter, Message));
                        return(null);
                    }
                }
                else
                {
                    string Message = $"The {FhirSearchQuery.TermHas} query does not finish with a search parameter and value.";
                    Outcome !.InvalidSearchQueryList.Add(new InvalidSearchQueryParameter(RawHasParameter, Message));
                    return(null);
                }
            }
        }