From d5106b6be3fd644d52795be18536e8343e98a514 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 15 Feb 2022 14:19:07 +0100 Subject: [PATCH] Polishing. Reorder methods and query options alphabetically. Update since tags. See #1220 --- .../data/cassandra/core/DeleteOptions.java | 59 ++-- .../data/cassandra/core/InsertOptions.java | 58 ++-- .../data/cassandra/core/UpdateOptions.java | 132 ++++----- .../data/cassandra/core/cql/QueryOptions.java | 253 +++++++++--------- .../cassandra/core/cql/QueryOptionsUtil.java | 25 +- .../data/cassandra/core/cql/WriteOptions.java | 58 ++-- .../core/cql/QueryOptionsUnitTests.java | 16 +- .../core/cql/QueryOptionsUtilUnitTests.java | 8 +- .../core/cql/WriteOptionsUnitTests.java | 18 +- 9 files changed, 320 insertions(+), 307 deletions(-) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/DeleteOptions.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/DeleteOptions.java index b61297d81..131bdcce2 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/DeleteOptions.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/DeleteOptions.java @@ -48,13 +48,14 @@ public class DeleteOptions extends WriteOptions { private final @Nullable Filter ifCondition; private DeleteOptions(@Nullable ConsistencyLevel consistencyLevel, ExecutionProfileResolver executionProfileResolver, - @Nullable CqlIdentifier keyspace, @Nullable Integer pageSize, @Nullable ConsistencyLevel serialConsistencyLevel, + @Nullable Boolean idempotent, @Nullable CqlIdentifier keyspace, @Nullable Integer pageSize, + @Nullable CqlIdentifier routingKeyspace, @Nullable ByteBuffer routingKey, + @Nullable ConsistencyLevel serialConsistencyLevel, Duration timeout, Duration ttl, @Nullable Long timestamp, @Nullable Boolean tracing, boolean ifExists, - @Nullable Filter ifCondition, @Nullable Boolean idempotent, @Nullable CqlIdentifier routingKeyspace, - @Nullable ByteBuffer routingKey) { + @Nullable Filter ifCondition) { - super(consistencyLevel, executionProfileResolver, keyspace, pageSize, serialConsistencyLevel, timeout, ttl, - timestamp, tracing, idempotent, routingKeyspace, routingKey); + super(consistencyLevel, executionProfileResolver, idempotent, keyspace, pageSize, routingKeyspace, routingKey, + serialConsistencyLevel, timeout, ttl, timestamp, tracing); this.ifExists = ifExists; this.ifCondition = ifCondition; @@ -181,6 +182,13 @@ public class DeleteOptions extends WriteOptions { return this; } + @Override + public DeleteOptionsBuilder idempotent(boolean idempotent) { + + super.idempotent(idempotent); + return this; + } + @Override public DeleteOptionsBuilder keyspace(CqlIdentifier keyspace) { @@ -211,6 +219,20 @@ public class DeleteOptions extends WriteOptions { return this; } + @Override + public DeleteOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { + + super.routingKeyspace(routingKeyspace); + return this; + } + + @Override + public DeleteOptionsBuilder routingKey(ByteBuffer routingKey) { + + super.routingKey(routingKey); + return this; + } + @Override public DeleteOptionsBuilder serialConsistencyLevel(ConsistencyLevel consistencyLevel) { super.serialConsistencyLevel(consistencyLevel); @@ -245,13 +267,6 @@ public class DeleteOptions extends WriteOptions { return this; } - @Override - public DeleteOptionsBuilder idempotent(boolean idempotent) { - - super.idempotent(idempotent); - return this; - } - public DeleteOptionsBuilder ttl(int ttl) { super.ttl(ttl); @@ -272,20 +287,6 @@ public class DeleteOptions extends WriteOptions { return this; } - @Override - public DeleteOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { - - super.routingKeyspace(routingKeyspace); - return this; - } - - @Override - public DeleteOptionsBuilder routingKey(ByteBuffer routingKey) { - - super.routingKey(routingKey); - return this; - } - /** * Use light-weight transactions by applying {@code IF EXISTS}. Replaces a previous {@link #ifCondition(Filter)}. * @@ -347,9 +348,9 @@ public class DeleteOptions extends WriteOptions { */ public DeleteOptions build() { - return new DeleteOptions(this.consistencyLevel, this.executionProfileResolver, this.keyspace, this.pageSize, - this.serialConsistencyLevel, this.timeout, this.ttl, this.timestamp, this.tracing, this.ifExists, - this.ifCondition, this.idempotent, this.routingKeyspace, this.routingKey); + return new DeleteOptions(this.consistencyLevel, this.executionProfileResolver, this.idempotent, this.keyspace, + this.pageSize, this.routingKeyspace, this.routingKey, this.serialConsistencyLevel, this.timeout, this.ttl, + this.timestamp, this.tracing, this.ifExists, this.ifCondition); } } } 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 daa535793..fb792a6fc 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 @@ -45,13 +45,14 @@ public class InsertOptions extends WriteOptions { private final boolean insertNulls; private InsertOptions(@Nullable ConsistencyLevel consistencyLevel, ExecutionProfileResolver executionProfileResolver, - @Nullable CqlIdentifier keyspace, @Nullable Integer pageSize, @Nullable ConsistencyLevel serialConsistencyLevel, + @Nullable Boolean idempotent, @Nullable CqlIdentifier keyspace, @Nullable Integer pageSize, + @Nullable CqlIdentifier routingKeyspace, @Nullable ByteBuffer routingKey, + @Nullable ConsistencyLevel serialConsistencyLevel, Duration timeout, Duration ttl, @Nullable Long timestamp, @Nullable Boolean tracing, boolean ifNotExists, - boolean insertNulls, @Nullable Boolean idempotent, @Nullable CqlIdentifier routingKeyspace, - @Nullable ByteBuffer routingKey) { + boolean insertNulls) { - super(consistencyLevel, executionProfileResolver, keyspace, pageSize, serialConsistencyLevel, timeout, ttl, - timestamp, tracing, idempotent, routingKeyspace, routingKey); + super(consistencyLevel, executionProfileResolver, idempotent, keyspace, pageSize, routingKeyspace, routingKey, + serialConsistencyLevel, timeout, ttl, timestamp, tracing); this.ifNotExists = ifNotExists; this.insertNulls = insertNulls; @@ -181,6 +182,13 @@ public class InsertOptions extends WriteOptions { return (InsertOptionsBuilder) super.fetchSize(fetchSize); } + @Override + public InsertOptionsBuilder idempotent(boolean idempotent) { + + super.idempotent(idempotent); + return this; + } + @Override public InsertOptionsBuilder keyspace(CqlIdentifier keyspace) { @@ -209,6 +217,20 @@ public class InsertOptions extends WriteOptions { return this; } + @Override + public InsertOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { + + super.routingKeyspace(routingKeyspace); + return this; + } + + @Override + public InsertOptionsBuilder routingKey(ByteBuffer routingKey) { + + super.routingKey(routingKey); + return this; + } + @Override public InsertOptionsBuilder serialConsistencyLevel(ConsistencyLevel consistencyLevel) { super.serialConsistencyLevel(consistencyLevel); @@ -264,27 +286,6 @@ public class InsertOptions extends WriteOptions { return this; } - @Override - public InsertOptionsBuilder idempotent(boolean idempotent) { - - super.idempotent(idempotent); - return this; - } - - @Override - public InsertOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { - - super.routingKeyspace(routingKeyspace); - return this; - } - - @Override - public InsertOptionsBuilder routingKey(ByteBuffer routingKey) { - - super.routingKey(routingKey); - return this; - } - /** * Use light-weight transactions by applying {@code IF NOT EXISTS}. * @@ -341,9 +342,10 @@ public class InsertOptions extends WriteOptions { * @return a new {@link InsertOptions} with the configured values */ public InsertOptions build() { - return new InsertOptions(this.consistencyLevel, this.executionProfileResolver, this.keyspace, this.pageSize, + return new InsertOptions(this.consistencyLevel, this.executionProfileResolver, this.idempotent, this.keyspace, + this.pageSize, this.routingKeyspace, this.routingKey, this.serialConsistencyLevel, this.timeout, this.ttl, this.timestamp, this.tracing, this.ifNotExists, - this.insertNulls, this.idempotent, this.routingKeyspace, this.routingKey); + this.insertNulls); } } } 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 2c9b6a988..3bf070f2c 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 @@ -44,21 +44,21 @@ public class UpdateOptions extends WriteOptions { private static final UpdateOptions EMPTY = new UpdateOptionsBuilder().build(); - private final boolean ifExists; - private final @Nullable Filter ifCondition; + private final boolean ifExists; + private UpdateOptions(@Nullable ConsistencyLevel consistencyLevel, ExecutionProfileResolver executionProfileResolver, - @Nullable CqlIdentifier keyspace, @Nullable Integer pageSize, @Nullable ConsistencyLevel serialConsistencyLevel, - Duration timeout, Duration ttl, @Nullable Long timestamp, @Nullable Boolean tracing, boolean ifExists, - @Nullable Filter ifCondition, @Nullable Boolean idempotent, @Nullable CqlIdentifier routingKeyspace, - @Nullable ByteBuffer routingKey) { + @Nullable Filter ifCondition, boolean ifExists, @Nullable Boolean idempotent, @Nullable CqlIdentifier keyspace, + @Nullable Integer pageSize, @Nullable CqlIdentifier routingKeyspace, @Nullable ByteBuffer routingKey, + @Nullable ConsistencyLevel serialConsistencyLevel, Duration timeout, Duration ttl, @Nullable Long timestamp, + @Nullable Boolean tracing) { - super(consistencyLevel, executionProfileResolver, keyspace, pageSize, serialConsistencyLevel, timeout, ttl, - timestamp, tracing, idempotent, routingKeyspace, routingKey); + super(consistencyLevel, executionProfileResolver, idempotent, keyspace, pageSize, routingKeyspace, routingKey, + serialConsistencyLevel, timeout, ttl, timestamp, tracing); - this.ifExists = ifExists; this.ifCondition = ifCondition; + this.ifExists = ifExists; } /** @@ -90,13 +90,6 @@ public class UpdateOptions extends WriteOptions { return new UpdateOptionsBuilder(this); } - /** - * @return {@literal true} to apply {@code IF EXISTS} to {@code UPDATE} operations. - */ - public boolean isIfExists() { - return this.ifExists; - } - /** * @return the {@link Filter IF condition} for conditional updates. * @since 2.2 @@ -106,6 +99,13 @@ public class UpdateOptions extends WriteOptions { return ifCondition; } + /** + * @return {@literal true} to apply {@code IF EXISTS} to {@code UPDATE} operations. + */ + public boolean isIfExists() { + return this.ifExists; + } + @Override public boolean equals(Object o) { @@ -147,18 +147,18 @@ public class UpdateOptions extends WriteOptions { */ public static class UpdateOptionsBuilder extends WriteOptionsBuilder { - private boolean ifExists; - private @Nullable Filter ifCondition; + private boolean ifExists; + private UpdateOptionsBuilder() {} private UpdateOptionsBuilder(UpdateOptions updateOptions) { super(updateOptions); - this.ifExists = updateOptions.ifExists; this.ifCondition = updateOptions.ifCondition; + this.ifExists = updateOptions.ifExists; } @Override @@ -188,6 +188,13 @@ public class UpdateOptions extends WriteOptions { return this; } + @Override + public UpdateOptionsBuilder idempotent(boolean idempotent) { + + super.idempotent(idempotent); + return this; + } + @Override public UpdateOptionsBuilder keyspace(CqlIdentifier keyspace) { @@ -218,6 +225,20 @@ public class UpdateOptions extends WriteOptions { return this; } + @Override + public UpdateOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { + + super.routingKeyspace(routingKeyspace); + return this; + } + + @Override + public UpdateOptionsBuilder routingKey(ByteBuffer routingKey) { + + super.routingKey(routingKey); + return this; + } + @Override public UpdateOptionsBuilder serialConsistencyLevel(ConsistencyLevel consistencyLevel) { super.serialConsistencyLevel(consistencyLevel); @@ -252,13 +273,6 @@ public class UpdateOptions extends WriteOptions { return this; } - @Override - public UpdateOptionsBuilder idempotent(boolean idempotent) { - - super.idempotent(idempotent); - return this; - } - public UpdateOptionsBuilder ttl(int ttl) { super.ttl(ttl); @@ -279,43 +293,6 @@ public class UpdateOptions extends WriteOptions { return this; } - @Override - public UpdateOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { - - super.routingKeyspace(routingKeyspace); - return this; - } - - @Override - public UpdateOptionsBuilder routingKey(ByteBuffer routingKey) { - - super.routingKey(routingKey); - return this; - } - - /** - * Use light-weight transactions by applying {@code IF EXISTS}. Replaces a previous {@link #ifCondition(Filter)}. - * - * @return {@code this} {@link UpdateOptionsBuilder} - */ - public UpdateOptionsBuilder withIfExists() { - return ifExists(true); - } - - /** - * Use light-weight transactions by applying {@code IF EXISTS}. Replaces a previous {@link #ifCondition(Filter)}. - * - * @param ifNotExists {@literal true} to enable {@code IF EXISTS}. - * @return {@code this} {@link UpdateOptionsBuilder} - */ - public UpdateOptionsBuilder ifExists(boolean ifNotExists) { - - this.ifExists = ifNotExists; - this.ifCondition = null; - - return this; - } - /** * Use light-weight transactions by applying {@code IF} {@link CriteriaDefinition condition}. Replaces a previous * {@link #ifCondition(Filter)} and {@link #ifExists(boolean)}. @@ -349,15 +326,38 @@ public class UpdateOptions extends WriteOptions { return this; } + /** + * Use light-weight transactions by applying {@code IF EXISTS}. Replaces a previous {@link #ifCondition(Filter)}. + * + * @return {@code this} {@link UpdateOptionsBuilder} + */ + public UpdateOptionsBuilder withIfExists() { + return ifExists(true); + } + + /** + * Use light-weight transactions by applying {@code IF EXISTS}. Replaces a previous {@link #ifCondition(Filter)}. + * + * @param ifNotExists {@literal true} to enable {@code IF EXISTS}. + * @return {@code this} {@link UpdateOptionsBuilder} + */ + public UpdateOptionsBuilder ifExists(boolean ifNotExists) { + + this.ifExists = ifNotExists; + this.ifCondition = null; + + return this; + } + /** * Builds a new {@link UpdateOptions} with the configured values. * * @return a new {@link UpdateOptions} with the configured values */ public UpdateOptions build() { - return new UpdateOptions(this.consistencyLevel, this.executionProfileResolver, this.keyspace, this.pageSize, - this.serialConsistencyLevel, this.timeout, this.ttl, this.timestamp, this.tracing, this.ifExists, - this.ifCondition, this.idempotent, this.routingKeyspace, this.routingKey); + return new UpdateOptions(this.consistencyLevel, this.executionProfileResolver, this.ifCondition, this.ifExists, + this.idempotent, this.keyspace, this.pageSize, this.routingKeyspace, this.routingKey, + this.serialConsistencyLevel, this.timeout, this.ttl, this.timestamp, this.tracing); } } } 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 fe8e76732..37dda5e5a 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 @@ -45,37 +45,37 @@ public class QueryOptions { private final ExecutionProfileResolver executionProfileResolver; + private final @Nullable Boolean idempotent; + private final @Nullable CqlIdentifier keyspace; private final @Nullable Integer pageSize; + private final @Nullable CqlIdentifier routingKeyspace; + + private final @Nullable ByteBuffer routingKey; + private final @Nullable ConsistencyLevel serialConsistencyLevel; private final Duration timeout; private final @Nullable Boolean tracing; - private final @Nullable Boolean idempotent; - - private final @Nullable CqlIdentifier routingKeyspace; - - private final @Nullable ByteBuffer routingKey; - protected QueryOptions(@Nullable ConsistencyLevel consistencyLevel, ExecutionProfileResolver executionProfileResolver, - @Nullable CqlIdentifier keyspace, @Nullable Integer pageSize, @Nullable ConsistencyLevel serialConsistencyLevel, - Duration timeout, @Nullable Boolean tracing, @Nullable Boolean idempotent, @Nullable CqlIdentifier routingKeyspace, - @Nullable ByteBuffer routingKey) { + @Nullable Boolean idempotent, @Nullable CqlIdentifier keyspace, @Nullable Integer pageSize, + @Nullable CqlIdentifier routingKeyspace, @Nullable ByteBuffer routingKey, + @Nullable ConsistencyLevel serialConsistencyLevel, Duration timeout, @Nullable Boolean tracing) { this.consistencyLevel = consistencyLevel; this.executionProfileResolver = executionProfileResolver; + this.idempotent = idempotent; this.keyspace = keyspace; this.pageSize = pageSize; + this.routingKey = routingKey; + this.routingKeyspace = routingKeyspace; this.serialConsistencyLevel = serialConsistencyLevel; this.timeout = timeout; this.tracing = tracing; - this.idempotent = idempotent; - this.routingKey = routingKey; - this.routingKeyspace = routingKeyspace; } /** @@ -109,7 +109,7 @@ public class QueryOptions { } /** - * @return the the driver {@link ConsistencyLevel}. + * @return the driver {@link ConsistencyLevel}. * @since 1.5 */ @Nullable @@ -118,13 +118,33 @@ public class QueryOptions { } /** - * @return the the {@link ExecutionProfileResolver}. + * @return the {@link ExecutionProfileResolver}. * @since 3.0 */ protected ExecutionProfileResolver getExecutionProfileResolver() { return this.executionProfileResolver; } + /** + * @return whether query is idempotent. May be {@literal null} if not set. + * @since 3.4 + * @see com.datastax.oss.driver.api.core.cql.Statement#setIdempotent(Boolean) + */ + @Nullable + protected Boolean isIdempotent() { + return this.idempotent; + } + + /** + * @return the keyspace associated with the query. If it is {@literal null}, it means that either keyspace configured + * on the statement or from the {@link CqlSession} will be used. + * @since 3.1 + */ + @Nullable + public CqlIdentifier getKeyspace() { + return keyspace; + } + /** * @return the number of rows to fetch per chunking request. May be {@literal null} if not set. * @since 1.5 @@ -145,6 +165,26 @@ public class QueryOptions { return getTimeout(); } + /** + * @return the keyspace used for token-aware routing. May be {@literal null} if token-aware routing is disabled. + * @since 3.4 + * @see com.datastax.oss.driver.api.core.cql.Statement#setRoutingKeyspace(CqlIdentifier) + */ + @Nullable + protected CqlIdentifier getRoutingKeyspace() { + return this.routingKeyspace; + } + + /** + * @return the key used for token-aware routing. May be {@literal null} if token-aware routing is disabled. + * @since 3.4 + * @see com.datastax.oss.driver.api.core.cql.Statement#setRoutingKey(ByteBuffer) + */ + @Nullable + protected ByteBuffer getRoutingKey() { + return this.routingKey; + } + /** * @return the command timeout. May be {@link Duration#isNegative() negative} if not set. * @since 3.0 @@ -155,7 +195,7 @@ public class QueryOptions { } /** - * @return the the serial {@link ConsistencyLevel}. + * @return the serial {@link ConsistencyLevel}. * @since 3.0 * @see com.datastax.oss.driver.api.core.cql.Statement#setSerialConsistencyLevel(ConsistencyLevel) */ @@ -172,46 +212,6 @@ public class QueryOptions { return this.tracing; } - /** - * @return whether query is idempotent. May be {@literal null} if not set. - * @since 3.3.2 - * @see com.datastax.oss.driver.api.core.cql.Statement#setIdempotent(Boolean) - */ - @Nullable - protected Boolean isIdempotent() { - return this.idempotent; - } - - /** - * @return the keyspace associated with the query. If it is {@literal null}, it means that either keyspace configured - * on the statement or from the {@link CqlSession} will be used. - * @since 3.1 - */ - @Nullable - public CqlIdentifier getKeyspace() { - return keyspace; - } - - /** - * @return the keyspace used for token-aware routing. May be {@literal null} if token-aware routing is disabled. - * @since 3.3.2 - * @see com.datastax.oss.driver.api.core.cql.Statement#setRoutingKeyspace(CqlIdentifier) - */ - @Nullable - protected CqlIdentifier getRoutingKeyspace() { - return this.routingKeyspace; - } - - /** - * @return the key used for token-aware routing. May be {@literal null} if token-aware routing is disabled. - * @since 3.3.2 - * @see com.datastax.oss.driver.api.core.cql.Statement#setRoutingKey(ByteBuffer) - */ - @Nullable - protected ByteBuffer getRoutingKey() { - return this.routingKey; - } - @Override public boolean equals(Object o) { @@ -233,10 +233,22 @@ public class QueryOptions { return false; } + if (!ObjectUtils.nullSafeEquals(idempotent, options.idempotent)) { + return false; + } + if (!ObjectUtils.nullSafeEquals(pageSize, options.pageSize)) { return false; } + if (!ObjectUtils.nullSafeEquals(routingKeyspace, options.routingKeyspace)) { + return false; + } + + if (!ObjectUtils.nullSafeEquals(routingKey, options.routingKey)) { + return false; + } + if (!ObjectUtils.nullSafeEquals(serialConsistencyLevel, options.serialConsistencyLevel)) { return false; } @@ -249,18 +261,6 @@ public class QueryOptions { return false; } - if (!ObjectUtils.nullSafeEquals(idempotent, options.idempotent)) { - return false; - } - - if (!ObjectUtils.nullSafeEquals(routingKeyspace, options.routingKeyspace)) { - return false; - } - - if (!ObjectUtils.nullSafeEquals(routingKey, options.routingKey)) { - return false; - } - return ObjectUtils.nullSafeEquals(keyspace, options.keyspace); } @@ -268,14 +268,15 @@ public class QueryOptions { public int hashCode() { int result = ObjectUtils.nullSafeHashCode(consistencyLevel); result = 31 * result + ObjectUtils.nullSafeHashCode(executionProfileResolver); + result = 31 * result + ObjectUtils.nullSafeHashCode(idempotent); + result = 31 * result + ObjectUtils.nullSafeHashCode(keyspace); result = 31 * result + ObjectUtils.nullSafeHashCode(pageSize); + result = 31 * result + ObjectUtils.nullSafeHashCode(routingKeyspace); + result = 31 * result + ObjectUtils.nullSafeHashCode(routingKey); result = 31 * result + ObjectUtils.nullSafeHashCode(serialConsistencyLevel); result = 31 * result + ObjectUtils.nullSafeHashCode(timeout); result = 31 * result + ObjectUtils.nullSafeHashCode(tracing); - result = 31 * result + ObjectUtils.nullSafeHashCode(idempotent); - result = 31 * result + ObjectUtils.nullSafeHashCode(keyspace); - result = 31 * result + ObjectUtils.nullSafeHashCode(routingKeyspace); - result = 31 * result + ObjectUtils.nullSafeHashCode(routingKey); + return result; } @@ -291,8 +292,12 @@ public class QueryOptions { protected ExecutionProfileResolver executionProfileResolver = ExecutionProfileResolver.none(); + protected @Nullable Boolean idempotent; + protected @Nullable CqlIdentifier keyspace; + protected @Nullable ByteBuffer routingKey; + protected @Nullable CqlIdentifier routingKeyspace; protected @Nullable Integer pageSize; @@ -303,24 +308,20 @@ public class QueryOptions { protected @Nullable Boolean tracing; - protected @Nullable Boolean idempotent; - - protected @Nullable ByteBuffer routingKey; - QueryOptionsBuilder() {} QueryOptionsBuilder(QueryOptions queryOptions) { this.consistencyLevel = queryOptions.consistencyLevel; this.executionProfileResolver = queryOptions.executionProfileResolver; + this.idempotent = queryOptions.idempotent; this.keyspace = queryOptions.keyspace; this.pageSize = queryOptions.pageSize; + this.routingKey = queryOptions.routingKey; + this.routingKeyspace = queryOptions.routingKeyspace; this.serialConsistencyLevel = queryOptions.serialConsistencyLevel; this.timeout = queryOptions.timeout; this.tracing = queryOptions.tracing; - this.idempotent = queryOptions.idempotent; - this.routingKeyspace = queryOptions.routingKeyspace; - this.routingKey = queryOptions.routingKey; } /** @@ -383,6 +384,20 @@ public class QueryOptions { return pageSize(fetchSize); } + /** + * Set query execution idempotency. + * + * @param idempotent {@literal true} to mark the query as idempotent. + * @return {@code this} {@link QueryOptionsBuilder}. + * @since 3.4 + */ + public QueryOptionsBuilder idempotent(boolean idempotent) { + + this.idempotent = idempotent; + + return this; + } + /** * Sets the {@link CqlIdentifier keyspace} to use. If left unconfigured, then the keyspace set on the statement or * {@link CqlSession} will be used. @@ -404,8 +419,9 @@ public class QueryOptions { * Sets the query fetch size for {@link com.datastax.oss.driver.api.core.cql.ResultSet} chunks. *

* The fetch size controls how much resulting rows will be retrieved simultaneously (the goal being to avoid loading - * too much results in memory for queries yielding large results). Please note that while value as low as 1 can be - * used, it is *highly* discouraged to use such a low value in practice as it will yield very poor performance. + * too many results in memory for queries yielding large results). Please note that while value as low as 1 can be + * used, it is highly discouraged to use such a low value in practice as it will yield very poor + * performance. * * @param pageSize the number of rows to fetch per chunking request. To disable chunking of the result set, use * {@code pageSize == Integer.MAX_VALUE}. Negative values are not allowed. @@ -474,6 +490,38 @@ public class QueryOptions { return this; } + /** + * Set query routing keyspace. + * + * @param routingKeyspace the routing keyspace to use for token-aware routing. + * @return {@code this} {@link QueryOptionsBuilder}. + * @since 3.4 + */ + public QueryOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { + + Assert.notNull(routingKeyspace, "Routing keyspace must not be null"); + + this.routingKeyspace = routingKeyspace; + + return this; + } + + /** + * Set query routing key. + * + * @param routingKey the routing key to use for token-aware routing. + * @return {@code this} {@link QueryOptionsBuilder} + * @since 3.4 + */ + public QueryOptionsBuilder routingKey(ByteBuffer routingKey) { + + Assert.notNull(routingKey, "Routing key must not be null"); + + this.routingKey = routingKey; + + return this; + } + /** * Sets the serial {@link ConsistencyLevel} to use. * @@ -529,54 +577,15 @@ public class QueryOptions { return tracing(true); } - /** - * Set query execution idempotency. - * - * @param idempotent {@literal true} to mark the query as idempotent. - * @return {@code this} {@link QueryOptionsBuilder} - */ - public QueryOptionsBuilder idempotent(boolean idempotent) { - - this.idempotent = idempotent; - - return this; - } - - /** - * Set query routing keyspace. - * - * @param routingKeyspace the routing keyspace to use for token-aware routing. Can be {@literal null}. - * @return {@code this} {@link QueryOptionsBuilder} - */ - public QueryOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { - - this.routingKeyspace = routingKeyspace; - - return this; - } - - /** - * Set query routing key. - * - * @param routingKey the routing key to use for token-aware routing. Can be {@literal null}. - * @return {@code this} {@link QueryOptionsBuilder} - */ - public QueryOptionsBuilder routingKey(ByteBuffer routingKey) { - - this.routingKey = routingKey; - - return this; - } - /** * Builds a new {@link QueryOptions} with the configured values. * * @return a new {@link QueryOptions} with the configured values */ public QueryOptions build() { - return new QueryOptions(this.consistencyLevel, this.executionProfileResolver, this.keyspace, - this.pageSize, this.serialConsistencyLevel, this.timeout, this.tracing, this.idempotent, - this.routingKeyspace, this.routingKey); + return new QueryOptions(this.consistencyLevel, this.executionProfileResolver, this.idempotent, this.keyspace, + this.pageSize, this.routingKeyspace, this.routingKey, this.serialConsistencyLevel, this.timeout, + this.tracing); } } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/QueryOptionsUtil.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/QueryOptionsUtil.java index 0a61e0f6d..45ce50ec5 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/QueryOptionsUtil.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/QueryOptionsUtil.java @@ -57,13 +57,24 @@ public abstract class QueryOptionsUtil { if (queryOptions.getConsistencyLevel() != null) { statementToUse = statementToUse.setConsistencyLevel(queryOptions.getConsistencyLevel()); } - statementToUse = queryOptions.getExecutionProfileResolver().apply(statementToUse); + if (queryOptions.isIdempotent() != null) { + statementToUse = statementToUse.setIdempotent(queryOptions.isIdempotent()); + } + if (queryOptions.getPageSize() != null) { statementToUse = statementToUse.setPageSize(queryOptions.getPageSize()); } + if (queryOptions.getRoutingKeyspace() != null) { + statementToUse = statementToUse.setRoutingKeyspace(queryOptions.getRoutingKeyspace()); + } + + if (queryOptions.getRoutingKey() != null) { + statementToUse = statement.setRoutingKey(queryOptions.getRoutingKey()); + } + if (queryOptions.getSerialConsistencyLevel() != null) { statementToUse = statementToUse.setSerialConsistencyLevel(queryOptions.getSerialConsistencyLevel()); } @@ -79,18 +90,6 @@ public abstract class QueryOptionsUtil { statementToUse = statementToUse.setTracing(Boolean.TRUE.equals(queryOptions.getTracing())); } - if (queryOptions.isIdempotent() != null) { - statementToUse = statementToUse.setIdempotent(queryOptions.isIdempotent()); - } - - if (queryOptions.getRoutingKeyspace() != null) { - statementToUse = statementToUse.setRoutingKeyspace(queryOptions.getRoutingKeyspace()); - } - - if (queryOptions.getRoutingKey() != null) { - statementToUse = statement.setRoutingKey(queryOptions.getRoutingKey()); - } - if (queryOptions.getKeyspace() != null) { if (statementToUse instanceof BoundStatement) { throw new IllegalArgumentException("Keyspace cannot be set for a BoundStatement"); 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 ce0d8cee0..1325d1276 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 @@ -47,11 +47,13 @@ public class WriteOptions extends QueryOptions { private final @Nullable Long timestamp; protected WriteOptions(@Nullable ConsistencyLevel consistencyLevel, ExecutionProfileResolver executionProfileResolver, - @Nullable CqlIdentifier keyspace, @Nullable Integer pageSize, @Nullable ConsistencyLevel serialConsistencyLevel, - Duration timeout, Duration ttl, @Nullable Long timestamp, @Nullable Boolean tracing, @Nullable Boolean idempotent, - @Nullable CqlIdentifier routingKeyspace, @Nullable ByteBuffer routingKey) { + @Nullable Boolean idempotent, @Nullable CqlIdentifier keyspace, @Nullable Integer pageSize, + @Nullable CqlIdentifier routingKeyspace, @Nullable ByteBuffer routingKey, + @Nullable ConsistencyLevel serialConsistencyLevel, Duration timeout, Duration ttl, @Nullable Long timestamp, + @Nullable Boolean tracing) { - super(consistencyLevel, executionProfileResolver, keyspace, pageSize, serialConsistencyLevel, timeout, tracing, idempotent, routingKeyspace, routingKey); + super(consistencyLevel, executionProfileResolver, idempotent, keyspace, pageSize, routingKeyspace, routingKey, + serialConsistencyLevel, timeout, tracing); this.ttl = ttl; this.timestamp = timestamp; @@ -186,6 +188,13 @@ public class WriteOptions extends QueryOptions { return this; } + @Override + public WriteOptionsBuilder idempotent(boolean idempotent) { + + super.idempotent(idempotent); + return this; + } + @Override public WriteOptionsBuilder keyspace(CqlIdentifier keyspace) { @@ -216,6 +225,20 @@ public class WriteOptions extends QueryOptions { return this; } + @Override + public WriteOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { + + super.routingKeyspace(routingKeyspace); + return this; + } + + @Override + public WriteOptionsBuilder routingKey(ByteBuffer routingKey) { + + super.routingKey(routingKey); + return this; + } + @Override public WriteOptionsBuilder serialConsistencyLevel(ConsistencyLevel consistencyLevel) { super.serialConsistencyLevel(consistencyLevel); @@ -243,27 +266,6 @@ public class WriteOptions extends QueryOptions { return this; } - @Override - public WriteOptionsBuilder idempotent(boolean idempotent) { - - super.idempotent(idempotent); - return this; - } - - @Override - public WriteOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { - - super.routingKeyspace(routingKeyspace); - return this; - } - - @Override - public WriteOptionsBuilder routingKey(ByteBuffer routingKey) { - - super.routingKey(routingKey); - return this; - } - /** * Sets the time to live in seconds for write operations. * @@ -335,9 +337,9 @@ public class WriteOptions extends QueryOptions { * @return a new {@link WriteOptions} with the configured values */ public WriteOptions build() { - return new WriteOptions(this.consistencyLevel, this.executionProfileResolver, this.keyspace, this.pageSize, - this.serialConsistencyLevel, this.timeout, this.ttl, this.timestamp, this.tracing, this.idempotent, - this.routingKeyspace, this.routingKey); + return new WriteOptions(this.consistencyLevel, this.executionProfileResolver, this.idempotent, this.keyspace, + this.pageSize, this.routingKeyspace, this.routingKey, this.serialConsistencyLevel, this.timeout, this.ttl, + this.timestamp, this.tracing); } } } 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 b57a37032..e7771b526 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 @@ -34,7 +34,7 @@ import com.datastax.oss.driver.api.core.DefaultConsistencyLevel; */ class QueryOptionsUnitTests { - @Test // DATACASS-202 + @Test // DATACASS-202, GH-1220 void buildQueryOptions() { QueryOptions queryOptions = QueryOptions.builder() // @@ -43,9 +43,9 @@ class QueryOptionsUnitTests { .pageSize(10) // .tracing(true) // .keyspace(CqlIdentifier.fromCql("ks1")) // - .idempotent(true) - .routingKeyspace(CqlIdentifier.fromCql("rksl")) - .routingKey(ByteBuffer.allocate(1)) + .idempotent(true) // + .routingKeyspace(CqlIdentifier.fromCql("rksl")) // + .routingKey(ByteBuffer.allocate(1)) // .build(); assertThat(queryOptions.getClass()).isEqualTo(QueryOptions.class); @@ -59,7 +59,7 @@ class QueryOptionsUnitTests { assertThat(queryOptions.getRoutingKey()).isEqualTo(ByteBuffer.allocate(1)); } - @Test // DATACASS-56 + @Test // DATACASS-56, GH-1220 void buildQueryOptionsMutate() { QueryOptions queryOptions = QueryOptions.builder() // @@ -68,9 +68,9 @@ class QueryOptionsUnitTests { .pageSize(10) // .tracing(true) // .keyspace(CqlIdentifier.fromCql("ks1")) // - .idempotent(true) - .routingKeyspace(CqlIdentifier.fromCql("rksl")) - .routingKey(ByteBuffer.allocate(1)) + .idempotent(true) // + .routingKeyspace(CqlIdentifier.fromCql("rksl")) // + .routingKey(ByteBuffer.allocate(1)) // .build(); QueryOptions mutated = queryOptions.mutate().timeout(Duration.ofSeconds(5)).build(); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/QueryOptionsUtilUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/QueryOptionsUtilUnitTests.java index 95086966c..d53c98095 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/QueryOptionsUtilUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/QueryOptionsUtilUnitTests.java @@ -78,7 +78,7 @@ class QueryOptionsUtilUnitTests { verifyNoInteractions(simpleStatement); } - @Test // DATACASS-202 + @Test // DATACASS-202, GH-1220 void addStatementQueryOptionsShouldAddGenericQueryOptions() { when(simpleStatement.setPageSize(anyInt())).thenReturn(simpleStatement); @@ -92,9 +92,9 @@ class QueryOptionsUtilUnitTests { .pageSize(10) // .readTimeout(1, TimeUnit.MINUTES) // .withTracing() // - .idempotent(true) - .routingKeyspace(CqlIdentifier.fromCql("routing_ks")) - .routingKey(ByteBuffer.allocate(1)) + .idempotent(true) // + .routingKeyspace(CqlIdentifier.fromCql("routing_ks")) // + .routingKey(ByteBuffer.allocate(1)) // .build(); QueryOptionsUtil.addQueryOptions(simpleStatement, queryOptions); 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 307d22895..87baa031c 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 @@ -36,7 +36,7 @@ import com.datastax.oss.driver.api.core.DefaultConsistencyLevel; */ class WriteOptionsUnitTests { - @Test // DATACASS-202, DATACASS-767 + @Test // DATACASS-202, DATACASS-767, GH-1220 void buildWriteOptions() { WriteOptions writeOptions = WriteOptions.builder() // @@ -46,10 +46,10 @@ class WriteOptionsUnitTests { .readTimeout(1) // .pageSize(10) // .withTracing() // - .keyspace(CqlIdentifier.fromCql("my_keyspace")) - .idempotent(true) - .routingKeyspace(CqlIdentifier.fromCql("routing_keyspace")) - .routingKey(ByteBuffer.allocate(1)) + .keyspace(CqlIdentifier.fromCql("my_keyspace")) // + .idempotent(true) // + .routingKeyspace(CqlIdentifier.fromCql("routing_keyspace")) // + .routingKey(ByteBuffer.allocate(1)) // .build(); assertThat(writeOptions.getTtl()).isEqualTo(Duration.ofSeconds(123)); @@ -75,7 +75,7 @@ class WriteOptionsUnitTests { assertThat(writeOptions.getTracing()).isNull(); } - @Test // DATACASS-56 + @Test // DATACASS-56, GH-1220 void buildWriteOptionsMutate() { Instant now = LocalDateTime.now().toInstant(ZoneOffset.UTC); @@ -86,9 +86,9 @@ class WriteOptionsUnitTests { .readTimeout(1) // .pageSize(10) // .withTracing() // - .idempotent(true) - .routingKeyspace(CqlIdentifier.fromCql("routing_keyspace")) - .routingKey(ByteBuffer.allocate(1)) + .idempotent(true) // + .routingKeyspace(CqlIdentifier.fromCql("routing_keyspace")) // + .routingKey(ByteBuffer.allocate(1)) // .build(); WriteOptions mutated = writeOptions.mutate().timeout(Duration.ofMillis(100)).build();