From d412cafc09240e0362351e93a1f111af6e3d19bc 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 | 277 +++++++++++++++ .../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, 2390 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 eb9ffcf2344c19..0d5f969364a0fd 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 7e4f53d72c44d0..cedbf72431104b 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 e2b4fe74ffbc6a..5836d90e79140c 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 7281e4496305e9..9e287e844a07ee 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 245ffc77bcb0df..3205238f9454ed 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 9f077a676a4ec9..9d61ed060c9bf3 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 94d98b0e840df5..45df0bb42fd93a 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 822840bdfb298d..a5b8332d98810b 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 fb76d6723738ff..5402b3ebee389d 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 156ba825f1a120..2fd74d7e7d4271 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 7c1f87c2b814e6..3004aaccfd5953 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 585c7d7c616a31..10783371f62d7d 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 81776932055531..85a743b0e01c34 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 73bdb2afdf47da..fcbe689fb142fc 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 46f79ac15778f6..f4cf167cd81cf9 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 976f00539ff787..7d23e48f075a69 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 28436520b96a63..ac992c038ad786 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 309025d60f5137..62b7d9c3402a98 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 22efbb7d5ccce2..d5bc340eb0d93b 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 cf13af8a325dbd..817fb9015522be 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 00000000000000..5966a68c43d41a --- /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 00000000000000..ab7bc9768d25f4 --- /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 00000000000000..896d7793a3a07f --- /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 00000000000000..c03af517867a49 --- /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 00000000000000..5f049513019921 --- /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 00000000000000..2f6416d11e8458 --- /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 9e63100f54a426..de857f54c512de 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 ecb876cc3d06b3..4a18d9e8e7cff1 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 d5bcd0ae9554f6..44ea8cf91f6fa1 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 ee0df37733f487..69f5579c91eba1 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 14f5323a06149f..4fe60f9a537c3e 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 06c8d5d016bbc1..ed4e1aafe7fb9c 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 445c348ff821e5..ef0df74339db36 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 229a4a5c0cc16a..4b50d6ff726b2b 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 044b972d139fe2..7f5f3221d620ee 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 8d3d98581e91c6..4d19310339e36b 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 42604f3f359017..0259dbb3e4647a 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); @@ -136,7 +136,7 @@ void expire() { @Test 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); @@ -148,7 +148,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); @@ -161,7 +161,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); @@ -180,7 +180,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(); @@ -190,7 +190,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(); @@ -204,7 +204,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(); @@ -213,7 +213,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); @@ -224,7 +224,7 @@ void pexpire() { @Test 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); @@ -237,7 +237,7 @@ void pexpireWithArgs() { @Test 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); @@ -249,7 +249,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); @@ -261,7 +261,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); @@ -272,7 +272,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); @@ -281,20 +281,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 @@ -304,10 +304,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(); } @@ -319,14 +319,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); @@ -336,7 +336,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); @@ -356,7 +356,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); @@ -384,7 +384,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); @@ -394,7 +394,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)); @@ -454,7 +454,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 8c619f5fd6b0ad..64534ee7aab180 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 9fe2333ac1db79..5dd8accc16dc2e 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 439e9dc9dc1a95..5a6170e97a2735 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 d6fce83fbca04e..eae74e154ca9a3 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 f0abbbd6b16d3e..c9d8f6864fde61 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 00000000000000..7745073b19ba4d --- /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 00000000000000..720ed9a6bef9dc --- /dev/null +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/ValueCommandsTest.java @@ -0,0 +1,277 @@ +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 + 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 a499078ca4afaa..ddc2124a95162c 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 3ab9ac711fdde0..e088c44fce7f69 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 6b92c6a1415a58..37a59e84aaa3c0 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 2544675e33baa9..75e0c09b701871 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