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 c1f081c03..eff118eec 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 @@ -511,16 +511,34 @@ private GraphQLInputType getWhereAttributeType(Attribute attribute) { if(attribute.getJavaType().equals(String.class)) { builder.field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.LIKE.name()) - .description("Like criteria") + .description("Like criteria, case sensitive") .type(getAttributeInputType(attribute)) .build() ) + .field(GraphQLInputObjectField.newInputObjectField() + .name(Criteria.LIKE_.name()) + .description("Like criteria, case insensitive") + .type(getAttributeInputType(attribute)) + .build() + ) .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.LOWER.name()) .description("Case insensitive match criteria") .type(getAttributeInputType(attribute)) .build() ) + .field(GraphQLInputObjectField.newInputObjectField() + .name(Criteria.EQ_.name()) + .description("Case equals case insensitive match criteria") + .type(getAttributeInputType(attribute)) + .build() + ) + .field(GraphQLInputObjectField.newInputObjectField() + .name(Criteria.NE_.name()) + .description("Not equals case insensitive match criteria") + .type(getAttributeInputType(attribute)) + .build() + ) .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.CASE.name()) .description("Case sensitive match criteria") @@ -529,15 +547,27 @@ private GraphQLInputType getWhereAttributeType(Attribute attribute) { ) .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.STARTS.name()) - .description("Starts with criteria") + .description("Starts with criteria, case sensitive") .type(getAttributeInputType(attribute)) .build() ) + .field(GraphQLInputObjectField.newInputObjectField() + .name(Criteria.STARTS_.name()) + .description("Starts with criteria, case insensitive") + .type(getAttributeInputType(attribute)) + .build() + ) .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.ENDS.name()) - .description("Ends with criteria") + .description("Ends with criteria, case sensitive") .type(getAttributeInputType(attribute)) .build() + ) + .field(GraphQLInputObjectField.newInputObjectField() + .name(Criteria.ENDS_.name()) + .description("Ends with criteria, case insensitive") + .type(getAttributeInputType(attribute)) + .build() ); } else if (attribute.getJavaMember().getClass().isAssignableFrom(Field.class) 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 1b79ed7bb..05d08f541 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; @@ -130,43 +131,47 @@ protected Predicate getStringPredicate(Path root, PredicateFilter filter String compareValue = filter.getValue().toString(); Expression fieldValue = root; - if (filter.getCriterias().contains(PredicateFilter.Criteria.IN)) { - CriteriaBuilder.In in = cb.in(root); + if (filter.anyMatch(Criteria.EQ_, Criteria.NE_, Criteria.LIKE_, Criteria.STARTS_, Criteria.ENDS_, Criteria.LOWER)) { + compareValue = compareValue.toLowerCase(); + fieldValue = cb.lower(fieldValue); + }; + + if (filter.getCriterias().contains(Criteria.IN)) { + CriteriaBuilder.In in = cb.in(fieldValue); return in.value(compareValue); } - if (filter.getCriterias().contains(PredicateFilter.Criteria.NIN)) { - return cb.not(root.in(compareValue)); + if (filter.getCriterias().contains(Criteria.NIN)) { + return cb.not(fieldValue.in(compareValue)); } - if (filter.getCriterias().contains(PredicateFilter.Criteria.EQ)) { + if (filter.anyMatch(Criteria.EQ, Criteria.LOWER, Criteria.EQ_)) { return cb.equal(fieldValue, compareValue); } - else if (filter.getCriterias().contains(PredicateFilter.Criteria.LOWER)) { - return cb.equal(cb.lower(fieldValue), - compareValue.toLowerCase()); - } - else if (filter.getCriterias().contains(PredicateFilter.Criteria.NE)) { + else if (filter.anyMatch(Criteria.NE, Criteria.NE_)) { return cb.notEqual(fieldValue, compareValue); } - else if (filter.getCriterias().contains(PredicateFilter.Criteria.LIKE)) { + else if (filter.anyMatch(Criteria.LIKE, Criteria.LIKE_)) { compareValue = "%" + compareValue + "%"; } - else if (filter.getCriterias().contains(PredicateFilter.Criteria.ENDS)) { + else if (filter.anyMatch(Criteria.STARTS, Criteria.STARTS_)) { + compareValue = compareValue + "%"; + } + else if (filter.anyMatch(Criteria.ENDS, Criteria.ENDS_)) { compareValue = "%" + compareValue; } - else if (filter.getCriterias().contains(PredicateFilter.Criteria.EXACT)) { + else if (filter.anyMatch(Criteria.EXACT, Criteria.CASE)) { // do nothing - } - // STARTS or empty (default) + } // default empty else { - compareValue = compareValue + "%"; + compareValue = "%"; } + return cb.like(fieldValue, compareValue); } return arrayValuePredicate; } - + protected Predicate getBooleanPredicate(Path root, PredicateFilter filter) { Boolean bool = (Boolean) filter.getValue(); if (filter.getCriterias().contains(PredicateFilter.Criteria.NE)) { diff --git a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/PredicateFilter.java b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/PredicateFilter.java index b4840ec39..db9accfcc 100644 --- a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/PredicateFilter.java +++ b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/PredicateFilter.java @@ -20,6 +20,7 @@ import java.util.EnumSet; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; class PredicateFilter implements Comparable, Serializable { @@ -53,9 +54,13 @@ public enum Criteria { */ EQ, /** - * not equal (numbers, dates, booleans) + * not equal (numbers, dates, booleans, strings) */ NE, + /** + * not equal strings, case insensitive + */ + NE_, /** * case sensitive (strings) */ @@ -64,21 +69,35 @@ public enum Criteria { * case insensitive match *
LOWER(field) = LOWER(SEARCH)
*/ - LOWER, + LOWER, EQ_, /** - * end of the string matches + * end of the string matches, case sensitive */ ENDS, /** - * beginning of string matches + * end of the string matches, case insensitive + */ + ENDS_, + /** + * beginning of string matches, case sensitive *
LIKE SEARCH%
*/ STARTS, /** - * any part of the string matches + * beginning of string matches, case insensitive + *
LIKE SEARCH%
+ */ + STARTS_, + /** + * any part of the string matches, case sensitive *
LIKE %SEARCH%
*/ LIKE, + /** + * any part of the string matches, case insensitive + *
LIKE %SEARCH%
+ */ + LIKE_, /** * full string match = */ @@ -151,4 +170,10 @@ public Set getCriterias() { public int compareTo(PredicateFilter o) { return this.getField().compareTo(o.getField()); } + + public boolean anyMatch(Criteria...criterias) { + return Stream.of(criterias) + .anyMatch(criteria -> this.getCriterias() + .contains(criteria)); + } } \ No newline at end of file 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 cc4a35591..ba03321a5 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 @@ -1578,6 +1578,237 @@ public void queryWithLOWERMatchingCase() { //when: Object result = executor.execute(query).getData(); + //then: + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryWithEQCaseInsensitive() { + //given: + String query = "query { Books ( where: { title: {EQ_ : \"WAR AND PEACE\"}}) { select { id title} } }"; + + String expected = "{Books={select=[" + + "{id=2, title=War and Peace}" + + "]}}"; + + //when: + Object result = executor.execute(query).getData(); + + //then: + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryWithEQCaseSensitive() { + //given: + String query = "query { Books ( where: { title: {EQ : \"War and Peace\"}}) { select { id title} } }"; + + String expected = "{Books={select=[" + + "{id=2, title=War and Peace}" + + "]}}"; + + //when: + Object result = executor.execute(query).getData(); + + //then: + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryWithEQCaseSensitiveNotMatching() { + //given: + String query = "query { Books ( where: { title: {EQ : \"war and peace\"}}) { select { id title} } }"; + + String expected = "{Books={select=[]}}"; + + //when: + Object result = executor.execute(query).getData(); + + //then: + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryWithNECaseInsensitive() { + //given: + String query = "query { Books ( where: { title: {NE_ : \"ANNA karenina\"} author: {id: {EQ: 1}}}) { select { id title} } }"; + + String expected = "{Books={select=[" + + "{id=2, title=War and Peace}" + + "]}}"; + + //when: + Object result = executor.execute(query).getData(); + + //then: + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryWithNECaseSensitive() { + //given: + String query = "query { Books ( where: { title: {NE : \"Anna Karenina\"} author: {id: {EQ: 1}}}) { select { id title} } }"; + + String expected = "{Books={select=[" + + "{id=2, title=War and Peace}" + + "]}}"; + + //when: + Object result = executor.execute(query).getData(); + + //then: + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryWithNECaseSensitiveNonMatching() { + //given: + String query = "query { Books ( where: { title: {NE : \"anna karenina\"} author: {id: {EQ: 1}}}) { select { id title} } }"; + + String expected = "{Books={select=[" + + "{id=2, title=War and Peace}, " + + "{id=3, title=Anna Karenina}" + + "]}}"; + + //when: + Object result = executor.execute(query).getData(); + + //then: + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryWithLIKECaseInsensitive() { + //given: + String query = "query { Books ( where: { title: {LIKE_ : \"AND\"}}) { select { id title} } }"; + + String expected = "{Books={select=[" + + "{id=2, title=War and Peace}" + + "]}}"; + + //when: + Object result = executor.execute(query).getData(); + + //then: + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryWithLIKECaseSensitive() { + //given: + String query = "query { Books ( where: { title: {LIKE : \"and\"}}) { select { id title} } }"; + + String expected = "{Books={select=[" + + "{id=2, title=War and Peace}" + + "]}}"; + + //when: + Object result = executor.execute(query).getData(); + + //then: + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryWithLIKECaseSensitiveNonMatching() { + //given: + String query = "query { Books ( where: { title: {LIKE : \"And\"}}) { select { id title} } }"; + + String expected = "{Books={select=[]}}"; + + //when: + Object result = executor.execute(query).getData(); + + //then: + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryWithSTARTSCaseInsensitive() { + //given: + String query = "query { Books ( where: { title: {STARTS_ : \"WAR\"}}) { select { id title} } }"; + + String expected = "{Books={select=[" + + "{id=2, title=War and Peace}" + + "]}}"; + + //when: + Object result = executor.execute(query).getData(); + + //then: + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryWithSTARTSCaseSensitive() { + //given: + String query = "query { Books ( where: { title: {STARTS : \"War\"}}) { select { id title} } }"; + + String expected = "{Books={select=[" + + "{id=2, title=War and Peace}" + + "]}}"; + + //when: + Object result = executor.execute(query).getData(); + + //then: + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryWithSTARTSCaseSensitiveNonMatching() { + //given: + String query = "query { Books ( where: { title: {STARTS : \"war\"}}) { select { id title} } }"; + + String expected = "{Books={select=[]}}"; + + //when: + Object result = executor.execute(query).getData(); + + //then: + assertThat(result.toString()).isEqualTo(expected); + } + + @Test + public void queryWithENDSCaseInsensitive() { + //given: + String query = "query { Books ( where: { title: {ENDS_ : \"PEACE\"}}) { select { id title} } }"; + + String expected = "{Books={select=[" + + "{id=2, title=War and Peace}" + + "]}}"; + + //when: + Object result = executor.execute(query).getData(); + + //then: + assertThat(result.toString()).isEqualTo(expected); + } + + public void queryWithENDSCaseSensitive() { + //given: + String query = "query { Books ( where: { title: {ENDS : \"Peace\"}}) { select { id title} } }"; + + String expected = "{Books={select=[" + + "{id=2, title=War and Peace}" + + "]}}"; + + //when: + Object result = executor.execute(query).getData(); + + //then: + assertThat(result.toString()).isEqualTo(expected); + } + + public void queryWithENDSCaseSensitiveNonMatching() { + //given: + String query = "query { Books ( where: { title: {ENDS : \"peace\"}}) { select { id title} } }"; + + String expected = "{Books={select=[]}}"; + + //when: + Object result = executor.execute(query).getData(); + //then: assertThat(result.toString()).isEqualTo(expected); }