diff --git a/CHANGELOG.md b/CHANGELOG.md index 843a1ad87..691e42bd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Change Log -## 0.3.17-SNAPSHOT +## 0.3.18-SNAPSHOT +* chore: enable Docker build by default [ec3f1a6](https://github.com/introproventures/graphql-jpa-query/commit/ec3f1a6c5daa3390fd738e2d2cef4f7a58b24e2d) +* fix: use bean naming convention for property names [6df3c30](https://github.com/introproventures/graphql-jpa-query/commit/6df3c30d1a16681da07d81d7ca64fed9d885ac57) +* distinct sql and ignore field in filters and sorting (#95) [bde04d5](https://github.com/introproventures/graphql-jpa-query/commit/bde04d5702943cd7d5e70d071e8a49df4ef8ad9f) * fix: use embeddableType javaType to cache corresponding GraphQL type (#98) [ce4f85a](https://github.com/introproventures/graphql-jpa-query/commit/ce4f85a462d9c746d62c56e3f69be5beebd9d28c) * feat: add where relation attributes criteria expressions (#96) [b296d8a](https://github.com/introproventures/graphql-jpa-query/commit/b296d8a2c9ad9d0a8b6b58d54f5cd6dcfded953f) * chore: skip Docker plugin on release [2933500](https://github.com/introproventures/graphql-jpa-query/commit/2933500644bd6b781919a24c5583c6708f046a13) diff --git a/graphql-jpa-query-annotations/pom.xml b/graphql-jpa-query-annotations/pom.xml index 217138be4..7c9e6f5ba 100644 --- a/graphql-jpa-query-annotations/pom.xml +++ b/graphql-jpa-query-annotations/pom.xml @@ -6,7 +6,7 @@ com.introproventures graphql-jpa-query-dependencies - 0.3.17-SNAPSHOT + 0.3.18-SNAPSHOT ../graphql-jpa-query-dependencies diff --git a/graphql-jpa-query-annotations/src/main/java/com/introproventures/graphql/jpa/query/annotation/GraphQLIgnoreFilter.java b/graphql-jpa-query-annotations/src/main/java/com/introproventures/graphql/jpa/query/annotation/GraphQLIgnoreFilter.java new file mode 100644 index 000000000..138f356e1 --- /dev/null +++ b/graphql-jpa-query-annotations/src/main/java/com/introproventures/graphql/jpa/query/annotation/GraphQLIgnoreFilter.java @@ -0,0 +1,14 @@ +package com.introproventures.graphql.jpa.query.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Target( { TYPE, FIELD }) +@Retention(RUNTIME) +public @interface GraphQLIgnoreFilter { +} + diff --git a/graphql-jpa-query-annotations/src/main/java/com/introproventures/graphql/jpa/query/annotation/GraphQLIgnoreOrder.java b/graphql-jpa-query-annotations/src/main/java/com/introproventures/graphql/jpa/query/annotation/GraphQLIgnoreOrder.java new file mode 100644 index 000000000..851a5f2a3 --- /dev/null +++ b/graphql-jpa-query-annotations/src/main/java/com/introproventures/graphql/jpa/query/annotation/GraphQLIgnoreOrder.java @@ -0,0 +1,14 @@ +package com.introproventures.graphql.jpa.query.annotation; + + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Target( { FIELD }) +@Retention(RUNTIME) +public @interface GraphQLIgnoreOrder { +} + diff --git a/graphql-jpa-query-autoconfigure/pom.xml b/graphql-jpa-query-autoconfigure/pom.xml index a2f28c8ed..f9d98e529 100644 --- a/graphql-jpa-query-autoconfigure/pom.xml +++ b/graphql-jpa-query-autoconfigure/pom.xml @@ -3,7 +3,7 @@ com.introproventures graphql-jpa-query-build - 0.3.17-SNAPSHOT + 0.3.18-SNAPSHOT ../graphql-jpa-query-build graphql-jpa-query-autoconfigure diff --git a/graphql-jpa-query-autoconfigure/src/main/java/com/introproventures/graphql/jpa/query/autoconfigure/GraphQLJpaQueryProperties.java b/graphql-jpa-query-autoconfigure/src/main/java/com/introproventures/graphql/jpa/query/autoconfigure/GraphQLJpaQueryProperties.java index d01882581..5d3a420d3 100644 --- a/graphql-jpa-query-autoconfigure/src/main/java/com/introproventures/graphql/jpa/query/autoconfigure/GraphQLJpaQueryProperties.java +++ b/graphql-jpa-query-autoconfigure/src/main/java/com/introproventures/graphql/jpa/query/autoconfigure/GraphQLJpaQueryProperties.java @@ -36,6 +36,16 @@ public class GraphQLJpaQueryProperties { @NotEmpty private String description; + /** + * Enable or disable distinct parameter. + */ + private boolean isUseDistinctParameter = false; + + /** + * Enable or disable distinct distinct sql query fetcher. + */ + private boolean isDefaultDistinct = false; + /** * Enable or disable QraphQL module services. */ @@ -78,6 +88,34 @@ public void setDescription(String description) { this.description = description; } + /** + * @return the useDistinctParameter + */ + public boolean isUseDistinctParameter() { + return isUseDistinctParameter; + } + + /** + * @param useDistinctParameter the useDistinctParameter to set + */ + public void setUseDistinctParameter(boolean useDistinctParameter) { + this.isUseDistinctParameter = useDistinctParameter; + } + + /** + * @return the distinctFetcher + */ + public boolean isDefautltDistinct() { + return isDefaultDistinct; + } + + /** + * @param isDefaultDistinct the distinctFetcher to set + */ + public void setDefaultDistinct(boolean isDefaultDistinct) { + this.isDefaultDistinct = isDefaultDistinct; + } + /** * @return the enabled */ diff --git a/graphql-jpa-query-autoconfigure/src/main/resources/com/introproventures/graphql/jpa/query/boot/autoconfigure/default.properties b/graphql-jpa-query-autoconfigure/src/main/resources/com/introproventures/graphql/jpa/query/boot/autoconfigure/default.properties index 8a9deba1d..b9d9d296e 100644 --- a/graphql-jpa-query-autoconfigure/src/main/resources/com/introproventures/graphql/jpa/query/boot/autoconfigure/default.properties +++ b/graphql-jpa-query-autoconfigure/src/main/resources/com/introproventures/graphql/jpa/query/boot/autoconfigure/default.properties @@ -1,4 +1,6 @@ spring.graphql.jpa.query.name=Query spring.graphql.jpa.query.description= +spring.graphql.jpa.query.useDistinctParameter=false +spring.graphql.jpa.query.defaultDistinct=false spring.graphql.jpa.query.enabled=true spring.graphql.jpa.query.path=/graphql \ No newline at end of file diff --git a/graphql-jpa-query-boot-starter/pom.xml b/graphql-jpa-query-boot-starter/pom.xml index 1eaa43cbb..df42b8cc2 100644 --- a/graphql-jpa-query-boot-starter/pom.xml +++ b/graphql-jpa-query-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.introproventures graphql-jpa-query-build - 0.3.17-SNAPSHOT + 0.3.18-SNAPSHOT ../graphql-jpa-query-build diff --git a/graphql-jpa-query-boot-starter/src/main/resources/com/introproventures/graphql/jpa/query/boot/autoconfigure/default.properties b/graphql-jpa-query-boot-starter/src/main/resources/com/introproventures/graphql/jpa/query/boot/autoconfigure/default.properties index 345d9ccf2..5465f5831 100644 --- a/graphql-jpa-query-boot-starter/src/main/resources/com/introproventures/graphql/jpa/query/boot/autoconfigure/default.properties +++ b/graphql-jpa-query-boot-starter/src/main/resources/com/introproventures/graphql/jpa/query/boot/autoconfigure/default.properties @@ -1,4 +1,6 @@ spring.graphql.jpa.query.name=GraphQLJpaQuery spring.graphql.jpa.query.description=GraphQL Jpa Query Schema Specification +spring.graphql.jpa.query.useDistinctParameter=false +spring.graphql.jpa.query.distinctFetcher=false spring.graphql.jpa.query.enabled=true spring.graphql.jpa.query.path=/graphql \ No newline at end of file diff --git a/graphql-jpa-query-build/pom.xml b/graphql-jpa-query-build/pom.xml index a7346f109..2fb13b501 100644 --- a/graphql-jpa-query-build/pom.xml +++ b/graphql-jpa-query-build/pom.xml @@ -3,7 +3,7 @@ com.introproventures graphql-jpa-query-dependencies - 0.3.17-SNAPSHOT + 0.3.18-SNAPSHOT ../graphql-jpa-query-dependencies graphql-jpa-query-build diff --git a/graphql-jpa-query-dependencies/pom.xml b/graphql-jpa-query-dependencies/pom.xml index 7234f7063..4d5f7d9b1 100644 --- a/graphql-jpa-query-dependencies/pom.xml +++ b/graphql-jpa-query-dependencies/pom.xml @@ -3,7 +3,7 @@ com.introproventures graphql-jpa-query - 0.3.17-SNAPSHOT + 0.3.18-SNAPSHOT .. graphql-jpa-query-dependencies diff --git a/graphql-jpa-query-example-merge/pom.xml b/graphql-jpa-query-example-merge/pom.xml index 0697910a6..a236a7830 100644 --- a/graphql-jpa-query-example-merge/pom.xml +++ b/graphql-jpa-query-example-merge/pom.xml @@ -7,13 +7,13 @@ com.introproventures graphql-jpa-query-build - 0.3.17-SNAPSHOT + 0.3.18-SNAPSHOT ../graphql-jpa-query-build true - ${maven.deploy.skip} + false @@ -32,7 +32,7 @@ com.introproventures graphql-jpa-query-autoconfigure - + org.springframework.boot spring-boot-starter-web diff --git a/graphql-jpa-query-example-merge/src/main/java/com/introproventures/graphql/jpa/query/example/books/Book.java b/graphql-jpa-query-example-merge/src/main/java/com/introproventures/graphql/jpa/query/example/books/Book.java index a81493125..07fce13ab 100644 --- a/graphql-jpa-query-example-merge/src/main/java/com/introproventures/graphql/jpa/query/example/books/Book.java +++ b/graphql-jpa-query-example-merge/src/main/java/com/introproventures/graphql/jpa/query/example/books/Book.java @@ -23,6 +23,8 @@ import javax.persistence.Id; import javax.persistence.ManyToOne; +import com.introproventures.graphql.jpa.query.annotation.GraphQLIgnoreFilter; +import com.introproventures.graphql.jpa.query.annotation.GraphQLIgnoreOrder; import lombok.Data; @Data @@ -31,6 +33,8 @@ public class Book { @Id Long id; + @GraphQLIgnoreOrder + @GraphQLIgnoreFilter String title; @ManyToOne(fetch=FetchType.LAZY) diff --git a/graphql-jpa-query-example-merge/src/main/java/com/introproventures/graphql/jpa/query/example/books/BooksSchemaConfiguration.java b/graphql-jpa-query-example-merge/src/main/java/com/introproventures/graphql/jpa/query/example/books/BooksSchemaConfiguration.java index 85d099889..605bc389c 100644 --- a/graphql-jpa-query-example-merge/src/main/java/com/introproventures/graphql/jpa/query/example/books/BooksSchemaConfiguration.java +++ b/graphql-jpa-query-example-merge/src/main/java/com/introproventures/graphql/jpa/query/example/books/BooksSchemaConfiguration.java @@ -7,11 +7,13 @@ import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; +import com.introproventures.graphql.jpa.query.autoconfigure.GraphQLJpaQueryProperties; import com.introproventures.graphql.jpa.query.autoconfigure.GraphQLSchemaConfigurer; import com.introproventures.graphql.jpa.query.autoconfigure.GraphQLShemaRegistration; import com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaSchemaBuilder; import org.hibernate.cfg.AvailableSettings; import org.hibernate.dialect.H2Dialect; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; @@ -74,14 +76,22 @@ public static class GraphQLJpaQuerySchemaConfigurer implements GraphQLSchemaConf private final EntityManager entityManager; + @Autowired + private GraphQLJpaQueryProperties properties; + public GraphQLJpaQuerySchemaConfigurer(@Qualifier("bookEntityManager") EntityManagerFactory entityManager) { this.entityManager = entityManager.createEntityManager(); } @Override public void configure(GraphQLShemaRegistration registry) { - - registry.register(new GraphQLJpaSchemaBuilder(entityManager).name("GraphQLBooks").build()); + registry.register( + new GraphQLJpaSchemaBuilder(entityManager) + .name("GraphQLBooks") + .useDistinctParameter(properties.isUseDistinctParameter()) + .setDefaultDistinct(properties.isDefautltDistinct()) + .build() + ); } } diff --git a/graphql-jpa-query-example-merge/src/main/resources/application.yml b/graphql-jpa-query-example-merge/src/main/resources/application.yml index b23f02b12..9983202bc 100644 --- a/graphql-jpa-query-example-merge/src/main/resources/application.yml +++ b/graphql-jpa-query-example-merge/src/main/resources/application.yml @@ -10,7 +10,9 @@ spring: query: name: Query description: Combined GraphQL Jpa Query for Starwars and Books Example + useDistinctParameter: true enabled: true + path: graphql starwars: hikari: diff --git a/graphql-jpa-query-example/pom.xml b/graphql-jpa-query-example/pom.xml index 8c27cf64f..41668030f 100644 --- a/graphql-jpa-query-example/pom.xml +++ b/graphql-jpa-query-example/pom.xml @@ -7,13 +7,13 @@ com.introproventures graphql-jpa-query-build - 0.3.17-SNAPSHOT + 0.3.18-SNAPSHOT ../graphql-jpa-query-build true - ${maven.deploy.skip} + false diff --git a/graphql-jpa-query-schema/pom.xml b/graphql-jpa-query-schema/pom.xml index c97c5742a..c2d9e0a16 100644 --- a/graphql-jpa-query-schema/pom.xml +++ b/graphql-jpa-query-schema/pom.xml @@ -5,7 +5,7 @@ com.introproventures graphql-jpa-query-build - 0.3.17-SNAPSHOT + 0.3.18-SNAPSHOT ../graphql-jpa-query-build diff --git a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaQueryDataFetcher.java b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaQueryDataFetcher.java index 5c5277148..b1a8c2dfb 100644 --- a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaQueryDataFetcher.java +++ b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaQueryDataFetcher.java @@ -46,6 +46,8 @@ * */ class GraphQLJpaQueryDataFetcher extends QraphQLJpaBaseDataFetcher { + + private boolean defaultDistinct = false; private static final String HIBERNATE_QUERY_PASS_DISTINCT_THROUGH = "hibernate.query.passDistinctThrough"; private static final String ORG_HIBERNATE_CACHEABLE = "org.hibernate.cacheable"; @@ -57,6 +59,19 @@ public GraphQLJpaQueryDataFetcher(EntityManager entityManager, EntityType ent super(entityManager, entityType); } + public GraphQLJpaQueryDataFetcher(EntityManager entityManager, EntityType entityType, boolean defaultDistinct) { + super(entityManager, entityType); + this.defaultDistinct = defaultDistinct; + } + + public boolean isDefaultDistinct() { + return defaultDistinct; + } + + public void setDefaultDistinct(boolean defaultDistinct) { + this.defaultDistinct = defaultDistinct; + } + @Override public Object get(DataFetchingEnvironment environment) { Field field = environment.getFields().iterator().next(); @@ -69,7 +84,7 @@ public Object get(DataFetchingEnvironment environment) { Optional pageArgument = getPageArgument(field); Page page = extractPageArgument(environment, field); - Argument distinctArg = extractArgument(environment, field, GraphQLJpaSchemaBuilder.SELECT_DISTINCT_PARAM_NAME, new BooleanValue(true)); + Argument distinctArg = extractArgument(environment, field, GraphQLJpaSchemaBuilder.SELECT_DISTINCT_PARAM_NAME, new BooleanValue(defaultDistinct)); boolean isDistinct = ((BooleanValue) distinctArg.getValue()).isValue(); diff --git a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaSchemaBuilder.java b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaSchemaBuilder.java index 2226ad17b..20c07785d 100644 --- a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaSchemaBuilder.java +++ b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaSchemaBuilder.java @@ -48,6 +48,8 @@ import com.introproventures.graphql.jpa.query.annotation.GraphQLDescription; import com.introproventures.graphql.jpa.query.annotation.GraphQLIgnore; +import com.introproventures.graphql.jpa.query.annotation.GraphQLIgnoreFilter; +import com.introproventures.graphql.jpa.query.annotation.GraphQLIgnoreOrder; import com.introproventures.graphql.jpa.query.schema.GraphQLSchemaBuilder; import com.introproventures.graphql.jpa.query.schema.JavaScalars; import com.introproventures.graphql.jpa.query.schema.NamingStrategy; @@ -113,6 +115,9 @@ public class GraphQLJpaSchemaBuilder implements GraphQLSchemaBuilder { private String description = "GraphQL Schema for all entities in this JPA application"; + private boolean isUseDistinctParameter = false; + private boolean isDefaultDistinct = false; + public GraphQLJpaSchemaBuilder(EntityManager entityManager) { this.entityManager = entityManager; } @@ -192,22 +197,35 @@ private GraphQLFieldDefinition getQueryFieldSelectDefinition(EntityType entit .build() ) .build(); - - return GraphQLFieldDefinition.newFieldDefinition() + + GraphQLFieldDefinition.Builder fdBuilder = GraphQLFieldDefinition.newFieldDefinition() .name(namingStrategy.pluralize(entityType.getName())) .description("Query request wrapper for " + entityType.getName() + " to request paginated data. " + "Use query request arguments to specify query filter criterias. " + "Use the '"+QUERY_SELECT_PARAM_NAME+"' field to request actual fields. " + "Use the '"+ORDER_BY_PARAM_NAME+"' on a field to specify sort order for each field. ") .type(pageType) - .dataFetcher(new GraphQLJpaQueryDataFetcher(entityManager, entityType)) + .dataFetcher(new GraphQLJpaQueryDataFetcher(entityManager, entityType, isDefaultDistinct)) .argument(paginationArgument) - .argument(getWhereArgument(entityType)) - .build(); + .argument(getWhereArgument(entityType)); + if (isUseDistinctParameter) { + fdBuilder.argument(distinctArgument(entityType)); + } + + return fdBuilder.build(); } private Map, GraphQLArgument> whereArgumentsMap = new HashMap<>(); + private GraphQLArgument distinctArgument(EntityType entityType) { + return GraphQLArgument.newArgument() + .name(SELECT_DISTINCT_PARAM_NAME) + .description("Distinct logical specification") + .type(Scalars.GraphQLBoolean) + .defaultValue(isDefaultDistinct) + .build(); + } + private GraphQLArgument getWhereArgument(ManagedType managedType) { String typeName=""; if (managedType instanceof EmbeddableType){ @@ -241,18 +259,21 @@ private GraphQLArgument getWhereArgument(ManagedType managedType) { .fields(managedType.getAttributes().stream() .filter(this::isValidInput) .filter(this::isNotIgnored) + .filter(this::isNotIgnoredFilter) .map(this::getWhereInputField) .collect(Collectors.toList()) ) .fields(managedType.getAttributes().stream() .filter(this::isToOne) .filter(this::isNotIgnored) + .filter(this::isNotIgnoredFilter) .map(this::getInputObjectField) .collect(Collectors.toList()) ) .fields(managedType.getAttributes().stream() .filter(this::isToMany) .filter(this::isNotIgnored) + .filter(this::isNotIgnoredFilter) .map(this::getInputObjectField) .collect(Collectors.toList()) ) @@ -302,6 +323,7 @@ private GraphQLInputObjectType computeWhereInputType(ManagedType managedType) .fields(managedType.getAttributes().stream() .filter(this::isValidInput) .filter(this::isNotIgnored) + .filter(this::isNotIgnoredFilter) .map(this::getWhereInputField) .collect(Collectors.toList()) ) @@ -568,7 +590,8 @@ private GraphQLFieldDefinition getObjectField(Attribute attribute) { // Only add the orderBy argument for basic attribute types if (attribute instanceof SingularAttribute - && attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.BASIC) { + && attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.BASIC + && isNotIgnoredOrder(attribute) ) { arguments.add(GraphQLArgument.newArgument() .name(ORDER_BY_PARAM_NAME) .description("Specifies field sort direction in the query results.") @@ -816,6 +839,37 @@ private boolean isNotIgnored(AnnotatedElement annotatedElement) { return false; } + + protected boolean isNotIgnoredFilter(Attribute attribute) { + return isNotIgnoredFilter(attribute.getJavaMember()) && isNotIgnoredFilter(attribute.getJavaType()); + } + + protected boolean isNotIgnoredFilter(EntityType entityType) { + return isNotIgnoredFilter(entityType.getJavaType()); + } + + protected boolean isNotIgnoredFilter(Member member) { + return member instanceof AnnotatedElement && isNotIgnoredFilter((AnnotatedElement) member); + } + + protected boolean isNotIgnoredFilter(AnnotatedElement annotatedElement) { + if (annotatedElement != null) { + GraphQLIgnoreFilter schemaDocumentation = annotatedElement.getAnnotation(GraphQLIgnoreFilter.class); + return schemaDocumentation == null; + } + + return false; + } + + protected boolean isNotIgnoredOrder(Attribute attribute) { + AnnotatedElement annotatedElement = (AnnotatedElement)attribute.getJavaMember(); + if (annotatedElement != null) { + GraphQLIgnoreOrder schemaDocumentation = annotatedElement.getAnnotation(GraphQLIgnoreOrder.class); + return schemaDocumentation == null; + } + return false; + } + @SuppressWarnings( "unchecked" ) private GraphQLOutputType getGraphQLTypeFromJavaType(Class clazz) { @@ -934,6 +988,26 @@ public GraphQLJpaSchemaBuilder description(String description) { return this; } + public GraphQLJpaSchemaBuilder useDistinctParameter(boolean distinctArgument) { + this.isUseDistinctParameter = distinctArgument; + + return this; + } + + public boolean isDistinctParameter() { + return isUseDistinctParameter; + } + + public boolean isDistinctFetcher() { + return isDefaultDistinct; + } + + public GraphQLJpaSchemaBuilder setDefaultDistinct(boolean distinctFetcher) { + this.isDefaultDistinct = distinctFetcher; + + return this; + } + /** * @param namingStrategy the namingStrategy to set */ diff --git a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/GraphQLExecutorTests.java b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/GraphQLExecutorTests.java index 7f1e88731..03d76f669 100644 --- a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/GraphQLExecutorTests.java +++ b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/GraphQLExecutorTests.java @@ -18,11 +18,17 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; - +import java.util.List; import javax.persistence.EntityManager; - +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; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -34,8 +40,6 @@ 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; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment=WebEnvironment.NONE) @@ -671,5 +675,92 @@ public void queryWithWhereInsideOneToManyRelationsWithExplictOR() { assertThat(result.toString()).isEqualTo(expected); } - + + @Test + public void ignoreFilter() { + //given + String query = "{ Books(where: {description: {LIKE: \"%Chekhov%\"}} ) { select { id title description} }}"; + + ExecutionResult res = executor.execute(query); + + + List result = executor.execute(query).getErrors(); + + //then + assertThat(result).hasSize(1); + assertThat(result.get(0)).isExactlyInstanceOf(ValidationError.class) + .extracting(ValidationError.class::cast) + .extracting("errorType", "queryPath") + .contains(ErrorType.ValidationError, Arrays.asList("Books")); + + } + + @Test + public void ignoreSubFilter() { + //given + String query = "query { " + + "Authors(where: {" + + " books: {" + + " OR: { "+ + " genre: {IN: NOVEL}" + + " description: {LIKE: \"War\"}" + + " }" + + " }" + + " }) {" + + " select {" + + " id" + + " name" + + " books {" + + " id" + + " title" + + " genre" + + " }" + + " }" + + " }" + + "}"; + + List result = executor.execute(query).getErrors(); + + //then + assertThat(result).hasSize(1); + assertThat(result.get(0)).isExactlyInstanceOf(ValidationError.class) + .extracting(ValidationError.class::cast) + .extracting("errorType", "queryPath") + .contains(ErrorType.ValidationError, Arrays.asList("Authors")); + + } + + @Test + public void ignoreOrder() { + //given + String query = "{ Books{ select { id description(orderBy:ASC) } }}"; + + List result = executor.execute(query).getErrors(); + + //then + assertThat(result).hasSize(1); + assertThat(result.get(0)).isExactlyInstanceOf(ValidationError.class) + .extracting(ValidationError.class::cast) + .extracting("errorType", "queryPath") + .contains(ErrorType.ValidationError, Arrays.asList("Books", "select", "description")); + + } + + @Test + public void titleOrder() { + //given + String query = "{ Books{ select { id title(orderBy:ASC) description } }}"; + + String expected = "{Books={select=[" + + "{id=3, title=Anna Karenina, description=A complex novel in eight parts, with more than a dozen major characters, it is spread over more than 800 pages (depending on the translation), typically contained in two volumes.}, " + + "{id=5, title=The Cherry Orchard, description=The play concerns an aristocratic Russian landowner who returns to her family estate (which includes a large and well-known cherry orchard) just before it is auctioned to pay the mortgage.}, " + + "{id=6, title=The Seagull, description=It dramatises the romantic and artistic conflicts between four characters}, " + + "{id=7, title=Three Sisters, description=The play is sometimes included on the short list of Chekhov's outstanding plays, along with The Cherry Orchard, The Seagull and Uncle Vanya.[1]}, " + + "{id=2, title=War and Peace, description=The novel chronicles the history of the French invasion of Russia and the impact of the Napoleonic era on Tsarist society through the stories of five Russian aristocratic families.}]}}"; + //when: + Object result = executor.execute(query).getData(); + + //then: + assertThat(result.toString()).isEqualTo(expected); + } } \ No newline at end of file diff --git a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/StarwarsSchemaBuildWithDistinctTest.java b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/StarwarsSchemaBuildWithDistinctTest.java new file mode 100644 index 000000000..64b98fda8 --- /dev/null +++ b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/StarwarsSchemaBuildWithDistinctTest.java @@ -0,0 +1,83 @@ +package com.introproventures.graphql.jpa.query.schema; + +import com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaExecutor; +import com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaSchemaBuilder; +import graphql.schema.GraphQLSchema; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.persistence.EntityManager; + +import java.util.LinkedHashMap; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest( + webEnvironment= SpringBootTest.WebEnvironment.NONE +) +public class StarwarsSchemaBuildWithDistinctTest { + @SpringBootApplication + static class TestConfiguration { + @Bean + public GraphQLJpaSchemaBuilder graphQLSchemaBuilder(EntityManager entityManager) { + return new GraphQLJpaSchemaBuilder(entityManager) + .name("Starwars") + .description("Starwars Universe Schema") + .useDistinctParameter(true); + } + + @Bean + public GraphQLExecutor graphQLExecutor(final GraphQLSchemaBuilder graphQLSchemaBuilder) { + return new GraphQLJpaExecutor(graphQLSchemaBuilder.build()); + } + } + + @Autowired + private GraphQLJpaSchemaBuilder builder; + + @Autowired + private GraphQLExecutor executor; + + @Before + public void setup() { + } + + @Test + public void correctlyDerivesPageableSchemaFromGivenEntities() { + //when + GraphQLSchema schema = builder.build(); + + // then + assertThat(schema) + .describedAs("Ensure the schema is generated") + .isNotNull(); + + + //then + assertThat(schema.getQueryType() + .getFieldDefinition("CodeLists").getArguments() + ) + .describedAs("Ensure query has three arguments") + .hasSize(3); + } + + @Test + public void distinctFalse() { + //given + String query = "{ Books(distinct: false) { select { genre } }}"; + + //when + LinkedHashMap select = (LinkedHashMap)((LinkedHashMap)executor.execute(query).getData()).get("Books"); + List books = (List)select.get("select"); + + org.junit.Assert.assertTrue(books.size() > 2); + } +} diff --git a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/model/book/Book.java b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/model/book/Book.java index d5b85bdfb..9b395c1d4 100644 --- a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/model/book/Book.java +++ b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/model/book/Book.java @@ -25,6 +25,8 @@ import javax.persistence.Id; import javax.persistence.ManyToOne; +import com.introproventures.graphql.jpa.query.annotation.GraphQLIgnoreFilter; +import com.introproventures.graphql.jpa.query.annotation.GraphQLIgnoreOrder; import lombok.Data; @Data @@ -35,6 +37,10 @@ public class Book { String title; + @GraphQLIgnoreOrder + @GraphQLIgnoreFilter + String description; + @ManyToOne(fetch=FetchType.LAZY) Author author; diff --git a/graphql-jpa-query-schema/src/test/resources/data.sql b/graphql-jpa-query-schema/src/test/resources/data.sql index 1b8940258..589b9cc00 100644 --- a/graphql-jpa-query-schema/src/test/resources/data.sql +++ b/graphql-jpa-query-schema/src/test/resources/data.sql @@ -108,12 +108,17 @@ insert into thing (id, type) values -- Books insert into author (id, name, genre) values (1, 'Leo Tolstoy', 'NOVEL'); -insert into book (id, title, author_id, genre, publication_date) values (2, 'War and Peace', 1, 'NOVEL', '1869-01-01'); -insert into book (id, title, author_id, genre, publication_date) values (3, 'Anna Karenina', 1, 'NOVEL', '1877-04-01'); +insert into book (id, title, author_id, genre, publication_date, description) +values (2, 'War and Peace', 1, 'NOVEL', '1869-01-01', 'The novel chronicles the history of the French invasion of Russia and the impact of the Napoleonic era on Tsarist society through the stories of five Russian aristocratic families.'); +insert into book (id, title, author_id, genre, publication_date, description) +values (3, 'Anna Karenina', 1, 'NOVEL', '1877-04-01', 'A complex novel in eight parts, with more than a dozen major characters, it is spread over more than 800 pages (depending on the translation), typically contained in two volumes.'); insert into author (id, name, genre) values (4, 'Anton Chekhov', 'PLAY'); -insert into book (id, title, author_id, genre, publication_date) values (5, 'The Cherry Orchard', 4, 'PLAY', '1904-01-17'); -insert into book (id, title, author_id, genre, publication_date) values (6, 'The Seagull', 4, 'PLAY', '1896-10-17'); -insert into book (id, title, author_id, genre, publication_date) values (7, 'Three Sisters', 4, 'PLAY', '1900-01-01'); +insert into book (id, title, author_id, genre, publication_date, description) +values (5, 'The Cherry Orchard', 4, 'PLAY', '1904-01-17', 'The play concerns an aristocratic Russian landowner who returns to her family estate (which includes a large and well-known cherry orchard) just before it is auctioned to pay the mortgage.'); +insert into book (id, title, author_id, genre, publication_date, description) +values (6, 'The Seagull', 4, 'PLAY', '1896-10-17', 'It dramatises the romantic and artistic conflicts between four characters'); +insert into book (id, title, author_id, genre, publication_date, description) +values (7, 'Three Sisters', 4, 'PLAY', '1900-01-01', 'The play is sometimes included on the short list of Chekhov''s outstanding plays, along with The Cherry Orchard, The Seagull and Uncle Vanya.[1]'); insert into author_phone_numbers(phone_number, author_id) values ('1-123-1234', 1), diff --git a/graphql-jpa-query-web/pom.xml b/graphql-jpa-query-web/pom.xml index f3f6aa334..7288f0a36 100644 --- a/graphql-jpa-query-web/pom.xml +++ b/graphql-jpa-query-web/pom.xml @@ -3,7 +3,7 @@ com.introproventures graphql-jpa-query-build - 0.3.17-SNAPSHOT + 0.3.18-SNAPSHOT ../graphql-jpa-query-build graphql-jpa-query-web diff --git a/pom.xml b/pom.xml index 716480c57..84469e27f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.introproventures graphql-jpa-query - 0.3.17-SNAPSHOT + 0.3.18-SNAPSHOT pom