Skip to content

Commit 2a01382

Browse files
anotenderigdianov
authored andcommitted
fix: Added support for binding orderBy argument as a variable (#195)
1 parent 33da4bb commit 2a01382

File tree

3 files changed

+73
-20
lines changed

3 files changed

+73
-20
lines changed

graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaSchemaBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,8 +1027,8 @@ private void setNoOpCoercing(GraphQLType type) {
10271027
GraphQLEnumType.newEnum()
10281028
.name("OrderBy")
10291029
.description("Specifies the direction (Ascending / Descending) to sort a field.")
1030-
.value("ASC", 0, "Ascending")
1031-
.value("DESC", 1, "Descending")
1030+
.value("ASC", "ASC", "Ascending")
1031+
.value("DESC", "DESC", "Descending")
10321032
.build();
10331033

10341034

graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/QraphQLJpaBaseDataFetcher.java

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,6 @@ class QraphQLJpaBaseDataFetcher implements DataFetcher<Object> {
107107
private static final String WHERE = "where";
108108

109109
protected static final String OPTIONAL = "optional";
110-
111-
protected static final List<String> ARGUMENTS = Arrays.asList(OPTIONAL);
112110

113111
// "__typename" is part of the graphql introspection spec and has to be ignored
114112
private static final String TYPENAME = "__typename";
@@ -182,16 +180,17 @@ protected final List<Predicate> getFieldPredicates(Field field, CriteriaQuery<?>
182180
// Build predicate arguments for singular attributes only
183181
if(fieldPath.getModel() instanceof SingularAttribute) {
184182
// Process the orderBy clause
185-
Optional<Argument> orderByArgument = selectedField.getArguments().stream()
186-
.filter(this::isOrderByArgument)
187-
.findFirst();
188-
189-
if (orderByArgument.isPresent()) {
190-
if ("DESC".equals(((EnumValue) orderByArgument.get().getValue()).getName()))
191-
query.orderBy(cb.desc(fieldPath));
192-
else
193-
query.orderBy(cb.asc(fieldPath));
194-
}
183+
selectedField.getArguments().stream()
184+
.filter(this::isOrderByArgument)
185+
.findFirst()
186+
.map(a -> getOrderByValue(a, environment))
187+
.ifPresent(orderBy -> {
188+
if ("DESC".equals(orderBy.getName())) {
189+
query.orderBy(cb.desc(fieldPath));
190+
} else {
191+
query.orderBy(cb.asc(fieldPath));
192+
}
193+
});
195194

196195
// Check if it's an object and the foreign side is One. Then we can eagerly join causing an inner join instead of 2 queries
197196
SingularAttribute<?,?> attribute = (SingularAttribute<?,?>) fieldPath.getModel();
@@ -391,12 +390,7 @@ private <R extends Value<?>> R getValue(Argument argument, DataFetchingEnvironme
391390
Value<?> value = argument.getValue();
392391

393392
if(VariableReference.class.isInstance(value)) {
394-
String variableName = VariableReference.class.cast(value)
395-
.getName();
396-
397-
Object variableValue = environment.getExecutionContext()
398-
.getVariables()
399-
.get(variableName);
393+
Object variableValue = getVariableReferenceValue((VariableReference) value, environment);
400394

401395
GraphQLArgument graphQLArgument = environment.getExecutionStepInfo()
402396
.getFieldDefinition()
@@ -408,6 +402,22 @@ private <R extends Value<?>> R getValue(Argument argument, DataFetchingEnvironme
408402
return (R) value;
409403
}
410404

405+
private EnumValue getOrderByValue(Argument argument, DataFetchingEnvironment environment) {
406+
Value<?> value = argument.getValue();
407+
408+
if(VariableReference.class.isInstance(value)) {
409+
Object variableValue = getVariableReferenceValue((VariableReference) value, environment);
410+
return EnumValue.newEnumValue(variableValue.toString()).build();
411+
}
412+
return (EnumValue) value;
413+
}
414+
415+
private Object getVariableReferenceValue(VariableReference variableReference, DataFetchingEnvironment env) {
416+
return env.getExecutionContext()
417+
.getVariables()
418+
.get(variableReference.getName());
419+
}
420+
411421
protected Predicate getWherePredicate(CriteriaBuilder cb, Root<?> root, From<?,?> path, DataFetchingEnvironment environment, Argument argument) {
412422
ObjectValue whereValue = getValue(argument, environment);
413423

graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/GraphQLExecutorTests.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import static org.assertj.core.api.Assertions.assertThat;
2020
import static org.assertj.core.api.Assertions.tuple;
21+
import static org.assertj.core.api.BDDAssertions.then;
2122
import static org.assertj.core.util.Lists.list;
2223

2324
import java.util.Arrays;
@@ -28,6 +29,7 @@
2829

2930
import javax.persistence.EntityManager;
3031

32+
import org.assertj.core.util.Maps;
3133
import org.junit.Test;
3234
import org.junit.runner.RunWith;
3335
import org.springframework.beans.factory.annotation.Autowired;
@@ -1568,4 +1570,45 @@ public void shouldNotReturnStaleCacheResultsFromPreviousQueryForEmbeddedCriteria
15681570
assertThat(result2.toString()).isEqualTo(expected2);
15691571
}
15701572

1573+
@Test
1574+
public void queryWithEnumParameterShouldExecuteWithNoError() {
1575+
//given
1576+
String query = "" +
1577+
"query($orderById: OrderBy) {" +
1578+
" Books {" +
1579+
" select {" +
1580+
" id(orderBy: $orderById)" +
1581+
" title" +
1582+
" }" +
1583+
" }" +
1584+
"}";
1585+
Map<String, Object> variables = Maps.newHashMap("orderById",
1586+
"DESC");
1587+
1588+
//when
1589+
ExecutionResult executionResult = executor.execute(query,
1590+
variables);
1591+
1592+
// then
1593+
List<GraphQLError> errors = executionResult.getErrors();
1594+
Map<String, Object> data = executionResult.getData();
1595+
then(errors).isEmpty();
1596+
then(data)
1597+
.isNotNull().isNotEmpty()
1598+
.extracting("Books")
1599+
.flatExtracting("select")
1600+
.extracting("id", "title")
1601+
.containsExactly(
1602+
tuple(7L,
1603+
"Three Sisters"),
1604+
tuple(6L,
1605+
"The Seagull"),
1606+
tuple(5L,
1607+
"The Cherry Orchard"),
1608+
tuple(3L,
1609+
"Anna Karenina"),
1610+
tuple(2L,
1611+
"War and Peace")
1612+
);
1613+
}
15711614
}

0 commit comments

Comments
 (0)