Skip to content

Commit

Permalink
Java: Add Zmscore command. (Sorted Set Command Group) (valkey-io#1234)
Browse files Browse the repository at this point in the history
* Java: Add Zmscore command. (Sorted Set Command Group) (#173)

* Minor update + remove change log.

* Minor documentation update.

* Minor IT update.

* Rebase + Spotless.

* Minor IT test update.
  • Loading branch information
SanHalacogluImproving authored Apr 10, 2024
1 parent ae0a8f4 commit 4ce976c
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 1 deletion.
3 changes: 2 additions & 1 deletion glide-core/src/protobuf/redis_request.proto
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ enum RequestType {
Blpop = 100;
RPushX = 102;
LPushX = 103;
ZMScore = 104;
}

message Command {
Expand All @@ -169,7 +170,7 @@ message Transaction {

message RedisRequest {
uint32 callback_idx = 1;

oneof command {
Command single_command = 2;
Transaction transaction = 3;
Expand Down
3 changes: 3 additions & 0 deletions glide-core/src/request_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ pub enum RequestType {
Blpop = 100,
RPushX = 102,
LPushX = 103,
ZMScore = 104,
}

fn get_two_word_command(first: &str, second: &str) -> Cmd {
Expand Down Expand Up @@ -225,6 +226,7 @@ impl From<::protobuf::EnumOrUnknown<ProtobufRequestType>> for RequestType {
ProtobufRequestType::LPushX => RequestType::LPushX,
ProtobufRequestType::Blpop => RequestType::Blpop,
ProtobufRequestType::Spop => RequestType::Spop,
ProtobufRequestType::ZMScore => RequestType::ZMScore,
}
}
}
Expand Down Expand Up @@ -335,6 +337,7 @@ impl RequestType {
RequestType::LPushX => Some(cmd("LPUSHX")),
RequestType::Blpop => Some(cmd("BLPOP")),
RequestType::Spop => Some(cmd("SPOP")),
RequestType::ZMScore => Some(cmd("ZMSCORE")),
}
}
}
10 changes: 10 additions & 0 deletions java/client/src/main/java/glide/api/BaseClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.Type;
import static redis_request.RedisRequestOuterClass.RequestType.Unlink;
import static redis_request.RedisRequestOuterClass.RequestType.XAdd;
import static redis_request.RedisRequestOuterClass.RequestType.ZMScore;
import static redis_request.RedisRequestOuterClass.RequestType.ZPopMax;
import static redis_request.RedisRequestOuterClass.RequestType.ZPopMin;
import static redis_request.RedisRequestOuterClass.RequestType.ZScore;
Expand Down Expand Up @@ -714,6 +715,15 @@ public CompletableFuture<Object[]> zrankWithScore(@NonNull String key, @NonNull
Zrank, new String[] {key, member, WITH_SCORE_REDIS_API}, this::handleArrayOrNullResponse);
}

@Override
public CompletableFuture<Double[]> 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<String> xadd(@NonNull String key, @NonNull Map<String, String> values) {
return xadd(key, values, StreamAddOptions.builder().build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -456,4 +456,22 @@ CompletableFuture<Map<String, Double>> zrangeWithScores(
* }</pre>
*/
CompletableFuture<Object[]> zrankWithScore(String key, String member);

/**
* Returns the scores associated with the specified <code>members</code> in the sorted set stored
* at <code>key</code>.
*
* @see <a href="https://redis.io/commands/zmscore/">redis.io</a> for more details.
* @param key The key of the sorted set.
* @param members An array of members in the sorted set.
* @return An <code>Array</code> of scores of the <code>members</code>.<br>
* If a <code>member</code> does not exist, the corresponding value in the <code>Array</code>
* will be <code>null</code>.
* @example
* <pre>{@code
* Double[] payload = client.zmscore(key1, new String[] {"one", "nonExistentMember", "three"}).get();
* assert payload.equals(new Double[] {1.0, null, 3.0});
* }</pre>
*/
CompletableFuture<Double[]> zmscore(String key, String[] members);
}
18 changes: 18 additions & 0 deletions java/client/src/main/java/glide/api/models/BaseTransaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.Type;
import static redis_request.RedisRequestOuterClass.RequestType.Unlink;
import static redis_request.RedisRequestOuterClass.RequestType.XAdd;
import static redis_request.RedisRequestOuterClass.RequestType.ZMScore;
import static redis_request.RedisRequestOuterClass.RequestType.ZPopMax;
import static redis_request.RedisRequestOuterClass.RequestType.ZPopMin;
import static redis_request.RedisRequestOuterClass.RequestType.ZScore;
Expand Down Expand Up @@ -1514,6 +1515,23 @@ public T zrankWithScore(@NonNull String key, @NonNull String member) {
return getThis();
}

/**
* Returns the scores associated with the specified <code>members</code> in the sorted set stored
* at <code>key</code>.
*
* @see <a href="https://redis.io/commands/zmscore/">redis.io</a> for more details.
* @param key The key of the sorted set.
* @param members An array of members in the sorted set.
* @return Command Response - An <code>Array</code> of scores of the <code>members</code>.<br>
* If a <code>member</code> does not exist, the corresponding value in the <code>Array</code>
* will be <code>null</code>.
*/
public T zmscore(@NonNull String key, @NonNull String[] members) {
ArgsArray commandArgs = buildArgs(ArrayUtils.addFirst(members, key));
protobufTransaction.addCommands(buildCommand(ZMScore, commandArgs));
return getThis();
}

/**
* Adds an entry to the specified stream.
*
Expand Down
26 changes: 26 additions & 0 deletions java/client/src/test/java/glide/api/RedisClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.Type;
import static redis_request.RedisRequestOuterClass.RequestType.Unlink;
import static redis_request.RedisRequestOuterClass.RequestType.XAdd;
import static redis_request.RedisRequestOuterClass.RequestType.ZMScore;
import static redis_request.RedisRequestOuterClass.RequestType.ZPopMax;
import static redis_request.RedisRequestOuterClass.RequestType.ZPopMin;
import static redis_request.RedisRequestOuterClass.RequestType.ZScore;
Expand Down Expand Up @@ -2269,6 +2270,31 @@ public void zrankWithScore_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<Double[]> testResponse = new CompletableFuture<>();
testResponse.complete(value);

// match on protobuf request
when(commandManager.<Double[]>submitNewCommand(eq(ZMScore), eq(arguments), any()))
.thenReturn(testResponse);

// exercise
CompletableFuture<Double[]> response = service.zmscore(key, members);
Double[] payload = response.get();

// verify
assertEquals(testResponse, response);
assertEquals(value, payload);
}

@SneakyThrows
@Test
public void xadd_returns_success() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.Type;
import static redis_request.RedisRequestOuterClass.RequestType.Unlink;
import static redis_request.RedisRequestOuterClass.RequestType.XAdd;
import static redis_request.RedisRequestOuterClass.RequestType.ZMScore;
import static redis_request.RedisRequestOuterClass.RequestType.ZPopMax;
import static redis_request.RedisRequestOuterClass.RequestType.ZPopMin;
import static redis_request.RedisRequestOuterClass.RequestType.ZScore;
Expand Down Expand Up @@ -343,6 +344,12 @@ public void transaction_builds_protobuf_request(BaseTransaction<?> transaction)
transaction.zrankWithScore("key", "member");
results.add(Pair.of(Zrank, buildArgs("key", "member", WITH_SCORE_REDIS_API)));

transaction.zmscore("key", new String[] {"member1", "member2"});
results.add(
Pair.of(
ZMScore,
ArgsArray.newBuilder().addArgs("key").addArgs("member1").addArgs("member2").build()));

transaction.xadd("key", Map.of("field1", "foo1"));
results.add(Pair.of(XAdd, buildArgs("key", "*", "field1", "foo1")));

Expand Down
27 changes: 27 additions & 0 deletions java/integTest/src/test/java/glide/SharedCommandTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -1315,6 +1315,33 @@ public void zrank(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<String, Double> 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[] {1.0, null, null, 3.0},
client
.zmscore(key1, new String[] {"one", "nonExistentMember", "nonExistentMember", "three"})
.get());
assertArrayEquals(
new Double[] {null}, client.zmscore("nonExistentKey", new String[] {"one"}).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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,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.zrange(key8, new RangeByIndex(0, 1));
baseTransaction.zrangeWithScores(key8, new RangeByIndex(0, 1));
baseTransaction.zscore(key8, "two");
Expand Down Expand Up @@ -192,6 +193,7 @@ public static Object[] transactionTestResult() {
4.0,
1L,
2L,
new Double[] {2.0, 3.0}, // zmscore(key8, new String[] {"two", "three"})
new String[] {"two", "three"}, // zrange
Map.of("two", 2.0, "three", 3.0), // zrangeWithScores
2.0, // zscore(key8, "two")
Expand Down

0 comments on commit 4ce976c

Please sign in to comment.