/// Given a syntax of someCollection { fields, to, selection, from, object } /// it will build a select assuming 'someCollection' is an IEnumerables private IGraphQLNode BuildDynamicSelectOnCollection(QueryResult queryResult, string name, EntityGraphQLParser.EntityQueryContext context, bool isRootSelect) { var elementType = queryResult.BodyType.GetEnumerableType(); var contextParameter = Expression.Parameter(elementType); var exp = queryResult.LambdaExpression.Body; var oldContext = selectContext; selectContext = contextParameter; // visit child fields. Will be field or entityQueries again var fieldExpressions = context.fields.children.Select(c => Visit(c)).Where(n => n != null).ToList(); // Default we select out sub objects/relations. So Select(d => new {Field = d.Field, Relation = new { d.Relation.Field }}) var selectExpression = (ExpressionResult)ExpressionUtil.SelectDynamic(contextParameter, exp, fieldExpressions, schemaProvider); selectContext = oldContext; var t = MergeConstantParametersFromFields(queryResult, fieldExpressions, contextParameter); var parameters = t.Item1; var constantParameterValues = t.Item2; var gqlNode = new GraphQLNode(name, new QueryResult(selectExpression, parameters, constantParameterValues), (ExpressionResult)exp); return(gqlNode); }
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); }
/// Given a syntax of someField { fields, to, selection, from, object } /// it will build the correct select statement private IGraphQLNode BuildDynamicSelectForObjectGraph(string query, string name, EntityGraphQLParser.EntityQueryContext context, QueryResult rootField) { var selectWasNull = false; if (selectContext == null) { selectContext = Expression.Parameter(schemaProvider.ContextType); selectWasNull = true; } if (schemaProvider.TypeHasField(selectContext.Type.Name, name, new string[0])) { name = schemaProvider.GetActualFieldName(selectContext.Type.Name, name); } try { Expression exp = rootField.LambdaExpression.Body; var oldContext = selectContext; var rootFieldParam = Expression.Parameter(exp.Type); selectContext = rootField.IsMutation ? rootFieldParam : exp; // visit child fields. Will be field or entityQueries again var fieldExpressions = context.fields.children.Select(c => Visit(c)).Where(n => n != null).ToList(); var newExp = ExpressionUtil.CreateNewExpression(selectContext, fieldExpressions, schemaProvider); var anonType = newExp.Type; // make a null check from this new expression if (!rootField.IsMutation) { newExp = Expression.Condition(Expression.MakeBinary(ExpressionType.Equal, selectContext, Expression.Constant(null)), Expression.Constant(null, anonType), newExp, anonType); } selectContext = oldContext; var t = MergeConstantParametersFromFields(rootField, fieldExpressions, rootFieldParam); var parameters = t.Item1; var constantParameterValues = t.Item2; var graphQLNode = new GraphQLNode(name, new QueryResult((ExpressionResult)newExp, parameters, constantParameterValues), (ExpressionResult)exp); if (selectWasNull) { selectContext = null; } return(graphQLNode); } catch (EntityGraphQLCompilerException ex) { throw SchemaException.MakeFieldCompileError(query, ex.Message); } }
public override IGraphQLNode VisitMutationQuery(EntityGraphQLParser.MutationQueryContext context) { var root = new GraphQLNode("root", null, null, null, null); var operationName = GetOperationName(context.operationName()); foreach (var c in context.gqlBody().children) { var mutation = Visit(c); if (mutation != null) { root.Fields.Add(mutation); } } return(root); }
/// This is our top level node. /// { /// entityQuery { fields [, field] }, /// entityQuery { fields [, field] }, /// ... /// } public override IGraphQLNode VisitDataQuery(EntityGraphQLParser.DataQueryContext context) { var root = new GraphQLNode("root", null, null, null, null); var operationName = GetOperationName(context.operationName()); // Just visit each child node. All top level will be entityQueries foreach (var c in context.gqlBody().children) { var n = Visit(c); if (n != null) { root.Fields.Add(n); } } return(root); }
/// Given a syntax of someField { fields, to, selection, from, object } /// it will build the correct select statement private IGraphQLNode BuildDynamicSelectForObjectGraph(string query, string name, EntityGraphQLParser.EntityQueryContext context, CompiledQueryResult rootField) { var selectWasNull = false; if (selectContext == null) { selectContext = Expression.Parameter(schemaProvider.ContextType); selectWasNull = true; } if (schemaProvider.TypeHasField(selectContext.Type.Name, name, new string[0])) { name = schemaProvider.GetActualFieldName(selectContext.Type.Name, name); } try { var exp = (Expression)rootField.ExpressionResult; var oldContext = selectContext; var rootFieldParam = Expression.Parameter(exp.Type); selectContext = rootField.IsMutation ? rootFieldParam : exp; // visit child fields. Will be field or entityQueries again var fieldExpressions = context.fields.children.Select(c => Visit(c)).Where(n => n != null).ToList(); var graphQLNode = new GraphQLNode(schemaProvider, fragments, name, null, (ExpressionResult)selectContext, (rootField.IsMutation ? new ParameterExpression[] { rootFieldParam } : rootField.ContextParams.ToArray()), fieldExpressions, null); if (rootField != null && rootField.ConstantParameters != null) { graphQLNode.AddConstantParameters(rootField.ConstantParameters); } selectContext = oldContext; if (selectWasNull) { selectContext = null; } return(graphQLNode); } catch (EntityGraphQLCompilerException ex) { throw SchemaException.MakeFieldCompileError(query, ex.Message); } }
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); } }
/// Given a syntax of someCollection { fields, to, selection, from, object } /// it will build a select assuming 'someCollection' is an IEnumerables private IGraphQLNode BuildDynamicSelectOnCollection(CompiledQueryResult queryResult, string name, EntityGraphQLParser.EntityQueryContext context) { var elementType = queryResult.BodyType.GetEnumerableOrArrayType(); var contextParameter = Expression.Parameter(elementType, $"param_{elementType}"); var exp = queryResult.ExpressionResult; var oldContext = selectContext; selectContext = contextParameter; // visit child fields. Will be field or entityQueries again var fieldExpressions = context.fields.children.Select(c => Visit(c)).Where(n => n != null).ToList(); var gqlNode = new GraphQLNode(schemaProvider, fragments, name, null, exp, queryResult.ContextParams, fieldExpressions, contextParameter); selectContext = oldContext; return(gqlNode); }
/// <summary> /// This is one of our top level node. /// mutation MyMutation {...} /// </summary> /// <param name="context"></param> /// <returns></returns> public override IGraphQLBaseNode VisitMutationQuery(EntityGraphQLParser.MutationQueryContext context) { var operation = GetOperation(context.operationName()); foreach (var item in operation.Arguments.Where(a => a.DefaultValue != null)) { variables[item.ArgName] = Expression.Lambda(item.DefaultValue.Expression).Compile().DynamicInvoke(); } var mutation = new GraphQLNode(schemaProvider, fragments, operation.Name, null, null, null, null, null); foreach (var c in context.gqlBody().children) { var n = Visit(c); if (n != null) { mutation.AddField((IGraphQLNode)n); } } rootQueries.Add(mutation); return(mutation); }