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 b65f89554..c4c2c4b6f 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; @@ -201,6 +202,16 @@ public class DeleteOptions extends WriteOptions { return this; } + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.cql.WriteOptions.WriteOptionsBuilder#idempotent(boolean) + */ + @Override + public DeleteOptionsBuilder idempotent(boolean idempotent) { + + super.idempotent(idempotent); + return this; + } + /* (non-Javadoc) * @see org.springframework.data.cassandra.core.cql.WriteOptions.WriteOptionsBuilder#keyspace() */ @@ -243,6 +254,26 @@ public class DeleteOptions extends WriteOptions { return this; } + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(com.datastax.oss.driver.api.core.CqlIdentifier) + */ + @Override + public DeleteOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { + + super.routingKeyspace(routingKeyspace); + return this; + } + + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(java.nio.ByteBuffer) + */ + @Override + public DeleteOptionsBuilder routingKey(ByteBuffer routingKey) { + + super.routingKey(routingKey); + return this; + } + /* (non-Javadoc) * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#serialConsistencyLevel(com.datastax.oss.driver.api.core.ConsistencyLevel) */ @@ -292,16 +323,6 @@ public class DeleteOptions extends WriteOptions { return this; } - /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.cql.WriteOptions.WriteOptionsBuilder#idempotent(boolean) - */ - @Override - public DeleteOptionsBuilder idempotent(boolean idempotent) { - - super.idempotent(idempotent); - return this; - } - /* (non-Javadoc) * @see org.springframework.data.cassandra.core.cql.WriteOptions.WriteOptionsBuilder#ttl(int) */ @@ -331,26 +352,6 @@ public class DeleteOptions extends WriteOptions { return this; } - /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(com.datastax.oss.driver.api.core.CqlIdentifier) - */ - @Override - public DeleteOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { - - super.routingKeyspace(routingKeyspace); - return this; - } - - /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(java.nio.ByteBuffer) - */ - @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)}. * @@ -412,9 +413,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 0edc329e8..c1fdd2e91 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; @@ -201,6 +202,16 @@ public class InsertOptions extends WriteOptions { return (InsertOptionsBuilder) super.fetchSize(fetchSize); } + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#idempotent(boolean) + */ + @Override + public InsertOptionsBuilder idempotent(boolean idempotent) { + + super.idempotent(idempotent); + return this; + } + /* (non-Javadoc) * @see org.springframework.data.cassandra.core.cql.WriteOptions.WriteOptionsBuilder#keyspace() */ @@ -241,6 +252,26 @@ public class InsertOptions extends WriteOptions { return this; } + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(com.datastax.oss.driver.api.core.CqlIdentifier) + */ + @Override + public InsertOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { + + super.routingKeyspace(routingKeyspace); + return this; + } + + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(java.nio.ByteBuffer) + */ + @Override + public InsertOptionsBuilder routingKey(ByteBuffer routingKey) { + + super.routingKey(routingKey); + return this; + } + /* (non-Javadoc) * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#serialConsistencyLevel(com.datastax.oss.driver.api.core.ConsistencyLevel) */ @@ -320,36 +351,6 @@ public class InsertOptions extends WriteOptions { return this; } - /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#idempotent(boolean) - */ - @Override - public InsertOptionsBuilder idempotent(boolean idempotent) { - - super.idempotent(idempotent); - return this; - } - - /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(com.datastax.oss.driver.api.core.CqlIdentifier) - */ - @Override - public InsertOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { - - super.routingKeyspace(routingKeyspace); - return this; - } - - /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(java.nio.ByteBuffer) - */ - @Override - public InsertOptionsBuilder routingKey(ByteBuffer routingKey) { - - super.routingKey(routingKey); - return this; - } - /** * Use light-weight transactions by applying {@code IF NOT EXISTS}. * @@ -406,9 +407,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 27c37e3d9..50720bc1d 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; + } + /* * (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) @@ -155,18 +155,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; } /* (non-Javadoc) @@ -208,6 +208,16 @@ public class UpdateOptions extends WriteOptions { return this; } + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.cql.WriteOptions.WriteOptionsBuilder#idempotent(boolean) + */ + @Override + public UpdateOptionsBuilder idempotent(boolean idempotent) { + + super.idempotent(idempotent); + return this; + } + /* (non-Javadoc) * @see org.springframework.data.cassandra.core.cql.WriteOptions.WriteOptionsBuilder#keyspace() */ @@ -250,6 +260,26 @@ public class UpdateOptions extends WriteOptions { return this; } + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(com.datastax.oss.driver.api.core.CqlIdentifier) + */ + @Override + public UpdateOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { + + super.routingKeyspace(routingKeyspace); + return this; + } + + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(java.nio.ByteBuffer) + */ + @Override + public UpdateOptionsBuilder routingKey(ByteBuffer routingKey) { + + super.routingKey(routingKey); + return this; + } + /* (non-Javadoc) * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#serialConsistencyLevel(com.datastax.oss.driver.api.core.ConsistencyLevel) */ @@ -299,16 +329,6 @@ public class UpdateOptions extends WriteOptions { return this; } - /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.cql.WriteOptions.WriteOptionsBuilder#idempotent(boolean) - */ - @Override - public UpdateOptionsBuilder idempotent(boolean idempotent) { - - super.idempotent(idempotent); - return this; - } - /* (non-Javadoc) * @see org.springframework.data.cassandra.core.cql.WriteOptions.WriteOptionsBuilder#ttl(int) */ @@ -338,49 +358,6 @@ public class UpdateOptions extends WriteOptions { return this; } - /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(com.datastax.oss.driver.api.core.CqlIdentifier) - */ - @Override - public UpdateOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { - - super.routingKeyspace(routingKeyspace); - return this; - } - - /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(java.nio.ByteBuffer) - */ - @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)}. @@ -414,15 +391,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 3586c9666..9140f8ed7 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; - } - /* * (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) @@ -237,10 +237,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; } @@ -253,18 +265,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); } @@ -276,14 +276,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; } @@ -299,8 +300,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; @@ -311,24 +316,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; } /** @@ -391,6 +392,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. @@ -412,8 +427,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. @@ -482,6 +498,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. * @@ -537,54 +585,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 50e305322..e5595f14f 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; @@ -206,6 +208,16 @@ public class WriteOptions extends QueryOptions { return this; } + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#idempotent(boolean) + */ + @Override + public WriteOptionsBuilder idempotent(boolean idempotent) { + + super.idempotent(idempotent); + return this; + } + /* (non-Javadoc) * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#keyspace() */ @@ -248,6 +260,26 @@ public class WriteOptions extends QueryOptions { return this; } + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(com.datastax.oss.driver.api.core.CqlIdentifier) + */ + @Override + public WriteOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { + + super.routingKeyspace(routingKeyspace); + return this; + } + + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(java.nio.ByteBuffer) + */ + @Override + public WriteOptionsBuilder routingKey(ByteBuffer routingKey) { + + super.routingKey(routingKey); + return this; + } + /* (non-Javadoc) * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#serialConsistencyLevel(com.datastax.oss.driver.api.core.ConsistencyLevel) */ @@ -287,36 +319,6 @@ public class WriteOptions extends QueryOptions { return this; } - /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#idempotent(boolean) - */ - @Override - public WriteOptionsBuilder idempotent(boolean idempotent) { - - super.idempotent(idempotent); - return this; - } - - /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(com.datastax.oss.driver.api.core.CqlIdentifier) - */ - @Override - public WriteOptionsBuilder routingKeyspace(CqlIdentifier routingKeyspace) { - - super.routingKeyspace(routingKeyspace); - return this; - } - - /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#routingKeyspace(java.nio.ByteBuffer) - */ - @Override - public WriteOptionsBuilder routingKey(ByteBuffer routingKey) { - - super.routingKey(routingKey); - return this; - } - /** * Sets the time to live in seconds for write operations. * @@ -388,9 +390,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();