diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dc8a3580f..551734e648 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ * Core: Enabled Cluster Mode periodic checks by default ([#1089](https://github.com/aws/glide-for-redis/pull/1089)) * Node: Added Rename command. ([#1124](https://github.com/aws/glide-for-redis/pull/1124)) * Python: Added JSON.TOGGLE command ([#1184](https://github.com/aws/glide-for-redis/pull/1184)) +* Java: Added ZMSCORE command (TODO ADD HERE PR #) #### Features diff --git a/glide-core/src/protobuf/redis_request.proto b/glide-core/src/protobuf/redis_request.proto index 327b9fa335..bc9002fd5e 100644 --- a/glide-core/src/protobuf/redis_request.proto +++ b/glide-core/src/protobuf/redis_request.proto @@ -135,6 +135,7 @@ enum RequestType { Rename = 91; DBSize = 92; Brpop = 93; + ZMScore = 94; } message Command { diff --git a/glide-core/src/socket_listener.rs b/glide-core/src/socket_listener.rs index 232ee3089c..33748b99a3 100644 --- a/glide-core/src/socket_listener.rs +++ b/glide-core/src/socket_listener.rs @@ -365,6 +365,7 @@ fn get_command(request: &Command) -> Option { RequestType::Rename => Some(cmd("RENAME")), RequestType::DBSize => Some(cmd("DBSIZE")), RequestType::Brpop => Some(cmd("BRPOP")), + RequestType::ZMScore => Some(cmd("ZMSCORE")), } } diff --git a/java/client/src/main/java/glide/api/BaseClient.java b/java/client/src/main/java/glide/api/BaseClient.java index bc38e68fd9..1605361c4f 100644 --- a/java/client/src/main/java/glide/api/BaseClient.java +++ b/java/client/src/main/java/glide/api/BaseClient.java @@ -45,6 +45,7 @@ import static redis_request.RedisRequestOuterClass.RequestType.TTL; import static redis_request.RedisRequestOuterClass.RequestType.Type; import static redis_request.RedisRequestOuterClass.RequestType.Unlink; +import static redis_request.RedisRequestOuterClass.RequestType.ZMScore; import static redis_request.RedisRequestOuterClass.RequestType.Zadd; import static redis_request.RedisRequestOuterClass.RequestType.Zcard; import static redis_request.RedisRequestOuterClass.RequestType.Zrem; @@ -594,6 +595,15 @@ public CompletableFuture zcard(@NonNull String key) { return commandManager.submitNewCommand(Zcard, new String[] {key}, this::handleLongResponse); } + @Override + public CompletableFuture zmscore(@NonNull String key, @NonNull String[] members) { + String[] arguments = ArrayUtils.addFirst(members, key); + return commandManager.submitNewCommand( + ZMScore, + arguments, + response -> castArray(handleArrayOrNullResponse(response), Double.class)); + } + @Override public CompletableFuture type(@NonNull String key) { return commandManager.submitNewCommand(Type, new String[] {key}, this::handleStringResponse); diff --git a/java/client/src/main/java/glide/api/commands/SortedSetBaseCommands.java b/java/client/src/main/java/glide/api/commands/SortedSetBaseCommands.java index 67415dcaae..0129812d87 100644 --- a/java/client/src/main/java/glide/api/commands/SortedSetBaseCommands.java +++ b/java/client/src/main/java/glide/api/commands/SortedSetBaseCommands.java @@ -183,4 +183,23 @@ CompletableFuture zaddIncr( * } */ CompletableFuture zcard(String key); + + /** + * Returns the scores associated with the specified members in the sorted set stored + * at key. + * + * @see redis.io for more details. + * @param key The key of the sorted set. + * @param members An array of members whose scores are to be retrieved. + * @return An array representing the scores for the specified members. + *
+ * If a member does not exist, the corresponding value in the array + * will be null. + * @example + *
{@code
+     * Double[] payload = client.zmscore(key1, new String[] {"one", "nonExistentMember", "three"}).get();
+     * assert payload.equals(new Double[] {1.0, null, 3.0});
+     * }
+ */ + CompletableFuture zmscore(String key, String[] members); } 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 cfe793adb2..6c3505e5ce 100644 --- a/java/client/src/main/java/glide/api/models/BaseTransaction.java +++ b/java/client/src/main/java/glide/api/models/BaseTransaction.java @@ -53,6 +53,7 @@ import static redis_request.RedisRequestOuterClass.RequestType.TTL; import static redis_request.RedisRequestOuterClass.RequestType.Type; import static redis_request.RedisRequestOuterClass.RequestType.Unlink; +import static redis_request.RedisRequestOuterClass.RequestType.ZMScore; import static redis_request.RedisRequestOuterClass.RequestType.Zadd; import static redis_request.RedisRequestOuterClass.RequestType.Zcard; import static redis_request.RedisRequestOuterClass.RequestType.Zrem; @@ -1272,6 +1273,24 @@ public T zcard(@NonNull String key) { return getThis(); } + /** + * Returns the scores associated with the specified members in the sorted set stored + * at key. + * + * @see redis.io for more details. + * @param key The key of the sorted set. + * @param members An array of members whose scores are to be retrieved. + * @return Command Response - An array representing the scores for the specified + * members.
+ * If a member does not exist, the corresponding value in the array + * will be null. + */ + public T zmscore(@NonNull String key, @NonNull String[] members) { + ArgsArray commandArgs = buildArgs(ArrayUtils.addFirst(members, key)); + protobufTransaction.addCommands(buildCommand(ZMScore, commandArgs)); + return getThis(); + } + /** * Returns the string representation of the type of the value stored at key. * diff --git a/java/client/src/test/java/glide/api/RedisClientTest.java b/java/client/src/test/java/glide/api/RedisClientTest.java index 9ecc764e69..9d62dc13b9 100644 --- a/java/client/src/test/java/glide/api/RedisClientTest.java +++ b/java/client/src/test/java/glide/api/RedisClientTest.java @@ -65,6 +65,7 @@ import static redis_request.RedisRequestOuterClass.RequestType.TTL; import static redis_request.RedisRequestOuterClass.RequestType.Type; import static redis_request.RedisRequestOuterClass.RequestType.Unlink; +import static redis_request.RedisRequestOuterClass.RequestType.ZMScore; import static redis_request.RedisRequestOuterClass.RequestType.Zadd; import static redis_request.RedisRequestOuterClass.RequestType.Zcard; import static redis_request.RedisRequestOuterClass.RequestType.Zrem; @@ -1685,6 +1686,31 @@ public void zcard_returns_success() { assertEquals(value, payload); } + @SneakyThrows + @Test + public void zmscore_returns_success() { + // setup + String key = "testKey"; + String[] members = new String[] {"member1", "member2"}; + String[] arguments = new String[] {key, "member1", "member2"}; + Double[] value = new Double[] {2.5, 8.2}; + + CompletableFuture testResponse = new CompletableFuture<>(); + testResponse.complete(value); + + // match on protobuf request + when(commandManager.submitNewCommand(eq(ZMScore), eq(arguments), any())) + .thenReturn(testResponse); + + // exercise + CompletableFuture response = service.zmscore(key, members); + Double[] payload = response.get(); + + // verify + assertEquals(testResponse, response); + assertEquals(value, payload); + } + @SneakyThrows @Test public void type_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 5600eb7454..67d7720e9e 100644 --- a/java/client/src/test/java/glide/api/models/TransactionTests.java +++ b/java/client/src/test/java/glide/api/models/TransactionTests.java @@ -51,6 +51,7 @@ import static redis_request.RedisRequestOuterClass.RequestType.TTL; import static redis_request.RedisRequestOuterClass.RequestType.Type; import static redis_request.RedisRequestOuterClass.RequestType.Unlink; +import static redis_request.RedisRequestOuterClass.RequestType.ZMScore; import static redis_request.RedisRequestOuterClass.RequestType.Zadd; import static redis_request.RedisRequestOuterClass.RequestType.Zcard; import static redis_request.RedisRequestOuterClass.RequestType.Zrem; @@ -381,6 +382,12 @@ public void transaction_builds_protobuf_request(BaseTransaction transaction) transaction.zcard("key"); results.add(Pair.of(Zcard, ArgsArray.newBuilder().addArgs("key").build())); + transaction.zmscore("key", new String[] {"member1", "member2"}); + results.add( + Pair.of( + ZMScore, + ArgsArray.newBuilder().addArgs("key").addArgs("member1").addArgs("member2").build())); + transaction.type("key"); results.add(Pair.of(Type, ArgsArray.newBuilder().addArgs("key").build())); diff --git a/java/integTest/src/test/java/glide/SharedCommandTests.java b/java/integTest/src/test/java/glide/SharedCommandTests.java index 0dc9c935d2..daa8579726 100644 --- a/java/integTest/src/test/java/glide/SharedCommandTests.java +++ b/java/integTest/src/test/java/glide/SharedCommandTests.java @@ -1031,6 +1031,34 @@ public void zcard(BaseClient client) { assertTrue(executionException.getCause() instanceof RequestException); } + @SneakyThrows + @ParameterizedTest + @MethodSource("getClients") + public void zmscore(BaseClient client) { + String key1 = UUID.randomUUID().toString(); + String key2 = UUID.randomUUID().toString(); + Map membersScores = Map.of("one", 1.0, "two", 2.0, "three", 3.0); + assertEquals(3, client.zadd(key1, membersScores).get()); + assertArrayEquals( + new Double[] {1.0, 2.0, 3.0}, + client.zmscore(key1, new String[] {"one", "two", "three"}).get()); + assertArrayEquals( + new Double[] {2.0, 3.0}, client.zmscore(key1, new String[] {"two", "three"}).get()); + assertArrayEquals( + new Double[] {1.0, null, 3.0}, + client.zmscore(key1, new String[] {"one", "nonExistentMember", "three"}).get()); + assertArrayEquals( + new Double[] {null}, + client.zmscore("nonExistentKey", new String[] {"nonExistentMember"}).get()); + + // Key exists, but it is not a set + assertEquals(OK, client.set(key2, "bar").get()); + ExecutionException executionException = + assertThrows( + ExecutionException.class, () -> client.zmscore(key2, new String[] {"one"}).get()); + assertTrue(executionException.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 c70ab0e2d6..90775174c0 100644 --- a/java/integTest/src/test/java/glide/TransactionTestUtilities.java +++ b/java/integTest/src/test/java/glide/TransactionTestUtilities.java @@ -87,6 +87,7 @@ public static BaseTransaction transactionTest(BaseTransaction baseTransact baseTransaction.zaddIncr(key8, "one", 3); baseTransaction.zrem(key8, new String[] {"one"}); baseTransaction.zcard(key8); + baseTransaction.zmscore(key8, new String[] {"two", "three"}); baseTransaction.configSet(Map.of("timeout", "1000")); baseTransaction.configGet(new String[] {"timeout"}); @@ -145,6 +146,7 @@ public static Object[] transactionTestResult() { 4.0, 1L, 2L, + new Double[] {2.0, 3.0}, // zmscore(key8, new String[] {"two", "three"}) OK, Map.of("timeout", "1000"), OK,