コード例 #1
0
ファイル: DefinitionsFactory.cs プロジェクト: schellack/spark
        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);
        }
コード例 #2
0
        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));
                }
            }
        }
コード例 #3
0
ファイル: DefinitionsFactory.cs プロジェクト: jjrdk/spark
        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);
        }
コード例 #4
0
        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);
            }
        }
コード例 #5
0
        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));
                }
            }
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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.");
                }
            }
        }
コード例 #9
0
        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));
        }
コード例 #10
0
 public static void SetOriginalDefinition(this SearchParameter searchParameter, ModelInfo.SearchParamDefinition definition)
 {
     searchParameter.UserData.Add("original_definition", definition);
 }
コード例 #11
0
 public static void SetOriginalDefinition(this SearchParameter searchParameter, ModelInfo.SearchParamDefinition definition)
 {
     searchParameter.AddAnnotation(definition);
 }
コード例 #12
0
        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.");
                }
            }
        }