From b05802452a69c9f299c6b21c26e7b83c3faa70c3 Mon Sep 17 00:00:00 2001 From: Clement Escoffier Date: Mon, 12 Sep 2022 14:24:42 +0200 Subject: [PATCH] Deprecate the Redis string group (because it's misleading, as it refers to Redis strings, not Java strings) and rename it to "value." This change is backward compatible, it adds the new groups and deprecates the previous one. --- docs/src/main/asciidoc/redis-reference.adoc | 22 +- docs/src/main/asciidoc/redis.adoc | 4 +- .../datasource/DataSourceInjectionTest.java | 8 +- .../deployment/datasource/DataSourceTest.java | 6 +- .../deployment/devmode/IncrementResource.java | 6 +- .../deployment/patterns/BinaryTest.java | 6 +- .../client/deployment/patterns/CacheTest.java | 6 +- .../deployment/patterns/CounterTest.java | 6 +- .../patterns/PubSubOnStartupTest.java | 6 +- .../deployment/patterns/PubSubTest.java | 6 +- .../datasource/ReactiveRedisDataSource.java | 33 ++ .../redis/datasource/RedisDataSource.java | 35 ++ .../redis/datasource/string/GetExArgs.java | 5 +- .../string/ReactiveStringCommands.java | 2 + .../ReactiveTransactionalStringCommands.java | 1 + .../redis/datasource/string/SetArgs.java | 5 +- .../datasource/string/StringCommands.java | 2 + .../string/TransactionalStringCommands.java | 1 + .../ReactiveTransactionalRedisDataSource.java | 35 ++ .../TransactionalRedisDataSource.java | 35 ++ .../redis/datasource/value/GetExArgs.java | 156 +++++++++ .../ReactiveTransactionalValueCommands.java | 329 ++++++++++++++++++ .../value/ReactiveValueCommands.java | 322 +++++++++++++++++ .../redis/datasource/value/SetArgs.java | 208 +++++++++++ .../value/TransactionalValueCommands.java | 280 +++++++++++++++ .../redis/datasource/value/ValueCommands.java | 321 +++++++++++++++++ .../datasource/AbstractStringCommands.java | 31 ++ .../BlockingRedisDataSourceImpl.java | 8 +- .../BlockingStringCommandsImpl.java | 28 +- ...ckingTransactionalRedisDataSourceImpl.java | 8 +- ...ockingTransactionalStringCommandsImpl.java | 24 +- .../ReactiveRedisDataSourceImpl.java | 6 + .../ReactiveStringCommandsImpl.java | 22 +- ...ctiveTransactionalRedisDataSourceImpl.java | 9 +- ...activeTransactionalStringCommandsImpl.java | 21 +- .../datasource/ConnectionRecyclingTest.java | 8 +- .../redis/datasource/KeyCommandsTest.java | 98 +++--- .../redis/datasource/NumericCommandsTest.java | 6 +- .../quarkus/redis/datasource/PubSubTest.java | 10 +- .../redis/datasource/SortCommandsTest.java | 6 +- .../redis/datasource/StringCommandsTest.java | 1 + .../TransactionalStringCommandsTest.java | 1 + .../TransactionalValueCommandsTest.java | 73 ++++ .../redis/datasource/ValueCommandsTest.java | 278 +++++++++++++++ .../java/org/acme/redis/IncrementService.java | 13 +- .../io/quarkus/redis/it/RedisResource.java | 12 +- .../it/RedisResourceWithNamedClient.java | 12 +- .../it/RedisWithProvidedHostsResource.java | 12 +- 48 files changed, 2391 insertions(+), 142 deletions(-) create mode 100644 extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/GetExArgs.java create mode 100644 extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/ReactiveTransactionalValueCommands.java create mode 100644 extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/ReactiveValueCommands.java create mode 100644 extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/SetArgs.java create mode 100644 extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/TransactionalValueCommands.java create mode 100644 extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/ValueCommands.java create mode 100644 extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/TransactionalValueCommandsTest.java create mode 100644 extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/ValueCommandsTest.java diff --git a/docs/src/main/asciidoc/redis-reference.adoc b/docs/src/main/asciidoc/redis-reference.adoc index eb9ffcf2344c1..0d5f969364a0f 100644 --- a/docs/src/main/asciidoc/redis-reference.adoc +++ b/docs/src/main/asciidoc/redis-reference.adoc @@ -275,7 +275,7 @@ As mentioned above, the API is divided into groups: - set - `.set(memberType)` - sorted-set - `.sortedSet(memberType)` - stream (not available yet) -- string - `.string(valueType)` +- string - `.value(valueType)` - transactions - `withTransaction` Each of these methods returns an object that lets you execute the commands related to the group. @@ -317,9 +317,9 @@ In this case, `quarkus-jackson` is used. To store binary data, use `byte[]`. -=== The `string` group +=== The `value` group -The `string` group is used to manipulate https://redis.io/docs/manual/data-types/#strings[Redis Strings]. +The `value` group is used to manipulate https://redis.io/docs/manual/data-types/#strings[Redis Strings]. Thus, this group is not limited to Java Strings but can be used for integers (like a counter) or binary content (like images). ==== Caching values @@ -332,10 +332,10 @@ The following snippet shows how such a command can be used to store `BusinessObj @ApplicationScoped public static class MyRedisCache { - private final StringCommands commands; + private final ValueCommands commands; public MyRedisCache(RedisDataSource ds) { - commands = ds.string(BusinessObject.class); + commands = ds.value(BusinessObject.class); } public BusinessObject get(String key) { @@ -375,10 +375,10 @@ In this case, we will use `byte[]` as value type: @ApplicationScoped public static class MyBinaryRepository { - private final StringCommands commands; + private final ValueCommands commands; public MyBinaryRepository(RedisDataSource ds) { - commands = ds.string(byte[].class); + commands = ds.value(byte[].class); } public byte[] get(String key) { @@ -408,10 +408,10 @@ You can store counters in Redis as demonstrated below: @ApplicationScoped public static class MyRedisCounter { - private final StringCommands commands; + private final ValueCommands commands; public MyRedisCounter(RedisDataSource ds) { - commands = ds.string(Long.class); // <1> + commands = ds.value(Long.class); // <1> } public long get(String key) { @@ -490,11 +490,11 @@ public static class MySubscriber implements Consumer { @ApplicationScoped public static class MyCache { - private final StringCommands commands; + private final ValueCommands commands; private final PubSubCommands pub; public MyCache(RedisDataSource ds) { - commands = ds.string(BusinessObject.class); + commands = ds.value(BusinessObject.class); pub = ds.pubsub(Notification.class); } diff --git a/docs/src/main/asciidoc/redis.adoc b/docs/src/main/asciidoc/redis.adoc index 7e4f53d72c44d..cedbf72431104 100644 --- a/docs/src/main/asciidoc/redis.adoc +++ b/docs/src/main/asciidoc/redis.adoc @@ -120,10 +120,10 @@ public class IncrementService { // Regular applications will pick one of them. private ReactiveKeyCommands keyCommands; // <1> - private StringCommands countCommands; // <2> + private ValueCommands countCommands; // <2> public IncrementService(RedisDataSource ds, ReactiveRedisDataSource reactive) { // <3> - countCommands = ds.string(Long.class); // <4> + countCommands = ds.value(Long.class); // <4> keyCommands = reactive.key(); // <5> } diff --git a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/datasource/DataSourceInjectionTest.java b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/datasource/DataSourceInjectionTest.java index e2b4fe74ffbc6..5836d90e79140 100644 --- a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/datasource/DataSourceInjectionTest.java +++ b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/datasource/DataSourceInjectionTest.java @@ -60,24 +60,24 @@ public static class MyRedisApp { ReactiveRedisDataSource myRedisReactive; public void set(String data) { - reactive.string(String.class, String.class) + reactive.value(String.class, String.class) .set("foo", data) .await().indefinitely(); } public String get() { - return blocking.string(String.class, String.class) + return blocking.value(String.class, String.class) .get("foo"); } public void setMyRedis(String data) { - myRedisReactive.string(String.class, String.class) + myRedisReactive.value(String.class, String.class) .set("foo", data) .await().indefinitely(); } public String getMyRedis() { - return myRedisBlocking.string(String.class, String.class) + return myRedisBlocking.value(String.class, String.class) .get("foo"); } diff --git a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/datasource/DataSourceTest.java b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/datasource/DataSourceTest.java index 7281e4496305e..9e287e844a07e 100644 --- a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/datasource/DataSourceTest.java +++ b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/datasource/DataSourceTest.java @@ -11,7 +11,7 @@ import io.quarkus.redis.client.RedisClientName; import io.quarkus.redis.client.deployment.RedisTestResource; import io.quarkus.redis.datasource.RedisDataSource; -import io.quarkus.redis.datasource.string.StringCommands; +import io.quarkus.redis.datasource.value.ValueCommands; import io.quarkus.test.QuarkusUnitTest; import io.quarkus.test.common.QuarkusTestResource; @@ -34,8 +34,8 @@ public class DataSourceTest { @Test public void testThatTheDatasourceUseDifferentDatabases() { - StringCommands r1s = r1.string(String.class); - StringCommands r2s = r2.string(String.class); + ValueCommands r1s = r1.value(String.class); + ValueCommands r2s = r2.value(String.class); r1s.set("key", "hello"); Assertions.assertThat(r2s.get("key")).isNull(); diff --git a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/devmode/IncrementResource.java b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/devmode/IncrementResource.java index 74f344693b5f5..336538a19261c 100644 --- a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/devmode/IncrementResource.java +++ b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/devmode/IncrementResource.java @@ -4,16 +4,16 @@ import javax.ws.rs.Path; import io.quarkus.redis.datasource.RedisDataSource; -import io.quarkus.redis.datasource.string.StringCommands; +import io.quarkus.redis.datasource.value.ValueCommands; @Path("/inc") public class IncrementResource { public static final long INCREMENT = 1; - private final StringCommands commands; + private final ValueCommands commands; public IncrementResource(RedisDataSource ds) { - commands = ds.string(Integer.class); + commands = ds.value(Integer.class); } @GET diff --git a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/BinaryTest.java b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/BinaryTest.java index 9f077a676a4ec..9d61ed060c9bf 100644 --- a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/BinaryTest.java +++ b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/BinaryTest.java @@ -14,7 +14,7 @@ import io.quarkus.redis.client.deployment.RedisTestResource; import io.quarkus.redis.datasource.RedisDataSource; -import io.quarkus.redis.datasource.string.StringCommands; +import io.quarkus.redis.datasource.value.ValueCommands; import io.quarkus.test.QuarkusUnitTest; import io.quarkus.test.common.QuarkusTestResource; @@ -52,10 +52,10 @@ void binary() { @ApplicationScoped public static class MyBinaryRepository { - private final StringCommands commands; + private final ValueCommands commands; public MyBinaryRepository(RedisDataSource ds) { - commands = ds.string(byte[].class); + commands = ds.value(byte[].class); } public byte[] get(String key) { diff --git a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/CacheTest.java b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/CacheTest.java index 94d98b0e840df..45df0bb42fd93 100644 --- a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/CacheTest.java +++ b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/CacheTest.java @@ -13,7 +13,7 @@ import io.quarkus.redis.client.deployment.RedisTestResource; import io.quarkus.redis.datasource.RedisDataSource; -import io.quarkus.redis.datasource.string.StringCommands; +import io.quarkus.redis.datasource.value.ValueCommands; import io.quarkus.test.QuarkusUnitTest; import io.quarkus.test.common.QuarkusTestResource; @@ -68,10 +68,10 @@ public BusinessObject(String v) { @ApplicationScoped public static class MyRedisCache { - private final StringCommands commands; + private final ValueCommands commands; public MyRedisCache(RedisDataSource ds) { - commands = ds.string(BusinessObject.class); + commands = ds.value(BusinessObject.class); } public BusinessObject get(String key) { diff --git a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/CounterTest.java b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/CounterTest.java index 822840bdfb298..a5b8332d98810 100644 --- a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/CounterTest.java +++ b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/CounterTest.java @@ -11,7 +11,7 @@ import io.quarkus.redis.client.deployment.RedisTestResource; import io.quarkus.redis.datasource.RedisDataSource; -import io.quarkus.redis.datasource.string.StringCommands; +import io.quarkus.redis.datasource.value.ValueCommands; import io.quarkus.test.QuarkusUnitTest; import io.quarkus.test.common.QuarkusTestResource; @@ -47,10 +47,10 @@ void counter() { @ApplicationScoped public static class MyRedisCounter { - private final StringCommands commands; + private final ValueCommands commands; public MyRedisCounter(RedisDataSource ds) { - commands = ds.string(Long.class); + commands = ds.value(Long.class); } public long get(String key) { diff --git a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/PubSubOnStartupTest.java b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/PubSubOnStartupTest.java index fb76d6723738f..5402b3ebee389 100644 --- a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/PubSubOnStartupTest.java +++ b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/PubSubOnStartupTest.java @@ -21,7 +21,7 @@ import io.quarkus.redis.datasource.RedisDataSource; import io.quarkus.redis.datasource.pubsub.PubSubCommands; import io.quarkus.redis.datasource.pubsub.ReactivePubSubCommands; -import io.quarkus.redis.datasource.string.StringCommands; +import io.quarkus.redis.datasource.value.ValueCommands; import io.quarkus.runtime.Startup; import io.quarkus.test.QuarkusUnitTest; import io.quarkus.test.common.QuarkusTestResource; @@ -115,11 +115,11 @@ public List list() { @ApplicationScoped public static class MyCache { - private final StringCommands commands; + private final ValueCommands commands; private final PubSubCommands pub; public MyCache(RedisDataSource ds) { - commands = ds.string(BusinessObject.class); + commands = ds.value(BusinessObject.class); pub = ds.pubsub(Notification.class); } diff --git a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/PubSubTest.java b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/PubSubTest.java index 156ba825f1a12..2fd74d7e7d427 100644 --- a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/PubSubTest.java +++ b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/patterns/PubSubTest.java @@ -19,7 +19,7 @@ import io.quarkus.redis.client.deployment.RedisTestResource; import io.quarkus.redis.datasource.RedisDataSource; import io.quarkus.redis.datasource.pubsub.PubSubCommands; -import io.quarkus.redis.datasource.string.StringCommands; +import io.quarkus.redis.datasource.value.ValueCommands; import io.quarkus.runtime.Startup; import io.quarkus.test.QuarkusUnitTest; import io.quarkus.test.common.QuarkusTestResource; @@ -109,11 +109,11 @@ public List list() { @ApplicationScoped public static class MyCache { - private final StringCommands commands; + private final ValueCommands commands; private final PubSubCommands pub; public MyCache(RedisDataSource ds) { - commands = ds.string(BusinessObject.class); + commands = ds.value(BusinessObject.class); pub = ds.pubsub(Notification.class); } diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/ReactiveRedisDataSource.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/ReactiveRedisDataSource.java index 7c1f87c2b814e..3004aaccfd595 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/ReactiveRedisDataSource.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/ReactiveRedisDataSource.java @@ -17,6 +17,7 @@ import io.quarkus.redis.datasource.transactions.ReactiveTransactionalRedisDataSource; import io.quarkus.redis.datasource.transactions.TransactionResult; import io.quarkus.redis.datasource.transactions.TransactionalRedisDataSource; +import io.quarkus.redis.datasource.value.ReactiveValueCommands; import io.smallrye.mutiny.Uni; import io.vertx.mutiny.redis.client.Command; import io.vertx.mutiny.redis.client.Redis; @@ -232,6 +233,34 @@ default ReactiveSortedSetCommands sortedSet(Class valueType) { return sortedSet(String.class, valueType); } + /** + * Gets the object to execute commands manipulating stored strings. + *

+ * NOTE: Instead of {@code string}, this group is named {@code value} to avoid the confusion with the + * Java String type. Indeed, Redis strings can be strings, numbers, byte arrays... + * + * @param redisKeyType the type of the keys + * @param valueType the type of the value, often String, or the value are encoded/decoded using codecs. + * @param the type of the key + * @param the type of the value + * @return the object to manipulate stored strings. + */ + ReactiveValueCommands value(Class redisKeyType, Class valueType); + + /** + * Gets the object to execute commands manipulating stored strings. + *

+ * NOTE: Instead of {@code string}, this group is named {@code value} to avoid the confusion with the + * Java String type. Indeed, Redis strings can be strings, numbers, byte arrays... + * + * @param valueType the type of the value, often String, or the value are encoded/decoded using codecs. + * @param the type of the value + * @return the object to manipulate stored strings. + */ + default ReactiveValueCommands value(Class valueType) { + return value(String.class, valueType); + } + /** * Gets the object to execute commands manipulating stored strings. * @@ -240,7 +269,9 @@ default ReactiveSortedSetCommands sortedSet(Class valueType) { * @param the type of the key * @param the type of the value * @return the object to manipulate stored strings. + * @deprecated Use {@link #value(Class, Class)} instead */ + @Deprecated ReactiveStringCommands string(Class redisKeyType, Class valueType); /** @@ -249,7 +280,9 @@ default ReactiveSortedSetCommands sortedSet(Class valueType) { * @param valueType the type of the value, often String, or the value are encoded/decoded using codecs. * @param the type of the value * @return the object to manipulate stored strings. + * @deprecated Use {@link #value(Class)} instead */ + @Deprecated default ReactiveStringCommands string(Class valueType) { return string(String.class, valueType); } diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/RedisDataSource.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/RedisDataSource.java index 585c7d7c616a3..10783371f62d7 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/RedisDataSource.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/RedisDataSource.java @@ -17,6 +17,7 @@ import io.quarkus.redis.datasource.transactions.OptimisticLockingTransactionResult; import io.quarkus.redis.datasource.transactions.TransactionResult; import io.quarkus.redis.datasource.transactions.TransactionalRedisDataSource; +import io.quarkus.redis.datasource.value.ValueCommands; import io.vertx.mutiny.redis.client.Command; import io.vertx.mutiny.redis.client.Response; @@ -228,6 +229,36 @@ default SortedSetCommands sortedSet(Class valueType) { return sortedSet(String.class, valueType); } + /** + * Gets the object to execute commands manipulating stored strings. + * + *

+ * NOTE: Instead of {@code string}, this group is named {@code value} to avoid the confusion with the + * Java String type. Indeed, Redis strings can be strings, numbers, byte arrays... + * + * @param redisKeyType the type of the keys + * @param valueType the type of the value, often String, or the value are encoded/decoded using codecs. + * @param the type of the key + * @param the type of the value + * @return the object to manipulate stored strings. + */ + ValueCommands value(Class redisKeyType, Class valueType); + + /** + * Gets the object to execute commands manipulating stored strings. + * + *

+ * NOTE: Instead of {@code string}, this group is named {@code value} to avoid the confusion with the + * Java String type. Indeed, Redis strings can be strings, numbers, byte arrays... + * + * @param valueType the type of the value, often String, or the value are encoded/decoded using codecs. + * @param the type of the value + * @return the object to manipulate stored strings. + */ + default ValueCommands value(Class valueType) { + return value(String.class, valueType); + } + /** * Gets the object to execute commands manipulating stored strings. * @@ -236,7 +267,9 @@ default SortedSetCommands sortedSet(Class valueType) { * @param the type of the key * @param the type of the value * @return the object to manipulate stored strings. + * @deprecated Use {@link #value(Class, Class)} instead */ + @Deprecated StringCommands string(Class redisKeyType, Class valueType); /** @@ -245,7 +278,9 @@ default SortedSetCommands sortedSet(Class valueType) { * @param valueType the type of the value, often String, or the value are encoded/decoded using codecs. * @param the type of the value * @return the object to manipulate stored strings. + * @deprecated Use {@link #value(Class)} instead */ + @Deprecated default StringCommands string(Class valueType) { return string(String.class, valueType); } diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/GetExArgs.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/GetExArgs.java index 8177693205553..85a743b0e01c3 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/GetExArgs.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/GetExArgs.java @@ -9,8 +9,11 @@ /** * Argument list for the Redis GETEX command. + * + * @deprecated use {@link io.quarkus.redis.datasource.value.GetExArgs} instead */ -public class GetExArgs implements RedisCommandExtraArguments { +@Deprecated +public class GetExArgs extends io.quarkus.redis.datasource.value.GetExArgs implements RedisCommandExtraArguments { private long ex = -1; private long exAt = -1; diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/ReactiveStringCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/ReactiveStringCommands.java index 73bdb2afdf47d..fcbe689fb142f 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/ReactiveStringCommands.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/ReactiveStringCommands.java @@ -15,7 +15,9 @@ * * @param the type of the key * @param the type of the value + * @deprecated Use {@link io.quarkus.redis.datasource.value.ReactiveValueCommands} instead. */ +@Deprecated public interface ReactiveStringCommands extends ReactiveRedisCommands { /** diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/ReactiveTransactionalStringCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/ReactiveTransactionalStringCommands.java index 46f79ac15778f..f4cf167cd81cf 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/ReactiveTransactionalStringCommands.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/ReactiveTransactionalStringCommands.java @@ -5,6 +5,7 @@ import io.quarkus.redis.datasource.ReactiveTransactionalRedisCommands; import io.smallrye.mutiny.Uni; +@Deprecated public interface ReactiveTransactionalStringCommands extends ReactiveTransactionalRedisCommands { /** diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/SetArgs.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/SetArgs.java index 976f00539ff78..7d23e48f075a6 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/SetArgs.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/SetArgs.java @@ -9,8 +9,11 @@ /** * Argument list for the Redis SET command. + * + * @deprecated Use {@link io.quarkus.redis.datasource.value.SetArgs} instead. */ -public class SetArgs implements RedisCommandExtraArguments { +@Deprecated +public class SetArgs extends io.quarkus.redis.datasource.value.SetArgs implements RedisCommandExtraArguments { private long ex = -1; private long exAt = -1; diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/StringCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/StringCommands.java index 28436520b96a6..ac992c038ad78 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/StringCommands.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/StringCommands.java @@ -14,7 +14,9 @@ * * @param the type of the key * @param the type of the value + * @deprecated Use {@link io.quarkus.redis.datasource.value.ValueCommands} instead. */ +@Deprecated public interface StringCommands extends RedisCommands { /** diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/TransactionalStringCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/TransactionalStringCommands.java index 309025d60f513..62b7d9c3402a9 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/TransactionalStringCommands.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/TransactionalStringCommands.java @@ -4,6 +4,7 @@ import io.quarkus.redis.datasource.TransactionalRedisCommands; +@Deprecated public interface TransactionalStringCommands extends TransactionalRedisCommands { /** diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/transactions/ReactiveTransactionalRedisDataSource.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/transactions/ReactiveTransactionalRedisDataSource.java index 22efbb7d5ccce..d5bc340eb0d93 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/transactions/ReactiveTransactionalRedisDataSource.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/transactions/ReactiveTransactionalRedisDataSource.java @@ -9,6 +9,7 @@ import io.quarkus.redis.datasource.set.ReactiveTransactionalSetCommands; import io.quarkus.redis.datasource.sortedset.ReactiveTransactionalSortedSetCommands; import io.quarkus.redis.datasource.string.ReactiveTransactionalStringCommands; +import io.quarkus.redis.datasource.value.ReactiveTransactionalValueCommands; import io.smallrye.mutiny.Uni; import io.vertx.mutiny.redis.client.Command; @@ -128,6 +129,36 @@ default ReactiveTransactionalSortedSetCommands sortedSet(Class return sortedSet(String.class, valueType); } + /** + * Gets the object to execute commands manipulating stored strings. + * + *

+ * NOTE: Instead of {@code string}, this group is named {@code value} to avoid the confusion with the + * Java String type. Indeed, Redis strings can be strings, numbers, byte arrays... + * + * @param redisKeyType the type of the keys + * @param valueType the type of the value, often String, or the value are encoded/decoded using codecs. + * @param the type of the key + * @param the type of the value + * @return the object to manipulate stored strings. + */ + ReactiveTransactionalValueCommands value(Class redisKeyType, Class valueType); + + /** + * Gets the object to execute commands manipulating stored strings. + * + *

+ * NOTE: Instead of {@code string}, this group is named {@code value} to avoid the confusion with the + * Java String type. Indeed, Redis strings can be strings, numbers, byte arrays... + * + * @param valueType the type of the value, often String, or the value are encoded/decoded using codecs. + * @param the type of the value + * @return the object to manipulate stored strings. + */ + default ReactiveTransactionalValueCommands value(Class valueType) { + return value(String.class, valueType); + } + /** * Gets the object to execute commands manipulating stored strings. * @@ -136,7 +167,9 @@ default ReactiveTransactionalSortedSetCommands sortedSet(Class * @param the type of the key * @param the type of the value * @return the object to manipulate stored strings. + * @deprecated Use {@link #value(Class, Class)} instead */ + @Deprecated ReactiveTransactionalStringCommands string(Class redisKeyType, Class valueType); /** @@ -145,7 +178,9 @@ default ReactiveTransactionalSortedSetCommands sortedSet(Class * @param valueType the type of the value, often String, or the value are encoded/decoded using codecs. * @param the type of the value * @return the object to manipulate stored strings. + * @deprecated Use {@link #value(Class)} instead */ + @Deprecated default ReactiveTransactionalStringCommands string(Class valueType) { return string(String.class, valueType); } diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/transactions/TransactionalRedisDataSource.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/transactions/TransactionalRedisDataSource.java index cf13af8a325db..817fb9015522b 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/transactions/TransactionalRedisDataSource.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/transactions/TransactionalRedisDataSource.java @@ -9,6 +9,7 @@ import io.quarkus.redis.datasource.set.TransactionalSetCommands; import io.quarkus.redis.datasource.sortedset.TransactionalSortedSetCommands; import io.quarkus.redis.datasource.string.TransactionalStringCommands; +import io.quarkus.redis.datasource.value.TransactionalValueCommands; import io.vertx.mutiny.redis.client.Command; /** @@ -126,6 +127,36 @@ default TransactionalSortedSetCommands sortedSet(Class valueTy return sortedSet(String.class, valueType); } + /** + * Gets the object to execute commands manipulating stored strings. + * + *

+ * NOTE: Instead of {@code string}, this group is named {@code value} to avoid the confusion with the + * Java String type. Indeed, Redis strings can be strings, numbers, byte arrays... + * + * @param redisKeyType the type of the keys + * @param valueType the type of the value, often String, or the value are encoded/decoded using codecs. + * @param the type of the key + * @param the type of the value + * @return the object to manipulate stored strings. + */ + TransactionalValueCommands value(Class redisKeyType, Class valueType); + + /** + * Gets the object to execute commands manipulating stored strings. + * + *

+ * NOTE: Instead of {@code string}, this group is named {@code value} to avoid the confusion with the + * Java String type. Indeed, Redis strings can be strings, numbers, byte arrays... + * + * @param valueType the type of the value, often String, or the value are encoded/decoded using codecs. + * @param the type of the value + * @return the object to manipulate stored strings. + */ + default TransactionalValueCommands value(Class valueType) { + return value(String.class, valueType); + } + /** * Gets the object to execute commands manipulating stored strings. * @@ -134,7 +165,9 @@ default TransactionalSortedSetCommands sortedSet(Class valueTy * @param the type of the key * @param the type of the value * @return the object to manipulate stored strings. + * @deprecated Use {@link #value(Class, Class)} instead. */ + @Deprecated TransactionalStringCommands string(Class redisKeyType, Class valueType); /** @@ -143,7 +176,9 @@ default TransactionalSortedSetCommands sortedSet(Class valueTy * @param valueType the type of the value, often String, or the value are encoded/decoded using codecs. * @param the type of the value * @return the object to manipulate stored strings. + * @deprecated Use {@link #value(Class)} instead */ + @Deprecated default TransactionalStringCommands string(Class valueType) { return string(String.class, valueType); } diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/GetExArgs.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/GetExArgs.java new file mode 100644 index 0000000000000..5966a68c43d41 --- /dev/null +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/GetExArgs.java @@ -0,0 +1,156 @@ +package io.quarkus.redis.datasource.value; + +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import io.quarkus.redis.datasource.RedisCommandExtraArguments; + +/** + * Argument list for the Redis GETEX command. + */ +public class GetExArgs implements RedisCommandExtraArguments { + + private long ex = -1; + private long exAt = -1; + private long px = -1; + private long pxAt = -1; + private boolean persist; + + /** + * Set the specified expire time, in seconds. + * + * @param timeout expire time in seconds. + * @return the current {@code GetExArgs} + */ + public GetExArgs ex(long timeout) { + this.ex = timeout; + return this; + } + + /** + * Sets the expiration. + * + * @param timeout expire time in seconds. + * @return the current {@code GetExArgs} + */ + public GetExArgs ex(Duration timeout) { + if (timeout == null) { + throw new IllegalArgumentException("`timeout` must not be `null`"); + } + return ex(timeout.toMillis() / 1000); + } + + /** + * Sets the expiration time + * + * @param timestamp the timestamp + * @return the current {@code GetExArgs} + */ + public GetExArgs exAt(long timestamp) { + this.exAt = timestamp; + return this; + } + + /** + * Sets the expiration time + * + * @param timestamp the timestamp type: posix time in seconds. + * @return the current {@code GetExArgs} + */ + public GetExArgs exAt(Instant timestamp) { + if (timestamp == null) { + throw new IllegalArgumentException("`timestamp` must not be `null`"); + } + exAt(timestamp.toEpochMilli() / 1000); + return this; + } + + /** + * Set the specified expire time, in milliseconds. + * + * @param timeout expire time in milliseconds. + * @return the current {@code GetExArgs} + */ + public GetExArgs px(long timeout) { + this.px = timeout; + return this; + } + + /** + * Set the specified expire time, in milliseconds. + * + * @param timeout expire time in milliseconds. + * @return the current {@code GetExArgs} + */ + public GetExArgs px(Duration timeout) { + if (timeout == null) { + throw new IllegalArgumentException("`timeout` must not be `null`"); + } + return px(timeout.toMillis()); + } + + /** + * Set the specified Unix time at which the key will expire, in milliseconds. + * + * @param timestamp the timestamp + * @return the current {@code GetExArgs} + */ + public GetExArgs pxAt(long timestamp) { + this.pxAt = timestamp; + return this; + } + + /** + * Set the specified Unix time at which the key will expire, in milliseconds. + * + * @param timestamp the timestamp + * @return the current {@code GetExArgs} + */ + public GetExArgs pxAt(Instant timestamp) { + if (timestamp == null) { + throw new IllegalArgumentException("`timestamp` must not be `null`"); + } + return pxAt(timestamp.toEpochMilli()); + } + + /** + * Sets {@code PERSIST} + * + * @return the current {@code GetExArgs} + */ + public GetExArgs persist() { + this.persist = true; + return this; + } + + public List toArgs() { + List args = new ArrayList<>(); + if (ex >= 0) { + args.add("EX"); + args.add(Long.toString(ex)); + } + + if (exAt >= 0) { + args.add("EXAT"); + args.add(Long.toString(exAt)); + } + + if (px >= 0) { + args.add("PX"); + args.add(Long.toString(px)); + } + + if (pxAt >= 0) { + args.add("PXAT"); + args.add(Long.toString(pxAt)); + } + + if (persist) { + args.add("PERSIST"); + } + return args; + } + +} diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/ReactiveTransactionalValueCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/ReactiveTransactionalValueCommands.java new file mode 100644 index 0000000000000..ab7bc9768d25f --- /dev/null +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/ReactiveTransactionalValueCommands.java @@ -0,0 +1,329 @@ +package io.quarkus.redis.datasource.value; + +import java.util.Map; + +import io.quarkus.redis.datasource.ReactiveTransactionalRedisCommands; +import io.smallrye.mutiny.Uni; + +public interface ReactiveTransactionalValueCommands extends ReactiveTransactionalRedisCommands { + + /** + * Execute the command APPEND. + * Summary: Append a value to a key + * Group: string + * Requires Redis 2.0.0 + * + * @param key the key + * @param value the value + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni append(K key, V value); + + /** + * Execute the command DECR. + * Summary: Decrement the integer value of a key by one + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni decr(K key); + + /** + * Execute the command DECRBY. + * Summary: Decrement the integer value of a key by the given number + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param amount the amount, can be negative + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni decrby(K key, long amount); + + /** + * Execute the command GET. + * Summary: Get the value of a key + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni get(K key); + + /** + * Execute the command GETDEL. + * Summary: Get the value of a key and delete the key + * Group: string + * Requires Redis 6.2.0 + * + * @param key the key + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni getdel(K key); + + /** + * Execute the command GETEX. + * Summary: Get the value of a key and optionally set its expiration + * Group: string + * Requires Redis 6.2.0 + * + * @param key the key + * @param args the getex command extra-arguments + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni getex(K key, GetExArgs args); + + /** + * Execute the command GETRANGE. + * Summary: Get a substring of the string stored at a key + * Group: string + * Requires Redis 2.4.0 + * + * @param key the key + * @param start the start offset + * @param end the end offset + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni getrange(K key, long start, long end); + + /** + * Execute the command GETSET. + * Summary: Set the string value of a key and return its old value + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + * @deprecated See https://redis.io/commands/getset + */ + Uni getset(K key, V value); + + /** + * Execute the command INCR. + * Summary: Increment the integer value of a key by one + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni incr(K key); + + /** + * Execute the command INCRBY. + * Summary: Increment the integer value of a key by the given amount + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param amount the amount, can be negative + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni incrby(K key, long amount); + + /** + * Execute the command INCRBYFLOAT. + * Summary: Increment the float value of a key by the given amount + * Group: string + * Requires Redis 2.6.0 + * + * @param key the key + * @param amount the amount, can be negative + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni incrbyfloat(K key, double amount); + + /** + * Execute the command LCS. + * Summary: Find longest common substring + * Group: string + * Requires Redis 7.0.0 + * + * @param key1 the key + * @param key2 the key + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni lcs(K key1, K key2); + + /** + * Execute the command LCS. + * Summary: Find longest common substring and return the length (using {@code LEN}) + * Group: string + * Requires Redis 7.0.0 + * + * @param key1 the key + * @param key2 the key + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni lcsLength(K key1, K key2); + + /** + * Execute the command MGET. + * Summary: Get the values of all the given keys + * Group: string + * Requires Redis 1.0.0 + * + * @param keys the keys + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni mget(K... keys); + + /** + * Execute the command MSET. + * Summary: Set multiple keys to multiple values + * Group: string + * Requires Redis 1.0.1 + * + * @param map the key/value map containing the items to store + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni mset(Map map); + + /** + * Execute the command MSETNX. + * Summary: Set multiple keys to multiple values, only if none of the keys exist + * Group: string + * Requires Redis 1.0.1 + * + * @param map the key/value map containing the items to store + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni msetnx(Map map); + + /** + * Execute the command PSETEX. + * Summary: Set the value and expiration in milliseconds of a key + * Group: string + * Requires Redis 2.6.0 + * + * @param key the key + * @param milliseconds the duration in ms + * @param value the value + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni psetex(K key, long milliseconds, V value); + + /** + * Execute the command SET. + * Summary: Set the string value of a key + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni set(K key, V value); + + /** + * Execute the command SET. + * Summary: Set the string value of a key + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @param setArgs the set command extra-arguments + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni set(K key, V value, SetArgs setArgs); + + /** + * Execute the command SET. + * Summary: Set the string value of a key, and return the previous value + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni setGet(K key, V value); + + /** + * Execute the command SET. + * Summary: Set the string value of a key, and return the previous value + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @param setArgs the set command extra-arguments + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni setGet(K key, V value, SetArgs setArgs); + + /** + * Execute the command SETEX. + * Summary: Set the value and expiration of a key + * Group: string + * Requires Redis 2.0.0 + * + * @param key the key + * @param value the value + */ + Uni setex(K key, long seconds, V value); + + /** + * Execute the command SETNX. + * Summary: Set the value of a key, only if the key does not exist + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni setnx(K key, V value); + + /** + * Execute the command SETRANGE. + * Summary: Overwrite part of a string at key starting at the specified offset + * Group: string + * Requires Redis 2.2.0 + * + * @param key the key + * @param value the value + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni setrange(K key, long offset, V value); + + /** + * Execute the command STRLEN. + * Summary: Get the length of the value stored in a key + * Group: string + * Requires Redis 2.2.0 + * + * @param key the key + * @return A {@code Uni} emitting {@code null} when the command has been enqueued successfully in the transaction, a failure + * otherwise. In the case of failure, the transaction is discarded. + */ + Uni strlen(K key); +} diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/ReactiveValueCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/ReactiveValueCommands.java new file mode 100644 index 0000000000000..896d7793a3a07 --- /dev/null +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/ReactiveValueCommands.java @@ -0,0 +1,322 @@ +package io.quarkus.redis.datasource.value; + +import java.util.Map; + +import io.quarkus.redis.datasource.ReactiveRedisCommands; +import io.smallrye.mutiny.Uni; + +/** + * Allows executing commands from the {@code string} group. + * See the string command list for further information + * about these commands. + *

+ * This group can be used with value of type {@code String}, or a type which will be automatically + * serialized/deserialized with a codec. + *

+ * NOTE: Instead of {@code string}, this group is named {@code value} to avoid the confusion with the + * Java String type. Indeed, Redis strings can be strings, numbers, byte arrays... + * + * @param the type of the key + * @param the type of the value + */ +public interface ReactiveValueCommands extends ReactiveRedisCommands { + + /** + * Execute the command APPEND. + * Summary: Append a value to a key + * Group: string + * Requires Redis 2.0.0 + * + * @param key the key + * @param value the value + * @return the length of the string after the append operation. + **/ + Uni append(K key, V value); + + /** + * Execute the command DECR. + * Summary: Decrement the integer value of a key by one + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @return the value of key after the decrement + **/ + Uni decr(K key); + + /** + * Execute the command DECRBY. + * Summary: Decrement the integer value of a key by the given number + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param amount the amount, can be negative + * @return the value of key after the decrement + **/ + Uni decrby(K key, long amount); + + /** + * Execute the command GET. + * Summary: Get the value of a key + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @return the value of key, or {@code null} when key does not exist. + **/ + Uni get(K key); + + /** + * Execute the command GETDEL. + * Summary: Get the value of a key and delete the key + * Group: string + * Requires Redis 6.2.0 + * + * @param key the key + * @return the value of key, {@code null} when key does not exist, or an error if the key's value type isn't a string. + **/ + Uni getdel(K key); + + /** + * Execute the command GETEX. + * Summary: Get the value of a key and optionally set its expiration + * Group: string + * Requires Redis 6.2.0 + * + * @param key the key + * @param args the getex command extra-arguments + * @return the value of key, or {@code null} when key does not exist. + **/ + Uni getex(K key, GetExArgs args); + + /** + * Execute the command GETRANGE. + * Summary: Get a substring of the string stored at a key + * Group: string + * Requires Redis 2.4.0 + * + * @param key the key + * @param start the start offset + * @param end the end offset + * @return the sub-string + **/ + Uni getrange(K key, long start, long end); + + /** + * Execute the command GETSET. + * Summary: Set the string value of a key and return its old value + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @return the old value stored at key, or {@code null} when key did not exist. + * @deprecated See https://redis.io/commands/getset + **/ + Uni getset(K key, V value); + + /** + * Execute the command INCR. + * Summary: Increment the integer value of a key by one + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @return the value of key after the increment + **/ + Uni incr(K key); + + /** + * Execute the command INCRBY. + * Summary: Increment the integer value of a key by the given amount + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param amount the amount, can be negative + * @return the value of key after the increment + **/ + Uni incrby(K key, long amount); + + /** + * Execute the command INCRBYFLOAT. + * Summary: Increment the float value of a key by the given amount + * Group: string + * Requires Redis 2.6.0 + * + * @param key the key + * @param amount the amount, can be negative + * @return the value of key after the increment. + **/ + Uni incrbyfloat(K key, double amount); + + /** + * Execute the command LCS. + * Summary: Find longest common substring + * Group: string + * Requires Redis 7.0.0 + * + * @param key1 the key + * @param key2 the key + * @return the string representing the longest common substring is returned. + **/ + Uni lcs(K key1, K key2); + + /** + * Execute the command LCS. + * Summary: Find longest common substring and return the length (using {@code LEN}) + * Group: string + * Requires Redis 7.0.0 + * + * @param key1 the key + * @param key2 the key + * @return the length of the longest common substring. + **/ + Uni lcsLength(K key1, K key2); + + // TODO Add LCS with IDX support + + /** + * Execute the command MGET. + * Summary: Get the values of all the given keys + * Group: string + * Requires Redis 1.0.0 + * + * @param keys the keys + * @return list of values at the specified keys. + **/ + Uni> mget(K... keys); + + /** + * Execute the command MSET. + * Summary: Set multiple keys to multiple values + * Group: string + * Requires Redis 1.0.1 + * + * @param map the key/value map containing the items to store + * @return a Uni producing a {@code null} item on success, a failure otherwise + **/ + Uni mset(Map map); + + /** + * Execute the command MSETNX. + * Summary: Set multiple keys to multiple values, only if none of the keys exist + * Group: string + * Requires Redis 1.0.1 + * + * @param map the key/value map containing the items to store + * @return {@code true} the all the keys were set. {@code false} no key was set (at least one key already existed). + **/ + Uni msetnx(Map map); + + /** + * Execute the command PSETEX. + * Summary: Set the value and expiration in milliseconds of a key + * Group: string + * Requires Redis 2.6.0 + * + * @param key the key + * @param milliseconds the duration in ms + * @param value the value + * @return a Uni producing a {@code null} item on success, a failure otherwise + **/ + Uni psetex(K key, long milliseconds, V value); + + /** + * Execute the command SET. + * Summary: Set the string value of a key + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @return a Uni producing a {@code null} item on success, a failure otherwise + **/ + Uni set(K key, V value); + + /** + * Execute the command SET. + * Summary: Set the string value of a key + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @param setArgs the set command extra-arguments + * @return a Uni producing a {@code null} item on success, a failure otherwise + **/ + Uni set(K key, V value, SetArgs setArgs); + + /** + * Execute the command SET. + * Summary: Set the string value of a key, and return the previous value + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @return the old value, {@code null} if not present + **/ + Uni setGet(K key, V value); + + /** + * Execute the command SET. + * Summary: Set the string value of a key, and return the previous value + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @param setArgs the set command extra-arguments + * @return the old value, {@code null} if not present + **/ + Uni setGet(K key, V value, SetArgs setArgs); + + /** + * Execute the command SETEX. + * Summary: Set the value and expiration of a key + * Group: string + * Requires Redis 2.0.0 + * + * @param key the key + * @param value the value + **/ + Uni setex(K key, long seconds, V value); + + /** + * Execute the command SETNX. + * Summary: Set the value of a key, only if the key does not exist + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @return {@code true} the key was set {@code false} the key was not set + **/ + Uni setnx(K key, V value); + + /** + * Execute the command SETRANGE. + * Summary: Overwrite part of a string at key starting at the specified offset + * Group: string + * Requires Redis 2.2.0 + * + * @param key the key + * @param value the value + * @return the length of the string after it was modified by the command. + **/ + Uni setrange(K key, long offset, V value); + + /** + * Execute the command STRLEN. + * Summary: Get the length of the value stored in a key + * Group: string + * Requires Redis 2.2.0 + * + * @param key the key + * @return the length of the string at key, or 0 when key does not exist. + **/ + Uni strlen(K key); + +} diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/SetArgs.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/SetArgs.java new file mode 100644 index 0000000000000..c03af517867a4 --- /dev/null +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/SetArgs.java @@ -0,0 +1,208 @@ +package io.quarkus.redis.datasource.value; + +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import io.quarkus.redis.datasource.RedisCommandExtraArguments; + +/** + * Argument list for the Redis SET command. + */ +public class SetArgs implements RedisCommandExtraArguments { + + private long ex = -1; + private long exAt = -1; + private long px = -1; + private long pxAt = -1; + private boolean nx; + private boolean keepttl; + private boolean xx; + private boolean get; + + /** + * Set the specified expire time, in seconds. + * + * @param timeout expire time in seconds. + * @return the current {@code GetExArgs} + */ + public SetArgs ex(long timeout) { + if (timeout <= 0) { + throw new IllegalArgumentException("`timeout` must be positive"); + } + this.ex = timeout; + return this; + } + + /** + * Sets the expiration. + * + * @param timeout expire time in seconds. + * @return the current {@code GetExArgs} + */ + public SetArgs ex(Duration timeout) { + if (timeout == null) { + throw new IllegalArgumentException("`timeout` must not be `null`"); + } + return ex(timeout.toMillis() / 1000); + } + + /** + * Sets the expiration time + * + * @param timestamp the timestamp + * @return the current {@code GetExArgs} + */ + public SetArgs exAt(long timestamp) { + this.exAt = timestamp; + return this; + } + + /** + * Sets the expiration time + * + * @param timestamp the timestamp type: posix time in seconds. + * @return the current {@code GetExArgs} + */ + public SetArgs exAt(Instant timestamp) { + if (timestamp == null) { + throw new IllegalArgumentException("`timestamp` must not be `null`"); + } + exAt(timestamp.toEpochMilli() / 1000); + return this; + } + + /** + * Set the specified expire time, in milliseconds. + * + * @param timeout expire time in milliseconds. + * @return the current {@code GetExArgs} + */ + public SetArgs px(long timeout) { + if (timeout < 0) { + throw new IllegalArgumentException("`timeout` must be positive"); + } + this.px = timeout; + return this; + } + + /** + * Set the specified expire time, in milliseconds. + * + * @param timeout expire time in milliseconds. + * @return the current {@code GetExArgs} + */ + public SetArgs px(Duration timeout) { + if (timeout == null) { + throw new IllegalArgumentException("`timeout` must not be `null`"); + } + return px(timeout.toMillis()); + } + + /** + * Set the specified Unix time at which the key will expire, in milliseconds. + * + * @param timestamp the timestamp + * @return the current {@code GetExArgs} + */ + public SetArgs pxAt(long timestamp) { + this.pxAt = timestamp; + return this; + } + + /** + * Set the specified Unix time at which the key will expire, in milliseconds. + * + * @param timestamp the timestamp + * @return the current {@code SetArgs} + */ + public SetArgs pxAt(Instant timestamp) { + if (timestamp == null) { + throw new IllegalArgumentException("`timestamp` must not be `null`"); + } + return pxAt(timestamp.toEpochMilli()); + } + + /** + * Only set the key if it does not already exist. + * + * @return the current {@code SetArgs} + */ + public SetArgs nx() { + this.nx = true; + return this; + } + + /** + * Set the value and retain the existing TTL. + * + * @return the current {@code SetArgs} + */ + public SetArgs keepttl() { + this.keepttl = true; + return this; + } + + /** + * Only set the key if it already exists. + * + * @return the current {@code SetArgs} + */ + public SetArgs xx() { + this.xx = true; + return this; + } + + /** + * Return the old string stored at key, or nil if key did not exist. An error is returned and SET aborted if the + * value stored at key is not a string. + * + * @return the current {@code SetArgs} + */ + public SetArgs get() { + this.get = true; + return this; + } + + public List toArgs() { + List args = new ArrayList<>(); + if (ex >= 0) { + args.add("EX"); + args.add(Long.toString(ex)); + } + + if (exAt >= 0) { + args.add("EXAT"); + args.add(Long.toString(exAt)); + } + + if (px >= 0) { + args.add("PX"); + args.add(Long.toString(px)); + } + + if (pxAt >= 0) { + args.add("PXAT"); + args.add(Long.toString(pxAt)); + } + + if (nx) { + args.add("NX"); + } + + if (xx) { + args.add("XX"); + } + + if (keepttl) { + args.add("KEEPTTL"); + } + + if (get) { + args.add("GET"); + } + return args; + } + +} diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/TransactionalValueCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/TransactionalValueCommands.java new file mode 100644 index 0000000000000..5f04951301992 --- /dev/null +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/TransactionalValueCommands.java @@ -0,0 +1,280 @@ +package io.quarkus.redis.datasource.value; + +import java.util.Map; + +import io.quarkus.redis.datasource.TransactionalRedisCommands; + +public interface TransactionalValueCommands extends TransactionalRedisCommands { + + /** + * Execute the command APPEND. + * Summary: Append a value to a key + * Group: string + * Requires Redis 2.0.0 + * + * @param key the key + * @param value the value + */ + void append(K key, V value); + + /** + * Execute the command DECR. + * Summary: Decrement the integer value of a key by one + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + */ + void decr(K key); + + /** + * Execute the command DECRBY. + * Summary: Decrement the integer value of a key by the given number + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param amount the amount, can be negative + */ + void decrby(K key, long amount); + + /** + * Execute the command GET. + * Summary: Get the value of a key + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + */ + void get(K key); + + /** + * Execute the command GETDEL. + * Summary: Get the value of a key and delete the key + * Group: string + * Requires Redis 6.2.0 + * + * @param key the key + */ + void getdel(K key); + + /** + * Execute the command GETEX. + * Summary: Get the value of a key and optionally set its expiration + * Group: string + * Requires Redis 6.2.0 + * + * @param key the key + * @param args the getex command extra-arguments + */ + void getex(K key, GetExArgs args); + + /** + * Execute the command GETRANGE. + * Summary: Get a substring of the string stored at a key + * Group: string + * Requires Redis 2.4.0 + * + * @param key the key + * @param start the start offset + * @param end the end offset + */ + void getrange(K key, long start, long end); + + /** + * Execute the command GETSET. + * Summary: Set the string value of a key and return its old value + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @deprecated See https://redis.io/commands/getset + */ + void getset(K key, V value); + + /** + * Execute the command INCR. + * Summary: Increment the integer value of a key by one + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + */ + void incr(K key); + + /** + * Execute the command INCRBY. + * Summary: Increment the integer value of a key by the given amount + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param amount the amount, can be negative + */ + void incrby(K key, long amount); + + /** + * Execute the command INCRBYFLOAT. + * Summary: Increment the float value of a key by the given amount + * Group: string + * Requires Redis 2.6.0 + * + * @param key the key + * @param amount the amount, can be negative + */ + void incrbyfloat(K key, double amount); + + /** + * Execute the command LCS. + * Summary: Find longest common substring + * Group: string + * Requires Redis 7.0.0 + * + * @param key1 the key + * @param key2 the key + */ + void lcs(K key1, K key2); + + /** + * Execute the command LCS. + * Summary: Find longest common substring and return the length (using {@code LEN}) + * Group: string + * Requires Redis 7.0.0 + * + * @param key1 the key + * @param key2 the key + */ + void lcsLength(K key1, K key2); + + /** + * Execute the command MGET. + * Summary: Get the values of all the given keys + * Group: string + * Requires Redis 1.0.0 + * + * @param keys the keys + */ + void mget(K... keys); + + /** + * Execute the command MSET. + * Summary: Set multiple keys to multiple values + * Group: string + * Requires Redis 1.0.1 + * + * @param map the key/value map containing the items to store + */ + void mset(Map map); + + /** + * Execute the command MSETNX. + * Summary: Set multiple keys to multiple values, only if none of the keys exist + * Group: string + * Requires Redis 1.0.1 + * + * @param map the key/value map containing the items to store + */ + void msetnx(Map map); + + /** + * Execute the command PSETEX. + * Summary: Set the value and expiration in milliseconds of a key + * Group: string + * Requires Redis 2.6.0 + * + * @param key the key + * @param milliseconds the duration in ms + * @param value the value + */ + void psetex(K key, long milliseconds, V value); + + /** + * Execute the command SET. + * Summary: Set the string value of a key + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + */ + void set(K key, V value); + + /** + * Execute the command SET. + * Summary: Set the string value of a key + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @param setArgs the set command extra-arguments + */ + void set(K key, V value, SetArgs setArgs); + + /** + * Execute the command SET. + * Summary: Set the string value of a key, and return the previous value + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + */ + void setGet(K key, V value); + + /** + * Execute the command SET. + * Summary: Set the string value of a key, and return the previous value + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @param setArgs the set command extra-arguments + */ + void setGet(K key, V value, SetArgs setArgs); + + /** + * Execute the command SETEX. + * Summary: Set the value and expiration of a key + * Group: string + * Requires Redis 2.0.0 + * + * @param key the key + * @param value the value + */ + void setex(K key, long seconds, V value); + + /** + * Execute the command SETNX. + * Summary: Set the value of a key, only if the key does not exist + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + */ + void setnx(K key, V value); + + /** + * Execute the command SETRANGE. + * Summary: Overwrite part of a string at key starting at the specified offset + * Group: string + * Requires Redis 2.2.0 + * + * @param key the key + * @param value the value + */ + void setrange(K key, long offset, V value); + + /** + * Execute the command STRLEN. + * Summary: Get the length of the value stored in a key + * Group: string + * Requires Redis 2.2.0 + * + * @param key the key + */ + void strlen(K key); +} diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/ValueCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/ValueCommands.java new file mode 100644 index 0000000000000..2f6416d11e845 --- /dev/null +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/ValueCommands.java @@ -0,0 +1,321 @@ +package io.quarkus.redis.datasource.value; + +import java.util.Map; + +import io.quarkus.redis.datasource.RedisCommands; + +/** + * Allows executing commands from the {@code string} group. + * See the string command list for further information + * about these commands. + *

+ * This group can be used with value of type {@code String}, or a type which will be automatically + * serialized/deserialized with a codec. + *

+ * NOTE: Instead of {@code string}, this group is named {@code value} to avoid the confusion with the + * Java String type. Indeed, Redis strings can be strings, numbers, byte arrays... + * + * @param the type of the key + * @param the type of the value + */ +public interface ValueCommands extends RedisCommands { + + /** + * Execute the command APPEND. + * Summary: Append a value to a key + * Group: string + * Requires Redis 2.0.0 + * + * @param key the key + * @param value the value + * @return the length of the string after the append operation. + **/ + long append(K key, V value); + + /** + * Execute the command DECR. + * Summary: Decrement the integer value of a key by one + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @return the value of key after the decrement + **/ + long decr(K key); + + /** + * Execute the command DECRBY. + * Summary: Decrement the integer value of a key by the given number + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param amount the amount, can be negative + * @return the value of key after the decrement + **/ + long decrby(K key, long amount); + + /** + * Execute the command GET. + * Summary: Get the value of a key + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @return the value of key, or {@code null} when key does not exist. + **/ + V get(K key); + + /** + * Execute the command GETDEL. + * Summary: Get the value of a key and delete the key + * Group: string + * Requires Redis 6.2.0 + * + * @param key the key + * @return the value of key, {@code null} when key does not exist, or an error if the key's value type isn't a string. + **/ + V getdel(K key); + + /** + * Execute the command GETEX. + * Summary: Get the value of a key and optionally set its expiration + * Group: string + * Requires Redis 6.2.0 + * + * @param key the key + * @param args the getex command extra-arguments + * @return the value of key, or {@code null} when key does not exist. + **/ + V getex(K key, GetExArgs args); + + /** + * Execute the command GETRANGE. + * Summary: Get a substring of the string stored at a key + * Group: string + * Requires Redis 2.4.0 + * + * @param key the key + * @param start the start offset + * @param end the end offset + * @return the sub-string + **/ + String getrange(K key, long start, long end); + + /** + * Execute the command GETSET. + * Summary: Set the string value of a key and return its old value + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @return the old value stored at key, or {@code null} when key did not exist. + * @deprecated See https://redis.io/commands/getset + **/ + V getset(K key, V value); + + /** + * Execute the command INCR. + * Summary: Increment the integer value of a key by one + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @return the value of key after the increment + **/ + long incr(K key); + + /** + * Execute the command INCRBY. + * Summary: Increment the integer value of a key by the given amount + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param amount the amount, can be negative + * @return the value of key after the increment + **/ + long incrby(K key, long amount); + + /** + * Execute the command INCRBYFLOAT. + * Summary: Increment the float value of a key by the given amount + * Group: string + * Requires Redis 2.6.0 + * + * @param key the key + * @param amount the amount, can be negative + * @return the value of key after the increment. + **/ + double incrbyfloat(K key, double amount); + + /** + * Execute the command LCS. + * Summary: Find longest common substring + * Group: string + * Requires Redis 7.0.0 + * + * @param key1 the key + * @param key2 the key + * @return the string representing the longest common substring is returned. + **/ + String lcs(K key1, K key2); + + /** + * Execute the command LCS. + * Summary: Find longest common substring and return the length (using {@code LEN}) + * Group: string + * Requires Redis 7.0.0 + * + * @param key1 the key + * @param key2 the key + * @return the length of the longest common substring. + **/ + long lcsLength(K key1, K key2); + + // TODO Add LCS with IDX support + + /** + * Execute the command MGET. + * Summary: Get the values of all the given keys + * Group: string + * Requires Redis 1.0.0 + * + * @param keys the keys + * @return list of values at the specified keys. + **/ + Map mget(K... keys); + + /** + * Execute the command MSET. + * Summary: Set multiple keys to multiple values + * Group: string + * Requires Redis 1.0.1 + * + * @param map the key/value map containing the items to store + * @return a Uni producing a {@code null} item on success, a failure otherwise + **/ + void mset(Map map); + + /** + * Execute the command MSETNX. + * Summary: Set multiple keys to multiple values, only if none of the keys exist + * Group: string + * Requires Redis 1.0.1 + * + * @param map the key/value map containing the items to store + * @return {@code true} the all the keys were set. {@code false} no key was set (at least one key already existed). + **/ + boolean msetnx(Map map); + + /** + * Execute the command PSETEX. + * Summary: Set the value and expiration in milliseconds of a key + * Group: string + * Requires Redis 2.6.0 + * + * @param key the key + * @param milliseconds the duration in ms + * @param value the value + * @return a Uni producing a {@code null} item on success, a failure otherwise + **/ + void psetex(K key, long milliseconds, V value); + + /** + * Execute the command SET. + * Summary: Set the string value of a key + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @return a Uni producing a {@code null} item on success, a failure otherwise + **/ + void set(K key, V value); + + /** + * Execute the command SET. + * Summary: Set the string value of a key + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @param setArgs the set command extra-arguments + * @return a Uni producing a {@code null} item on success, a failure otherwise + **/ + void set(K key, V value, SetArgs setArgs); + + /** + * Execute the command SET. + * Summary: Set the string value of a key, and return the previous value + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @return the old value, {@code null} if not present + **/ + V setGet(K key, V value); + + /** + * Execute the command SET. + * Summary: Set the string value of a key, and return the previous value + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @param setArgs the set command extra-arguments + * @return the old value, {@code null} if not present + **/ + V setGet(K key, V value, SetArgs setArgs); + + /** + * Execute the command SETEX. + * Summary: Set the value and expiration of a key + * Group: string + * Requires Redis 2.0.0 + * + * @param key the key + * @param value the value + **/ + void setex(K key, long seconds, V value); + + /** + * Execute the command SETNX. + * Summary: Set the value of a key, only if the key does not exist + * Group: string + * Requires Redis 1.0.0 + * + * @param key the key + * @param value the value + * @return {@code true} the key was set {@code false} the key was not set + **/ + boolean setnx(K key, V value); + + /** + * Execute the command SETRANGE. + * Summary: Overwrite part of a string at key starting at the specified offset + * Group: string + * Requires Redis 2.2.0 + * + * @param key the key + * @param value the value + * @return the length of the string after it was modified by the command. + **/ + long setrange(K key, long offset, V value); + + /** + * Execute the command STRLEN. + * Summary: Get the length of the value stored in a key + * Group: string + * Requires Redis 2.2.0 + * + * @param key the key + * @return the length of the string at key, or 0 when key does not exist. + **/ + long strlen(K key); + +} diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractStringCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractStringCommands.java index 9e63100f54a42..de857f54c512d 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractStringCommands.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractStringCommands.java @@ -45,6 +45,17 @@ Uni _set(K key, V value, SetArgs setArgs) { return execute(cmd); } + Uni _set(K key, V value, io.quarkus.redis.datasource.value.SetArgs setArgs) { + nonNull(key, "key"); + nonNull(value, "value"); + nonNull(setArgs, "setArgs"); + RedisCommand cmd = RedisCommand.of(Command.SET); + cmd.put(marshaller.encode(key)); + cmd.put(marshaller.encode(value)); + cmd.putArgs(setArgs); + return execute(cmd); + } + Uni _setGet(K key, V value) { nonNull(key, "key"); nonNull(value, "value"); @@ -70,6 +81,17 @@ Uni _setGet(K key, V value, SetArgs setArgs) { return execute(cmd); } + Uni _setGet(K key, V value, io.quarkus.redis.datasource.value.SetArgs setArgs) { + nonNull(key, "key"); + nonNull(value, "value"); + nonNull(setArgs, "setArgs"); + RedisCommand cmd = RedisCommand.of(Command.SET); + cmd.put(marshaller.encode(key)); + cmd.put(marshaller.encode(value)); + cmd.putArgs(setArgs.get()); + return execute(cmd); + } + Uni _setex(K key, long seconds, V value) { nonNull(key, "key"); positive(seconds, "seconds"); @@ -148,6 +170,15 @@ Uni _getex(K key, GetExArgs args) { return execute(cmd); } + Uni _getex(K key, io.quarkus.redis.datasource.value.GetExArgs args) { + nonNull(key, "key"); + nonNull(args, "args"); + RedisCommand cmd = RedisCommand.of(Command.GETEX); + cmd.put(marshaller.encode(key)); + cmd.putArgs(args); + return execute(cmd); + } + Uni _getrange(K key, long start, long end) { nonNull(key, "key"); positiveOrZero(start, "start"); diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingRedisDataSourceImpl.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingRedisDataSourceImpl.java index ecb876cc3d06b..4a18d9e8e7cff 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingRedisDataSourceImpl.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingRedisDataSourceImpl.java @@ -22,6 +22,7 @@ import io.quarkus.redis.datasource.transactions.OptimisticLockingTransactionResult; import io.quarkus.redis.datasource.transactions.TransactionResult; import io.quarkus.redis.datasource.transactions.TransactionalRedisDataSource; +import io.quarkus.redis.datasource.value.ValueCommands; import io.vertx.mutiny.core.Vertx; import io.vertx.mutiny.redis.client.Command; import io.vertx.mutiny.redis.client.Redis; @@ -192,7 +193,12 @@ public SortedSetCommands sortedSet(Class redisKeyType, Clas @Override public StringCommands string(Class redisKeyType, Class valueType) { - return new BlockingStringCommandsImpl<>(this, reactive.string(redisKeyType, valueType), timeout); + return new BlockingStringCommandsImpl<>(this, reactive.value(redisKeyType, valueType), timeout); + } + + @Override + public ValueCommands value(Class redisKeyType, Class valueType) { + return new BlockingStringCommandsImpl<>(this, reactive.value(redisKeyType, valueType), timeout); } @Override diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingStringCommandsImpl.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingStringCommandsImpl.java index d5bcd0ae9554f..44ea8cf91f6fa 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingStringCommandsImpl.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingStringCommandsImpl.java @@ -5,15 +5,17 @@ import io.quarkus.redis.datasource.RedisDataSource; import io.quarkus.redis.datasource.string.GetExArgs; -import io.quarkus.redis.datasource.string.ReactiveStringCommands; import io.quarkus.redis.datasource.string.SetArgs; import io.quarkus.redis.datasource.string.StringCommands; +import io.quarkus.redis.datasource.value.ReactiveValueCommands; +import io.quarkus.redis.datasource.value.ValueCommands; -public class BlockingStringCommandsImpl extends AbstractRedisCommandGroup implements StringCommands { +public class BlockingStringCommandsImpl extends AbstractRedisCommandGroup + implements StringCommands, ValueCommands { - private final ReactiveStringCommands reactive; + private final ReactiveValueCommands reactive; - public BlockingStringCommandsImpl(RedisDataSource ds, ReactiveStringCommands reactive, Duration timeout) { + public BlockingStringCommandsImpl(RedisDataSource ds, ReactiveValueCommands reactive, Duration timeout) { super(ds, timeout); this.reactive = reactive; } @@ -50,6 +52,12 @@ public V getex(K key, GetExArgs args) { .await().atMost(timeout); } + @Override + public V getex(K key, io.quarkus.redis.datasource.value.GetExArgs args) { + return reactive.getex(key, args) + .await().atMost(timeout); + } + @Override public String getrange(K key, long start, long end) { return reactive.getrange(key, start, end) @@ -119,6 +127,12 @@ public void set(K key, V value, SetArgs setArgs) { .await().atMost(timeout); } + @Override + public void set(K key, V value, io.quarkus.redis.datasource.value.SetArgs setArgs) { + reactive.set(key, value, setArgs) + .await().atMost(timeout); + } + @Override public V setGet(K key, V value) { return reactive.setGet(key, value) @@ -131,6 +145,12 @@ public V setGet(K key, V value, SetArgs setArgs) { .await().atMost(timeout); } + @Override + public V setGet(K key, V value, io.quarkus.redis.datasource.value.SetArgs setArgs) { + return reactive.setGet(key, value, setArgs) + .await().atMost(timeout); + } + @Override public void setex(K key, long seconds, V value) { reactive.setex(key, seconds, value) diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingTransactionalRedisDataSourceImpl.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingTransactionalRedisDataSourceImpl.java index ee0df37733f48..69f5579c91eba 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingTransactionalRedisDataSourceImpl.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingTransactionalRedisDataSourceImpl.java @@ -13,6 +13,7 @@ import io.quarkus.redis.datasource.string.TransactionalStringCommands; import io.quarkus.redis.datasource.transactions.ReactiveTransactionalRedisDataSource; import io.quarkus.redis.datasource.transactions.TransactionalRedisDataSource; +import io.quarkus.redis.datasource.value.TransactionalValueCommands; import io.vertx.mutiny.redis.client.Command; public class BlockingTransactionalRedisDataSourceImpl implements TransactionalRedisDataSource { @@ -64,7 +65,12 @@ public TransactionalSortedSetCommands sortedSet(Class redisKeyTy @Override public TransactionalStringCommands string(Class redisKeyType, Class valueType) { - return new BlockingTransactionalStringCommandsImpl<>(this, reactive.string(redisKeyType, valueType), timeout); + return new BlockingTransactionalStringCommandsImpl<>(this, reactive.value(redisKeyType, valueType), timeout); + } + + @Override + public TransactionalValueCommands value(Class redisKeyType, Class valueType) { + return new BlockingTransactionalStringCommandsImpl<>(this, reactive.value(redisKeyType, valueType), timeout); } @Override diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingTransactionalStringCommandsImpl.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingTransactionalStringCommandsImpl.java index 14f5323a06149..4fe60f9a537c3 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingTransactionalStringCommandsImpl.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/BlockingTransactionalStringCommandsImpl.java @@ -4,18 +4,19 @@ import java.util.Map; import io.quarkus.redis.datasource.string.GetExArgs; -import io.quarkus.redis.datasource.string.ReactiveTransactionalStringCommands; import io.quarkus.redis.datasource.string.SetArgs; import io.quarkus.redis.datasource.string.TransactionalStringCommands; import io.quarkus.redis.datasource.transactions.TransactionalRedisDataSource; +import io.quarkus.redis.datasource.value.ReactiveTransactionalValueCommands; +import io.quarkus.redis.datasource.value.TransactionalValueCommands; public class BlockingTransactionalStringCommandsImpl extends AbstractTransactionalRedisCommandGroup - implements TransactionalStringCommands { + implements TransactionalStringCommands, TransactionalValueCommands { - private final ReactiveTransactionalStringCommands reactive; + private final ReactiveTransactionalValueCommands reactive; public BlockingTransactionalStringCommandsImpl(TransactionalRedisDataSource ds, - ReactiveTransactionalStringCommands reactive, Duration timeout) { + ReactiveTransactionalValueCommands reactive, Duration timeout) { super(ds, timeout); this.reactive = reactive; } @@ -50,6 +51,11 @@ public void getex(K key, GetExArgs args) { this.reactive.getex(key, args).await().atMost(this.timeout); } + @Override + public void getex(K key, io.quarkus.redis.datasource.value.GetExArgs args) { + this.reactive.getex(key, args).await().atMost(this.timeout); + } + @Override public void getrange(K key, long start, long end) { this.reactive.getrange(key, start, end).await().atMost(this.timeout); @@ -115,6 +121,11 @@ public void set(K key, V value, SetArgs setArgs) { this.reactive.set(key, value, setArgs).await().atMost(this.timeout); } + @Override + public void set(K key, V value, io.quarkus.redis.datasource.value.SetArgs setArgs) { + this.reactive.set(key, value, setArgs).await().atMost(this.timeout); + } + @Override public void setGet(K key, V value) { this.reactive.setGet(key, value).await().atMost(this.timeout); @@ -125,6 +136,11 @@ public void setGet(K key, V value, SetArgs setArgs) { this.reactive.setGet(key, value, setArgs).await().atMost(this.timeout); } + @Override + public void setGet(K key, V value, io.quarkus.redis.datasource.value.SetArgs setArgs) { + this.reactive.setGet(key, value, setArgs).await().atMost(this.timeout); + } + @Override public void setex(K key, long seconds, V value) { this.reactive.setex(key, seconds, value).await().atMost(this.timeout); diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveRedisDataSourceImpl.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveRedisDataSourceImpl.java index 06c8d5d016bbc..ed4e1aafe7fb9 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveRedisDataSourceImpl.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveRedisDataSourceImpl.java @@ -23,6 +23,7 @@ import io.quarkus.redis.datasource.transactions.OptimisticLockingTransactionResult; import io.quarkus.redis.datasource.transactions.ReactiveTransactionalRedisDataSource; import io.quarkus.redis.datasource.transactions.TransactionResult; +import io.quarkus.redis.datasource.value.ReactiveValueCommands; import io.smallrye.mutiny.Uni; import io.vertx.mutiny.core.Vertx; import io.vertx.mutiny.redis.client.Command; @@ -251,6 +252,11 @@ public ReactiveStringCommands string(Class redisKeyType, Class(this, redisKeyType, valueType); } + @Override + public ReactiveValueCommands value(Class redisKeyType, Class valueType) { + return new ReactiveStringCommandsImpl<>(this, redisKeyType, valueType); + } + @Override public ReactiveSetCommands set(Class redisKeyType, Class memberType) { return new ReactiveSetCommandsImpl<>(this, redisKeyType, memberType); diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveStringCommandsImpl.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveStringCommandsImpl.java index 445c348ff821e..ef0df74339db3 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveStringCommandsImpl.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveStringCommandsImpl.java @@ -6,10 +6,12 @@ import io.quarkus.redis.datasource.string.GetExArgs; import io.quarkus.redis.datasource.string.ReactiveStringCommands; import io.quarkus.redis.datasource.string.SetArgs; +import io.quarkus.redis.datasource.value.ReactiveValueCommands; import io.smallrye.mutiny.Uni; import io.vertx.mutiny.redis.client.Response; -public class ReactiveStringCommandsImpl extends AbstractStringCommands implements ReactiveStringCommands { +public class ReactiveStringCommandsImpl extends AbstractStringCommands + implements ReactiveStringCommands, ReactiveValueCommands { private final ReactiveRedisDataSource reactive; @@ -35,6 +37,12 @@ public Uni set(K key, V value, SetArgs setArgs) { .replaceWithVoid(); } + @Override + public Uni set(K key, V value, io.quarkus.redis.datasource.value.SetArgs setArgs) { + return super._set(key, value, setArgs) + .replaceWithVoid(); + } + @Override public Uni setGet(K key, V value) { return super._setGet(key, value) @@ -47,6 +55,12 @@ public Uni setGet(K key, V value, SetArgs setArgs) { .map(this::decodeV); } + @Override + public Uni setGet(K key, V value, io.quarkus.redis.datasource.value.SetArgs setArgs) { + return super._setGet(key, value, setArgs) + .map(this::decodeV); + } + @Override public Uni setex(K key, long seconds, V value) { return super._setex(key, seconds, value) @@ -107,6 +121,12 @@ public Uni getex(K key, GetExArgs args) { .map(this::decodeV); } + @Override + public Uni getex(K key, io.quarkus.redis.datasource.value.GetExArgs args) { + return super._getex(key, args) + .map(this::decodeV); + } + @Override public Uni getrange(K key, long start, long end) { return super._getrange(key, start, end) diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveTransactionalRedisDataSourceImpl.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveTransactionalRedisDataSourceImpl.java index 229a4a5c0cc16..4b50d6ff726b2 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveTransactionalRedisDataSourceImpl.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveTransactionalRedisDataSourceImpl.java @@ -15,6 +15,7 @@ import io.quarkus.redis.datasource.sortedset.ReactiveTransactionalSortedSetCommands; import io.quarkus.redis.datasource.string.ReactiveTransactionalStringCommands; import io.quarkus.redis.datasource.transactions.ReactiveTransactionalRedisDataSource; +import io.quarkus.redis.datasource.value.ReactiveTransactionalValueCommands; import io.smallrye.mutiny.Uni; import io.vertx.mutiny.redis.client.Command; @@ -60,10 +61,16 @@ public ReactiveTransactionalSortedSetCommands sortedSet(Class re (ReactiveSortedSetCommandsImpl) this.reactive.sortedSet(redisKeyType, valueType), tx); } + @Override + public ReactiveTransactionalValueCommands value(Class redisKeyType, Class valueType) { + return new ReactiveTransactionalStringCommandsImpl<>(this, + (ReactiveStringCommandsImpl) this.reactive.value(redisKeyType, valueType), tx); + } + @Override public ReactiveTransactionalStringCommands string(Class redisKeyType, Class valueType) { return new ReactiveTransactionalStringCommandsImpl<>(this, - (ReactiveStringCommandsImpl) this.reactive.string(redisKeyType, valueType), tx); + (ReactiveStringCommandsImpl) this.reactive.value(redisKeyType, valueType), tx); } @Override diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveTransactionalStringCommandsImpl.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveTransactionalStringCommandsImpl.java index 044b972d139fe..7f5f3221d620e 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveTransactionalStringCommandsImpl.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveTransactionalStringCommandsImpl.java @@ -6,11 +6,12 @@ import io.quarkus.redis.datasource.string.ReactiveTransactionalStringCommands; import io.quarkus.redis.datasource.string.SetArgs; import io.quarkus.redis.datasource.transactions.ReactiveTransactionalRedisDataSource; +import io.quarkus.redis.datasource.value.ReactiveTransactionalValueCommands; import io.smallrye.mutiny.Uni; import io.vertx.mutiny.redis.client.Response; public class ReactiveTransactionalStringCommandsImpl extends AbstractTransactionalCommands - implements ReactiveTransactionalStringCommands { + implements ReactiveTransactionalStringCommands, ReactiveTransactionalValueCommands { private final ReactiveStringCommandsImpl reactive; @@ -56,6 +57,12 @@ public Uni getex(K key, GetExArgs args) { return this.reactive._getex(key, args).invoke(this::queuedOrDiscard).replaceWithVoid(); } + @Override + public Uni getex(K key, io.quarkus.redis.datasource.value.GetExArgs args) { + this.tx.enqueue(this.reactive::decodeV); + return this.reactive._getex(key, args).invoke(this::queuedOrDiscard).replaceWithVoid(); + } + @Override public Uni getrange(K key, long start, long end) { this.tx.enqueue(Response::toString); @@ -134,6 +141,12 @@ public Uni set(K key, V value, SetArgs setArgs) { return this.reactive._set(key, value, setArgs).invoke(this::queuedOrDiscard).replaceWithVoid(); } + @Override + public Uni set(K key, V value, io.quarkus.redis.datasource.value.SetArgs setArgs) { + this.tx.enqueue(resp -> null); + return this.reactive._set(key, value, setArgs).invoke(this::queuedOrDiscard).replaceWithVoid(); + } + @Override public Uni setGet(K key, V value) { this.tx.enqueue(this.reactive::decodeV); @@ -146,6 +159,12 @@ public Uni setGet(K key, V value, SetArgs setArgs) { return this.reactive._setGet(key, value, setArgs).invoke(this::queuedOrDiscard).replaceWithVoid(); } + @Override + public Uni setGet(K key, V value, io.quarkus.redis.datasource.value.SetArgs setArgs) { + this.tx.enqueue(this.reactive::decodeV); + return this.reactive._setGet(key, value, setArgs).invoke(this::queuedOrDiscard).replaceWithVoid(); + } + @Override public Uni setex(K key, long seconds, V value) { this.tx.enqueue(resp -> null); diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/ConnectionRecyclingTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/ConnectionRecyclingTest.java index 8d3d98581e91c..4d19310339e36 100644 --- a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/ConnectionRecyclingTest.java +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/ConnectionRecyclingTest.java @@ -25,20 +25,20 @@ public void tearDown() { void verifyThatConnectionsAreClosed() { String k = "increment"; for (int i = 0; i < 1000; i++) { - ds.withConnection(x -> x.string(String.class, Integer.class).incr(k)); + ds.withConnection(x -> x.value(String.class, Integer.class).incr(k)); } - assertThat(ds.string(String.class, Integer.class).get(k)).isEqualTo(1000); + assertThat(ds.value(String.class, Integer.class).get(k)).isEqualTo(1000); } @Test void verifyThatConnectionsAreClosedWithTheReactiveDataSource() { String k = "increment"; for (int i = 0; i < 1000; i++) { - rds.withConnection(x -> x.string(String.class, Integer.class).incr(k) + rds.withConnection(x -> x.value(String.class, Integer.class).incr(k) .replaceWithVoid()).await().indefinitely(); } - assertThat(rds.string(String.class, Integer.class).get(k).await().indefinitely()).isEqualTo(1000); + assertThat(rds.value(String.class, Integer.class).get(k).await().indefinitely()).isEqualTo(1000); } } diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/KeyCommandsTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/KeyCommandsTest.java index 92636f4a6457e..90949c1cfc581 100644 --- a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/KeyCommandsTest.java +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/KeyCommandsTest.java @@ -26,7 +26,7 @@ import io.quarkus.redis.datasource.keys.RedisValueType; import io.quarkus.redis.datasource.list.ListCommands; import io.quarkus.redis.datasource.sortedset.SortedSetCommands; -import io.quarkus.redis.datasource.string.StringCommands; +import io.quarkus.redis.datasource.value.ValueCommands; import io.quarkus.redis.runtime.datasource.BlockingRedisDataSourceImpl; public class KeyCommandsTest extends DatasourceTestBase { @@ -35,13 +35,13 @@ public class KeyCommandsTest extends DatasourceTestBase { static String key = "key-generic"; private KeyCommands keys; - private StringCommands strings; + private ValueCommands values; @BeforeEach void initialize() { ds = new BlockingRedisDataSourceImpl(vertx, redis, api, Duration.ofSeconds(1)); - strings = ds.string(Person.class); + values = ds.value(Person.class); keys = ds.key(); } @@ -57,75 +57,75 @@ void getDataSource() { @Test void del() { - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat((long) keys.del(key)).isEqualTo(1); - strings.set(key + "1", Person.person7); - strings.set(key + "2", Person.person7); + values.set(key + "1", Person.person7); + values.set(key + "2", Person.person7); assertThat(keys.del(key + "1", key + "2")).isEqualTo(2); } @Test void unlink() { - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat((long) keys.unlink(key)).isEqualTo(1); - strings.set(key + "1", Person.person7); - strings.set(key + "2", Person.person7); + values.set(key + "1", Person.person7); + values.set(key + "2", Person.person7); assertThat(keys.unlink(key + "1", key + "2")).isEqualTo(2); } @Test void copy() { - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.copy(key, key + "2")).isTrue(); assertThat(keys.copy("unknown", key + "2")).isFalse(); - assertThat(strings.get(key + "2")).isEqualTo(Person.person7); + assertThat(values.get(key + "2")).isEqualTo(Person.person7); } @Test void copyWithReplace() { - strings.set(key, Person.person7); - strings.set(key + 2, Person.person1); + values.set(key, Person.person7); + values.set(key + 2, Person.person1); assertThat(keys.copy(key, key + "2", new CopyArgs().replace(true))).isTrue(); - assertThat(strings.get(key + "2")).isEqualTo(Person.person7); + assertThat(values.get(key + "2")).isEqualTo(Person.person7); } @Test void copyWithDestinationDb() { ds.withConnection(connection -> { - connection.string(String.class, Person.class).set(key, Person.person7); + connection.value(String.class, Person.class).set(key, Person.person7); connection.key(String.class).copy(key, key, new CopyArgs().destinationDb(2)); connection.select(2); - assertThat(connection.string(String.class, Person.class).get(key)).isEqualTo(Person.person7); + assertThat(connection.value(String.class, Person.class).get(key)).isEqualTo(Person.person7); }); } @Test void dump() { assertThat(keys.dump("invalid")).isNull(); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.dump(key).length() > 0).isTrue(); } @Test void exists() { assertThat(keys.exists(key)).isFalse(); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.exists(key)).isTrue(); } @Test void existsVariadic() { assertThat(keys.exists(key, "key2", "key3")).isEqualTo(0); - strings.set(key, Person.person7); - strings.set("key2", Person.person7); + values.set(key, Person.person7); + values.set("key2", Person.person7); assertThat(keys.exists(key, "key2", "key3")).isEqualTo(2); } @Test void expire() { assertThat(keys.expire(key, 10)).isFalse(); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.expire(key, 10)).isTrue(); assertThat(keys.ttl(key)).isBetween(5L, 10L); @@ -137,7 +137,7 @@ void expire() { @RequiresRedis7OrHigher void expireWithArgs() { assertThat(keys.expire(key, 10, new ExpireArgs().xx())).isFalse(); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.expire(key, 10, new ExpireArgs().nx())).isTrue(); assertThat(keys.ttl(key)).isBetween(5L, 10L); @@ -149,7 +149,7 @@ void expireWithArgs() { void expireat() { Date expiration = new Date(System.currentTimeMillis() + 10000); assertThat(keys.expireat(key, expiration.toInstant().toEpochMilli())).isFalse(); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.expireat(key, expiration.toInstant())).isTrue(); assertThat(keys.ttl(key)).isGreaterThanOrEqualTo(8); @@ -163,7 +163,7 @@ void expireat() { void expireatWithArgs() { Date expiration = new Date(System.currentTimeMillis() + 10000); assertThat(keys.expireat(key, expiration.toInstant().getEpochSecond(), new ExpireArgs().xx())).isFalse(); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.expireat(key, expiration.toInstant(), new ExpireArgs().nx())).isTrue(); assertThat(keys.ttl(key)).isGreaterThanOrEqualTo(8); @@ -182,7 +182,7 @@ void keys() { map.put("one", Person.person1); map.put("two", Person.person2); map.put("three", Person.person3); - strings.mset(map); + values.mset(map); List k = keys.keys("???"); assertThat(k).hasSize(2); assertThat(k.contains("one")).isTrue(); @@ -192,7 +192,7 @@ void keys() { @Test public void move() { ds.withConnection(connection -> { - StringCommands commands = connection.string(String.class, Person.class); + ValueCommands commands = connection.value(String.class, Person.class); commands.set("foo", Person.person3); commands.set(key, Person.person7); assertThat(connection.key(String.class).move(key, 1)).isTrue(); @@ -206,7 +206,7 @@ public void move() { @Test void persist() { assertThat(keys.persist(key)).isFalse(); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.persist(key)).isFalse(); keys.expire(key, 10); assertThat(keys.persist(key)).isTrue(); @@ -215,7 +215,7 @@ void persist() { @Test void pexpire() { assertThat(keys.pexpire(key, 5000)).isFalse(); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.pexpire(key, 5000)).isTrue(); assertThat(keys.pttl(key)).isGreaterThan(0).isLessThanOrEqualTo(5000); @@ -227,7 +227,7 @@ void pexpire() { @RequiresRedis7OrHigher void pexpireWithArgs() { assertThat(keys.pexpire(key, 5000, new ExpireArgs().xx())).isFalse(); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.pexpire(key, 5000, new ExpireArgs().nx())).isTrue(); assertThat(keys.pttl(key)).isGreaterThan(0).isLessThanOrEqualTo(5000); @@ -241,7 +241,7 @@ void pexpireWithArgs() { @RequiresRedis7OrHigher void pexpireWithDuration() { assertThat(keys.pexpire(key, Duration.ofSeconds(5))).isFalse(); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.pexpire(key, Duration.ofSeconds(1))).isTrue(); assertThat(keys.pttl(key)).isGreaterThan(0).isLessThanOrEqualTo(1000); @@ -253,7 +253,7 @@ void pexpireWithDuration() { void pexpireat() { Instant expiration = new Date(System.currentTimeMillis() + 5000).toInstant(); assertThat(keys.pexpireat(key, expiration.getEpochSecond())).isFalse(); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.pexpireat(key, expiration)).isTrue(); assertThat(keys.pttl(key)).isGreaterThan(0); @@ -266,7 +266,7 @@ void pexpireat() { void pexpireatWithArgs() { Instant expiration = new Date(System.currentTimeMillis() + 5000).toInstant(); assertThat(keys.pexpireat(key, expiration.getEpochSecond(), new ExpireArgs().xx())).isFalse(); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.pexpireat(key, expiration, new ExpireArgs().nx())).isTrue(); assertThat(keys.pttl(key)).isGreaterThan(0); @@ -277,7 +277,7 @@ void pexpireatWithArgs() { @Test void pttl() { assertThatThrownBy(() -> keys.pttl(key)).isInstanceOf(RedisKeyNotFoundException.class); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.pttl(key)).isEqualTo(-1); keys.pexpire(key, 5000); assertThat(keys.pttl(key)).isGreaterThan(0).isLessThanOrEqualTo(5000); @@ -286,20 +286,20 @@ void pttl() { @Test void randomkey() { assertThat(keys.randomkey()).isNull(); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.randomkey()).isEqualTo(key); } @Test void rename() { - strings.set(key, Person.person7); + values.set(key, Person.person7); keys.rename(key, key + "X"); - assertThat(strings.get(key)).isNull(); - assertThat(strings.get(key + "X")).isEqualTo(Person.person7); - strings.set(key, Person.person4); + assertThat(values.get(key)).isNull(); + assertThat(values.get(key + "X")).isEqualTo(Person.person7); + values.set(key, Person.person4); keys.rename(key + "X", key); - assertThat(strings.get(key)).isEqualTo(Person.person7); + assertThat(values.get(key)).isEqualTo(Person.person7); } @Test @@ -309,10 +309,10 @@ void renameNonexistentKey() { @Test void renamenx() { - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.renamenx(key, key + "X")).isTrue(); - assertThat(strings.get(key + "X")).isEqualTo(Person.person7); - strings.set(key, Person.person7); + assertThat(values.get(key + "X")).isEqualTo(Person.person7); + values.set(key, Person.person7); assertThat(keys.renamenx(key + "X", key)).isFalse(); } @@ -324,14 +324,14 @@ void renamenxNonexistentKey() { @Test void touch() { assertThat((long) keys.touch(key)).isEqualTo(0); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat((long) keys.touch(key, "key2")).isEqualTo(1); } @Test void ttl() { assertThatThrownBy(() -> keys.pttl(key)).isInstanceOf(RedisKeyNotFoundException.class); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.ttl(key)).isEqualTo(-1); keys.expire(key, 10); assertThat(keys.ttl(key)).isEqualTo(10); @@ -341,7 +341,7 @@ void ttl() { void type() { assertThat(keys.type(key)).isEqualTo(RedisValueType.NONE); - strings.set(key, Person.person7); + values.set(key, Person.person7); assertThat(keys.type(key)).isEqualTo(RedisValueType.STRING); ds.hash(String.class, String.class, Person.class).hset(key + "H", "p3", Person.person3); @@ -361,7 +361,7 @@ void type() { @Test void scan() { - strings.set(key, Person.person7); + values.set(key, Person.person7); KeyScanCursor cursor = keys.scan(); assertThat(cursor.cursorId()).isEqualTo(Cursor.INITIAL_CURSOR_ID); assertThat(cursor.next()).containsExactly(key); @@ -389,7 +389,7 @@ void scanIterableEmpty() { @Test void scanWithArgs() { - strings.set(key, Person.person7); + values.set(key, Person.person7); KeyScanCursor cursor = keys.scan(new KeyScanArgs().count(10)); assertThat(cursor.cursorId()).isEqualTo(Cursor.INITIAL_CURSOR_ID); assertThat(cursor.next()).containsExactly(key); @@ -399,7 +399,7 @@ void scanWithArgs() { @Test void scanWithType() { - strings.set("key1", Person.person7); + values.set("key1", Person.person7); ds.list(Person.class).lpush("key2", Person.person7); KeyScanCursor cursor = keys.scan(new KeyScanArgs().type(RedisValueType.STRING)); @@ -459,7 +459,7 @@ void scanMatch() { void populateMany(Set expect) { for (int i = 0; i < 100; i++) { - strings.set(key + i, new Person("a", "b" + i)); + values.set(key + i, new Person("a", "b" + i)); expect.add(key + i); } } diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/NumericCommandsTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/NumericCommandsTest.java index 8c619f5fd6b0a..64534ee7aab18 100644 --- a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/NumericCommandsTest.java +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/NumericCommandsTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import io.quarkus.redis.datasource.string.StringCommands; +import io.quarkus.redis.datasource.value.ValueCommands; import io.quarkus.redis.runtime.datasource.BlockingRedisDataSourceImpl; public class NumericCommandsTest extends DatasourceTestBase { @@ -17,12 +17,12 @@ public class NumericCommandsTest extends DatasourceTestBase { private RedisDataSource ds; static String key = "key-sort"; - private StringCommands num; + private ValueCommands num; @BeforeEach void initialize() { ds = new BlockingRedisDataSourceImpl(vertx, redis, api, Duration.ofSeconds(5)); - num = ds.string(Long.class); + num = ds.value(Long.class); } @AfterEach diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/PubSubTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/PubSubTest.java index 9fe2333ac1db7..5dd8accc16dc2 100644 --- a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/PubSubTest.java +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/PubSubTest.java @@ -48,7 +48,7 @@ void testWithSingleChannel() throws InterruptedException { ps.publish("people", person1).await().indefinitely(); ps.publish("people", person2).await().indefinitely(); - ds.string(String.class, String.class) + ds.value(String.class, String.class) .set("hello", "foo").await().indefinitely(); ps.publish("people", person2).await().indefinitely(); @@ -68,7 +68,7 @@ void testWithSinglePattern() throws InterruptedException { ps.publish("people", person1).await().indefinitely(); ps.publish("people", person2).await().indefinitely(); - ds.string(String.class, String.class) + ds.value(String.class, String.class) .set("hello", "foo").await().indefinitely(); ps.publish("people", person2).await().indefinitely(); @@ -87,7 +87,7 @@ void testWithMultipleChannels() throws InterruptedException { ps.publish("people1", person1).await().indefinitely(); ps.publish("people2", person2).await().indefinitely(); - ds.string(String.class, String.class) + ds.value(String.class, String.class) .set("hello", "foo").await().indefinitely(); ps.publish("people1", person2).await().indefinitely(); @@ -109,7 +109,7 @@ void testWithMultipleChannelsAndASinglePattern() throws InterruptedException { ps.publish("people1", person1).await().indefinitely(); ps.publish("people2", person2).await().indefinitely(); - ds.string(String.class, String.class) + ds.value(String.class, String.class) .set("hello", "foo").await().indefinitely(); ps.publish("people1", person2).await().indefinitely(); @@ -132,7 +132,7 @@ void testWithMulti() throws InterruptedException { ps.publish("people", new Person("p" + i, "")).await().indefinitely(); } - ds.string(String.class, String.class) + ds.value(String.class, String.class) .set("hello", "foo").await().indefinitely(); assertThat(latch.await(5, TimeUnit.SECONDS)).isTrue(); diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SortCommandsTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SortCommandsTest.java index 439e9dc9dc1a9..5a6170e97a273 100644 --- a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SortCommandsTest.java +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SortCommandsTest.java @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test; import io.quarkus.redis.datasource.list.ListCommands; -import io.quarkus.redis.datasource.string.StringCommands; +import io.quarkus.redis.datasource.value.ValueCommands; import io.quarkus.redis.runtime.datasource.BlockingRedisDataSourceImpl; public class SortCommandsTest extends DatasourceTestBase { @@ -19,14 +19,14 @@ public class SortCommandsTest extends DatasourceTestBase { static String key = "key-sort"; private ListCommands lists; - private StringCommands strings; + private ValueCommands strings; @BeforeEach void initialize() { ds = new BlockingRedisDataSourceImpl(vertx, redis, api, Duration.ofSeconds(5)); lists = ds.list(String.class); - strings = ds.string(String.class); + strings = ds.value(String.class); } @AfterEach diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/StringCommandsTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/StringCommandsTest.java index 00b3f7746d3d7..bb73b2b134bce 100644 --- a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/StringCommandsTest.java +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/StringCommandsTest.java @@ -21,6 +21,7 @@ import io.quarkus.redis.datasource.string.StringCommands; import io.quarkus.redis.runtime.datasource.BlockingRedisDataSourceImpl; +@SuppressWarnings("deprecation") public class StringCommandsTest extends DatasourceTestBase { private RedisDataSource ds; diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/TransactionalStringCommandsTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/TransactionalStringCommandsTest.java index f0abbbd6b16d3..c9d8f6864fde6 100644 --- a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/TransactionalStringCommandsTest.java +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/TransactionalStringCommandsTest.java @@ -15,6 +15,7 @@ import io.quarkus.redis.runtime.datasource.BlockingRedisDataSourceImpl; import io.quarkus.redis.runtime.datasource.ReactiveRedisDataSourceImpl; +@SuppressWarnings("deprecation") public class TransactionalStringCommandsTest extends DatasourceTestBase { private RedisDataSource blocking; diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/TransactionalValueCommandsTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/TransactionalValueCommandsTest.java new file mode 100644 index 0000000000000..7745073b19ba4 --- /dev/null +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/TransactionalValueCommandsTest.java @@ -0,0 +1,73 @@ + +package io.quarkus.redis.datasource; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.Duration; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import io.quarkus.redis.datasource.transactions.TransactionResult; +import io.quarkus.redis.datasource.value.ReactiveTransactionalValueCommands; +import io.quarkus.redis.datasource.value.TransactionalValueCommands; +import io.quarkus.redis.runtime.datasource.BlockingRedisDataSourceImpl; +import io.quarkus.redis.runtime.datasource.ReactiveRedisDataSourceImpl; + +public class TransactionalValueCommandsTest extends DatasourceTestBase { + + private RedisDataSource blocking; + private ReactiveRedisDataSource reactive; + + @BeforeEach + void initialize() { + blocking = new BlockingRedisDataSourceImpl(vertx, redis, api, Duration.ofSeconds(60)); + reactive = new ReactiveRedisDataSourceImpl(vertx, redis, api); + } + + @AfterEach + public void clear() { + blocking.flushall(); + } + + @Test + public void setBlocking() { + TransactionResult result = blocking.withTransaction(tx -> { + TransactionalValueCommands string = tx.value(String.class); + assertThat(string.getDataSource()).isEqualTo(tx); + string.set(key, "hello"); + string.setnx("k2", "bonjour"); + string.append(key, "-1"); + string.get(key); + string.strlen("k2"); + }); + assertThat(result.size()).isEqualTo(5); + assertThat(result.discarded()).isFalse(); + assertThat(result. get(0)).isNull(); + assertThat((boolean) result.get(1)).isTrue(); + assertThat((long) result.get(2)).isEqualTo(7L); + assertThat((String) result.get(3)).isEqualTo("hello-1"); + assertThat((long) result.get(4)).isEqualTo(7L); + } + + @Test + public void setReactive() { + TransactionResult result = reactive.withTransaction(tx -> { + ReactiveTransactionalValueCommands string = tx.value(String.class); + return string.set(key, "hello") + .chain(() -> string.setnx("k2", "bonjour")) + .chain(() -> string.append(key, "-1")) + .chain(() -> string.get(key)) + .chain(() -> string.strlen("k2")); + }).await().atMost(Duration.ofSeconds(5)); + assertThat(result.size()).isEqualTo(5); + assertThat(result.discarded()).isFalse(); + assertThat(result. get(0)).isNull(); + assertThat((boolean) result.get(1)).isTrue(); + assertThat((long) result.get(2)).isEqualTo(7L); + assertThat((String) result.get(3)).isEqualTo("hello-1"); + assertThat((long) result.get(4)).isEqualTo(7L); + } + +} diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/ValueCommandsTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/ValueCommandsTest.java new file mode 100644 index 0000000000000..0bd8815e307a2 --- /dev/null +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/ValueCommandsTest.java @@ -0,0 +1,278 @@ +package io.quarkus.redis.datasource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.entry; + +import java.time.Duration; +import java.time.Instant; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Random; +import java.util.UUID; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import io.quarkus.redis.datasource.keys.KeyCommands; +import io.quarkus.redis.datasource.value.GetExArgs; +import io.quarkus.redis.datasource.value.SetArgs; +import io.quarkus.redis.datasource.value.ValueCommands; +import io.quarkus.redis.runtime.datasource.BlockingRedisDataSourceImpl; + +public class ValueCommandsTest extends DatasourceTestBase { + + private RedisDataSource ds; + + String value = UUID.randomUUID().toString(); + private ValueCommands values; + + @BeforeEach + void initialize() { + ds = new BlockingRedisDataSourceImpl(vertx, redis, api, Duration.ofSeconds(1)); + + values = ds.value(String.class); + } + + @AfterEach + void clear() { + ds.flushall(); + } + + @Test + void getDataSource() { + assertThat(ds).isEqualTo(values.getDataSource()); + } + + @Test + void append() { + assertThat(values.append(key, value)).isEqualTo(value.length()); + assertThat(values.append(key, "X")).isEqualTo(value.length() + 1); + } + + @Test + void get() { + assertThat(values.get(key)).isNull(); + values.set(key, value); + assertThat(values.get(key)).isEqualTo(value); + } + + @Test + void getbit() { + assertThat(ds.bitmap(String.class).getbit(key, 0)).isEqualTo(0); + ds.bitmap(String.class).setbit(key, 0, 1); + assertThat(ds.bitmap(String.class).getbit(key, 0)).isEqualTo(1); + } + + @Test + void getdel() { + values.set(key, value); + assertThat(values.getdel(key)).isEqualTo(value); + assertThat(values.get(key)).isNull(); + } + + @Test + void getex() { + values.set(key, value); + assertThat(values.getex(key, new GetExArgs().ex(Duration.ofSeconds(100)))).isEqualTo(value); + assertThat(ds.key(String.class).ttl(key)).isGreaterThan(1); + assertThat(values.getex(key, new GetExArgs().persist())).isEqualTo(value); + assertThat(ds.key(String.class).ttl(key)).isEqualTo(-1); + } + + @Test + void getrange() { + assertThat(values.getrange(key, 0, -1)).isEqualTo(""); + values.set(key, "foobar"); + assertThat(values.getrange(key, 2, 4)).isEqualTo("oba"); + assertThat(values.getrange(key, 3, -1)).isEqualTo("bar"); + } + + @SuppressWarnings("deprecation") + @Test + void getset() { + assertThat(values.getset(key, value)).isNull(); + assertThat(values.getset(key, "two")).isEqualTo(value); + assertThat(values.get(key)).isEqualTo("two"); + } + + @Test + void mget() { + assertThat(values.mget(key)).isEmpty(); + values.set("one", "1"); + values.set("two", "2"); + assertThat(values.mget("one", "two")).containsExactly(entry("one", "1"), entry("two", "2")); + } + + @Test + void mset() { + assertThat(values.mget("one", "two")).isEmpty(); + Map map = new LinkedHashMap<>(); + map.put("one", "1"); + map.put("two", "2"); + values.mset(map); + assertThat(values.mget("one", "two")).containsExactly(entry("one", "1"), entry("two", "2")); + } + + @Test + void msetnx() { + values.set("one", "1"); + Map map = new LinkedHashMap<>(); + map.put("one", "1"); + map.put("two", "2"); + assertThat(values.msetnx(map)).isFalse(); + ds.key(String.class).del("one"); + assertThat(values.msetnx(map)).isTrue(); + assertThat(values.get("two")).isEqualTo("2"); + } + + @Test + void set() { + KeyCommands keys = ds.key(String.class); + assertThat(values.get(key)).isNull(); + values.set(key, value); + assertThat(values.get(key)).isEqualTo(value); + + values.set(key, value, new SetArgs().px(20000)); + values.set(key, value, new SetArgs().ex(10)); + assertThat(values.get(key)).isEqualTo(value); + assertThat(keys.ttl(key)).isGreaterThanOrEqualTo(9); + + values.set(key, value, new SetArgs().ex(Duration.ofSeconds(10))); + assertThat(keys.ttl(key)).isBetween(5L, 10L); + + values.set(key, value, new SetArgs().px(Duration.ofSeconds(10))); + assertThat(keys.ttl(key)).isBetween(5L, 10L); + + values.set(key, value, new SetArgs().px(10000)); + assertThat(values.get(key)).isEqualTo(value); + assertThat(keys.ttl(key)).isGreaterThanOrEqualTo(9); + + values.set(key, value, new SetArgs().nx()); + values.set(key, value, new SetArgs().xx()); + assertThat(values.get(key)).isEqualTo(value); + + keys.del(key); + values.set(key, value, new SetArgs().nx()); + assertThat(values.get(key)).isEqualTo(value); + + keys.del(key); + + values.set(key, value, new SetArgs().px(20000).nx()); + assertThat(values.get(key)).isEqualTo(value); + assertThat(keys.ttl(key) >= 19).isTrue(); + } + + @Test + void setExAt() { + KeyCommands keys = ds.key(String.class); + + values.set(key, value, new SetArgs().exAt(Instant.now().plusSeconds(60))); + assertThat(keys.ttl(key)).isBetween(50L, 61L); + + values.set(key, value, new SetArgs().pxAt(Instant.now().plusSeconds(60))); + assertThat(keys.ttl(key)).isBetween(50L, 61L); + } + + @Test + void setKeepTTL() { + KeyCommands keys = ds.key(String.class); + + values.set(key, value, new SetArgs().ex(10)); + values.set(key, "value2", new SetArgs().keepttl()); + assertThat(values.get(key)).isEqualTo("value2"); + assertThat(keys.ttl(key) >= 1).isTrue(); + } + + @Test + void setNegativeEX() { + assertThatThrownBy(() -> values.set(key, value, new SetArgs().ex(-10))).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void setNegativePX() { + assertThatThrownBy(() -> values.set(key, value, new SetArgs().px(-1000))).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void setGet() { + assertThat(values.setGet(key, value)).isNull(); + assertThat(values.setGet(key, "value2")).isEqualTo(value); + assertThat(values.get(key)).isEqualTo("value2"); + } + + @Test + void setGetWithArgs() { + KeyCommands keys = ds.key(String.class); + + assertThat(values.setGet(key, value)).isNull(); + assertThat(values.setGet(key, "value2", new SetArgs().ex(100))).isEqualTo(value); + assertThat(values.get(key)).isEqualTo("value2"); + assertThat(keys.ttl(key)).isGreaterThanOrEqualTo(10); + } + + @Test + void setbit() { + assertThat(ds.bitmap(String.class).setbit(key, 0, 1)).isEqualTo(0); + assertThat(ds.bitmap(String.class).setbit(key, 0, 0)).isEqualTo(1); + } + + @Test + void setex() { + KeyCommands keys = ds.key(String.class); + + values.setex(key, 10, value); + assertThat(values.get(key)).isEqualTo(value); + assertThat(keys.ttl(key) >= 9).isTrue(); + } + + @Test + void psetex() { + KeyCommands keys = ds.key(String.class); + + values.psetex(key, 20000, value); + assertThat(values.get(key)).isEqualTo(value); + assertThat(keys.pttl(key) >= 19000).isTrue(); + } + + @Test + void setnx() { + assertThat(values.setnx(key, value)).isTrue(); + assertThat(values.setnx(key, value)).isFalse(); + } + + @Test + void setrange() { + assertThat(values.setrange(key, 0, "foo")).isEqualTo("foo".length()); + assertThat(values.setrange(key, 3, "bar")).isEqualTo(6); + assertThat(values.get(key)).isEqualTo("foobar"); + } + + @Test + void strlen() { + assertThat(values.strlen(key)).isEqualTo(0); + values.set(key, value); + assertThat(values.strlen(key)).isEqualTo(value.length()); + } + + @Test + @RequiresRedis7OrHigher + void lcs() { + values.mset(Map.of("key1", "ohmytext", "key2", "mynewtext")); + assertThat(values.lcs("key1", "key2")).isEqualTo("mytext"); + + // LEN parameter + assertThat(values.lcsLength("key1", "key2")).isEqualTo(6); + } + + @Test + void binary() { + byte[] content = new byte[2048]; + new Random().nextBytes(content); + ValueCommands commands = ds.value(byte[].class); + commands.set(key, content); + byte[] bytes = commands.get(key); + assertThat(bytes).isEqualTo(content); + } +} diff --git a/integration-tests/container-image/maven-invoker-way/src/it/container-image-jib-with-redis/src/main/java/org/acme/redis/IncrementService.java b/integration-tests/container-image/maven-invoker-way/src/it/container-image-jib-with-redis/src/main/java/org/acme/redis/IncrementService.java index a499078ca4afa..ddc2124a95162 100644 --- a/integration-tests/container-image/maven-invoker-way/src/it/container-image-jib-with-redis/src/main/java/org/acme/redis/IncrementService.java +++ b/integration-tests/container-image/maven-invoker-way/src/it/container-image-jib-with-redis/src/main/java/org/acme/redis/IncrementService.java @@ -2,7 +2,7 @@ import io.quarkus.redis.datasource.RedisDataSource; import io.quarkus.redis.datasource.keys.KeyCommands; -import io.quarkus.redis.datasource.string.StringCommands; +import io.quarkus.redis.datasource.value.ValueCommands; import javax.inject.Singleton; import java.util.List; @@ -12,12 +12,12 @@ class IncrementService { private final KeyCommands keyCommands; - private final StringCommands stringCommands; + private final ValueCommands valueCommands; public IncrementService(RedisDataSource ds) { keyCommands = ds.key(); - stringCommands = ds.string(Integer.class); + valueCommands = ds.value(Integer.class); } @@ -26,16 +26,15 @@ void del(String key) { } Integer get(String key) { - return stringCommands.get(key); + return valueCommands.get(key); } void set(String key, Integer value) { - stringCommands.set(key, value); - ; + valueCommands.set(key, value); } void increment(String key, Integer incrementBy) { - stringCommands.incrby(key, incrementBy); + valueCommands.incrby(key, incrementBy); } List keys() { diff --git a/integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisResource.java b/integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisResource.java index 3ab9ac711fdde..e088c44fce7f6 100644 --- a/integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisResource.java +++ b/integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisResource.java @@ -8,21 +8,21 @@ import io.quarkus.redis.datasource.ReactiveRedisDataSource; import io.quarkus.redis.datasource.RedisDataSource; -import io.quarkus.redis.datasource.string.ReactiveStringCommands; -import io.quarkus.redis.datasource.string.StringCommands; +import io.quarkus.redis.datasource.value.ReactiveValueCommands; +import io.quarkus.redis.datasource.value.ValueCommands; import io.smallrye.mutiny.Uni; @Path("/quarkus-redis") @ApplicationScoped public class RedisResource { - private final StringCommands blocking; - private final ReactiveStringCommands reactive; + private final ValueCommands blocking; + private final ReactiveValueCommands reactive; public RedisResource(RedisDataSource ds, ReactiveRedisDataSource reactiveDs) { - blocking = ds.string(String.class); - reactive = reactiveDs.string(String.class); + blocking = ds.value(String.class); + reactive = reactiveDs.value(String.class); } // synchronous diff --git a/integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisResourceWithNamedClient.java b/integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisResourceWithNamedClient.java index 6b92c6a1415a5..37a59e84aaa3c 100644 --- a/integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisResourceWithNamedClient.java +++ b/integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisResourceWithNamedClient.java @@ -9,22 +9,22 @@ import io.quarkus.redis.client.RedisClientName; import io.quarkus.redis.datasource.ReactiveRedisDataSource; import io.quarkus.redis.datasource.RedisDataSource; -import io.quarkus.redis.datasource.string.ReactiveStringCommands; -import io.quarkus.redis.datasource.string.StringCommands; +import io.quarkus.redis.datasource.value.ReactiveValueCommands; +import io.quarkus.redis.datasource.value.ValueCommands; import io.smallrye.mutiny.Uni; @Path("/quarkus-redis-with-name") @ApplicationScoped public class RedisResourceWithNamedClient { - private final StringCommands blocking; - private final ReactiveStringCommands reactive; + private final ValueCommands blocking; + private final ReactiveValueCommands reactive; public RedisResourceWithNamedClient( @RedisClientName("named-client") RedisDataSource ds, @RedisClientName("named-reactive-client") ReactiveRedisDataSource reactiveDs) { - blocking = ds.string(String.class); - reactive = reactiveDs.string(String.class); + blocking = ds.value(String.class); + reactive = reactiveDs.value(String.class); } // synchronous diff --git a/integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisWithProvidedHostsResource.java b/integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisWithProvidedHostsResource.java index 2544675e33baa..75e0c09b70187 100644 --- a/integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisWithProvidedHostsResource.java +++ b/integration-tests/redis-client/src/main/java/io/quarkus/redis/it/RedisWithProvidedHostsResource.java @@ -10,22 +10,22 @@ import io.quarkus.redis.client.RedisClientName; import io.quarkus.redis.datasource.ReactiveRedisDataSource; import io.quarkus.redis.datasource.RedisDataSource; -import io.quarkus.redis.datasource.string.ReactiveStringCommands; -import io.quarkus.redis.datasource.string.StringCommands; +import io.quarkus.redis.datasource.value.ReactiveValueCommands; +import io.quarkus.redis.datasource.value.ValueCommands; import io.smallrye.mutiny.Uni; @Path("/quarkus-redis-provided-hosts") @ApplicationScoped public class RedisWithProvidedHostsResource { - private final StringCommands blocking; - private final ReactiveStringCommands reactive; + private final ValueCommands blocking; + private final ReactiveValueCommands reactive; @Inject public RedisWithProvidedHostsResource(@RedisClientName("provided-hosts") RedisDataSource ds, @RedisClientName("provided-hosts") ReactiveRedisDataSource reactiveDs) { - blocking = ds.string(String.class); - reactive = reactiveDs.string(String.class); + blocking = ds.value(String.class); + reactive = reactiveDs.value(String.class); } @GET