From 10186a303254e146f00ec3c0ad238582dfc7cdd3 Mon Sep 17 00:00:00 2001 From: SanHalacogluImproving <144171266+SanHalacogluImproving@users.noreply.github.com> Date: Mon, 4 Mar 2024 15:42:47 -0800 Subject: [PATCH] Java: Add LLen command. (List Commands) (#1042) * Java: Add LLen command. (List Commands) * Added examples. * Star import fix. * Rebase Spotless. --- .../src/main/java/glide/api/BaseClient.java | 6 +++++ .../glide/api/commands/ListBaseCommands.java | 15 ++++++++++++ .../glide/api/models/BaseTransaction.java | 16 +++++++++++++ .../test/java/glide/api/RedisClientTest.java | 24 +++++++++++++++++++ .../glide/api/models/TransactionTests.java | 4 ++++ .../test/java/glide/SharedCommandTests.java | 19 +++++++++++++++ .../java/glide/TransactionTestUtilities.java | 2 ++ 7 files changed, 86 insertions(+) diff --git a/java/client/src/main/java/glide/api/BaseClient.java b/java/client/src/main/java/glide/api/BaseClient.java index b345902957..1b78309d34 100644 --- a/java/client/src/main/java/glide/api/BaseClient.java +++ b/java/client/src/main/java/glide/api/BaseClient.java @@ -22,6 +22,7 @@ import static redis_request.RedisRequestOuterClass.RequestType.Incr; import static redis_request.RedisRequestOuterClass.RequestType.IncrBy; import static redis_request.RedisRequestOuterClass.RequestType.IncrByFloat; +import static redis_request.RedisRequestOuterClass.RequestType.LLen; import static redis_request.RedisRequestOuterClass.RequestType.LPop; import static redis_request.RedisRequestOuterClass.RequestType.LPush; import static redis_request.RedisRequestOuterClass.RequestType.LRange; @@ -377,6 +378,11 @@ public CompletableFuture ltrim(@NonNull String key, long start, long end this::handleStringResponse); } + @Override + public CompletableFuture llen(@NonNull String key) { + return commandManager.submitNewCommand(LLen, new String[] {key}, this::handleLongResponse); + } + @Override public CompletableFuture rpush(@NonNull String key, @NonNull String[] elements) { String[] arguments = ArrayUtils.addFirst(elements, key); diff --git a/java/client/src/main/java/glide/api/commands/ListBaseCommands.java b/java/client/src/main/java/glide/api/commands/ListBaseCommands.java index 948f91b52a..053f0d6697 100644 --- a/java/client/src/main/java/glide/api/commands/ListBaseCommands.java +++ b/java/client/src/main/java/glide/api/commands/ListBaseCommands.java @@ -122,6 +122,21 @@ public interface ListBaseCommands { */ CompletableFuture ltrim(String key, long start, long end); + /** + * Returns the length of the list stored at key. + * + * @see redis.io for details. + * @param key The key of the list. + * @return The length of the list at key.
+ * If key does not exist, it is interpreted as an empty list and 0 is returned. + * @example + *
+     * Long lenList = client.llen("my_list").get()
+     * assert lenList == 3L //Indicates that there are 3 elements in the list.
+     * 
+ */ + CompletableFuture llen(String key); + /** * Inserts all the specified values at the tail of the list stored at key.
* elements are inserted one after the other to the tail of the list, from the diff --git a/java/client/src/main/java/glide/api/models/BaseTransaction.java b/java/client/src/main/java/glide/api/models/BaseTransaction.java index e1d2443a83..d5ca352558 100644 --- a/java/client/src/main/java/glide/api/models/BaseTransaction.java +++ b/java/client/src/main/java/glide/api/models/BaseTransaction.java @@ -22,6 +22,7 @@ import static redis_request.RedisRequestOuterClass.RequestType.IncrBy; import static redis_request.RedisRequestOuterClass.RequestType.IncrByFloat; import static redis_request.RedisRequestOuterClass.RequestType.Info; +import static redis_request.RedisRequestOuterClass.RequestType.LLen; import static redis_request.RedisRequestOuterClass.RequestType.LPop; import static redis_request.RedisRequestOuterClass.RequestType.LPush; import static redis_request.RedisRequestOuterClass.RequestType.LRange; @@ -580,6 +581,21 @@ public T ltrim(@NonNull String key, long start, long end) { return getThis(); } + /** + * Returns the length of the list stored at key. + * + * @see redis.io for details. + * @param key The key of the list. + * @return Command Response - The length of the list at key.
+ * If key does not exist, it is interpreted as an empty list and 0 is returned. + */ + public T llen(@NonNull String key) { + ArgsArray commandArgs = buildArgs(key); + + protobufTransaction.addCommands(buildCommand(LLen, commandArgs)); + return getThis(); + } + /** * Inserts all the specified values at the tail of the list stored at key.
* elements are inserted one after the other to the tail of the list, from the diff --git a/java/client/src/test/java/glide/api/RedisClientTest.java b/java/client/src/test/java/glide/api/RedisClientTest.java index 9a8fcd6aed..b8f89ac6d9 100644 --- a/java/client/src/test/java/glide/api/RedisClientTest.java +++ b/java/client/src/test/java/glide/api/RedisClientTest.java @@ -32,6 +32,7 @@ import static redis_request.RedisRequestOuterClass.RequestType.IncrBy; import static redis_request.RedisRequestOuterClass.RequestType.IncrByFloat; import static redis_request.RedisRequestOuterClass.RequestType.Info; +import static redis_request.RedisRequestOuterClass.RequestType.LLen; import static redis_request.RedisRequestOuterClass.RequestType.LPop; import static redis_request.RedisRequestOuterClass.RequestType.LPush; import static redis_request.RedisRequestOuterClass.RequestType.LRange; @@ -1093,6 +1094,29 @@ public void ltrim_returns_success() { assertEquals(OK, payload); } + @SneakyThrows + @Test + public void llen_returns_success() { + // setup + String key = "testKey"; + String[] args = new String[] {key}; + long value = 2L; + + CompletableFuture testResponse = mock(CompletableFuture.class); + when(testResponse.get()).thenReturn(value); + + // match on protobuf request + when(commandManager.submitNewCommand(eq(LLen), eq(args), any())).thenReturn(testResponse); + + // exercise + CompletableFuture response = service.llen(key); + Long payload = response.get(); + + // verify + assertEquals(testResponse, response); + assertEquals(value, payload); + } + @SneakyThrows @Test public void rpush_returns_success() { diff --git a/java/client/src/test/java/glide/api/models/TransactionTests.java b/java/client/src/test/java/glide/api/models/TransactionTests.java index 0a86c6dbee..89a507fbb7 100644 --- a/java/client/src/test/java/glide/api/models/TransactionTests.java +++ b/java/client/src/test/java/glide/api/models/TransactionTests.java @@ -22,6 +22,7 @@ import static redis_request.RedisRequestOuterClass.RequestType.IncrBy; import static redis_request.RedisRequestOuterClass.RequestType.IncrByFloat; import static redis_request.RedisRequestOuterClass.RequestType.Info; +import static redis_request.RedisRequestOuterClass.RequestType.LLen; import static redis_request.RedisRequestOuterClass.RequestType.LPop; import static redis_request.RedisRequestOuterClass.RequestType.LPush; import static redis_request.RedisRequestOuterClass.RequestType.LRange; @@ -175,6 +176,9 @@ public void transaction_builds_protobuf_request(BaseTransaction transaction) results.add( Pair.of(LTrim, ArgsArray.newBuilder().addArgs("key").addArgs("1").addArgs("2").build())); + transaction.llen("key"); + results.add(Pair.of(LLen, ArgsArray.newBuilder().addArgs("key").build())); + transaction.rpush("key", new String[] {"element"}); results.add(Pair.of(RPush, ArgsArray.newBuilder().addArgs("key").addArgs("element").build())); diff --git a/java/integTest/src/test/java/glide/SharedCommandTests.java b/java/integTest/src/test/java/glide/SharedCommandTests.java index 1776dc5332..26acf92eda 100644 --- a/java/integTest/src/test/java/glide/SharedCommandTests.java +++ b/java/integTest/src/test/java/glide/SharedCommandTests.java @@ -603,6 +603,25 @@ public void ltrim_existing_non_existing_key_and_type_error(BaseClient client) { assertTrue(ltrimException.getCause() instanceof RequestException); } + @SneakyThrows + @ParameterizedTest + @MethodSource("getClients") + public void llen_existing_non_existing_key_and_type_error(BaseClient client) { + String key1 = UUID.randomUUID().toString(); + String key2 = UUID.randomUUID().toString(); + String[] valueArray = new String[] {"value4", "value3", "value2", "value1"}; + + assertEquals(4, client.lpush(key1, valueArray).get()); + assertEquals(4, client.llen(key1).get()); + assertEquals(0, client.llen("non_existing_key").get()); + + assertEquals(OK, client.set(key2, "foo").get()); + + Exception lrangeException = + assertThrows(ExecutionException.class, () -> client.llen(key2).get()); + assertTrue(lrangeException.getCause() instanceof RequestException); + } + @SneakyThrows @ParameterizedTest @MethodSource("getClients") diff --git a/java/integTest/src/test/java/glide/TransactionTestUtilities.java b/java/integTest/src/test/java/glide/TransactionTestUtilities.java index 61db76a57c..3524d7e26d 100644 --- a/java/integTest/src/test/java/glide/TransactionTestUtilities.java +++ b/java/integTest/src/test/java/glide/TransactionTestUtilities.java @@ -64,6 +64,7 @@ public static BaseTransaction transactionTest(BaseTransaction baseTransact baseTransaction.hincrByFloat(key4, field3, 5.5); baseTransaction.lpush(key5, new String[] {value1, value2, value3, value3}); + baseTransaction.llen(key5); baseTransaction.ltrim(key5, 1, -1); baseTransaction.lrange(key5, 0, -2); baseTransaction.lpop(key5); @@ -109,6 +110,7 @@ public static Object[] transactionTestResult() { 5L, 10.5, 4L, + 4L, OK, new String[] {value3, value2}, value3,