From d3126cadd014018a090fd0c623c201430e7cb1e9 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 19 Apr 2018 12:18:00 +0200 Subject: [PATCH] =?UTF-8?q?DATACASS-549=20-=20Add=20Criteria.ne(=E2=80=A6)?= =?UTF-8?q?=20and=20Criteria.isNotNull()=20operators.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/cassandra/core/StatementFactory.java | 16 +++++------ .../data/cassandra/core/query/Criteria.java | 25 +++++++++++++++++ .../core/query/CriteriaDefinition.java | 28 +++++++++++++++++++ .../core/query/SerializationUtils.java | 5 ++-- .../core/StatementFactoryUnitTests.java | 23 +++++++++++++-- .../core/query/CriteriaUnitTests.java | 16 +++++++++++ 6 files changed, 100 insertions(+), 13 deletions(-) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/StatementFactory.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/StatementFactory.java index 9b2e13db8..35cfc3c19 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/StatementFactory.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/StatementFactory.java @@ -65,14 +65,8 @@ import com.google.common.primitives.Ints; * * @author Mark Paluch * @author John Blum - * @see org.springframework.data.cassandra.core.query.Query - * @see org.springframework.data.cassandra.core.query.Update - * @see com.datastax.driver.core.querybuilder.Assignment - * @see com.datastax.driver.core.querybuilder.Clause - * @see com.datastax.driver.core.querybuilder.Delete - * @see com.datastax.driver.core.querybuilder.Ordering - * @see com.datastax.driver.core.querybuilder.QueryBuilder - * @see com.datastax.driver.core.querybuilder.Select + * @see Query + * @see Update * @since 2.0 */ public class StatementFactory { @@ -500,6 +494,9 @@ public class StatementFactory { case "=": return QueryBuilder.eq(columnName, predicate.getValue()); + case "!=": + return QueryBuilder.ne(columnName, predicate.getValue()); + case ">": return QueryBuilder.gt(columnName, predicate.getValue()); @@ -527,6 +524,9 @@ public class StatementFactory { case "LIKE": return QueryBuilder.like(columnName, predicate.getValue()); + case "IS NOT NULL": + return QueryBuilder.notNull(columnName); + case "CONTAINS": Assert.state(predicate.getValue() != null, () -> String.format("CONTAINS value for column %s is null", columnName)); diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/query/Criteria.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/query/Criteria.java index 1b3d77507..994906a4f 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/query/Criteria.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/query/Criteria.java @@ -92,6 +92,31 @@ public class Criteria implements CriteriaDefinition { return this; } + /** + * Create a criterion using the {@literal !=} operator. + * + * @param value the value to match against, may be {@literal null}. + * @return {@literal this} {@link Criteria} object. + * @since 2.1 + */ + public CriteriaDefinition ne(@Nullable Object value) { + + this.predicate = new Predicate(Operators.NE, value); + return this; + } + + /** + * Create a criterion using the {@literal IS NOT NULL} operator. + * + * @return {@literal this} {@link Criteria} object. + * @since 2.1 + */ + public CriteriaDefinition isNotNull() { + + this.predicate = new Predicate(Operators.IS_NOT_NULL, null); + return this; + } + /** * Create a criterion using the {@literal >} operator. * diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/query/CriteriaDefinition.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/query/CriteriaDefinition.java index b07fd81ea..b6ceba1a7 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/query/CriteriaDefinition.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/query/CriteriaDefinition.java @@ -93,6 +93,19 @@ public interface CriteriaDefinition { * @return the String representation of the operator. */ String toString(); + + /** + * Render to a CQL-like representation. Rendering does not apply conversion via + * {@link com.datastax.driver.core.CodecRegistry} therefore this output is an approximation towards CQL and not + * necessarily valid CQL. + * + * @param value optional predicate value, can be {@literal null}. + * @return A CQL-like representation. + * @since 2.1 + */ + default String toCql(@Nullable Object value) { + return String.format("%s %s", toString(), value); + } } /** @@ -103,6 +116,21 @@ public interface CriteriaDefinition { CONTAINS("CONTAINS"), CONTAINS_KEY("CONTAINS KEY"), EQ("="), + + /** + * @since 2.1 + */ + NE("!="), + + /** + * @since 2.1 + */ + IS_NOT_NULL("IS NOT NULL") { + @Override + public String toCql(@Nullable Object value) { + return toString(); + } + }, GT(">"), GTE(">="), LT("<"), diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/query/SerializationUtils.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/query/SerializationUtils.java index 0a22ad998..01c287309 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/query/SerializationUtils.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/query/SerializationUtils.java @@ -57,9 +57,8 @@ abstract class SerializationUtils { CriteriaDefinition.Predicate predicate = criteria.getPredicate(); - return serialize(criteria.getColumnName(), predicate.getOperator()) - .append(serializeToCqlSafely(predicate.getValue())).toString(); - + return String.format("%s %s", criteria.getColumnName(), + predicate.getOperator().toCql(serializeToCqlSafely(predicate.getValue()))); } /** diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/StatementFactoryUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/StatementFactoryUnitTests.java index 482972be0..e95eaa7c5 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/StatementFactoryUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/StatementFactoryUnitTests.java @@ -15,14 +15,13 @@ */ package org.springframework.data.cassandra.core; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.Test; - import org.springframework.data.annotation.Id; import org.springframework.data.cassandra.core.convert.CassandraConverter; import org.springframework.data.cassandra.core.convert.MappingCassandraConverter; @@ -73,6 +72,26 @@ public class StatementFactoryUnitTests { assertThat(select.toString()).isEqualTo("SELECT age FROM group WHERE foo='bar';"); } + @Test // DATACASS-549 + public void shouldMapSelectQueryNotEquals() { + + Query query = Query.query(Criteria.where("foo").ne("bar")).columns(Columns.from("age")); + + Statement select = statementFactory.select(query, groupEntity); + + assertThat(select.toString()).isEqualTo("SELECT age FROM group WHERE foo!='bar';"); + } + + @Test // DATACASS-549 + public void shouldMapSelectQueryIsNotNull() { + + Query query = Query.query(Criteria.where("foo").isNotNull()).columns(Columns.from("age")); + + Statement select = statementFactory.select(query, groupEntity); + + assertThat(select.toString()).isEqualTo("SELECT age FROM group WHERE foo IS NOT NULL;"); + } + @Test // DATACASS-343 public void shouldMapSelectQueryWithTtlColumns() { diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/query/CriteriaUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/query/CriteriaUnitTests.java index 075471fa4..5d3c3e6c3 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/query/CriteriaUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/query/CriteriaUnitTests.java @@ -38,6 +38,22 @@ public class CriteriaUnitTests { assertThat(serializeToCqlSafely(criteria)).isEqualTo("foo = 'bar'"); } + @Test // DATACASS-549 + public void shouldCreateIsNotEqualTo() { + + CriteriaDefinition criteria = Criteria.where("foo").ne("bar"); + + assertThat(serializeToCqlSafely(criteria)).isEqualTo("foo != 'bar'"); + } + + @Test // DATACASS-549 + public void shouldCreateIsNotNull() { + + CriteriaDefinition criteria = Criteria.where("foo").isNotNull(); + + assertThat(serializeToCqlSafely(criteria)).isEqualTo("foo IS NOT NULL"); + } + @Test // DATACASS-343 public void shouldCreateIsGreater() {