Esempio n. 1
0
        private FilterExpression CreateFilterByIds <TId>(ICollection <TId> ids, AttrAttribute idAttribute, FilterExpression existingFilter)
        {
            var idChain = new ResourceFieldChainExpression(idAttribute);

            FilterExpression filter = null;

            if (ids.Count == 1)
            {
                var constant = new LiteralConstantExpression(ids.Single().ToString());
                filter = new ComparisonExpression(ComparisonOperator.Equals, idChain, constant);
            }
            else if (ids.Count > 1)
            {
                var constants = ids.Select(id => new LiteralConstantExpression(id.ToString())).ToList();
                filter = new EqualsAnyOfExpression(idChain, constants);
            }

            // @formatter:keep_existing_linebreaks true

            return(filter == null
                ? existingFilter
                : existingFilter == null
                    ? filter
                    : new LogicalExpression(LogicalOperator.And, ArrayFactory.Create(filter, existingFilter)));

            // @formatter:keep_existing_linebreaks restore
        }
        public ExpressionInScope(ResourceFieldChainExpression scope, QueryExpression expression)
        {
            ArgumentGuard.NotNull(expression, nameof(expression));

            Scope      = scope;
            Expression = expression;
        }
            public override QueryExpression VisitResourceFieldChain(ResourceFieldChainExpression expression, object argument)
            {
                if (expression.Fields.First().Property.Name == nameof(TelevisionBroadcast.ArchivedAt))
                {
                    HasFilterOnArchivedAt = true;
                }

                return(base.VisitResourceFieldChain(expression, argument));
            }
Esempio n. 4
0
        protected CollectionNotEmptyExpression ParseHas()
        {
            EatText(Keywords.Has);
            EatSingleCharacterToken(TokenKind.OpenParen);

            ResourceFieldChainExpression targetCollection = ParseFieldChain(FieldChainRequirements.EndsInToMany, null);

            EatSingleCharacterToken(TokenKind.CloseParen);

            return(new CollectionNotEmptyExpression(targetCollection));
        }
        protected ResourceContext GetResourceContextForScope(ResourceFieldChainExpression scope)
        {
            if (scope == null)
            {
                return(RequestResource);
            }

            var lastField = scope.Fields.Last();
            var type      = lastField is RelationshipAttribute relationship ? relationship.RightType : lastField.Property.PropertyType;

            return(_resourceContextProvider.GetResourceContext(type));
        }
Esempio n. 6
0
        protected IncludeExpression ToIncludeExpression(params string[] includePaths)
        {
            var relationshipChains = new List <ResourceFieldChainExpression>();

            foreach (string includePath in includePaths)
            {
                ResourceFieldChainExpression relationshipChain = GetRelationshipsInPath(includePath);
                relationshipChains.Add(relationshipChain);
            }

            return(IncludeChainConverter.FromRelationshipChains(relationshipChains));
        }
        public override QueryExpression VisitResourceFieldChain(ResourceFieldChainExpression expression, object argument)
        {
            if (expression != null)
            {
                if (expression.Fields.Count > 1 || expression.Fields.First() is RelationshipAttribute)
                {
                    throw new UnsupportedRelationshipException();
                }
            }

            return(base.VisitResourceFieldChain(expression, argument));
        }
Esempio n. 8
0
            public MutablePaginationEntry ResolveEntryInScope(ResourceFieldChainExpression scope)
            {
                if (scope == null)
                {
                    return(_globalScope);
                }

                if (!_nestedScopes.ContainsKey(scope))
                {
                    _nestedScopes.Add(scope, new MutablePaginationEntry());
                }

                return(_nestedScopes[scope]);
            }
Esempio n. 9
0
        private static FilterExpression CreateFilterByIds <TId>(IReadOnlyCollection <TId> ids, ResourceContext resourceContext)
        {
            AttrAttribute idAttribute = resourceContext.Attributes.Single(attr => attr.Property.Name == nameof(Identifiable.Id));
            var           idChain     = new ResourceFieldChainExpression(idAttribute);

            if (ids.Count == 1)
            {
                var constant = new LiteralConstantExpression(ids.Single().ToString());
                return(new ComparisonExpression(ComparisonOperator.Equals, idChain, constant));
            }

            List <LiteralConstantExpression> constants = ids.Select(id => new LiteralConstantExpression(id.ToString())).ToList();

            return(new EqualsAnyOfExpression(idChain, constants));
        }
        private Expression ProcessRelationshipChain(ResourceFieldChainExpression chain, Expression source)
        {
            string     path   = null;
            Expression result = source;

            foreach (RelationshipAttribute relationship in chain.Fields.Cast <RelationshipAttribute>())
            {
                path = path == null ? relationship.RelationshipPath : path + "." + relationship.RelationshipPath;

                ResourceContext resourceContext = _resourceContextProvider.GetResourceContext(relationship.RightType);
                result = ApplyEagerLoads(result, resourceContext.EagerLoads, path);
            }

            return(IncludeExtensionMethodCall(result, path));
        }
Esempio n. 11
0
        private void StoreFilterInScope(FilterExpression filter, ResourceFieldChainExpression scope)
        {
            if (scope == null)
            {
                _filtersInGlobalScope.Add(filter);
            }
            else
            {
                if (!_filtersPerScope.ContainsKey(scope))
                {
                    _filtersPerScope[scope] = new List <FilterExpression>();
                }

                _filtersPerScope[scope].Add(filter);
            }
        }
        public void Reader_Read_Succeeds(string parameterName, string parameterValue, string valueExpected)
        {
            // Act
            _reader.Read(parameterName, parameterValue);

            IReadOnlyCollection <ExpressionInScope> constraints = _reader.GetConstraints();

            // Assert
            ResourceFieldChainExpression scope = constraints.Select(expressionInScope => expressionInScope.Scope).Single();

            scope.Should().BeNull();

            QueryExpression value = constraints.Select(expressionInScope => expressionInScope.Expression).Single();

            value.ToString().Should().Be(valueExpected);
        }
        /// <inheritdoc />
        public virtual void Read(string parameterName, StringValues parameterValue)
        {
            _lastParameterName = parameterName;

            try
            {
                ResourceFieldChainExpression scope = GetScope(parameterName);
                SortExpression sort = GetSort(parameterValue, scope);

                var expressionInScope = new ExpressionInScope(scope, sort);
                _constraints.Add(expressionInScope);
            }
            catch (QueryParseException exception)
            {
                throw new InvalidQueryStringParameterException(parameterName, "The specified sort is invalid.", exception.Message, exception);
            }
        }
        private QueryExpression CreateEqualityComparisonOnCompositeKey(ResourceFieldChainExpression existingCarIdChain,
                                                                       long regionIdValue, string licensePlateValue)
        {
            var regionIdChain      = ReplaceLastAttributeInChain(existingCarIdChain, _regionIdAttribute);
            var regionIdComparison = new ComparisonExpression(ComparisonOperator.Equals, regionIdChain,
                                                              new LiteralConstantExpression(regionIdValue.ToString()));

            var licensePlateChain      = ReplaceLastAttributeInChain(existingCarIdChain, _licensePlateAttribute);
            var licensePlateComparison = new ComparisonExpression(ComparisonOperator.Equals, licensePlateChain,
                                                                  new LiteralConstantExpression(licensePlateValue));

            return(new LogicalExpression(LogicalOperator.And, new[]
            {
                regionIdComparison,
                licensePlateComparison
            }));
        }
Esempio n. 15
0
        private QueryExpression RewriteFilterOnCarStringIds(ResourceFieldChainExpression existingCarIdChain, IEnumerable <string> carStringIds)
        {
            var outerTerms = new List <QueryExpression>();

            foreach (string carStringId in carStringIds)
            {
                var tempCar = new Car
                {
                    StringId = carStringId
                };

                QueryExpression keyComparison = CreateEqualityComparisonOnCompositeKey(existingCarIdChain, tempCar.RegionId, tempCar.LicensePlate);
                outerTerms.Add(keyComparison);
            }

            return(outerTerms.Count == 1 ? outerTerms[0] : new LogicalExpression(LogicalOperator.Or, outerTerms));
        }
Esempio n. 16
0
        protected CountExpression TryParseCount()
        {
            if (TokenStack.TryPeek(out Token nextToken) && nextToken.Kind == TokenKind.Text && nextToken.Value == Keywords.Count)
            {
                TokenStack.Pop();

                EatSingleCharacterToken(TokenKind.OpenParen);

                ResourceFieldChainExpression targetCollection = ParseFieldChain(FieldChainRequirements.EndsInToMany, null);

                EatSingleCharacterToken(TokenKind.CloseParen);

                return(new CountExpression(targetCollection));
            }

            return(null);
        }
Esempio n. 17
0
        protected MatchTextExpression ParseTextMatch(string matchFunctionName)
        {
            EatText(matchFunctionName);
            EatSingleCharacterToken(TokenKind.OpenParen);

            ResourceFieldChainExpression targetAttribute = ParseFieldChain(FieldChainRequirements.EndsInAttribute, null);

            EatSingleCharacterToken(TokenKind.Comma);

            LiteralConstantExpression constant = ParseConstant();

            EatSingleCharacterToken(TokenKind.CloseParen);

            var matchKind = Enum.Parse <TextMatchKind>(matchFunctionName.Pascalize());

            return(new MatchTextExpression(targetAttribute, constant, matchKind));
        }
        protected IncludeExpression ParseInclude(int?maximumDepth)
        {
            ResourceFieldChainExpression firstChain = ParseFieldChain(FieldChainRequirements.IsRelationship, "Relationship name expected.");

            List <ResourceFieldChainExpression> chains = firstChain.AsList();

            while (TokenStack.Any())
            {
                EatSingleCharacterToken(TokenKind.Comma);

                ResourceFieldChainExpression nextChain = ParseFieldChain(FieldChainRequirements.IsRelationship, "Relationship name expected.");
                chains.Add(nextChain);
            }

            ValidateMaximumIncludeDepth(maximumDepth, chains);

            return(IncludeChainConverter.FromRelationshipChains(chains));
        }
        protected SparseFieldSetExpression ParseSparseFieldSet()
        {
            var fields = new Dictionary <string, ResourceFieldAttribute>();

            while (TokenStack.Any())
            {
                if (fields.Count > 0)
                {
                    EatSingleCharacterToken(TokenKind.Comma);
                }

                ResourceFieldChainExpression nextChain = ParseFieldChain(FieldChainRequirements.EndsInAttribute, "Field name expected.");
                ResourceFieldAttribute       nextField = nextChain.Fields.Single();
                fields[nextField.PublicName] = nextField;
            }

            return(fields.Any() ? new SparseFieldSetExpression(fields.Values) : null);
        }
Esempio n. 20
0
        protected EqualsAnyOfExpression ParseAny()
        {
            EatText(Keywords.Any);
            EatSingleCharacterToken(TokenKind.OpenParen);

            ResourceFieldChainExpression targetAttribute = ParseFieldChain(FieldChainRequirements.EndsInAttribute, null);

            EatSingleCharacterToken(TokenKind.Comma);

            var constants = new List <LiteralConstantExpression>();

            LiteralConstantExpression constant = ParseConstant();

            constants.Add(constant);

            EatSingleCharacterToken(TokenKind.Comma);

            constant = ParseConstant();
            constants.Add(constant);

            while (TokenStack.TryPeek(out Token nextToken) && nextToken.Kind == TokenKind.Comma)
            {
                EatSingleCharacterToken(TokenKind.Comma);

                constant = ParseConstant();
                constants.Add(constant);
            }

            EatSingleCharacterToken(TokenKind.CloseParen);

            PropertyInfo targetAttributeProperty = targetAttribute.Fields.Last().Property;

            if (targetAttributeProperty.Name == nameof(Identifiable.Id))
            {
                for (int index = 0; index < constants.Count; index++)
                {
                    string stringId = constants[index].Value;
                    string id       = DeObfuscateStringId(targetAttributeProperty.ReflectedType, stringId);
                    constants[index] = new LiteralConstantExpression(id);
                }
            }

            return(new EqualsAnyOfExpression(targetAttribute, constants));
        }
Esempio n. 21
0
        private void ReadSingleValue(string parameterName, string parameterValue)
        {
            try
            {
                if (_options.EnableLegacyFilterNotation)
                {
                    (parameterName, parameterValue) = _legacyConverter.Convert(parameterName, parameterValue);
                }

                ResourceFieldChainExpression scope  = GetScope(parameterName);
                FilterExpression             filter = GetFilter(parameterValue, scope);

                StoreFilterInScope(filter, scope);
            }
            catch (QueryParseException exception)
            {
                throw new InvalidQueryStringParameterException(_lastParameterName, "The specified filter is invalid.", exception.Message, exception);
            }
        }
Esempio n. 22
0
        protected CollectionNotEmptyExpression ParseHas()
        {
            EatText(Keywords.Has);
            EatSingleCharacterToken(TokenKind.OpenParen);

            ResourceFieldChainExpression targetCollection = ParseFieldChain(FieldChainRequirements.EndsInToMany, null);
            FilterExpression             filter           = null;

            if (TokenStack.TryPeek(out Token nextToken) && nextToken.Kind == TokenKind.Comma)
            {
                EatSingleCharacterToken(TokenKind.Comma);

                filter = ParseFilterInHas((HasManyAttribute)targetCollection.Fields.Last());
            }

            EatSingleCharacterToken(TokenKind.CloseParen);

            return(new CollectionNotEmptyExpression(targetCollection, filter));
        }
        protected SparseFieldSetExpression ParseSparseFieldSet()
        {
            var attributes = new Dictionary <string, AttrAttribute>();

            ResourceFieldChainExpression nextChain = ParseFieldChain(FieldChainRequirements.EndsInAttribute, "Attribute name expected.");
            AttrAttribute nextAttribute            = nextChain.Fields.Cast <AttrAttribute>().Single();

            attributes[nextAttribute.PublicName] = nextAttribute;

            while (TokenStack.Any())
            {
                EatSingleCharacterToken(TokenKind.Comma);

                nextChain     = ParseFieldChain(FieldChainRequirements.EndsInAttribute, "Attribute name expected.");
                nextAttribute = nextChain.Fields.Cast <AttrAttribute>().Single();
                attributes[nextAttribute.PublicName] = nextAttribute;
            }

            return(new SparseFieldSetExpression(attributes.Values));
        }
Esempio n. 24
0
        protected QueryStringParameterScopeExpression ParseQueryStringParameterScope()
        {
            if (!TokenStack.TryPop(out Token token) || token.Kind != TokenKind.Text)
            {
                throw new QueryParseException("Parameter name expected.");
            }

            var name = new LiteralConstantExpression(token.Value);

            ResourceFieldChainExpression scope = null;

            if (TokenStack.TryPeek(out Token nextToken) && nextToken.Kind == TokenKind.OpenBracket)
            {
                TokenStack.Pop();

                scope = ParseFieldChain(_chainRequirements, null);

                EatSingleCharacterToken(TokenKind.CloseBracket);
            }

            return(new QueryStringParameterScopeExpression(name, scope));
        }
        protected PaginationElementQueryStringValueExpression ParsePaginationElement()
        {
            int?number = TryParseNumber();

            if (number != null)
            {
                return(new PaginationElementQueryStringValueExpression(null, number.Value));
            }

            ResourceFieldChainExpression scope = ParseFieldChain(FieldChainRequirements.EndsInToMany, "Number or relationship name expected.");

            EatSingleCharacterToken(TokenKind.Colon);

            number = TryParseNumber();

            if (number == null)
            {
                throw new QueryParseException("Number expected.");
            }

            return(new PaginationElementQueryStringValueExpression(scope, number.Value));
        }
Esempio n. 26
0
        public override QueryExpression VisitSort(SortExpression expression, object argument)
        {
            var newSortElements = new List <SortElementExpression>();

            foreach (SortElementExpression sortElement in expression.Elements)
            {
                if (IsSortOnCarId(sortElement))
                {
                    ResourceFieldChainExpression regionIdSort = ReplaceLastAttributeInChain(sortElement.TargetAttribute, _regionIdAttribute);
                    newSortElements.Add(new SortElementExpression(regionIdSort, sortElement.IsAscending));

                    ResourceFieldChainExpression licensePlateSort = ReplaceLastAttributeInChain(sortElement.TargetAttribute, _licensePlateAttribute);
                    newSortElements.Add(new SortElementExpression(licensePlateSort, sortElement.IsAscending));
                }
                else
                {
                    newSortElements.Add(sortElement);
                }
            }

            return(new SortExpression(newSortElements));
        }
Esempio n. 27
0
        protected SortElementExpression ParseSortElement()
        {
            bool isAscending = true;

            if (TokenStack.TryPeek(out Token nextToken) && nextToken.Kind == TokenKind.Minus)
            {
                TokenStack.Pop();
                isAscending = false;
            }

            CountExpression count = TryParseCount();

            if (count != null)
            {
                return(new SortElementExpression(count, isAscending));
            }

            var errorMessage = isAscending ? "-, count function or field name expected." : "Count function or field name expected.";
            ResourceFieldChainExpression targetAttribute = ParseFieldChain(FieldChainRequirements.EndsInAttribute, errorMessage);

            return(new SortElementExpression(targetAttribute, isAscending));
        }
        public override FilterExpression OnApplyFilter(FilterExpression existingFilter)
        {
            if (_request.IsReadOnly)
            {
                // Rule: hide archived broadcasts in collections, unless a filter is specified.

                if (IsReturningCollectionOfTelevisionBroadcasts() && !HasFilterOnArchivedAt(existingFilter))
                {
                    AttrAttribute archivedAtAttribute = ResourceContext.Attributes.Single(attr => attr.Property.Name == nameof(TelevisionBroadcast.ArchivedAt));

                    var archivedAtChain = new ResourceFieldChainExpression(archivedAtAttribute);

                    FilterExpression isUnarchived = new ComparisonExpression(ComparisonOperator.Equals, archivedAtChain, new NullConstantExpression());

                    return(existingFilter == null
                        ? isUnarchived
                        : new LogicalExpression(LogicalOperator.And, ArrayFactory.Create(existingFilter, isUnarchived)));
                }
            }

            return(base.OnApplyFilter(existingFilter));
        }
 public override Expression VisitResourceFieldChain(ResourceFieldChainExpression expression, TArgument argument)
 {
     return(CreatePropertyExpressionForFieldChain(expression.Fields, LambdaScope.Accessor));
 }
        private SortExpression GetSort(string parameterValue, ResourceFieldChainExpression scope)
        {
            ResourceContext resourceContextInScope = GetResourceContextForScope(scope);

            return(_sortParser.Parse(parameterValue, resourceContextInScope));
        }