Skip to content

feat: add support for variable where criteria expressions #162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
Expand Down Expand Up @@ -57,10 +58,12 @@

import com.introproventures.graphql.jpa.query.annotation.GraphQLDefaultOrderBy;
import com.introproventures.graphql.jpa.query.schema.impl.PredicateFilter.Criteria;

import graphql.GraphQLException;
import graphql.execution.ValuesResolver;
import graphql.language.Argument;
import graphql.language.ArrayValue;
import graphql.language.AstValueHelper;
import graphql.language.BooleanValue;
import graphql.language.Comment;
import graphql.language.EnumValue;
Expand All @@ -79,6 +82,7 @@
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import graphql.schema.DataFetchingEnvironmentBuilder;
import graphql.schema.GraphQLArgument;
import graphql.schema.GraphQLFieldDefinition;
import graphql.schema.GraphQLList;
import graphql.schema.GraphQLObjectType;
Expand Down Expand Up @@ -378,12 +382,29 @@ protected Predicate getPredicate(CriteriaBuilder cb, Root<?> from, From<?,?> pat


@SuppressWarnings( "unchecked" )
private <R extends Value> R getValue(Argument argument) {
return (R) argument.getValue();
private <R extends Value<?>> R getValue(Argument argument, DataFetchingEnvironment environment) {
Value<?> value = argument.getValue();

if(VariableReference.class.isInstance(value)) {
String variableName = VariableReference.class.cast(value)
.getName();

Object variableValue = environment.getExecutionContext()
.getVariables()
.get(variableName);

GraphQLArgument graphQLArgument = environment.getExecutionStepInfo()
.getFieldDefinition()
.getArgument(argument.getName());

return (R) AstValueHelper.astFromValue(variableValue, graphQLArgument.getType());
}

return (R) value;
}

protected Predicate getWherePredicate(CriteriaBuilder cb, Root<?> root, From<?,?> path, DataFetchingEnvironment environment, Argument argument) {
ObjectValue whereValue = getValue(argument);
ObjectValue whereValue = getValue(argument, environment);

if(whereValue.getChildren().isEmpty())
return cb.conjunction();
Expand All @@ -404,7 +425,7 @@ protected Predicate getWherePredicate(CriteriaBuilder cb, Root<?> root, From<?,
@SuppressWarnings({"unchecked", "rawtypes"})
protected Predicate getArgumentPredicate(CriteriaBuilder cb, From<?,?> from,
DataFetchingEnvironment environment, Argument argument) {
ObjectValue whereValue = getValue(argument);
ObjectValue whereValue = getValue(argument, environment);

if (whereValue.getChildren().isEmpty())
return cb.disjunction();
Expand Down Expand Up @@ -494,7 +515,7 @@ protected Predicate getArgumentsPredicate(CriteriaBuilder cb,
From<?, ?> path,
DataFetchingEnvironment environment,
Argument argument) {
ArrayValue whereValue = getValue(argument);
ArrayValue whereValue = getValue(argument, environment);

if (whereValue.getValues().isEmpty())
return cb.disjunction();
Expand Down Expand Up @@ -896,22 +917,41 @@ else if (value instanceof VariableReference) {
return argumentValue;
}
} else if (value instanceof ArrayValue) {
Object convertedValue = environment.getArgument(argument.getName());
if (convertedValue != null && !getJavaType(environment, argument).isEnum()) {
// unwrap [[EnumValue{name='value'}]]
if(convertedValue instanceof Collection
&& ((Collection) convertedValue).stream().allMatch(it->it instanceof Collection)) {
convertedValue = ((Collection) convertedValue).iterator().next();
Collection arrayValue = environment.getArgument(argument.getName());

if (arrayValue != null) {
// Let's unwrap array of array values
if(arrayValue.stream()
.allMatch(it->it instanceof Collection)) {
arrayValue = Collection.class.cast(arrayValue.iterator()
.next());
}

if(convertedValue instanceof Collection
&& ((Collection) convertedValue).stream().anyMatch(it->it instanceof Value)) {
return ((Collection) convertedValue).stream()
.map((it) -> convertValue(environment, argument, (Value) it))
.collect(Collectors.toList());

// Let's convert enum types, i.e. array of strings or EnumValue into Java type
if(getJavaType(environment, argument).isEnum()) {
Function<Object, Value> objectValue = (obj) -> Value.class.isInstance(obj)
? Value.class.cast(obj)
: new EnumValue(obj.toString());
// Return real typed resolved array values converted into Java enums
return arrayValue.stream()
.map((it) -> convertValue(environment,
argument,
objectValue.apply(it)))
.collect(Collectors.toList());
}
// Let's try handle Ast Value types
else if(arrayValue.stream()
.anyMatch(it->it instanceof Value)) {
return arrayValue.stream()
.map(it -> convertValue(environment,
argument,
Value.class.cast(it)))
.collect(Collectors.toList());
}
// Return real typed resolved array value, i.e. Date, UUID, Long
else {
return arrayValue;
}
// Return real typed resolved array value
return convertedValue;
} else {
// Wrap converted values in ArrayList
return ((ArrayValue) value).getValues().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.Assert;

import com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaExecutor;
import com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaSchemaBuilder;

import graphql.ErrorType;
import graphql.ExecutionResult;
import graphql.GraphQLError;
import graphql.validation.ValidationError;


@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.NONE)
Expand Down Expand Up @@ -1440,4 +1448,5 @@ public void queryForTransientMethodAnnotatedWithGraphQLIgnoreShouldFail() {
.extracting("validationErrorType", "queryPath")
.containsOnly(tuple(ValidationErrorType.FieldUndefined, list("Books", "select", "authorName")));
}

}
Loading