From f2da0e9876fdf1918729954ea52c46d4be48585d Mon Sep 17 00:00:00 2001 From: Igor Dianov Date: Sat, 4 May 2019 09:43:46 -0700 Subject: [PATCH 1/4] feat: add equals criteria support for custom attributes converters --- .../schema/impl/JpaPredicateBuilder.java | 23 ++- .../converter/GraphQLJpaConverterTests.java | 143 +++++++++++++++++- .../resources/GraphQLJpaConverterTests.sql | 7 +- 3 files changed, 165 insertions(+), 8 deletions(-) diff --git a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/JpaPredicateBuilder.java b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/JpaPredicateBuilder.java index 32f0e6930..35d1c8fed 100644 --- a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/JpaPredicateBuilder.java +++ b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/JpaPredicateBuilder.java @@ -16,6 +16,7 @@ package com.introproventures.graphql.jpa.query.schema.impl; +import java.lang.reflect.Constructor; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collection; @@ -31,6 +32,7 @@ import javax.persistence.criteria.Predicate; import com.introproventures.graphql.jpa.query.schema.impl.PredicateFilter.Criteria; +import graphql.language.NullValue; /** * Supported types to build predicates for @@ -414,8 +416,25 @@ else if(Collection.class.isAssignableFrom(type)) { } else if(type.isEnum()) { return getEnumPredicate((Path>) field, predicateFilter); } - else if (filter.getCriterias().contains(PredicateFilter.Criteria.LOCATE)) { - return cb.gt(cb.locate(from.get(filter.getField()), value.toString()), 0); + else if (Object.class.isAssignableFrom(type)) { + if (filter.getCriterias().contains(PredicateFilter.Criteria.LOCATE)) { + return cb.gt(cb.locate(from.get(filter.getField()), value.toString()), 0); + } + else if (Object.class.isAssignableFrom(type) && filter.getCriterias().contains(PredicateFilter.Criteria.EQ)) { + Object object = value; + + try { + Constructor constructor = type.getConstructor(Object.class); + if(constructor != null) { + Object arg = NullValue.class.isInstance(value) ? null : value; + object = constructor.newInstance(arg); + } + } catch (Exception e) { + e.printStackTrace(); + } + + return cb.equal(from.get(filter.getField()), object); + } } throw new IllegalArgumentException("Unsupported field type " + type + " for field " + predicateFilter.getField()); diff --git a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java index fa0e2ea2f..e4544d819 100644 --- a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java +++ b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java @@ -32,6 +32,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.introproventures.graphql.jpa.query.converter.model.JsonEntity; +import com.introproventures.graphql.jpa.query.converter.model.TaskVariableEntity; import com.introproventures.graphql.jpa.query.converter.model.VariableValue; import com.introproventures.graphql.jpa.query.schema.GraphQLExecutor; import com.introproventures.graphql.jpa.query.schema.GraphQLSchemaBuilder; @@ -66,7 +67,6 @@ public GraphQLExecutor graphQLExecutor(final GraphQLSchemaBuilder graphQLSchemaB @Bean public GraphQLSchemaBuilder graphQLSchemaBuilder(final EntityManager entityManager) { - JavaScalars.register(JsonNode.class, new GraphQLScalarType("Json", "Json type", new GraphQLObjectCoercing())); JavaScalars.register(VariableValue.class, new GraphQLScalarType("VariableValue", "VariableValue Type", new GraphQLObjectCoercing())); @@ -121,6 +121,27 @@ public void criteriaTester() { assertThat(result).isNotEmpty(); assertThat(result).hasSize(1); } + + @Test + @Transactional + public void criteriaTester2() { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery criteria = builder.createQuery(TaskVariableEntity.class); + Root taskVariable = criteria.from(TaskVariableEntity.class); + + Boolean object = new Boolean(true); + + VariableValue variableValue = new VariableValue<>(object); + criteria.select(taskVariable) + .where(builder.equal(taskVariable.get("value"), variableValue)); + + // when: + List result = entityManager.createQuery(criteria).getResultList(); + + // then: + assertThat(result).isNotEmpty(); + assertThat(result).hasSize(1); + } @Test // Problem with generating cast() in the where expression @Transactional @@ -239,7 +260,7 @@ public void queryTaskVariablesWhereSearchCriteria() { @Test public void queryTaskVariablesWhereSearchCriteriaVariableBinding() { //given - String query = "query($value: VariableValue!) {" + + String query = "query($value: Object!) {" + " TaskVariables(where: {" + "value: {LOCATE: $value }" + "}) {" + @@ -266,7 +287,7 @@ public void queryTaskVariablesWhereSearchCriteriaVariableBinding() { @Test public void queryProcessVariablesWhereSearchCriteriaVariableBindings() { //given - String query = "query($value: VariableValue!) {" + + String query = "query($value: Object!) {" + " ProcessVariables(where: {" + "value: {LOCATE: $value}" + "}) {" + @@ -312,5 +333,121 @@ public void queryProcessVariablesWhereSearchCriteria() { // then assertThat(result.toString()).isEqualTo(expected); } + + @Test + public void queryProcessVariablesWhereWithEQStringSearchCriteria() { + //given + String query = "query {" + + " TaskVariables(where: {" + + "value: {EQ: \"data\"}" + + "}) {" + + " select {" + + " name" + + " value" + + " }" + + " }" + + "}"; + + String expected = "{TaskVariables={select=[{name=variable1, value=data}]}}"; + + //when + Object result = executor.execute(query).getData(); + + // then + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryProcessVariablesWhereWithEQBooleanSearchCriteria() { + //given + String query = "query {" + + " TaskVariables(where: {" + + "value: {EQ: true}" + + "}) {" + + " select {" + + " name" + + " value" + + " }" + + " }" + + "}"; + + String expected = "{TaskVariables={select=[{name=variable2, value=true}]}}"; + + //when + Object result = executor.execute(query).getData(); + + // then + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryProcessVariablesWhereWithEQNullSearchCriteria() { + //given + String query = "query {" + + " TaskVariables(where: {" + + "value: {EQ: null}" + + "}) {" + + " select {" + + " name" + + " value" + + " }" + + " }" + + "}"; + + String expected = "{TaskVariables={select=[{name=variable3, value=null}]}}"; + + //when + Object result = executor.execute(query).getData(); + + // then + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryProcessVariablesWhereWithEQIntSearchCriteria() { + //given + String query = "query {" + + " TaskVariables(where: {" + + "value: {EQ: 12345}" + + "}) {" + + " select {" + + " name" + + " value" + + " }" + + " }" + + "}"; + + String expected = "{TaskVariables={select=[{name=variable6, value=12345}]}}"; + + //when + Object result = executor.execute(query).getData(); + + // then + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryProcessVariablesWhereWithEQDoubleSearchCriteria() { + //given + String query = "query {" + + " TaskVariables(where: {" + + "value: {EQ: 1.2345}" + + "}) {" + + " select {" + + " name" + + " value" + + " }" + + " }" + + "}"; + + String expected = "{TaskVariables={select=[{name=variable5, value=1.2345}]}}"; + + //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/resources/GraphQLJpaConverterTests.sql b/graphql-jpa-query-schema/src/test/resources/GraphQLJpaConverterTests.sql index 28a15be2d..d14d6c0e1 100644 --- a/graphql-jpa-query-schema/src/test/resources/GraphQLJpaConverterTests.sql +++ b/graphql-jpa-query-schema/src/test/resources/GraphQLJpaConverterTests.sql @@ -9,7 +9,8 @@ insert into PROCESS_VARIABLE (create_time, execution_id, last_updated_time, name insert into TASK_VARIABLE (create_time, execution_id, last_updated_time, name, process_instance_id, task_id, type, value) values (CURRENT_TIMESTAMP, 'execution_id', CURRENT_TIMESTAMP, 'variable1', 0, '1', 'string', '{"value":"data"}'), (CURRENT_TIMESTAMP, 'execution_id', CURRENT_TIMESTAMP, 'variable2', 0, '1', 'boolean', '{"value":true}'), - (CURRENT_TIMESTAMP, 'execution_id', CURRENT_TIMESTAMP, 'variable3', 0, '2', 'string', '{"value":null}'), + (CURRENT_TIMESTAMP, 'execution_id', CURRENT_TIMESTAMP, 'variable3', 0, '2', 'null', '{"value":null}'), (CURRENT_TIMESTAMP, 'execution_id', CURRENT_TIMESTAMP, 'variable4', 0, '2', 'json', '{"value":{"key":"data"}}'), - (CURRENT_TIMESTAMP, 'execution_id', CURRENT_TIMESTAMP, 'variable5', 1, '4', 'double', '{"value":1.0}'), - (CURRENT_TIMESTAMP, 'execution_id', CURRENT_TIMESTAMP, 'variable6', 1, '4', 'json', '{"value":[1,2,3,4,5]}'); \ No newline at end of file + (CURRENT_TIMESTAMP, 'execution_id', CURRENT_TIMESTAMP, 'variable5', 1, '4', 'double', '{"value":1.2345}'), + (CURRENT_TIMESTAMP, 'execution_id', CURRENT_TIMESTAMP, 'variable6', 1, '4', 'int', '{"value":12345}'), + (CURRENT_TIMESTAMP, 'execution_id', CURRENT_TIMESTAMP, 'variable7', 1, '4', 'json', '{"value":[1,2,3,4,5]}'); \ No newline at end of file From d03e98046e3bfdf80b19416a185247252381e687 Mon Sep 17 00:00:00 2001 From: Igor Dianov Date: Sat, 4 May 2019 09:54:43 -0700 Subject: [PATCH 2/4] fix: failing tests --- .../graphql/jpa/query/converter/GraphQLJpaConverterTests.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java index e4544d819..f831eda97 100644 --- a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java +++ b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java @@ -260,7 +260,7 @@ public void queryTaskVariablesWhereSearchCriteria() { @Test public void queryTaskVariablesWhereSearchCriteriaVariableBinding() { //given - String query = "query($value: Object!) {" + + String query = "query($value: VariableValue!) {" + " TaskVariables(where: {" + "value: {LOCATE: $value }" + "}) {" + @@ -287,7 +287,7 @@ public void queryTaskVariablesWhereSearchCriteriaVariableBinding() { @Test public void queryProcessVariablesWhereSearchCriteriaVariableBindings() { //given - String query = "query($value: Object!) {" + + String query = "query($value: VariableValue!) {" + " ProcessVariables(where: {" + "value: {LOCATE: $value}" + "}) {" + From 27285002fb41ce22216fad1143ac90e8ce2b63e0 Mon Sep 17 00:00:00 2001 From: Igor Dianov Date: Sat, 4 May 2019 22:29:54 -0700 Subject: [PATCH 3/4] fix: clean up code and improve tests --- .../graphql/jpa/query/schema/impl/JpaPredicateBuilder.java | 4 ++-- .../jpa/query/converter/GraphQLJpaConverterTests.java | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/JpaPredicateBuilder.java b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/JpaPredicateBuilder.java index 35d1c8fed..ed1e96164 100644 --- a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/JpaPredicateBuilder.java +++ b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/JpaPredicateBuilder.java @@ -415,12 +415,12 @@ else if(Collection.class.isAssignableFrom(type)) { return from.join(filter.getField()).in(value); } else if(type.isEnum()) { return getEnumPredicate((Path>) field, predicateFilter); - } + } // TODO need better detection mechanism else if (Object.class.isAssignableFrom(type)) { if (filter.getCriterias().contains(PredicateFilter.Criteria.LOCATE)) { return cb.gt(cb.locate(from.get(filter.getField()), value.toString()), 0); } - else if (Object.class.isAssignableFrom(type) && filter.getCriterias().contains(PredicateFilter.Criteria.EQ)) { + else if (filter.getCriterias().contains(PredicateFilter.Criteria.EQ)) { Object object = value; try { diff --git a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java index f831eda97..bfaf3af4d 100644 --- a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java +++ b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java @@ -339,6 +339,7 @@ public void queryProcessVariablesWhereWithEQStringSearchCriteria() { //given String query = "query {" + " TaskVariables(where: {" + + "name: {EQ: \"variable1\"}" + "value: {EQ: \"data\"}" + "}) {" + " select {" + @@ -362,6 +363,7 @@ public void queryProcessVariablesWhereWithEQBooleanSearchCriteria() { //given String query = "query {" + " TaskVariables(where: {" + + "name: {EQ: \"variable2\"}" + "value: {EQ: true}" + "}) {" + " select {" + @@ -385,6 +387,7 @@ public void queryProcessVariablesWhereWithEQNullSearchCriteria() { //given String query = "query {" + " TaskVariables(where: {" + + "name: {EQ: \"variable3\"}" + "value: {EQ: null}" + "}) {" + " select {" + @@ -408,6 +411,7 @@ public void queryProcessVariablesWhereWithEQIntSearchCriteria() { //given String query = "query {" + " TaskVariables(where: {" + + "name: {EQ: \"variable6\"}" + "value: {EQ: 12345}" + "}) {" + " select {" + @@ -431,6 +435,7 @@ public void queryProcessVariablesWhereWithEQDoubleSearchCriteria() { //given String query = "query {" + " TaskVariables(where: {" + + "name: {EQ: \"variable5\"}" + "value: {EQ: 1.2345}" + "}) {" + " select {" + From 9200feab506304feef521f55e92f0a3c1e510df9 Mon Sep 17 00:00:00 2001 From: Igor Dianov Date: Sat, 4 May 2019 22:41:09 -0700 Subject: [PATCH 4/4] fix: polish tests --- .../jpa/query/converter/GraphQLJpaConverterTests.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java index bfaf3af4d..eec768d3d 100644 --- a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java +++ b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java @@ -36,11 +36,8 @@ import com.introproventures.graphql.jpa.query.converter.model.VariableValue; import com.introproventures.graphql.jpa.query.schema.GraphQLExecutor; import com.introproventures.graphql.jpa.query.schema.GraphQLSchemaBuilder; -import com.introproventures.graphql.jpa.query.schema.JavaScalars; -import com.introproventures.graphql.jpa.query.schema.JavaScalars.GraphQLObjectCoercing; import com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaExecutor; import com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaSchemaBuilder; -import graphql.schema.GraphQLScalarType; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -67,12 +64,9 @@ public GraphQLExecutor graphQLExecutor(final GraphQLSchemaBuilder graphQLSchemaB @Bean public GraphQLSchemaBuilder graphQLSchemaBuilder(final EntityManager entityManager) { - JavaScalars.register(JsonNode.class, new GraphQLScalarType("Json", "Json type", new GraphQLObjectCoercing())); - JavaScalars.register(VariableValue.class, new GraphQLScalarType("VariableValue", "VariableValue Type", new GraphQLObjectCoercing())); - return new GraphQLJpaSchemaBuilder(entityManager) - .name("HashMapSchema") - .description("Json Entity test schema"); + .name("CustomAttributeConverterSchema") + .description("Custom Attribute Converter Schema"); } }