Skip to content
This repository has been archived by the owner on Feb 12, 2023. It is now read-only.

Commit

Permalink
feat(MultipleOperations) possibility to send multiple operations with…
Browse files Browse the repository at this point in the history
…in query a select which to execute
  • Loading branch information
Magdziak Marek committed Jul 24, 2016
1 parent fa02d19 commit 81a459a
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public JsonResult Post([FromBody] GraphiQLInput input)
return this.Json(
new
{
data = this.schema.Execute(input.Query, GetVariables(input))
data = this.schema.Execute(input.Query, GetVariables(input), input.OperationName)
}
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
public class GraphiQLInput
{
public string OperationName { get; set; }
public string Query { get; set; }
public string Variables { get; set; }
}
Expand Down
2 changes: 1 addition & 1 deletion examples/GraphQLCore.GraphiQLExample/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
"GraphQLCore": "1.0.0-alpha"
"GraphQLCore": "1.0.0-alpha-*"
},

"tools": {
Expand Down
25 changes: 17 additions & 8 deletions src/GraphQLCore/Execution/ExecutionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,20 @@ public void Dispose()
}

public dynamic Execute()
{
return this.Execute(null);
}

public dynamic Execute(string operationToExecute)
{
this.ValidateAstAndThrowErrorWhenFaulty();

foreach (var definition in this.ast.Definitions)
this.ResolveDefinition(definition);
this.ResolveDefinition(definition, operationToExecute);

if (this.operation == null)
if (this.operation == null && !string.IsNullOrWhiteSpace(operationToExecute))
throw new GraphQLException($"Unknown operation named \"{operationToExecute}\".");
if (this.operation == null && string.IsNullOrWhiteSpace(operationToExecute))
throw new GraphQLException("Must provide an operation.");

return this.ComposeResultForType(this.GetOperationRootType(), this.operation.SelectionSet);
Expand Down Expand Up @@ -160,12 +167,12 @@ private GraphQLObjectType GetOperationRootType()
return null;
}

private void ResolveDefinition(ASTNode definition)
private void ResolveDefinition(ASTNode definition, string operationToExecute)
{
switch (definition.Kind)
{
case ASTNodeKind.OperationDefinition:
this.ResolveOperationDefinition(definition as GraphQLOperationDefinition); break;
this.ResolveOperationDefinition(definition as GraphQLOperationDefinition, operationToExecute); break;
case ASTNodeKind.FragmentDefinition:
this.ResolveFragmentDefinition(definition as GraphQLFragmentDefinition); break;
default: throw new Exception($"GraphQL cannot execute a request containing a {definition.Kind}.");
Expand All @@ -177,12 +184,14 @@ private void ResolveFragmentDefinition(GraphQLFragmentDefinition graphQLFragment
this.fragments.Add(graphQLFragmentDefinition.Name.Value, graphQLFragmentDefinition);
}

private void ResolveOperationDefinition(GraphQLOperationDefinition graphQLOperationDefinition)
private void ResolveOperationDefinition(GraphQLOperationDefinition graphQLOperationDefinition, string operationToExecute)
{
if (this.operation != null)
throw new Exception("Must provide operation name if query contains multiple operations.");
if (this.operation != null && string.IsNullOrWhiteSpace(operationToExecute))
throw new GraphQLException("Must provide operation name if query contains multiple operations.");

if (this.operation == null)
if (!string.IsNullOrWhiteSpace(operationToExecute) && graphQLOperationDefinition.Name.Value == operationToExecute)
this.operation = graphQLOperationDefinition;
else if (string.IsNullOrWhiteSpace(operationToExecute) && this.operation == null)
this.operation = graphQLOperationDefinition;
}
}
Expand Down
16 changes: 16 additions & 0 deletions src/GraphQLCore/Type/GraphQLSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using Language.AST;
using System.Linq;
using Translation;
using System;
using System.Dynamic;

public class GraphQLSchema : IGraphQLSchema
{
Expand All @@ -21,6 +23,7 @@ public GraphQLSchema()

public IntrospectedSchemaType IntrospectedSchema { get; private set; }
public GraphQLObjectType MutationType { get; private set; }

public GraphQLObjectType QueryType { get; private set; }

public void AddKnownType(GraphQLBaseType type)
Expand All @@ -44,11 +47,24 @@ public dynamic Execute(string expression, dynamic variables)
}
}

public dynamic Execute(string expression, dynamic variables, string operationToExecute)
{
using (var context = new ExecutionContext(this, this.GetAst(expression), variables))
{
return context.Execute(operationToExecute);
}
}

public void Mutation(GraphQLObjectType root)
{
this.MutationType = root;
}

public object Execute(object multipleOperationQuery)
{
throw new NotImplementedException();
}

public void Query(GraphQLObjectType root)
{
this.QueryType = root;
Expand Down
2 changes: 2 additions & 0 deletions src/GraphQLCore/Type/IGraphQLSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public interface IGraphQLSchema

dynamic Execute(string query, dynamic variables);

dynamic Execute(string query, dynamic variables, string operationToExecute);

void Query(GraphQLObjectType root);
}
}
73 changes: 67 additions & 6 deletions test/GraphQLCore.Tests/Type/GraphQLSchemaTests.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,81 @@
namespace GraphQLCore.Tests.Type
{
using Exceptions;
using GraphQLCore.Type;
using NUnit.Framework;
using System;
using System.Dynamic;

[TestFixture]
public class GraphQLSchemaTests
{
private GraphQLSchema schema;
private string singleOperationQuery;
private string multipleOperationQuery;

[Test]
public void Execute_MultipleOperationsNoOperationName_ThrowsAnError()
public void SingleOperationNoOperationNameProvided_PicksSingleOne()
{
var exception = Assert.Throws<Exception>(new TestDelegate(() =>
this.schema.Execute("query Example { hello } query OtherExample { hello }")));
var result = this.schema.Execute(this.singleOperationQuery);

Assert.AreEqual("Must provide operation name if query contains multiple operations.",
exception.Message);
Assert.IsNotNull(result.a);
}

[Test]
public void SingleOperationOperationNameProvided_PicksOperationByOperationName()
{
var result = this.schema.Execute(this.singleOperationQuery, new ExpandoObject(), "q1");

Assert.IsNotNull(result.a);
}

[Test]
public void NotExistingOperationNameProvided_TrowsException()
{
var exception = Assert.Throws<GraphQLException>(() =>
{
var result = this.schema.Execute(this.singleOperationQuery, new ExpandoObject(), "q2");
});

Assert.AreEqual("Unknown operation named \"q2\".", exception.Message);
}

[Test]
public void MultipleOperationsNoOperationNameProvided_TrowsException()
{
var exception = Assert.Throws<GraphQLException>(() =>
{
var result = this.schema.Execute(this.multipleOperationQuery);
});

Assert.AreEqual("Must provide operation name if query contains multiple operations.", exception.Message);
}

[Test]
public void MultipleOperationsSelectingFirstOperation_ReturnsResultFromTheFirstOperation()
{
var result = this.schema.Execute(this.multipleOperationQuery, new ExpandoObject(), "q1");

Assert.IsNotNull(result.a);
}

[Test]
public void MultipleOperationsSelectingSecondOperation_ReturnsResultFromTheSecondOperation()
{
var result = this.schema.Execute(this.multipleOperationQuery, new ExpandoObject(), "q2");

Assert.IsNotNull(result.b);
}

[Test]
public void NoOperationProvided_ThrowsError()
{
var exception = Assert.Throws<GraphQLException>(() =>
{
var result = this.schema.Execute("");
});

Assert.AreEqual("Must provide an operation.", exception.Message);
}

[SetUp]
Expand All @@ -26,14 +85,16 @@ public void SetUp()
var rootType = new RootQueryType();

schema.Query(rootType);

this.singleOperationQuery = "query q1 { a : hello }";
this.multipleOperationQuery = "query q1 { a : hello } query q2 { b : hello }";
}

private class RootQueryType : GraphQLObjectType
{
public RootQueryType() : base("RootQueryType", "")
{
this.Field("hello", () => "world");
this.Field("test", () => "test");
}
}
}
Expand Down

0 comments on commit 81a459a

Please sign in to comment.