private async Task SetChain(Bug.Logic.DomainModel.SearchParameter SearchParameter, KeyValuePair <string, StringValues> SingleChainedParameter, bool IsChainedReferance) { IList <ISearchQueryBase> SearchQueryBaseList = await ISearchQueryFactory.Create(this.ResourceContext, SearchParameter, SingleChainedParameter, IsChainedReferance); foreach (ISearchQueryBase SearchQueryBase in SearchQueryBaseList) { if (SearchQueryBase.IsValid) { if (SearchQueryBase.CloneDeep() is ISearchQueryBase SearchQueryBaseClone) { if (ParentChainSearchParameter is null) { ParentChainSearchParameter = SearchQueryBaseClone; } else { if (ParentChainSearchParameter.ChainedSearchParameter is null) { ParentChainSearchParameter.ChainedSearchParameter = SearchQueryBaseClone; } if (PreviousChainSearchParameter is object) { PreviousChainSearchParameter.ChainedSearchParameter = SearchQueryBaseClone; } else { throw new NullReferenceException(nameof(PreviousChainSearchParameter)); } } PreviousChainSearchParameter = SearchQueryBaseClone; if (IsChainedReferance) { PreviousChainSearchParameter.Modifier = SearchModifierCode.Type; } } else { throw new InvalidCastException($"Internal Server Error: Unable to cast cloned SearchQueryBase to ISearchQueryBase"); } } else { string Message = $"Failed to parse the value of the chain search query. Additional information: {SearchQueryBase.InvalidMessage}"; ErrorInSearchParameterProcessing = true; InvalidSearchQueryParameterList.Add(new InvalidSearchQueryParameter(this.RawParameter, Message)); break; } } }
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); } } }