From 62e6d3331403d26a8d9bcd01e6ea6bbf89cf9a67 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 1 Sep 2017 10:39:38 +0200 Subject: [PATCH] DATACASS-56 - Allow query options mutation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now allow query option mutation through QueryOptions.mutate() returning an initialized builder. The mutation builder is initialized with the state of the QueryOptions object and allows further customization without changing the previous state of the immutable QueryOptions object. QueryOptions queryOptions = …; QueryOptions mutated = queryOptions.mutate().readTimeout(Duration.ofSeconds(5)).build(); --- .../data/cassandra/core/InsertOptions.java | 18 +++++++++++++++ .../data/cassandra/core/UpdateOptions.java | 18 +++++++++++++++ .../data/cassandra/core/cql/QueryOptions.java | 21 +++++++++++++++++ .../data/cassandra/core/cql/WriteOptions.java | 21 ++++++++++++++++- .../core/InsertOptionsUnitTests.java | 14 +++++++++++ .../core/UpdateOptionsUnitTests.java | 14 +++++++++++ .../core/cql/QueryOptionsUnitTests.java | 21 +++++++++++++++++ .../core/cql/WriteOptionsUnitTests.java | 23 +++++++++++++++++++ 8 files changed, 149 insertions(+), 1 deletion(-) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/InsertOptions.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/InsertOptions.java index b1c831103..4f9c90c15 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/InsertOptions.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/InsertOptions.java @@ -18,6 +18,7 @@ package org.springframework.data.cassandra.core; import java.time.Duration; import java.util.concurrent.TimeUnit; +import lombok.EqualsAndHashCode; import org.springframework.data.cassandra.core.cql.WriteOptions; import org.springframework.lang.Nullable; @@ -30,6 +31,7 @@ import com.datastax.driver.core.policies.RetryPolicy; * @author Mark Paluch * @since 2.0 */ +@EqualsAndHashCode(callSuper = true) public class InsertOptions extends WriteOptions { private static final InsertOptions EMPTY = new InsertOptionsBuilder().build(); @@ -62,6 +64,16 @@ public class InsertOptions extends WriteOptions { return new InsertOptionsBuilder(); } + /** + * Create a new {@link InsertOptionsBuilder} to mutate properties of this {@link InsertOptions}. + * + * @return a new {@link InsertOptionsBuilder} initialized with this {@link InsertOptions}. + */ + @Override + public InsertOptionsBuilder mutate() { + return new InsertOptionsBuilder(this); + } + /** * @return {@literal true} to apply {@code IF NOT EXISTS} to {@code INSERT} operations. */ @@ -81,6 +93,12 @@ public class InsertOptions extends WriteOptions { private InsertOptionsBuilder() {} + private InsertOptionsBuilder(InsertOptions insertOptions) { + + super(insertOptions); + this.ifNotExists = insertOptions.ifNotExists; + } + @Override public InsertOptionsBuilder consistencyLevel(com.datastax.driver.core.ConsistencyLevel consistencyLevel) { return (InsertOptionsBuilder) super.consistencyLevel(consistencyLevel); diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/UpdateOptions.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/UpdateOptions.java index 58f95f243..f6160e2d3 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/UpdateOptions.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/UpdateOptions.java @@ -18,6 +18,7 @@ package org.springframework.data.cassandra.core; import java.time.Duration; import java.util.concurrent.TimeUnit; +import lombok.EqualsAndHashCode; import org.springframework.data.cassandra.core.cql.WriteOptions; import org.springframework.lang.Nullable; @@ -30,6 +31,7 @@ import com.datastax.driver.core.policies.RetryPolicy; * @author Mark Paluch * @since 2.0 */ +@EqualsAndHashCode(callSuper = true) public class UpdateOptions extends WriteOptions { private static final UpdateOptions EMPTY = new UpdateOptionsBuilder().build(); @@ -62,6 +64,16 @@ public class UpdateOptions extends WriteOptions { return new UpdateOptionsBuilder(); } + /** + * Create a new {@link UpdateOptionsBuilder} to mutate properties of this {@link UpdateOptions}. + * + * @return a new {@link UpdateOptionsBuilder} initialized with this {@link UpdateOptions}. + */ + @Override + public UpdateOptionsBuilder mutate() { + return new UpdateOptionsBuilder(this); + } + /** * @return {@literal true} to apply {@code IF EXISTS} to {@code UPDATE} operations. */ @@ -81,6 +93,12 @@ public class UpdateOptions extends WriteOptions { private UpdateOptionsBuilder() {} + private UpdateOptionsBuilder(UpdateOptions updateOptions) { + + super(updateOptions); + this.ifExists = updateOptions.ifExists; + } + @Override public UpdateOptionsBuilder consistencyLevel(com.datastax.driver.core.ConsistencyLevel consistencyLevel) { return (UpdateOptionsBuilder) super.consistencyLevel(consistencyLevel); diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/QueryOptions.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/QueryOptions.java index dad353e92..5d87185c9 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/QueryOptions.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/QueryOptions.java @@ -18,6 +18,7 @@ package org.springframework.data.cassandra.core.cql; import java.time.Duration; import java.util.concurrent.TimeUnit; +import lombok.EqualsAndHashCode; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -32,6 +33,7 @@ import com.datastax.driver.core.policies.RetryPolicy; * @author David Webb * @author Mark Paluch */ +@EqualsAndHashCode public class QueryOptions { private static final QueryOptions EMPTY = QueryOptions.builder().build(); @@ -93,6 +95,16 @@ public class QueryOptions { return new QueryOptionsBuilder(); } + /** + * Create a new {@link QueryOptionsBuilder} to mutate properties of this {@link QueryOptions}. + * + * @return a new {@link QueryOptionsBuilder} initialized with this {@link QueryOptions}. + * @since 2.0 + */ + public QueryOptionsBuilder mutate() { + return new QueryOptionsBuilder(this); + } + /** * @return the the driver {@link ConsistencyLevel} * @since 1.5 @@ -156,6 +168,15 @@ public class QueryOptions { QueryOptionsBuilder() {} + QueryOptionsBuilder(QueryOptions queryOptions) { + + this.consistencyLevel = queryOptions.consistencyLevel; + this.retryPolicy = queryOptions.retryPolicy; + this.tracing = queryOptions.tracing; + this.fetchSize = queryOptions.fetchSize; + this.readTimeout = queryOptions.readTimeout; + } + /** * Sets the {@link ConsistencyLevel} to use. * diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/WriteOptions.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/WriteOptions.java index e3d64679c..d5b653b4e 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/WriteOptions.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/WriteOptions.java @@ -18,6 +18,7 @@ package org.springframework.data.cassandra.core.cql; import java.time.Duration; import java.util.concurrent.TimeUnit; +import lombok.EqualsAndHashCode; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -32,6 +33,7 @@ import com.datastax.driver.core.policies.RetryPolicy; * @author Mark Paluch * @see QueryOptions */ +@EqualsAndHashCode(callSuper = true) public class WriteOptions extends QueryOptions { private static final WriteOptions EMPTY = new WriteOptionsBuilder().build(); @@ -94,6 +96,17 @@ public class WriteOptions extends QueryOptions { return new WriteOptionsBuilder(); } + /** + * Create a new {@link WriteOptionsBuilder} to mutate properties of this {@link WriteOptions}. + * + * @return a new {@link WriteOptionsBuilder} initialized with this {@link WriteOptions}. + * @since 2.0 + */ + @Override + public WriteOptionsBuilder mutate() { + return new WriteOptionsBuilder(this); + } + /** * @return the time to live, if set. */ @@ -102,7 +115,7 @@ public class WriteOptions extends QueryOptions { } /** - * Builder for {@link QueryOptions}. + * Builder for {@link WriteOptions}. * * @author Mark Paluch * @since 1.5 @@ -113,6 +126,12 @@ public class WriteOptions extends QueryOptions { protected WriteOptionsBuilder() {} + protected WriteOptionsBuilder(WriteOptions writeOptions) { + + super(writeOptions); + this.ttl = writeOptions.ttl; + } + /* * (non-Javadoc) * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#consistencyLevel(com.datastax.driver.core.ConsistencyLevel) diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/InsertOptionsUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/InsertOptionsUnitTests.java index fb06f5b36..c4a5c84c5 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/InsertOptionsUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/InsertOptionsUnitTests.java @@ -39,4 +39,18 @@ public class InsertOptionsUnitTests { assertThat(insertOptions.getTtl()).isEqualTo(Duration.ofSeconds(10)); assertThat(insertOptions.isIfNotExists()).isTrue(); } + + @Test // DATACASS-56 + public void buildInsertOptionsMutate() { + + InsertOptions insertOptions = InsertOptions.builder() // + .ttl(10) // + .withIfNotExists() // + .build(); + + InsertOptions mutated = insertOptions.mutate().ttl(Duration.ofSeconds(5)).build(); + + assertThat(mutated.getTtl()).isEqualTo(Duration.ofSeconds(5)); + assertThat(mutated.isIfNotExists()).isTrue(); + } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/UpdateOptionsUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/UpdateOptionsUnitTests.java index 9a0a9a1d1..f316799cc 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/UpdateOptionsUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/UpdateOptionsUnitTests.java @@ -39,4 +39,18 @@ public class UpdateOptionsUnitTests { assertThat(updateOptions.getTtl()).isEqualTo(Duration.ofSeconds(10)); assertThat(updateOptions.isIfExists()).isTrue(); } + + @Test // DATACASS-56 + public void buildUpdateOptionsMutate() { + + UpdateOptions updateOptions = UpdateOptions.builder() // + .ttl(10) // + .withIfExists() // + .build(); + + UpdateOptions mutated = updateOptions.mutate().ttl(20).build(); + + assertThat(mutated.getTtl()).isEqualTo(Duration.ofSeconds(20)); + assertThat(mutated.isIfExists()).isTrue(); + } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/QueryOptionsUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/QueryOptionsUnitTests.java index 6da5bf81d..7815eeafd 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/QueryOptionsUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/QueryOptionsUnitTests.java @@ -73,4 +73,25 @@ public class QueryOptionsUnitTests { assertThat(writeOptions.getRetryPolicy()).isEqualTo(DowngradingConsistencyRetryPolicy.INSTANCE); } + + @Test // DATACASS-56 + public void buildQueryOptionsMutate() { + + QueryOptions queryOptions = QueryOptions.builder() // + .consistencyLevel(ConsistencyLevel.ANY) // + .retryPolicy(FallthroughRetryPolicy.INSTANCE) // + .readTimeout(1, TimeUnit.SECONDS)// + .fetchSize(10)// + .tracing(true)// + .build(); // + + QueryOptions mutated = queryOptions.mutate().readTimeout(Duration.ofSeconds(5)).build(); + + assertThat(mutated.getClass()).isEqualTo(QueryOptions.class); + assertThat(mutated.getRetryPolicy()).isEqualTo(FallthroughRetryPolicy.INSTANCE); + assertThat(mutated.getConsistencyLevel()).isEqualTo(ConsistencyLevel.ANY); + assertThat(mutated.getReadTimeout()).isEqualTo(Duration.ofSeconds(5)); + assertThat(mutated.getFetchSize()).isEqualTo(10); + assertThat(mutated.getTracing()).isTrue(); + } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/WriteOptionsUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/WriteOptionsUnitTests.java index aaaa5d789..d8c09a044 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/WriteOptionsUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/WriteOptionsUnitTests.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.*; import java.time.Duration; import java.util.concurrent.TimeUnit; +import com.datastax.driver.core.policies.DowngradingConsistencyRetryPolicy; import org.junit.Test; import com.datastax.driver.core.ConsistencyLevel; @@ -77,4 +78,26 @@ public class WriteOptionsUnitTests { assertThat(writeOptions.getRetryPolicy()).isEqualTo(FallthroughRetryPolicy.INSTANCE); } + + @Test // DATACASS-56 + public void buildWriteOptionsMutate() { + + WriteOptions writeOptions = WriteOptions.builder() // + .consistencyLevel(com.datastax.driver.core.ConsistencyLevel.ANY) // + .ttl(123) // + .retryPolicy(FallthroughRetryPolicy.INSTANCE) // + .readTimeout(1)// + .fetchSize(10)// + .withTracing()// + .build(); // + + WriteOptions mutated = writeOptions.mutate().retryPolicy(DowngradingConsistencyRetryPolicy.INSTANCE).build(); + + assertThat(mutated.getTtl()).isEqualTo(Duration.ofSeconds(123)); + assertThat(mutated.getRetryPolicy()).isEqualTo(DowngradingConsistencyRetryPolicy.INSTANCE); + assertThat(mutated.getConsistencyLevel()).isEqualTo(ConsistencyLevel.ANY); + assertThat(mutated.getReadTimeout()).isEqualTo(Duration.ofMillis(1)); + assertThat(mutated.getFetchSize()).isEqualTo(10); + assertThat(mutated.getTracing()).isTrue(); + } }