public Expression Build(
            string searchParameterName,
            SearchModifierCode?modifier,
            SearchComparator comparator,
            int?componentIndex,
            ISearchValue searchValue)
        {
            EnsureArg.IsNotNullOrWhiteSpace(searchParameterName, nameof(searchParameterName));
            Debug.Assert(
                modifier == null || Enum.IsDefined(typeof(SearchModifierCode), modifier.Value),
                "Invalid modifier.");
            Debug.Assert(
                Enum.IsDefined(typeof(SearchComparator), comparator),
                "Invalid comparator.");
            EnsureArg.IsNotNull(searchValue, nameof(searchValue));

            _searchParameterName = searchParameterName;
            _modifier            = modifier;
            _comparator          = comparator;
            _componentIndex      = componentIndex;

            searchValue.AcceptVisitor(this);

            return(_outputExpression);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="SearchIndexEntry"/> class.
        /// </summary>
        /// <param name="searchParameter">The search parameter</param>
        /// <param name="value">The searchable value.</param>
        public SearchIndexEntry(SearchParameterInfo searchParameter, ISearchValue value)
        {
            EnsureArg.IsNotNull(searchParameter, nameof(searchParameter));
            EnsureArg.IsNotNull(value, nameof(value));

            SearchParameter = searchParameter;
            Value           = value;
        }
Example #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SearchIndexEntry"/> class.
        /// </summary>
        /// <param name="paramName">The search parameter name.</param>
        /// <param name="value">The searchable value.</param>
        public SearchIndexEntry(string paramName, ISearchValue value)
        {
            EnsureArg.IsNotNullOrWhiteSpace(paramName, nameof(paramName));
            EnsureArg.IsNotNull(value, nameof(value));

            ParamName = paramName;
            Value     = value;
        }
Example #4
0
        public SortValue(ISearchValue low, ISearchValue high, Uri searchParameterUri)
        {
            EnsureArg.IsNotNull(searchParameterUri, nameof(searchParameterUri));

            Low  = low;
            High = high;
            SearchParameterUri = searchParameterUri;
        }
        public void GivenASearchValue_WhenIsValidCompositeComponentIsCalled_ThenFalseShouldBeReturned()
        {
            var components = new ISearchValue[]
            {
                new StringSearchValue("abc"),
            };

            var value = new CompositeSearchValue(new[] { components });

            Assert.False(value.IsValidAsCompositeComponent);
        }
Example #6
0
        public virtual bool Equals([AllowNull] ISearchValue other)
        {
            var uriSearchValueOther = other as UriSearchValue;

            if (uriSearchValueOther == null)
            {
                return(false);
            }

            // URLs are always considered to be case-sensitive (https://www.hl7.org/fhir/references.html#literal)
            return(string.Equals(ToString(), uriSearchValueOther.ToString(), StringComparison.Ordinal));
        }
        public bool Equals([AllowNull] ISearchValue other)
        {
            if (other == null)
            {
                return(false);
            }

            var stringSearchValueOther = other as StringSearchValue;

            if (stringSearchValueOther == null)
            {
                return(false);
            }

            return(String.Equals(stringSearchValueOther.String, System.StringComparison.OrdinalIgnoreCase));
        }
Example #8
0
        public bool Equals([AllowNull] ISearchValue other)
        {
            if (other == null)
            {
                return(false);
            }

            var compositeSearchValueOther = other as CompositeSearchValue;

            if (compositeSearchValueOther == null)
            {
                return(false);
            }

            return(Components.SequenceEqual(compositeSearchValueOther.Components));
        }
        public bool Equals([AllowNull] ISearchValue other)
        {
            if (other == null)
            {
                return(false);
            }

            var numberSearchValueOther = other as NumberSearchValue;

            if (numberSearchValueOther == null)
            {
                return(false);
            }

            return(Low == numberSearchValueOther.Low && High == numberSearchValueOther.High);
        }
        public bool Equals([AllowNull] ISearchValue other)
        {
            if (other == null)
            {
                return(false);
            }

            var dateTimeSearchValueOther = other as DateTimeSearchValue;

            if (dateTimeSearchValueOther == null)
            {
                return(false);
            }

            return(Start == dateTimeSearchValueOther.Start && End == dateTimeSearchValueOther.End);
        }
        public bool Equals([AllowNull] ISearchValue other)
        {
            if (other == null)
            {
                return(false);
            }

            var uriSearchValueOther = other as UriSearchValue;

            if (uriSearchValueOther == null)
            {
                return(false);
            }

            return(Uri == uriSearchValueOther.Uri);
        }
        public bool Equals([AllowNull] ISearchValue other)
        {
            if (other == null)
            {
                return(false);
            }

            var tokenSearchValueOther = other as TokenSearchValue;

            if (tokenSearchValueOther == null)
            {
                return(false);
            }

            return(string.Equals(System, tokenSearchValueOther.System, StringComparison.OrdinalIgnoreCase) &&
                   string.Equals(Code, tokenSearchValueOther.Code, StringComparison.OrdinalIgnoreCase) &&
                   string.Equals(Text, tokenSearchValueOther.Text, StringComparison.OrdinalIgnoreCase));
        }
        public bool Equals([AllowNull] ISearchValue other)
        {
            if (other == null)
            {
                return(false);
            }

            var referenceSearchValueOther = other as ReferenceSearchValue;

            if (referenceSearchValueOther == null)
            {
                return(false);
            }

            return(Kind == referenceSearchValueOther.Kind &&
                   BaseUri == referenceSearchValueOther.BaseUri &&
                   string.Equals(ResourceType, referenceSearchValueOther.ResourceType, StringComparison.OrdinalIgnoreCase) &&
                   string.Equals(ResourceId, referenceSearchValueOther.ResourceId, StringComparison.OrdinalIgnoreCase));
        }
Example #14
0
        public bool Equals([AllowNull] ISearchValue other)
        {
            if (other == null)
            {
                return(false);
            }

            var quantitytSearchValueOther = other as QuantitySearchValue;

            if (quantitytSearchValueOther == null)
            {
                return(false);
            }

            return(Low == quantitytSearchValueOther.Low &&
                   High == quantitytSearchValueOther.High &&
                   string.Equals(System, quantitytSearchValueOther.System, StringComparison.OrdinalIgnoreCase) &&
                   string.Equals(Code, quantitytSearchValueOther.Code, StringComparison.OrdinalIgnoreCase));
        }
        public void GivenASearchValue_WhenToStringIsCalled_ThenCorrectStringShouldBeReturned()
        {
            var components = new ISearchValue[][]
            {
                new ISearchValue[]
                {
                    new TokenSearchValue("system1", "code1", "text1"),
                    new TokenSearchValue("system2", "code2", "text2"),
                },
                new ISearchValue[]
                {
                    new NumberSearchValue(123),
                    new NumberSearchValue(789),
                },
            };

            var value = new CompositeSearchValue(components);

            Assert.Equal("(system1|code1), (system2|code2) $ (123), (789)", value.ToString());
        }
Example #16
0
        private async Task <(ResourceWrapper original, ResourceWrapper updated)> CreateUpdatedWrapperFromExistingPatient(
            SaveOutcome upsertResult,
            SearchParameter searchParam,
            ISearchValue searchValue,
            ResourceWrapper originalWrapper = null,
            string updatedId = null)
        {
            var searchIndex   = new SearchIndexEntry(searchParam.ToInfo(), searchValue);
            var searchIndices = new List <SearchIndexEntry> {
                searchIndex
            };

            if (originalWrapper == null)
            {
                // Get wrapper from data store directly
                var resourceKey = new ResourceKey(upsertResult.RawResourceElement.InstanceType, upsertResult.RawResourceElement.Id, upsertResult.RawResourceElement.VersionId);

                originalWrapper = await _dataStore.GetAsync(resourceKey, CancellationToken.None);
            }

            // Add new search index entry to existing wrapper
            var updatedWrapper = new ResourceWrapper(
                updatedId ?? originalWrapper.ResourceId,
                originalWrapper.Version,
                originalWrapper.ResourceTypeName,
                originalWrapper.RawResource,
                new ResourceRequest(HttpMethod.Post, null),
                originalWrapper.LastModified,
                deleted: false,
                searchIndices,
                originalWrapper.CompartmentIndices,
                originalWrapper.LastModifiedClaims,
                _searchParameterDefinitionManager.GetSearchParameterHashForResourceType("Patient"));

            return(originalWrapper, updatedWrapper);
        }
Example #17
0
        private Expression Build(
            SearchParameterInfo searchParameter,
            SearchModifierCode?modifier,
            int?componentIndex,
            string value)
        {
            ReadOnlySpan <char> valueSpan = value.AsSpan();

            // By default, the comparator is equal.
            SearchComparator comparator = SearchComparator.Eq;

            if (searchParameter.Type == ValueSets.SearchParamType.Date ||
                searchParameter.Type == ValueSets.SearchParamType.Number ||
                searchParameter.Type == ValueSets.SearchParamType.Quantity)
            {
                // If the search parameter type supports comparator, parse the comparator (if present).
                Tuple <string, SearchComparator> matchedComparator = SearchParamComparators.FirstOrDefault(
                    s => value.StartsWith(s.Item1, StringComparison.Ordinal));

                if (matchedComparator != null)
                {
                    comparator = matchedComparator.Item2;
                    valueSpan  = valueSpan.Slice(matchedComparator.Item1.Length);
                }
            }

            // Parse the value.
            Func <string, ISearchValue> parser = _parserDictionary[Enum.Parse <SearchParamType>(searchParameter.Type?.ToString())];

            // Build the expression.
            var helper = new SearchValueExpressionBuilderHelper();

            // If the value contains comma, then we need to convert it into in expression.
            // But in this case, the user cannot specify prefix.
            IReadOnlyList <string> parts = value.SplitByOrSeparator();

            if (parts.Count == 1)
            {
                // This is a single value expression.
                ISearchValue searchValue = parser(valueSpan.ToString());

                return(helper.Build(
                           searchParameter.Name,
                           modifier,
                           comparator,
                           componentIndex,
                           searchValue));
            }
            else
            {
                if (comparator != SearchComparator.Eq)
                {
                    throw new InvalidSearchOperationException(Core.Resources.SearchComparatorNotSupported);
                }

                // This is a multiple value expression.
                Expression[] expressions = parts.Select(part =>
                {
                    ISearchValue searchValue = parser(part);

                    return(helper.Build(
                               searchParameter.Name,
                               modifier,
                               comparator,
                               componentIndex,
                               searchValue));
                }).ToArray();

                return(Expression.Or(expressions));
            }
        }
 public static void ValidateDateTime(string expectedDateTime, ISearchValue sv)
 {
     ValidateDateTime((expectedDateTime, expectedDateTime), sv);
 }
 private void TestAndValidateOutput(string parameterName, ISearchValue value, params (string Name, object Value)[][] expectedValues)