public static Expression CreateFilterExpression(Type type, InvocationQuerySyntaxNode node)
        {
            var visitor    = new ExpressionFilterQuerySyntaxVisitor(type);
            var filterBody = visitor.Visit(node);

            return(Expression.Lambda(filterBody, visitor.Parameter));
        }
Beispiel #2
0
        public static Expression CreateSelectExpression(Type type, InvocationQuerySyntaxNode node)
        {
            var visitor    = new ExpressionSelectQuerySyntaxVisitor(type);
            var selectBody = visitor.Visit(node);

            return(Expression.Lambda(selectBody, visitor.Parameter));
        }
        /// <summary>
        /// Возвращает набор функций сортировки документов.
        /// </summary>
        protected IEnumerable <InvocationQuerySyntaxNode> ParseOrder(IHttpRequest request)
        {
            var parameter = GetQueryParameter(request, QuerySyntaxHelper.OrderParameterName);

            if (parameter != null)
            {
                var syntaxNodes = _syntaxTreeParser.Parse(parameter);

                if (syntaxNodes != null && syntaxNodes.Count > 0)
                {
                    foreach (var node in syntaxNodes)
                    {
                        var invocationNode = node as InvocationQuerySyntaxNode;

                        if (invocationNode != null)
                        {
                            yield return(invocationNode);
                        }
                        else
                        {
                            // По умолчанию перечисление полей объединяется методом asc()
                            var asc = new InvocationQuerySyntaxNode(QuerySyntaxHelper.AscMethodName);
                            asc.Arguments.Add(node);
                            yield return(asc);
                        }
                    }
                }
            }
        }
        public static Action <IDocumentProjectionBuilder> CreateSelectExpression(InvocationQuerySyntaxNode node)
        {
            var visitor    = new FuncSelectQuerySyntaxVisitor();
            var selectBody = visitor.Visit(node);

            return(selectBody);
        }
Beispiel #5
0
        public static Func <IDocumentFilterBuilder, object> CreateFilterExpression(InvocationQuerySyntaxNode node)
        {
            var visitor    = new FuncFilterQuerySyntaxVisitor();
            var filterBody = visitor.Visit(node);

            return(filterBody);
        }
Beispiel #6
0
        // Overrides

        public override Expression VisitInvocationExpression(InvocationQuerySyntaxNode node)
        {
            if (!string.Equals(node.Name, QuerySyntaxHelper.IncludeMethodName, StringComparison.OrdinalIgnoreCase))
            {
                return(base.VisitInvocationExpression(node));
            }

            return(QuerySyntaxHelper.Projection(node.Arguments.Select(Visit)));
        }
        // Overrides

        public override Expression VisitInvocationExpression(InvocationQuerySyntaxNode node)
        {
            Func <ExpressionFilterQuerySyntaxVisitor, InvocationQuerySyntaxNode, Expression> factory;

            if (!KnownFunctions.TryGetValue(node.Name, out factory))
            {
                return(base.VisitInvocationExpression(node));
            }

            return(factory(this, node));
        }
        /// <summary>
        /// Возвращает функцию фильтрации документов.
        /// </summary>
        protected InvocationQuerySyntaxNode ParseFilter(IHttpRequest request, string documentIdKey)
        {
            InvocationQuerySyntaxNode filter = null;

            // Если определен фильтр по идентификатору документа
            var documentId = GetRequestParameter(request, documentIdKey);

            if (!string.IsNullOrEmpty(documentId))
            {
                filter = new InvocationQuerySyntaxNode(QuerySyntaxHelper.EqMethodName);
                filter.Arguments.Add(new IdentifierNameQuerySyntaxNode("_id"));
                filter.Arguments.Add(new LiteralQuerySyntaxNode(documentId));
            }
            // Если определено условие фильтрации
            else
            {
                var documentQuery = GetQueryParameter(request, QuerySyntaxHelper.FilterParameterName);

                if (documentQuery != null)
                {
                    var syntaxNodes = _syntaxTreeParser.Parse(documentQuery);

                    if (syntaxNodes != null && syntaxNodes.Count > 0)
                    {
                        if (syntaxNodes.Count == 1)
                        {
                            return(syntaxNodes[0] as InvocationQuerySyntaxNode);
                        }

                        // По умолчанию все условия объединяются методом and()
                        var and = new InvocationQuerySyntaxNode(QuerySyntaxHelper.AndMethodName);
                        and.Arguments.AddRange(syntaxNodes);
                        return(and);
                    }
                }
            }

            return(filter);
        }
Beispiel #9
0
        // Overrides

        public override Expression VisitInvocationExpression(InvocationQuerySyntaxNode node)
        {
            if (string.Equals(node.Name, QuerySyntaxHelper.AscMethodName, StringComparison.OrdinalIgnoreCase))
            {
                var ascProperties = node.Arguments.Select(Visit)
                                    .OfType <MemberExpression>()
                                    .Select(i => new KeyValuePair <Expression, DocumentSortOrder>(Expression.Lambda(QuerySyntaxHelper.Convert(i, typeof(object)), Parameter), DocumentSortOrder.Asc))
                                    .ToArray();

                return(Expression.Constant(ascProperties));
            }

            if (string.Equals(node.Name, QuerySyntaxHelper.DescMethodName, StringComparison.OrdinalIgnoreCase))
            {
                var descProperties = node.Arguments.Select(Visit)
                                     .OfType <MemberExpression>()
                                     .Select(i => new KeyValuePair <Expression, DocumentSortOrder>(Expression.Lambda(QuerySyntaxHelper.Convert(i, typeof(object)), Parameter), DocumentSortOrder.Desc))
                                     .ToArray();

                return(Expression.Constant(descProperties));
            }

            return(base.VisitInvocationExpression(node));
        }
        private static Expression CreateSizeFilterForArrayProperty(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node, Func <Expression, Expression, Expression> filter)
        {
            // filter(arrayProperty, value) --> filter(Enumerable.Count(i.arrayProperty), value)
            var arrayProperty = visitor.Visit(node.Arguments[0]);
            var value         = visitor.Visit(node.Arguments[1]);
            var itemType      = QuerySyntaxHelper.GetCollectionItemType(arrayProperty.Type);

            return(QuerySyntaxHelper.Compare(QuerySyntaxHelper.InvokeCount(itemType, arrayProperty), value, filter));
        }
 private static Expression NotInInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
 {
     // notIn(property, value1, value2, value3, ...) --> !Enumerable.Contains(new[] { value1, value2, value3, ... }, i.property)
     return(Expression.Not(InInvocation(visitor, node)));
 }
        // Helpers

        private static Expression CreateFilterForArrayProperty(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node, Func <Type, Expression, Expression, Expression> filter)
        {
            // filter(arrayProperty, item1, item2, item3, ...) --> filter(new[] { item1, item2, item3, ... }, ii => Enumerable.Contains(i.arrayProperty, ii))
            var arrayProperty = visitor.Visit(node.Arguments[0]);
            var itemType      = QuerySyntaxHelper.GetCollectionItemType(arrayProperty.Type);
            var items         = QuerySyntaxHelper.NewArray(itemType, node.Arguments.Skip(1).Select(visitor.Visit));
            var itemParameter = Expression.Parameter(itemType);
            var itemFilter    = QuerySyntaxHelper.InvokeContains(itemType, arrayProperty, itemParameter);

            return(filter(itemType, items, Expression.Lambda(itemFilter, itemParameter)));
        }
        private static Expression CreateAnyFilterForArrayProperty(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node, Func <Expression, Expression, Expression> filter)
        {
            // filter(arrayProperty, item) --> Enumerable.Any(i.arrayProperty, ii => filter(ii, item))
            var arrayProperty = visitor.Visit(node.Arguments[0]);
            var item          = visitor.Visit(node.Arguments[1]);
            var itemType      = QuerySyntaxHelper.GetCollectionItemType(arrayProperty.Type);
            var itemParameter = Expression.Parameter(itemType);

            return(QuerySyntaxHelper.InvokeAny(itemType, arrayProperty, Expression.Lambda(QuerySyntaxHelper.Compare(itemParameter, item, filter), itemParameter)));
        }
Beispiel #14
0
        public static IEnumerable <KeyValuePair <Expression, DocumentSortOrder> > CreateOrderExpression(Type type, InvocationQuerySyntaxNode node)
        {
            var visitor         = new ExpressionOrderQuerySyntaxVisitor(type);
            var orderProperties = (ConstantExpression)visitor.Visit(node);

            return((IEnumerable <KeyValuePair <Expression, DocumentSortOrder> >)orderProperties.Value);
        }
        private static Expression RegexInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
        {
            // regex(property, pattern, 'option1', 'option2', 'option3', ...) --> Regex.IsMatch(i.property, pattern, option1 | option2 | option3 | ...)
            var property = visitor.Visit(node.Arguments[0]);
            var pattern  = visitor.Visit(node.Arguments[1]);
            var options  = Expression.Constant(node.Arguments.Skip(2).Aggregate(RegexOptions.None, (r, n) => r | n.AsEnumIdentifier <RegexOptions>()));

            return(QuerySyntaxHelper.InvokeRegex(property, pattern, options));
        }
 private static Expression AnyLteInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
 {
     // anyLte(arrayProperty, item) --> Enumerable.Any(i.arrayProperty, ii => ii <= item)
     return(CreateAnyFilterForArrayProperty(visitor, node, Expression.LessThanOrEqual));
 }
        private static Expression OrInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
        {
            // or(condition1, condition2, condition3, ...) --> (((condition1 || condition2) || condition3) || ...)

            Expression result = null;

            var conditions = node.Arguments.Select(visitor.Visit);

            foreach (var condition in conditions)
            {
                result = (result != null)
                    ? Expression.OrElse(result, condition)
                    : condition;
            }

            return(result);
        }
 private static Expression AnyNotEqInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
 {
     // anyNotEq(arrayProperty, item) --> !Enumerable.Any(i.arrayProperty, ii => ii == item)
     return(Expression.Not(AnyEqInvocation(visitor, node)));
 }
        private static Expression GtInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
        {
            // gt(property, value) --> i.property > value
            var property = visitor.Visit(node.Arguments[0]);
            var value    = visitor.Visit(node.Arguments[1]);

            return(QuerySyntaxHelper.Compare(property, value, Expression.GreaterThan));
        }
 private static Expression AnyNotInInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
 {
     // anyNotIn(arrayProperty, item1, item2, item3, ...) --> !Enumerable.Any(new[] { item1, item2, item3, ... }, ii => Enumerable.Contains(i.arrayProperty, ii))
     return(Expression.Not(AnyInInvocation(visitor, node)));
 }
 private static Expression AnyInInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
 {
     // anyIn(arrayProperty, item1, item2, item3, ...) --> Enumerable.Any(new[] { item1, item2, item3, ... }, ii => Enumerable.Contains(i.arrayProperty, ii))
     return(CreateFilterForArrayProperty(visitor, node, QuerySyntaxHelper.InvokeAny));
 }
        private static Expression MatchInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
        {
            // match(arrayProperty, filter) --> Enumerable.Any(i.arrayProperty, ii => filter(ii))
            var arrayProperty = visitor.Visit(node.Arguments[0]);
            var itemType      = QuerySyntaxHelper.GetCollectionItemType(arrayProperty.Type);
            var itemFilter    = CreateFilterExpression(itemType, (InvocationQuerySyntaxNode)node.Arguments[1]);

            return(QuerySyntaxHelper.InvokeAny(itemType, arrayProperty, itemFilter));
        }
        private static Expression InInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
        {
            // in(property, value1, value2, value3, ...) --> Enumerable.Contains(new[] { value1, value2, value3, ... }, i.property)
            var property = visitor.Visit(node.Arguments[0]);
            var values   = QuerySyntaxHelper.NewArray(property.Type, node.Arguments.Skip(1).Select(visitor.Visit));

            return(QuerySyntaxHelper.InvokeContains(property.Type, values, property));
        }
 private static Expression SizeGtInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
 {
     // sizeGt(arrayProperty, value) --> Enumerable.Count(i.arrayProperty) > value
     return(CreateSizeFilterForArrayProperty(visitor, node, Expression.GreaterThan));
 }
        // KnownFunctions

        private static Expression NotInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
        {
            // not(condition) --> !condition
            var condition = visitor.Visit(node.Arguments[0]);

            return(Expression.Not(condition));
        }
 private static Expression SizeLteInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
 {
     // sizeLte(arrayProperty, value) --> Enumerable.Count(i.arrayProperty) <= value
     return(CreateSizeFilterForArrayProperty(visitor, node, Expression.LessThanOrEqual));
 }
 /// <summary>
 /// Обрабатывает вызов метода.
 /// </summary>
 public virtual TResult VisitInvocationExpression(InvocationQuerySyntaxNode node)
 {
     return(DefaultVisit(node));
 }
        private static Expression DateInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
        {
            // date('value') --> DateTime.Parse('value')
            var dateTimeString = node.Arguments[0].AsStringLiteral();
            var dateTime       = DateTime.Parse(dateTimeString);

            return(Expression.Constant(dateTime));
        }
 private static Expression AnyGtInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
 {
     // anyGt(arrayProperty, item) --> Enumerable.Any(i.arrayProperty, ii => ii > item)
     return(CreateAnyFilterForArrayProperty(visitor, node, Expression.GreaterThan));
 }
        private static Expression LteInvocation(ExpressionFilterQuerySyntaxVisitor visitor, InvocationQuerySyntaxNode node)
        {
            // lte(property, value) --> i.property <= value
            var property = visitor.Visit(node.Arguments[0]);
            var value    = visitor.Visit(node.Arguments[1]);

            return(QuerySyntaxHelper.Compare(property, value, Expression.LessThanOrEqual));
        }