public static Definition CreateDefinition(ModelInfo.SearchParamDefinition paramdef) { Definition definition = new Definition(); definition.Argument = ArgumentFactory.Create(paramdef.Type); definition.Resource = paramdef.Resource; definition.ParamName = paramdef.Name; definition.Query = new ElementQuery(paramdef.Path); definition.ParamType = paramdef.Type; definition.Description = paramdef.Description; return(definition); }
private static FilterDefinition <BsonDocument> CreateFilter(ModelInfo.SearchParamDefinition parameter, Operator op, String modifier, Expression operand) { if (op == Operator.CHAIN) { throw new NotSupportedException("Chain operators should be handled in MongoSearcher."); } else // There's only one operand. { string parameterName = parameter.Name; if (parameterName == "_id") { parameterName = "fhir_id"; //See MongoIndexMapper for counterpart. // This search finds the patient resource with the given id (there can only be one resource for a given id). // Functionally, this is equivalent to a simple read operation modifier = Modifier.EXACT; } var valueOperand = (ValueExpression)operand; switch (parameter.Type) { case SearchParamType.Composite: return(CompositeQuery(parameter, op, modifier, valueOperand)); case SearchParamType.Date: return(DateQuery(parameterName, op, modifier, valueOperand)); case SearchParamType.Number: return(NumberQuery(parameter.Name, op, valueOperand)); case SearchParamType.Quantity: return(QuantityQuery(parameterName, op, modifier, valueOperand)); case SearchParamType.Reference: //Chain is handled in MongoSearcher, so here we have the result of a closed criterium: IN [ list of id's ] return(StringQuery(parameterName, op, modifier, valueOperand)); case SearchParamType.String: return(StringQuery(parameterName, op, modifier, valueOperand)); case SearchParamType.Token: return(TokenQuery(parameterName, op, modifier, valueOperand)); case SearchParamType.Uri: return(UriQuery(parameterName, op, modifier, valueOperand)); default: //return Builders<BsonDocument>.Filter.Null; throw new NotSupportedException(String.Format("SearchParamType {0} on parameter {1} not supported.", parameter.Type, parameter.Name)); } } }
public static Definition CreateDefinition(ModelInfo.SearchParamDefinition paramdef) { var definition = new Definition { Argument = ArgumentFactory.Create(paramdef.Type), Resource = paramdef.Resource, ParamName = paramdef.Name, Query = new ElementQuery(paramdef.Path), ParamType = paramdef.Type, Description = paramdef.Description?.Value }; return(definition); }
private static void ExtractExamplesFromResource(Dictionary <ModelInfo.SearchParamDefinition, Holder> exampleSearchValues, Resource resource, ModelInfo.SearchParamDefinition index) { var resourceModel = resource.ToTypedElement(); try { var results = resourceModel.Select(index.Expression, new EvaluationContext(resourceModel)); if (results.Count() > 0) { foreach (var t2 in results) { if (t2 != null) { if (t2 is PocoElementNode && (t2 as PocoElementNode).FhirValue != null) { // Validate the type of data returned against the type of search parameter // Debug.Write(index.Resource + "." + index.Name + ": "); // Debug.WriteLine((t2 as FhirPath.ModelNavigator).FhirValue.ToString());// + "\r\n"; exampleSearchValues[index].count++; } else if (t2.Value is Hl7.FhirPath.ConstantValue) { // Debug.Write(index.Resource + "." + index.Name + ": "); // Debug.WriteLine((t2.Value as Hl7.FhirPath.ConstantValue).Value); exampleSearchValues[index].count++; } else if (t2.Value is bool) { // Debug.Write(index.Resource + "." + index.Name + ": "); // Debug.WriteLine((bool)t2.Value); exampleSearchValues[index].count++; } else { Debug.Write(index.Resource + "." + index.Name + ": "); Debug.WriteLine(t2.Value); exampleSearchValues[index].count++; } } } } } catch (ArgumentException ex) { Debug.WriteLine("FATAL: Error parsing expression in search index {0}.{1} {2}\r\n\t{3}", index.Resource, index.Name, index.Expression, ex.Message); } }
private static IMongoQuery CreateFilter(ModelInfo.SearchParamDefinition parameter, Operator op, String modifier, Expression operand) { if (op == Operator.CHAIN) { throw new NotSupportedException("Chain operators should be handled in MongoSearcher."); } else // There's only one operand. { string parameterName = parameter.Name; if (parameterName == "_id") { parameterName = "fhir_id"; //See MongoIndexMapper for counterpart. } var valueOperand = (ValueExpression)operand; switch (parameter.Type) { case SearchParamType.Composite: return(CompositeQuery(parameter, op, modifier, valueOperand)); case SearchParamType.Date: return(DateQuery(parameterName, op, modifier, valueOperand)); case SearchParamType.Number: return(NumberQuery(parameter.Name, op, valueOperand)); case SearchParamType.Quantity: return(QuantityQuery(parameterName, op, modifier, valueOperand)); case SearchParamType.Reference: //Chain is handled in MongoSearcher, so here we have the result of a closed criterium: IN [ list of id's ] return(StringQuery(parameterName, op, modifier, valueOperand)); case SearchParamType.String: return(StringQuery(parameterName, op, modifier, valueOperand)); case SearchParamType.Token: return(TokenQuery(parameterName, op, modifier, valueOperand)); case SearchParamType.Uri: return(UriQuery(parameterName, op, modifier, valueOperand)); default: //return M.Query.Null; throw new NotSupportedException(String.Format("SearchParamType {0} on parameter {1} not supported.", parameter.Type, parameter.Name)); } } }
private Tuple <string, SortOrder> NormalizeSortItem(string resourceType, Tuple <string, SortOrder> sortItem) { ModelInfo.SearchParamDefinition definition = _fhirModel.FindSearchParameter(resourceType, sortItem.Item1)?.GetOriginalDefinition(); if (definition?.Type == SearchParamType.Token) { return(new Tuple <string, SortOrder>(sortItem.Item1 + ".code", sortItem.Item2)); } if (definition?.Type == SearchParamType.Date) { return(new Tuple <string, SortOrder>(sortItem.Item1 + ".start", sortItem.Item2)); } if (definition?.Type == SearchParamType.Quantity) { return(new Tuple <string, SortOrder>(sortItem.Item1 + ".value", sortItem.Item2)); } return(sortItem); }
private static List <string> GetTargetedReferenceTypes(ModelInfo.SearchParamDefinition parameter, String modifier) { var allowedResourceTypes = ModelInfo.SupportedResources; //TODO: restrict to parameter.ReferencedResources. This means not making this static, because you want to use IFhirModel. List <string> searchResourceTypes = new List <string>(); if (String.IsNullOrEmpty(modifier)) { searchResourceTypes.AddRange(allowedResourceTypes); } else if (allowedResourceTypes.Contains(modifier)) { searchResourceTypes.Add(modifier); } else { throw new NotSupportedException(String.Format("Referenced type cannot be of type %s.", modifier)); } return(searchResourceTypes); }
private static IMongoQuery CreateFilter(ModelInfo.SearchParamDefinition parameter, Operator op, String modifier, Expression operand) { if (op == Operator.CHAIN) { throw new NotSupportedException("Chain operators should be handled in MongoSearcher."); } else // There's only one operand. { var valueOperand = (ValueExpression)operand; switch (parameter.Type) { case Conformance.SearchParamType.Composite: return(CompositeQuery(parameter, op, modifier, valueOperand)); case Conformance.SearchParamType.Date: return(DateQuery(parameter.Name, op, modifier, valueOperand)); case Conformance.SearchParamType.Number: return(NumberQuery(parameter.Name, op, valueOperand)); case Conformance.SearchParamType.Quantity: return(QuantityQuery(parameter.Name, op, modifier, valueOperand)); case Conformance.SearchParamType.Reference: //Chain is handled in MongoSearcher, so here we have the result of a closed criterium: IN [ list of id's ] return(StringQuery(parameter.Name, op, modifier, valueOperand)); case Conformance.SearchParamType.String: return(StringQuery(parameter.Name, op, modifier, valueOperand)); case Conformance.SearchParamType.Token: return(TokenQuery(parameter.Name, op, modifier, valueOperand)); default: //return M.Query.Null; throw new NotSupportedException("Only SearchParamType.Number or String is supported."); } } }
private static IMongoQuery CompositeQuery(ModelInfo.SearchParamDefinition parameterDef, Operator optor, String modifier, ValueExpression operand) { if (optor == Operator.IN) { var choices = ((ChoiceValue)operand); var queries = new List <IMongoQuery>(); foreach (var choice in choices.Choices) { queries.Add(CompositeQuery(parameterDef, Operator.EQ, modifier, choice)); } return(M.Query.Or(queries)); } else if (optor == Operator.EQ) { var typedOperand = (CompositeValue)operand; var queries = new List <IMongoQuery>(); var components = typedOperand.Components; var subParams = parameterDef.CompositeParams; if (components.Count() != subParams.Count()) { throw new ArgumentException(String.Format("Parameter {0} requires exactly {1} composite values, not the currently provided {2} values.", parameterDef.Name, subParams.Count(), components.Count())); } for (int i = 0; i < subParams.Count(); i++) { var subCrit = new Criterium(); subCrit.Operator = Operator.EQ; subCrit.ParamName = subParams[i]; subCrit.Operand = components[i]; subCrit.Modifier = modifier; queries.Add(subCrit.ToFilter(parameterDef.Resource)); } return(M.Query.And(queries)); } throw new ArgumentException(String.Format("Invalid operator {0} on composite parameter {1}", optor.ToString(), parameterDef.Name)); }
public static void SetOriginalDefinition(this SearchParameter searchParameter, ModelInfo.SearchParamDefinition definition) { searchParameter.UserData.Add("original_definition", definition); }
public static void SetOriginalDefinition(this SearchParameter searchParameter, ModelInfo.SearchParamDefinition definition) { searchParameter.AddAnnotation(definition); }
private static FilterDefinition <BsonDocument> CreateFilter(ModelInfo.SearchParamDefinition parameter, Operator op, String modifier, Expression operand) { if (op == Operator.CHAIN) { throw new NotSupportedException("Chain operators should be handled in MongoSearcher."); } else // There's only one operand. { string parameterName = parameter.Name; if (parameterName == "_id") { parameterName = "fhir_id"; //See MongoIndexMapper for counterpart. // This search finds the patient resource with the given id (there can only be one resource for a given id). // Functionally, this is equivalent to a simple read operation modifier = Modifier.EXACT; } var valueOperand = (ValueExpression)operand; switch (parameter.Type) { case SearchParamType.Composite: return(CompositeQuery(parameter, op, modifier, valueOperand)); case SearchParamType.Date: return(DateQuery(parameterName, op, modifier, valueOperand)); case SearchParamType.Number: return(NumberQuery(parameter.Name, op, valueOperand)); case SearchParamType.Quantity: return(QuantityQuery(parameterName, op, valueOperand)); case SearchParamType.Reference: //Chain is handled in MongoSearcher, so here we have the result of a closed criterium: IN [ list of id's ] if (parameter.Target?.Any() == true && valueOperand != null && !valueOperand.ToUnescapedString().Contains("/")) { // For searching by reference without type specified. // If reference target type is known, create the exact query like ^(Person|Group)/(123|456)$ return(Builders <BsonDocument> .Filter.Regex(parameterName, new BsonRegularExpression(new Regex( $"^({string.Join("|", parameter.Target)})/({valueOperand.ToUnescapedString().Replace(",", "|")})$")))); } else { return(StringQuery(parameterName, op, Modifier.EXACT, valueOperand)); } case SearchParamType.String: return(StringQuery(parameterName, op, modifier, valueOperand)); case SearchParamType.Token: return(TokenQuery(parameterName, op, modifier, valueOperand)); case SearchParamType.Uri: return(UriQuery(parameterName, op, modifier, valueOperand)); default: //return Builders<BsonDocument>.Filter.Null; throw new NotSupportedException( $"SearchParamType {parameter.Type} on parameter {parameter.Name} not supported."); } } }