예제 #1
0
        private static object ParseObjectType(
            InputObjectType sourceType,
            Type targetType,
            IValueNode literal)
        {
            if (literal.IsNull())
            {
                return(null);
            }

            Dictionary <string, IValueNode> fieldValues =
                ((ObjectValueNode)literal).Fields
                .ToDictionary(t => t.Name.Value, t => t.Value);

            ILookup <string, PropertyInfo> properties =
                targetType.GetProperties()
                .ToLookup(t => t.Name, StringComparer.OrdinalIgnoreCase);

            object obj = Activator.CreateInstance(targetType);

            foreach (InputField field in sourceType.Fields)
            {
                PropertyInfo property = properties[field.Name].FirstOrDefault();
                if (property != null)
                {
                    SetProperty(field, fieldValues, obj, property);
                }
            }

            return(obj);
        }
예제 #2
0
        public override FieldMiddleware CreateExecutor <TEntityType>(NameString argumentName)
        {
            return(next => context => ExecuteAsync(next, context));

            async ValueTask ExecuteAsync(
                FieldDelegate next,
                IMiddlewareContext context)
            {
                // first we let the pipeline run and produce a result.
                await next(context).ConfigureAwait(false);

                // next we get the filter argument.
                IInputField argument = context.Field.Arguments[argumentName];
                IValueNode  filter   = context.ArgumentLiteral <IValueNode>(argumentName);

                // if no filter is defined we can stop here and yield back control.
                if (filter.IsNull())
                {
                    return;
                }

                IQueryable <TEntityType>?source = null;

                if (context.Result is IQueryable <TEntityType> q)
                {
                    source = q;
                }
                else if (context.Result is IEnumerable <TEntityType> e)
                {
                    source = e.AsQueryable();
                }

                if (source != null && argument.Type is IFilterInputType filterInput)
                {
                    var visitorContext = new QueryableFilterContext(
                        filterInput, source is EnumerableQuery);

                    // rewrite GraphQL input object into expression tree.
                    Visitor.Visit(filter, visitorContext);

                    // compile expression tree
                    if (visitorContext.TryCreateLambda(
                            out Expression <Func <TEntityType, bool> >?where))
                    {
                        context.Result = source.Where(where);
                    }
                    else
                    {
                        if (visitorContext.Errors.Count > 0)
                        {
                            context.Result = Array.Empty <TEntityType>();
                            foreach (IError error in visitorContext.Errors)
                            {
                                context.ReportError(error.WithPath(context.Path));
                            }
                        }
                    }
                }
            }
        }
예제 #3
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            Expression instance,
            ITypeConversion converter,
            out Expression expression)
        {
            if (operation.Type == typeof(string) &&
                (value is StringValueNode || value.IsNull()))
            {
                object parsedValue = type.ParseLiteral(value);

                MemberExpression property =
                    Expression.Property(instance, operation.Property);

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

            expression = null;
            return(false);
        }
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            Expression instance,
            ITypeConversion converter,
            out Expression expression)
        {
            if (operation.Type == typeof(bool) &&
                (value is BooleanValueNode || value.IsNull()))
            {
                MemberExpression property =
                    Expression.Property(instance, 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.Not(
                        FilterExpressionBuilder.Equals(
                            property, parserValue)
                        );
                    return(true);
                }
            }

            expression = null;
            return(false);
        }
 public static Report Validate(IType type, IValueNode value, Path path)
 {
     if (value.IsNull())
     {
         if (type.IsNonNullType())
         {
             return(new Report(type, path));
         }
         return(default);
        public static void IsNull_Null_True()
        {
            // arrange
            IValueNode value = default(IValueNode);

            // act
            bool result = value.IsNull();

            // assert
            Assert.True(result);
        }
예제 #7
0
 private static NonNullValidationReport CheckForNullValueViolation(
     IType type,
     IValueNode value,
     IList <object> path)
 {
     if (value.IsNull())
     {
         if (type.IsNonNullType())
         {
             return(new NonNullValidationReport(type, CreatePath(path)));
         }
         return(default);
        private static Report Validate(
            IType type,
            IValueNode value,
            Path path)
        {
            if (value.IsNull())
            {
                if (type.IsNonNullType())
                {
                    return new Report(type, path);
                }
                return default;
            }

            return ValidateInnerType(type, value, path);
        }
        public static Report Validate(
            IInputField field,
            IValueNode value,
            Path path)
        {
            if (value.IsNull())
            {
                if (field.Type.IsNonNullType()
                    && field.DefaultValue.IsNull())
                {
                    return new Report(field.Type, path);
                }
                return default;
            }

            return ValidateInnerType(field.Type, value, path);
        }
예제 #10
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            Expression instance,
            ITypeConversion converter,
            out Expression expression)
        {
            if (operation.Type == typeof(IComparable) &&
                (value is IntValueNode ||
                 value is FloatValueNode ||
                 value is EnumValueNode ||
                 value.IsNull()))
            {
                MemberExpression property =
                    Expression.Property(instance, operation.Property);
                var parsedValue = type.ParseLiteral(value);

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

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

            expression = null;
            return(false);
        }
예제 #11
0
        public override FieldMiddleware CreateExecutor <TEntityType>(NameString argumentName)
        {
            return(next => context => ExecuteAsync(next, context));

            async ValueTask ExecuteAsync(
                FieldDelegate next,
                IMiddlewareContext context)
            {
                // first we let the pipeline run and produce a result.
                await next(context).ConfigureAwait(false);

                // next we get the sort argument.
                IInputField argument = context.Field.Arguments[argumentName];
                IValueNode  sort     = context.ArgumentLiteral <IValueNode>(argumentName);

                // if no sort is defined we can stop here and yield back control.
                if (sort.IsNull() ||
                    (context.LocalContextData.TryGetValue(
                         SkipSortingKey,
                         out object?skipObject) &&
                     skipObject is bool skip &&
                     skip))
                {
                    return;
                }

                IQueryable <TEntityType>?source = null;

                if (context.Result is IQueryable <TEntityType> q)
                {
                    source = q;
                }
                else if (context.Result is IEnumerable <TEntityType> e)
                {
                    source = e.AsQueryable();
                }

                if (source != null &&
                    argument.Type is ListType lt &&
                    lt.ElementType is ISortInputType sortInput &&
                    context.Field.ContextData.TryGetValue(
                        ContextVisitSortArgumentKey,
                        out object?executorObj) &&
                    executorObj is VisitSortArgument executor)
                {
                    QueryableSortContext visitorContext = executor(
                        sort,
                        sortInput,
                        source is EnumerableQuery);

                    // compile expression tree
                    if (visitorContext.Errors.Count > 0)
                    {
                        context.Result = Array.Empty <TEntityType>();
                        foreach (IError error in visitorContext.Errors)
                        {
                            context.ReportError(error.WithPath(context.Path));
                        }
                    }
                    else
                    {
                        context.Result = visitorContext.Sort(source);
                    }
                }
            }
        }
예제 #12
0
        public override FieldMiddleware CreateExecutor <TEntityType>(NameString argumentName)
        {
            return(next => context => ExecuteAsync(next, context));

            async ValueTask ExecuteAsync(
                FieldDelegate next,
                IMiddlewareContext context)
            {
                // first we let the pipeline run and produce a result.
                await next(context).ConfigureAwait(false);

                // next we get the filter argument. If the filter argument is already on the context
                // we use this. This enabled overriding the context with LocalContextData
                IInputField argument = context.Field.Arguments[argumentName];
                IValueNode  filter   = context.LocalContextData.ContainsKey(ContextValueNodeKey) &&
                                       context.LocalContextData[ContextValueNodeKey] is IValueNode node
                        ? node
                        : context.ArgumentLiteral <IValueNode>(argumentName);

                // if no filter is defined we can stop here and yield back control.
                if (filter.IsNull() ||
                    (context.LocalContextData.TryGetValue(
                         SkipFilteringKey,
                         out object?skipObject) &&
                     skipObject is bool skip &&
                     skip))
                {
                    return;
                }

                if (argument.Type is IFilterInputType filterInput &&
                    context.Field.ContextData.TryGetValue(
                        ContextVisitFilterArgumentKey,
                        out object?executorObj) &&
                    executorObj is VisitFilterArgument executor)
                {
                    var inMemory =
                        context.Result is QueryableExecutable <TEntityType> executable &&
                        executable.InMemory ||
                        context.Result is not IQueryable ||
                        context.Result is EnumerableQuery;

                    QueryableFilterContext visitorContext = executor(
                        filter,
                        filterInput,
                        inMemory);

                    // compile expression tree
                    if (visitorContext.TryCreateLambda(
                            out Expression <Func <TEntityType, bool> >?where))
                    {
                        context.Result = context.Result switch
                        {
                            IQueryable <TEntityType> q => q.Where(where),
                            IEnumerable <TEntityType> e => e.AsQueryable().Where(where),
                            QueryableExecutable <TEntityType> ex =>
                            ex.WithSource(ex.Source.Where(where)),
                            _ => context.Result
                        };
                    }
                    else
                    {
                        if (visitorContext.Errors.Count > 0)
                        {
                            context.Result = Array.Empty <TEntityType>();
                            foreach (IError error in visitorContext.Errors)
                            {
                                context.ReportError(error.WithPath(context.Path));
                            }
                        }
                    }
                }
            }
        }
예제 #13
0
        public override FieldMiddleware CreateExecutor <TEntityType>(NameString argumentName)
        {
            return(next => context => ExecuteAsync(next, context));

            async ValueTask ExecuteAsync(
                FieldDelegate next,
                IMiddlewareContext context)
            {
                // first we let the pipeline run and produce a result.
                await next(context).ConfigureAwait(false);

                // next we get the sort argument.
                IInputField argument = context.Field.Arguments[argumentName];
                IValueNode  sort     = context.ArgumentLiteral <IValueNode>(argumentName);

                // if no sort is defined we can stop here and yield back control.
                var skipSorting =
                    context.LocalContextData.TryGetValue(SkipSortingKey, out object?skip) &&
                    skip is true;

                if (sort.IsNull() || skipSorting)
                {
                    return;
                }

                if (argument.Type is ListType lt &&
                    lt.ElementType is NonNullType nn &&
                    nn.NamedType() is ISortInputType sortInput &&
                    context.Field.ContextData.TryGetValue(
                        ContextVisitSortArgumentKey,
                        out object?executorObj) &&
                    executorObj is VisitSortArgument executor)
                {
                    var inMemory =
                        context.Result is QueryableExecutable <TEntityType> {
                        InMemory : true
                    } ||
                    context.Result is not IQueryable ||
                    context.Result is EnumerableQuery;

                    QueryableSortContext visitorContext = executor(
                        sort,
                        sortInput,
                        inMemory);

                    // compile expression tree
                    if (visitorContext.Errors.Count > 0)
                    {
                        context.Result = Array.Empty <TEntityType>();
                        foreach (IError error in visitorContext.Errors)
                        {
                            context.ReportError(error.WithPath(context.Path));
                        }
                    }
                    else
                    {
                        context.Result = context.Result switch
                        {
                            IQueryable <TEntityType> q => visitorContext.Sort(q),
                            IEnumerable <TEntityType> e => visitorContext.Sort(e.AsQueryable()),
                            QueryableExecutable <TEntityType> ex =>
                            ex.WithSource(visitorContext.Sort(ex.Source)),
                            _ => context.Result
                        };
                    }
                }
            }