Пример #1
0
        public bool Enter(
            FilterOperationField field,
            ObjectFieldNode node,
            IQueryableFilterVisitorContext context,
            out ISyntaxVisitorAction action)
        {
            if (field.Operation.Kind == FilterOperationKind.ArraySome ||
                field.Operation.Kind == FilterOperationKind.ArrayNone ||
                field.Operation.Kind == FilterOperationKind.ArrayAll)
            {
                MemberExpression nestedProperty = Expression.Property(
                    context.GetInstance(),
                    field.Operation.Property);

                context.PushInstance(nestedProperty);

                Type closureType = GetTypeFor(field.Operation);

                context.AddClosure(closureType);
                action = SyntaxVisitor.Continue;
                return(true);
            }
            action = SyntaxVisitor.Skip;
            return(false);
        }
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            out Expression expression)
        {
            if (operation.Type == typeof(string) &&
                type.IsInstanceOfType(value))
            {
                object parsedValue = type.ParseLiteral(value);

                Expression property = context.GetInstance();

                if (!operation.IsSimpleArrayType())
                {
                    property = Expression.Property(
                        context.GetInstance(), operation.Property);
                }

                return(TryCreateExpression(
                           operation,
                           property,
                           parsedValue,
                           out expression));
            }

            expression = null;
            return(false);
        }
Пример #3
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            [NotNullWhen(true)] out Expression?expression)
        {
            if (operation.Type == typeof(bool) && type.IsInstanceOfType(value))
            {
                Expression property = context.GetInstance();

                if (!operation.IsSimpleArrayType())
                {
                    property = Expression.Property(context.GetInstance(), operation.Property);
                }

                object parserValue = type.ParseLiteral(value);

                switch (operation.Kind)
                {
                case FilterOperationKind.Equals:
                    expression = FilterExpressionBuilder.Equals(
                        property, parserValue);
                    return(true);

                case FilterOperationKind.NotEquals:
                    expression = FilterExpressionBuilder.NotEquals(
                        property, parserValue);
                    return(true);
                }
            }

            expression = null;
            return(false);
        }
        public static bool EndsWith(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            [NotNullWhen(true)] out Expression?result)
        {
            object parsedValue = type.ParseLiteral(value);

            if (parsedValue == null)
            {
                context.ReportError(
                    ErrorHelper.CreateNonNullError(operation, type, value, context));

                result = null;
                return(false);
            }

            if (operation.Type == typeof(string) &&
                type.IsInstanceOfType(value))
            {
                Expression property = GetProperty(operation, context);

                result = FilterExpressionBuilder.EndsWith(property, parsedValue);
                return(true);
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
Пример #5
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            [NotNullWhen(true)] out Expression?expression)
        {
            if (operation.Type == typeof(IComparable) &&
                type.IsInstanceOfType(value))
            {
                Expression property = context.GetInstance();

                if (!operation.IsSimpleArrayType())
                {
                    property = Expression.Property(context.GetInstance(), operation.Property);
                }

                if (operation.Kind == FilterOperationKind.In)
                {
                    expression = FilterExpressionBuilder.In(
                        property,
                        operation.Property.PropertyType,
                        ParseValue());
                    return(true);
                }

                if (operation.Kind == FilterOperationKind.NotIn)
                {
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.In(
                            property,
                            operation.Property.PropertyType,
                            ParseValue()));
                    return(true);
                }
            }

            expression = null;
            return(false);

            object ParseValue()
            {
                var  parsedValue = type.ParseLiteral(value);
                Type elementType = type.ElementType().ToRuntimeType();

                if (operation.Property.PropertyType != elementType)
                {
                    Type listType = typeof(List <>).MakeGenericType(
                        operation.Property.PropertyType);

                    parsedValue = context.TypeConverter.Convert(
                        typeof(object),
                        listType,
                        parsedValue);
                }

                return(parsedValue);
            }
        }
Пример #6
0
        public void Leave(
            FilterOperationField field,
            ObjectFieldNode node,
            IQueryableFilterVisitorContext context)
        {
            if (field.Operation.Kind == FilterOperationKind.ArraySome ||
                field.Operation.Kind == FilterOperationKind.ArrayNone ||
                field.Operation.Kind == FilterOperationKind.ArrayAll)
            {
                QueryableClosure nestedClosure = context.PopClosure();
                LambdaExpression lambda        = nestedClosure.CreateLambda();
                Type             closureType   = GetTypeFor(field.Operation);

                Expression expression;
                switch (field.Operation.Kind)
                {
                case FilterOperationKind.ArraySome:
                    expression = FilterExpressionBuilder.Any(
                        closureType,
                        context.GetInstance(),
                        lambda
                        );
                    break;

                case FilterOperationKind.ArrayNone:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.Any(
                            closureType,
                            context.GetInstance(),
                            lambda
                            )
                        );
                    break;

                case FilterOperationKind.ArrayAll:
                    expression = FilterExpressionBuilder.All(
                        closureType,
                        context.GetInstance(),
                        lambda
                        );
                    break;

                default:
                    throw new NotSupportedException();
                }

                if (context.InMemory)
                {
                    expression = FilterExpressionBuilder.NotNullAndAlso(
                        context.GetInstance(), expression);
                }

                context.GetLevel().Enqueue(expression);
                context.PopInstance();
            }
        }
        public static QueryableClosure AddIsNullClosure(
            this IQueryableFilterVisitorContext context,
            Type type)
        {
            QueryableClosure closure =
                context.AddClosure(type, "_s" + context.Closures.Count, false);

            context.GetLevel().Enqueue(FilterExpressionBuilder.Equals(closure.Parameter, null));
            return(closure);
        }
        public static QueryableClosure AddClosure(
            this IQueryableFilterVisitorContext context,
            Type type,
            string parameterName,
            bool inMemory)
        {
            var closure = new QueryableClosure(type, parameterName, inMemory);

            context.Closures.Push(closure);
            return(closure);
        }
        private static Expression GetProperty(
            FilterOperation operation,
            IQueryableFilterVisitorContext context)
        {
            Expression property = context.GetInstance();

            if (!operation.IsSimpleArrayType())
            {
                property = Expression.Property(context.GetInstance(), operation.Property);
            }
            return(property);
        }
Пример #10
0
        public void FilterFieldLeave(
            FilterOperationField field,
            ObjectFieldNode node,
            IQueryableFilterVisitorContext context)
        {
            if (fieldLeaveHandler == null)
            {
                throw new InvalidOperationException();
            }

            fieldLeaveCallCounter++;
            fieldLeaveHandler(field, node, context);
        }
Пример #11
0
        public bool FilterFieldEnter(
            FilterOperationField field,
            ObjectFieldNode node,
            IQueryableFilterVisitorContext context,
            out ISyntaxVisitorAction action)
        {
            if (fieldEnterHandler == null)
            {
                throw new InvalidOperationException();
            }

            fieldEnterCallCounter++;
            return(fieldEnterHandler(field, node, context, out action));
        }
Пример #12
0
        public bool FilterOperationHandler(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            out Expression?result)
        {
            if (filterOperationHandler == null)
            {
                throw new InvalidOperationException();
            }

            filterOperationCallCounter++;
            return(filterOperationHandler(operation, type, value, context, out result));
        }
Пример #13
0
 public bool Enter(
     FilterOperationField field,
     ObjectFieldNode node,
     IQueryableFilterVisitorContext context,
     out ISyntaxVisitorAction action)
 {
     if (field.Operation.Kind == FilterOperationKind.Object)
     {
         MemberExpression nestedProperty = Expression.Property(
             context.GetInstance(),
             field.Operation.Property);
         context.PushInstance(nestedProperty);
         action = SyntaxVisitor.Continue;
         return(true);
     }
     action = SyntaxVisitor.SkipAndLeave;
     return(false);
 }
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            [NotNullWhen(true)] out Expression?expression)
        {
            if (operation.Kind == FilterOperationKind.ArrayAny &&
                type.IsInstanceOfType(value) &&
                context.InputParser.ParseLiteral(value, type) is bool parsedValue)
            {
                MemberExpression property =
                    Expression.Property(context.GetInstance(), operation.Property);
                Type propertyType = operation.Type;

                if (operation.TryGetSimpleFilterBaseType(out Type? baseType))
                {
                    propertyType = baseType;
                }

                if (parsedValue)
                {
                    expression = FilterExpressionBuilder.Any(
                        propertyType,
                        property);
                }
                else
                {
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.Any(
                            propertyType,
                            property));
                }
                if (context.InMemory)
                {
                    expression =
                        FilterExpressionBuilder.NotNullAndAlso(property, expression);
                }
                return(true);
            }
            expression = null;
            return(false);
        }
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            [NotNullWhen(true)] out Expression?expression)
        {
            if (operation.Type == typeof(string) && type.IsInstanceOfType(value))
            {
                Expression property = context.GetInstance();

                if (!operation.IsSimpleArrayType())
                {
                    property = Expression.Property(
                        context.GetInstance(), operation.Property);
                }

                object?parsedValue = type.ParseLiteral(value);

                if (operation.Kind == FilterOperationKind.In)
                {
                    expression = FilterExpressionBuilder.In(
                        property,
                        operation.Property.PropertyType,
                        parsedValue);
                    return(true);
                }

                if (operation.Kind == FilterOperationKind.NotIn)
                {
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.In(
                            property,
                            operation.Property.PropertyType,
                            parsedValue));
                    return(true);
                }
            }

            expression = null;
            return(false);
        }
Пример #16
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            [NotNullWhen(true)] out Expression?expression)
        {
            if (operation.Type == typeof(IComparable) &&
                type.IsInstanceOfType(value))
            {
                Expression property = context.GetInstance();

                if (!operation.IsSimpleArrayType())
                {
                    property = Expression.Property(context.GetInstance(), operation.Property);
                }

                return(TryCreateExpression(
                           operation,
                           property,
                           ParseValue,
                           out expression));
            }

            expression = null;
            return(false);

            object ParseValue()
            {
                var parsedValue = type.ParseLiteral(value);

                if (!operation.Property.PropertyType.IsInstanceOfType(parsedValue))
                {
                    parsedValue = context.TypeConverter.Convert(
                        typeof(object),
                        operation.Property.PropertyType,
                        parsedValue);
                }

                return(parsedValue);
            }
        }
Пример #17
0
        public static bool Enter(
            FilterOperationField field,
            ObjectFieldNode node,
            IQueryableFilterVisitorContext context,
            [NotNullWhen(true)] out ISyntaxVisitorAction?action)
        {
            if (node.Value.IsNull())
            {
                if (field.Operation.IsNullable)
                {
                    MemberExpression nestedProperty = Expression.Property(
                        context.GetInstance(),
                        field.Operation.Property);

                    Expression expression =
                        FilterExpressionBuilder.Equals(nestedProperty, null !);

                    context.GetLevel().Enqueue(expression);
                }
                else
                {
                    context.ReportError(
                        ErrorHelper.CreateNonNullError(field, node, context));
                }

                action = SyntaxVisitor.Skip;
                return(true);
            }

            if (field.Operation.Kind == FilterOperationKind.Object)
            {
                MemberExpression nestedProperty = Expression.Property(
                    context.GetInstance(),
                    field.Operation.Property);

                context.PushInstance(nestedProperty);
                action = SyntaxVisitor.Continue;
                return(true);
            }
            action = null;
            return(false);
        }
Пример #18
0
        public static bool Enter(
            FilterOperationField field,
            ObjectFieldNode node,
            IQueryableFilterVisitorContext context,
            [NotNullWhen(true)] out ISyntaxVisitorAction?action)
        {
            if (field.Operation.Kind == FilterOperationKind.ArraySome ||
                field.Operation.Kind == FilterOperationKind.ArrayNone ||
                field.Operation.Kind == FilterOperationKind.ArrayAll)
            {
                if (!field.Operation.IsNullable && node.Value.IsNull())
                {
                    context.ReportError(
                        ErrorHelper.CreateNonNullError(field, node, context));

                    action = SyntaxVisitor.Skip;
                    return(true);
                }

                MemberExpression nestedProperty = Expression.Property(
                    context.GetInstance(),
                    field.Operation.Property);

                context.PushInstance(nestedProperty);

                Type closureType = GetTypeFor(field.Operation);

                if (node.Value.IsNull())
                {
                    context.AddIsNullClosure(closureType);
                    action = SyntaxVisitor.SkipAndLeave;
                }
                else
                {
                    context.AddClosure(closureType);
                    action = SyntaxVisitor.Continue;
                }
                return(true);
            }
            action = null;
            return(false);
        }
Пример #19
0
        public static IError CreateNonNullError(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context)
        {
            IFilterInputType filterType = context.Types.OfType <IFilterInputType>().First();

            return(ErrorBuilder.New()
                   .SetMessage(
                       "The provided value for filter `{0}` of type {1} is invalid. " +
                       "Null values are not supported.",
                       context.Operations.Peek().Name,
                       filterType.Visualize())
                   .AddLocation(value)
                   .SetExtension("expectedType", new NonNullType(type).Visualize())
                   .SetExtension("filterKind", operation.FilterKind)
                   .SetExtension("operationKind", operation.Kind)
                   .SetExtension("filterType", filterType.Visualize())
                   .Build());
        }
Пример #20
0
        public static void Leave(
            FilterOperationField field,
            ObjectFieldNode node,
            IQueryableFilterVisitorContext context)
        {
            if (field.Operation.Kind == FilterOperationKind.Object)
            {
                // Deque last expression to prefix with nullcheck
                Expression condition = context.GetLevel().Dequeue();
                Expression property  = context.GetInstance();

                // wrap last expression only if  in memory
                if (context.InMemory)
                {
                    condition = FilterExpressionBuilder.NotNullAndAlso(
                        property, condition);
                }

                context.GetLevel().Enqueue(condition);
                context.PopInstance();
            }
        }
Пример #21
0
        public static bool NotEquals(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,

            [NotNullWhen(true)] out Expression?result)
        {
            object parsedValue = type.ParseLiteral(value);

            if (parsedValue == null)
            {
                context.ReportError(
                    ErrorHelper.CreateNonNullError(operation, type, value, context));

                result = null;
                return(false);
            }

            if (operation.Type == typeof(bool) &&
                type.IsInstanceOfType(value) &&
                parsedValue is bool)
            {
                Expression property = context.GetInstance();

                if (!operation.IsSimpleArrayType())
                {
                    property = Expression.Property(context.GetInstance(), operation.Property);
                }

                result = FilterExpressionBuilder.NotEquals(property, parsedValue);
                return(true);
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
Пример #22
0
        private static object ParseValue(
            object parsedValue,
            FilterOperation operation,
            IInputType type,
            IQueryableFilterVisitorContext context)
        {
            if (type.IsListType())
            {
                Type elementType = type.ElementType().ToClrType();

                if (operation.Property.PropertyType != elementType)
                {
                    Type listType = typeof(List <>).MakeGenericType(
                        operation.Property.PropertyType);

                    parsedValue = context.TypeConverter.Convert(
                        typeof(object),
                        listType,
                        parsedValue);
                }

                return(parsedValue);
            }
            else
            {
                if (!operation.Property.PropertyType.IsInstanceOfType(parsedValue))
                {
                    parsedValue = context.TypeConverter.Convert(
                        typeof(object),
                        operation.Property.PropertyType,
                        parsedValue);
                }

                return(parsedValue);
            }
        }
 public static void PushLevel(
     this IQueryableFilterVisitorContext context, Queue <Expression> nextLevel)
 => context.Closures.Peek().Level.Push(nextLevel);
 public static Expression PopInstance(
     this IQueryableFilterVisitorContext context)
 => context.Closures.Peek().Instance.Pop();
 public static void PushInstance(
     this IQueryableFilterVisitorContext context, Expression nextExpression)
 => context.Closures.Peek().Instance.Push(nextExpression);
 public static Queue <Expression> PopLevel(
     this IQueryableFilterVisitorContext context)
 => context.Closures.Peek().Level.Pop();
 public static QueryableClosure PopClosure(
     this IQueryableFilterVisitorContext context)
 => context.Closures.Pop();
 public static Expression <Func <TSource, bool> > CreateFilter <TSource>(
     this IQueryableFilterVisitorContext context)
 => context.GetClosure().CreateLambda <Func <TSource, bool> >();
 public static Expression CreateFilter(
     this IQueryableFilterVisitorContext context)
 => context.GetClosure().CreateLambda();
 public static QueryableClosure AddClosure(
     this IQueryableFilterVisitorContext context,
     Type type)
 => context.AddClosure(type, "_s" + context.Closures.Count, context.InMemory);