예제 #1
0
        public override IGraphQLBaseNode VisitField(EntityGraphQLParser.FieldContext context)
        {
            var name       = baseIdentityFinder.Visit(context);
            var result     = EqlCompiler.CompileWith(context.GetText(), selectContext, schemaProvider, methodProvider, variables);
            var actualName = schemaProvider.GetActualFieldName(schemaProvider.GetSchemaTypeNameForRealType(selectContext.Type), name);
            var node       = new GraphQLNode(schemaProvider, fragments, actualName, result, null);

            return(node);
        }
        private ExpressionResult BuildEntityQueryExpression(string query)
        {
            var prop         = ((Schema.Field)fieldArgumentContext).ArgumentTypesObject.GetType().GetProperties().FirstOrDefault(p => p.PropertyType.GetGenericTypeDefinition() == typeof(EntityQueryType <>));
            var eqlt         = prop.GetValue(((Schema.Field)fieldArgumentContext).ArgumentTypesObject) as BaseEntityQueryType;
            var contextParam = Expression.Parameter(eqlt.QueryType);

            if (string.IsNullOrEmpty(query))
            {
                return(null);
            }
            ExpressionResult expressionResult = EqlCompiler.CompileWith(query, contextParam, schemaProvider, claims, methodProvider, variables).ExpressionResult;

            expressionResult = (ExpressionResult)Expression.Lambda(expressionResult.Expression, contextParam);
            return(expressionResult);
        }
예제 #3
0
        public override IGraphQLBaseNode VisitAliasExp(EntityGraphQLParser.AliasExpContext context)
        {
            var name  = context.alias.name.GetText();
            var query = context.entity.GetText();

            if (selectContext == null)
            {
                // top level are queries on the context
                var exp  = EqlCompiler.Compile(query, schemaProvider, methodProvider, variables);
                var node = new GraphQLNode(schemaProvider, fragments, name, exp, null);
                return(node);
            }
            else
            {
                var result = EqlCompiler.CompileWith(query, selectContext, schemaProvider, methodProvider, variables);
                var node   = new GraphQLNode(schemaProvider, fragments, name, result, null);
                return(node);
            }
        }
예제 #4
0
        private ExpressionResult BuildEntityQueryExpression(string fieldName, string argName, string query)
        {
            if (string.IsNullOrEmpty(query))
            {
                return(null);
            }
            var prop = ((Field)fieldArgumentContext).ArgumentTypesObject.GetType().GetProperties().FirstOrDefault(p => p.Name == argName && p.PropertyType.GetGenericTypeDefinition() == typeof(EntityQueryType <>));

            if (prop == null)
            {
                throw new EntityGraphQLCompilerException($"Can not find argument {argName} of type EntityQuery on field {fieldName}");
            }

            var eqlt         = prop.GetValue(((Field)fieldArgumentContext).ArgumentTypesObject) as BaseEntityQueryType;
            var contextParam = Expression.Parameter(eqlt.QueryType);
            ExpressionResult expressionResult = EqlCompiler.CompileWith(query, contextParam, schemaProvider, claims, methodProvider, variables).ExpressionResult;

            expressionResult = (ExpressionResult)Expression.Lambda(expressionResult.Expression, contextParam);
            return(expressionResult);
        }
예제 #5
0
        public override GraphQLOperation VisitGqlTypeDef(EntityGraphQLParser.GqlTypeDefContext context)
        {
            var argName  = context.gqlVar().GetText().TrimStart('$');
            var isArray  = context.arrayType != null;
            var type     = isArray ? context.arrayType.type.GetText() : context.type.GetText();
            var required = context.required != null;
            CompiledQueryResult defaultValue = null;

            if (context.defaultValue != null)
            {
                defaultValue = EqlCompiler.CompileWith(context.defaultValue.GetText(), null, schemaProvider, null, variables);
            }

            if (required && !variables.ContainsKey(argName) && defaultValue == null)
            {
                throw new QueryException($"Missing required variable '{argName}' on query '{this.operation.Name}'");
            }

            this.operation.AddArgument(argName, type, isArray, required, defaultValue != null ? defaultValue.ExpressionResult : null);

            return(this.operation);
        }
예제 #6
0
        /// <summary>
        /// We compile each entityQuery with EqlCompiler and build a Select call from the fields
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override IGraphQLBaseNode VisitEntityQuery(EntityGraphQLParser.EntityQueryContext context)
        {
            string name;
            string query;

            if (context.alias != null)
            {
                name  = context.alias.name.GetText();
                query = context.entity.GetText();
            }
            else
            {
                query = context.entity.GetText();
                name  = query;
                if (name.IndexOf(".") > -1)
                {
                    name = name.Substring(0, name.IndexOf("."));
                }
                if (name.IndexOf("(") > -1)
                {
                    name = name.Substring(0, name.IndexOf("("));
                }
            }

            try
            {
                CompiledQueryResult result = null;
                if (selectContext == null)
                {
                    // top level are queries on the context
                    result = EqlCompiler.Compile(query, schemaProvider, methodProvider, variables);
                }
                else
                {
                    result = EqlCompiler.CompileWith(query, selectContext, schemaProvider, methodProvider, variables);
                }
                var exp = result.ExpressionResult;

                IGraphQLNode graphQLNode = null;
                if (exp.Type.IsEnumerableOrArray())
                {
                    graphQLNode = BuildDynamicSelectOnCollection(result, name, context);
                }
                else
                {
                    // Could be a list.First() that we need to turn into a select, or
                    // other levels are object selection. e.g. from the top level people query I am selecting all their children { field1, etc. }
                    // Can we turn a list.First() into and list.Select().First()
                    var listExp = Compiler.Util.ExpressionUtil.FindIEnumerable(result.ExpressionResult);
                    if (listExp.Item1 != null)
                    {
                        // yes we can
                        // rebuild the ExpressionResult so we keep any ConstantParameters
                        var item1 = (ExpressionResult)listExp.Item1;
                        item1.AddConstantParameters(result.ExpressionResult.ConstantParameters);
                        graphQLNode = BuildDynamicSelectOnCollection(new CompiledQueryResult(item1, result.ContextParams), name, context);
                        graphQLNode.SetNodeExpression((ExpressionResult)Compiler.Util.ExpressionUtil.CombineExpressions(graphQLNode.GetNodeExpression(), listExp.Item2));
                    }
                    else
                    {
                        graphQLNode = BuildDynamicSelectForObjectGraph(query, name, context, result);
                    }
                }
                // the query result may be a mutation
                if (result.IsMutation)
                {
                    return(new GraphQLMutationNode(result, graphQLNode));
                }
                return(graphQLNode);
            }
            catch (EntityGraphQLCompilerException ex)
            {
                throw SchemaException.MakeFieldCompileError(query, ex.Message);
            }
        }