diff --git a/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java b/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java index ca2f13e388..b93a999dd2 100644 --- a/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java +++ b/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java @@ -726,6 +726,16 @@ public RedisFuture getset(K key, V value) { return dispatch(commandBuilder.getset(key, value)); } + @Override + public RedisFuture setGet(K key, V value) { + return dispatch(commandBuilder.setGet(key, value)); + } + + @Override + public RedisFuture setGet(K key, V value, SetArgs setArgs) { + return dispatch(commandBuilder.setGet(key, value, setArgs)); + } + @Override public RedisFuture hdel(K key, K... fields) { return dispatch(commandBuilder.hdel(key, fields)); diff --git a/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java b/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java index e7245fc285..9948dfb2ad 100644 --- a/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java +++ b/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java @@ -787,6 +787,16 @@ public Mono getset(K key, V value) { return createMono(() -> commandBuilder.getset(key, value)); } + @Override + public Mono setGet(K key, V value) { + return createMono(() -> commandBuilder.setGet(key, value)); + } + + @Override + public Mono setGet(K key, V value, SetArgs setArgs) { + return createMono(() -> commandBuilder.setGet(key, value, setArgs)); + } + @Override public Mono hdel(K key, K... fields) { return createMono(() -> commandBuilder.hdel(key, fields)); diff --git a/src/main/java/io/lettuce/core/RedisCommandBuilder.java b/src/main/java/io/lettuce/core/RedisCommandBuilder.java index 5f024fe844..b24aa91238 100644 --- a/src/main/java/io/lettuce/core/RedisCommandBuilder.java +++ b/src/main/java/io/lettuce/core/RedisCommandBuilder.java @@ -1845,6 +1845,20 @@ Command set(K key, V value, SetArgs setArgs) { return createCommand(SET, new StatusOutput<>(codec), args); } + Command setGet(K key, V value) { + return setGet(key, value, new SetArgs()); + } + + Command setGet(K key, V value, SetArgs setArgs) { + notNullKey(key); + + CommandArgs args = new CommandArgs<>(codec).addKey(key).addValue(value); + setArgs.build(args); + args.add("GET"); + + return createCommand(SET, new ValueOutput<>(codec), args); + } + Command setbit(K key, long offset, int value) { notNullKey(key); diff --git a/src/main/java/io/lettuce/core/api/async/RedisStringAsyncCommands.java b/src/main/java/io/lettuce/core/api/async/RedisStringAsyncCommands.java index b0716c542d..2aca3ac029 100644 --- a/src/main/java/io/lettuce/core/api/async/RedisStringAsyncCommands.java +++ b/src/main/java/io/lettuce/core/api/async/RedisStringAsyncCommands.java @@ -306,6 +306,29 @@ public interface RedisStringAsyncCommands { */ RedisFuture set(K key, V value, SetArgs setArgs); + /** + * Set the string value of a key and return its old value. + * + * @param key the key + * @param value the value + * + * @return V bulk-string-reply the old value stored at {@code key}, or {@code null} when {@code key} did not exist. + * @since 6.2 + */ + RedisFuture setGet(K key, V value); + + /** + * Set the string value of a key and return its old value. + * + * @param key the key + * @param value the value + * @param setArgs the command arguments + * + * @return V bulk-string-reply the old value stored at {@code key}, or {@code null} when {@code key} did not exist. + * @since 6.2 + */ + RedisFuture setGet(K key, V value, SetArgs setArgs); + /** * Sets or clears the bit at offset in the string value stored at key. * diff --git a/src/main/java/io/lettuce/core/api/reactive/RedisStringReactiveCommands.java b/src/main/java/io/lettuce/core/api/reactive/RedisStringReactiveCommands.java index 74d23e7805..24488a12bc 100644 --- a/src/main/java/io/lettuce/core/api/reactive/RedisStringReactiveCommands.java +++ b/src/main/java/io/lettuce/core/api/reactive/RedisStringReactiveCommands.java @@ -309,6 +309,29 @@ public interface RedisStringReactiveCommands { */ Mono set(K key, V value, SetArgs setArgs); + /** + * Set the string value of a key and return its old value. + * + * @param key the key + * @param value the value + * + * @return V bulk-string-reply the old value stored at {@code key}, or {@code null} when {@code key} did not exist. + * @since 6.2 + */ + Mono setGet(K key, V value); + + /** + * Set the string value of a key and return its old value. + * + * @param key the key + * @param value the value + * @param setArgs the command arguments + * + * @return V bulk-string-reply the old value stored at {@code key}, or {@code null} when {@code key} did not exist. + * @since 6.2 + */ + Mono setGet(K key, V value, SetArgs setArgs); + /** * Sets or clears the bit at offset in the string value stored at key. * diff --git a/src/main/java/io/lettuce/core/api/sync/RedisStringCommands.java b/src/main/java/io/lettuce/core/api/sync/RedisStringCommands.java index a2a6659087..77bcf90ede 100644 --- a/src/main/java/io/lettuce/core/api/sync/RedisStringCommands.java +++ b/src/main/java/io/lettuce/core/api/sync/RedisStringCommands.java @@ -306,6 +306,29 @@ public interface RedisStringCommands { */ String set(K key, V value, SetArgs setArgs); + /** + * Set the string value of a key and return its old value. + * + * @param key the key + * @param value the value + * + * @return V bulk-string-reply the old value stored at {@code key}, or {@code null} when {@code key} did not exist. + * @since 6.2 + */ + V setGet(K key, V value); + + /** + * Set the string value of a key and return its old value. + * + * @param key the key + * @param value the value + * @param setArgs the command arguments + * + * @return V bulk-string-reply the old value stored at {@code key}, or {@code null} when {@code key} did not exist. + * @since 6.2 + */ + V setGet(K key, V value, SetArgs setArgs); + /** * Sets or clears the bit at offset in the string value stored at key. * diff --git a/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionStringAsyncCommands.java b/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionStringAsyncCommands.java index cff9f00c81..c5e261dc9a 100644 --- a/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionStringAsyncCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionStringAsyncCommands.java @@ -306,6 +306,29 @@ public interface NodeSelectionStringAsyncCommands { */ AsyncExecutions set(K key, V value, SetArgs setArgs); + /** + * Set the string value of a key and return its old value. + * + * @param key the key + * @param value the value + * + * @return V bulk-string-reply the old value stored at {@code key}, or {@code null} when {@code key} did not exist. + * @since 6.2 + */ + AsyncExecutions setGet(K key, V value); + + /** + * Set the string value of a key and return its old value. + * + * @param key the key + * @param value the value + * @param setArgs the command arguments + * + * @return V bulk-string-reply the old value stored at {@code key}, or {@code null} when {@code key} did not exist. + * @since 6.2 + */ + AsyncExecutions setGet(K key, V value, SetArgs setArgs); + /** * Sets or clears the bit at offset in the string value stored at key. * diff --git a/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionStringCommands.java b/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionStringCommands.java index cdcf2e8bf3..394553d36f 100644 --- a/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionStringCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionStringCommands.java @@ -306,6 +306,29 @@ public interface NodeSelectionStringCommands { */ Executions set(K key, V value, SetArgs setArgs); + /** + * Set the string value of a key and return its old value. + * + * @param key the key + * @param value the value + * + * @return V bulk-string-reply the old value stored at {@code key}, or {@code null} when {@code key} did not exist. + * @since 6.2 + */ + Executions setGet(K key, V value); + + /** + * Set the string value of a key and return its old value. + * + * @param key the key + * @param value the value + * @param setArgs the command arguments + * + * @return V bulk-string-reply the old value stored at {@code key}, or {@code null} when {@code key} did not exist. + * @since 6.2 + */ + Executions setGet(K key, V value, SetArgs setArgs); + /** * Sets or clears the bit at offset in the string value stored at key. * diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisStringCoroutinesCommands.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisStringCoroutinesCommands.kt index 69fd3d1250..2a5fd37845 100644 --- a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisStringCoroutinesCommands.kt +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisStringCoroutinesCommands.kt @@ -296,6 +296,27 @@ interface RedisStringCoroutinesCommands { */ suspend fun set(key: K, value: V, setArgs: SetArgs): String? + /** + * Set the string value of a key and return its old value. + * + * @param key the key + * @param value the value + * @return V bulk-string-reply the old value stored at `key`, or `null` when `key` did not exist. + * @since 6.2 + */ + suspend fun setGet(key: K, value: V): V? + + /** + * Set the string value of a key and return its old value. + * + * @param key the key + * @param value the value + * @param setArgs the command arguments + * @return V bulk-string-reply the old value stored at `key`, or `null` when `key` did not exist. + * @since 6.2 + */ + suspend fun setGet(key: K, value: V, setArgs: SetArgs): V? + /** * Sets or clears the bit at offset in the string value stored at key. * diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisStringCoroutinesCommandsImpl.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisStringCoroutinesCommandsImpl.kt index d1e562db2a..f6bb94b343 100644 --- a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisStringCoroutinesCommandsImpl.kt +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisStringCoroutinesCommandsImpl.kt @@ -85,6 +85,10 @@ internal class RedisStringCoroutinesCommandsImpl(internal val override suspend fun set(key: K, value: V, setArgs: SetArgs): String? = ops.set(key, value, setArgs).awaitFirstOrNull() + override suspend fun setGet(key: K, value: V): V? = ops.setGet(key, value).awaitFirstOrNull() + + override suspend fun setGet(key: K, value: V, setArgs: SetArgs): V? = ops.setGet(key, value, setArgs).awaitFirstOrNull() + override suspend fun setbit(key: K, offset: Long, value: Int): Long? = ops.setbit(key, offset, value).awaitFirstOrNull() override suspend fun setex(key: K, seconds: Long, value: V): String? = ops.setex(key, seconds, value).awaitFirstOrNull() diff --git a/src/main/templates/io/lettuce/core/api/RedisStringCommands.java b/src/main/templates/io/lettuce/core/api/RedisStringCommands.java index b4501ab4f7..0df617d772 100644 --- a/src/main/templates/io/lettuce/core/api/RedisStringCommands.java +++ b/src/main/templates/io/lettuce/core/api/RedisStringCommands.java @@ -305,6 +305,29 @@ public interface RedisStringCommands { */ String set(K key, V value, SetArgs setArgs); + /** + * Set the string value of a key and return its old value. + * + * @param key the key + * @param value the value + * + * @return V bulk-string-reply the old value stored at {@code key}, or {@code null} when {@code key} did not exist. + * @since 6.2 + */ + V setGet(K key, V value); + + /** + * Set the string value of a key and return its old value. + * + * @param key the key + * @param value the value + * @param setArgs the command arguments + * + * @return V bulk-string-reply the old value stored at {@code key}, or {@code null} when {@code key} did not exist. + * @since 6.2 + */ + V setGet(K key, V value, SetArgs setArgs); + /** * Sets or clears the bit at offset in the string value stored at key. * diff --git a/src/test/java/io/lettuce/core/commands/StringCommandIntegrationTests.java b/src/test/java/io/lettuce/core/commands/StringCommandIntegrationTests.java index 993578bba8..068f75cbfb 100644 --- a/src/test/java/io/lettuce/core/commands/StringCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/commands/StringCommandIntegrationTests.java @@ -43,6 +43,7 @@ * @author Will Glozer * @author Mark Paluch * @author dengliming + * @author Andrey Shlykov */ @ExtendWith(LettuceExtension.class) @TestInstance(TestInstance.Lifecycle.PER_CLASS) @@ -191,6 +192,14 @@ void setNegativePX() { assertThatThrownBy(() -> redis.set(key, value, px(-1000))).isInstanceOf(RedisException. class); } + @Test + @EnabledOnCommand("ZMSCORE") // Redis 6.2 + void setGet() { + assertThat(redis.setGet(key, value)).isNull(); + assertThat(redis.setGet(key, "value2")).isEqualTo(value); + assertThat(redis.get(key)).isEqualTo("value2"); + } + @Test void setbit() { assertThat(redis.setbit(key, 0, 1)).isEqualTo(0);