From cf62104efa25fdc5b2a0bab8da3a7abbbbe89ddd Mon Sep 17 00:00:00 2001 From: Andrew Carbonetto Date: Wed, 5 Jun 2024 21:25:11 -0700 Subject: [PATCH 1/7] Java: add `xrevrange` command (#341) * Init commit for XREVRANGE Signed-off-by: Andrew Carbonetto * Updates to xrevrange Signed-off-by: Andrew Carbonetto * Add XREVRANGE to rust Signed-off-by: Andrew Carbonetto * Revert set changes Signed-off-by: Andrew Carbonetto * Java: Add XREVRANGE command Signed-off-by: Andrew Carbonetto * Documentation updates for xrevrange Signed-off-by: Andrew Carbonetto * Revert small change Signed-off-by: Andrew Carbonetto --------- Signed-off-by: Andrew Carbonetto --- glide-core/src/client/value_conversion.rs | 2 +- glide-core/src/protobuf/redis_request.proto | 1 + glide-core/src/request_type.rs | 3 + .../src/main/java/glide/api/BaseClient.java | 21 +++++ .../api/commands/StreamBaseCommands.java | 82 ++++++++++++++++++- .../glide/api/models/BaseTransaction.java | 66 +++++++++++++++ .../test/java/glide/api/RedisClientTest.java | 65 +++++++++++++++ .../glide/api/models/TransactionTests.java | 16 ++++ .../test/java/glide/SharedCommandTests.java | 54 +++++++++++- .../java/glide/TransactionTestUtilities.java | 4 + 10 files changed, 310 insertions(+), 4 deletions(-) diff --git a/glide-core/src/client/value_conversion.rs b/glide-core/src/client/value_conversion.rs index 347fa11a54..8ae39698d8 100644 --- a/glide-core/src/client/value_conversion.rs +++ b/glide-core/src/client/value_conversion.rs @@ -683,7 +683,7 @@ pub(crate) fn expected_type_for_cmd(cmd: &Cmd) -> Option { // TODO use enum to avoid mistakes match command.as_slice() { - b"HGETALL" | b"CONFIG GET" | b"FT.CONFIG GET" | b"HELLO" | b"XRANGE" => { + b"HGETALL" | b"CONFIG GET" | b"FT.CONFIG GET" | b"HELLO" | b"XRANGE" | b"XREVRANGE" => { Some(ExpectedReturnType::Map { key_type: &None, value_type: &None, diff --git a/glide-core/src/protobuf/redis_request.proto b/glide-core/src/protobuf/redis_request.proto index 7a8f3a2746..8b629ec619 100644 --- a/glide-core/src/protobuf/redis_request.proto +++ b/glide-core/src/protobuf/redis_request.proto @@ -210,6 +210,7 @@ enum RequestType { BitFieldReadOnly = 173; Move = 174; SInterCard = 175; + XRevRange = 176; Copy = 178; } diff --git a/glide-core/src/request_type.rs b/glide-core/src/request_type.rs index 8e20449c1d..176a461fe0 100644 --- a/glide-core/src/request_type.rs +++ b/glide-core/src/request_type.rs @@ -180,6 +180,7 @@ pub enum RequestType { BitFieldReadOnly = 173, Move = 174, SInterCard = 175, + XRevRange = 176, Copy = 178, } @@ -365,6 +366,7 @@ impl From<::protobuf::EnumOrUnknown> for RequestType { ProtobufRequestType::SInterCard => RequestType::SInterCard, ProtobufRequestType::Copy => RequestType::Copy, ProtobufRequestType::Sort => RequestType::Sort, + ProtobufRequestType::XRevRange => RequestType::XRevRange, } } } @@ -545,6 +547,7 @@ impl RequestType { RequestType::SInterCard => Some(cmd("SINTERCARD")), RequestType::Copy => Some(cmd("COPY")), RequestType::Sort => Some(cmd("SORT")), + RequestType::XRevRange => Some(cmd("XREVRANGE")), } } } diff --git a/java/client/src/main/java/glide/api/BaseClient.java b/java/client/src/main/java/glide/api/BaseClient.java index db038b9373..21e050e416 100644 --- a/java/client/src/main/java/glide/api/BaseClient.java +++ b/java/client/src/main/java/glide/api/BaseClient.java @@ -118,6 +118,7 @@ import static redis_request.RedisRequestOuterClass.RequestType.XLen; import static redis_request.RedisRequestOuterClass.RequestType.XRange; import static redis_request.RedisRequestOuterClass.RequestType.XRead; +import static redis_request.RedisRequestOuterClass.RequestType.XRevRange; import static redis_request.RedisRequestOuterClass.RequestType.XTrim; import static redis_request.RedisRequestOuterClass.RequestType.ZAdd; import static redis_request.RedisRequestOuterClass.RequestType.ZCard; @@ -1337,6 +1338,26 @@ public CompletableFuture> xrange( XRange, arguments, response -> castMapOfArrays(handleMapResponse(response), String.class)); } + @Override + public CompletableFuture> xrevrange( + @NonNull String key, @NonNull StreamRange end, @NonNull StreamRange start) { + String[] arguments = ArrayUtils.addFirst(StreamRange.toArgs(end, start), key); + return commandManager.submitNewCommand( + XRevRange, + arguments, + response -> castMapOfArrays(handleMapResponse(response), String.class)); + } + + @Override + public CompletableFuture> xrevrange( + @NonNull String key, @NonNull StreamRange end, @NonNull StreamRange start, long count) { + String[] arguments = ArrayUtils.addFirst(StreamRange.toArgs(end, start, count), key); + return commandManager.submitNewCommand( + XRevRange, + arguments, + response -> castMapOfArrays(handleMapResponse(response), String.class)); + } + @Override public CompletableFuture pttl(@NonNull String key) { return commandManager.submitNewCommand(PTTL, new String[] {key}, this::handleLongResponse); diff --git a/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java b/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java index bdb9f000e1..e66d6d4a7c 100644 --- a/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java +++ b/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java @@ -184,8 +184,8 @@ CompletableFuture>> xread( *
  • Use {@link InfRangeBound#MAX} to end with the maximum available ID. * * - * @return @return A Map of key to stream entry data, where entry data is an array of - * item pairings. + * @return A Map of key to stream entry data, where entry data is an array of item + * pairings. * @example *
    {@code
          * // Retrieve all stream entries
    @@ -238,4 +238,82 @@ CompletableFuture>> xread(
          */
         CompletableFuture> xrange(
                 String key, StreamRange start, StreamRange end, long count);
    +
    +    /**
    +     * Returns stream entries matching a given range of IDs in reverse order.
    + * Equivalent to {@link #xrange(String, StreamRange, StreamRange)} but returns the entries in + * reverse order. + * + * @param key The key of the stream. + * @param end Ending stream ID bound for range. + *
      + *
    • Use {@link IdBound#of} to specify a stream ID. + *
    • Use {@link IdBound#ofExclusive} to specify an exclusive bounded stream ID. + *
    • Use {@link InfRangeBound#MAX} to end with the maximum available ID. + *
    + * + * @param start Starting stream ID bound for range. + *
      + *
    • Use {@link IdBound#of} to specify a stream ID. + *
    • Use {@link IdBound#ofExclusive} to specify an exclusive bounded stream ID. + *
    • Use {@link InfRangeBound#MIN} to start with the minimum available ID. + *
    + * + * @return A Map of key to stream entry data, where entry data is an array of item + * pairings. + * @example + *
    {@code
    +     * // Retrieve all stream entries
    +     * Map result = client.xrevrange("key", InfRangeBound.MAX, InfRangeBound.MIN).get();
    +     * result.forEach((k, v) -> {
    +     *     System.out.println("Stream ID: " + k);
    +     *     for (int i = 0; i < v.length;) {
    +     *         System.out.println(v[i++] + ": " + v[i++]);
    +     *     }
    +     * });
    +     * // Retrieve exactly one stream entry by id
    +     * Map result = client.xrevrange("key", IdBound.of(streamId), IdBound.of(streamId)).get();
    +     * System.out.println("Stream ID: " + streamid + " -> " + Arrays.toString(result.get(streamid)));
    +     * }
    + */ + CompletableFuture> xrevrange( + String key, StreamRange end, StreamRange start); + + /** + * Returns stream entries matching a given range of IDs in reverse order.
    + * Equivalent to {@link #xrange(String, StreamRange, StreamRange, long)} but returns the entries + * in reverse order. + * + * @param key The key of the stream. + * @param end Ending stream ID bound for range. + *
      + *
    • Use {@link IdBound#of} to specify a stream ID. + *
    • Use {@link IdBound#ofExclusive} to specify an exclusive bounded stream ID. + *
    • Use {@link InfRangeBound#MAX} to end with the maximum available ID. + *
    + * + * @param start Starting stream ID bound for range. + *
      + *
    • Use {@link IdBound#of} to specify a stream ID. + *
    • Use {@link IdBound#ofExclusive} to specify an exclusive bounded stream ID. + *
    • Use {@link InfRangeBound#MIN} to start with the minimum available ID. + *
    + * + * @param count Maximum count of stream entries to return. + * @return A Map of key to stream entry data, where entry data is an array of item + * pairings. + * @example + *
    {@code
    +     * // Retrieve the first 2 stream entries
    +     * Map result = client.xrange("key", InfRangeBound.MAX, InfRangeBound.MIN, 2).get();
    +     * result.forEach((k, v) -> {
    +     *     System.out.println("Stream ID: " + k);
    +     *     for (int i = 0; i < v.length;) {
    +     *         System.out.println(v[i++] + ": " + v[i++]);
    +     *     }
    +     * });
    +     * }
    + */ + CompletableFuture> xrevrange( + String key, StreamRange end, StreamRange start, long count); } 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 e61e5a146c..ea7db24adb 100644 --- a/java/client/src/main/java/glide/api/models/BaseTransaction.java +++ b/java/client/src/main/java/glide/api/models/BaseTransaction.java @@ -143,6 +143,7 @@ import static redis_request.RedisRequestOuterClass.RequestType.XLen; import static redis_request.RedisRequestOuterClass.RequestType.XRange; import static redis_request.RedisRequestOuterClass.RequestType.XRead; +import static redis_request.RedisRequestOuterClass.RequestType.XRevRange; import static redis_request.RedisRequestOuterClass.RequestType.XTrim; import static redis_request.RedisRequestOuterClass.RequestType.ZAdd; import static redis_request.RedisRequestOuterClass.RequestType.ZCard; @@ -2783,6 +2784,71 @@ public T xrange( return getThis(); } + /** + * Returns stream entries matching a given range of IDs in reverse order.
    + * Equivalent to {@link #xrange(String, StreamRange, StreamRange)} but returns the entries in + * reverse order. + * + * @param key The key of the stream. + * @param end Ending stream ID bound for range. + *
      + *
    • Use {@link StreamRange.IdBound#of} to specify a stream ID. + *
    • Use {@link StreamRange.IdBound#ofExclusive} to specify an exclusive bounded stream + * ID. + *
    • Use {@link StreamRange.InfRangeBound#MAX} to end with the maximum available ID. + *
    + * + * @param start Starting stream ID bound for range. + *
      + *
    • Use {@link StreamRange.IdBound#of} to specify a stream ID. + *
    • Use {@link StreamRange.IdBound#ofExclusive} to specify an exclusive bounded stream + * ID. + *
    • Use {@link StreamRange.InfRangeBound#MIN} to start with the minimum available ID. + *
    + * + * @return Command Response - A Map of key to stream entry data, where entry data is + * an array of item pairings. + */ + public T xrevrange(@NonNull String key, @NonNull StreamRange end, @NonNull StreamRange start) { + ArgsArray commandArgs = buildArgs(ArrayUtils.addFirst(StreamRange.toArgs(end, start), key)); + protobufTransaction.addCommands(buildCommand(XRevRange, commandArgs)); + return getThis(); + } + + /** + * Returns stream entries matching a given range of IDs in reverse order.
    + * Equivalent to {@link #xrange(String, StreamRange, StreamRange, long)} but returns the entries + * in reverse order. + * + * @param key The key of the stream. + * @param start Starting stream ID bound for range. + *
      + *
    • Use {@link StreamRange.IdBound#of} to specify a stream ID. + *
    • Use {@link StreamRange.IdBound#ofExclusive} to specify an exclusive bounded stream + * ID. + *
    • Use {@link StreamRange.InfRangeBound#MIN} to start with the minimum available ID. + *
    + * + * @param end Ending stream ID bound for range. + *
      + *
    • Use {@link StreamRange.IdBound#of} to specify a stream ID. + *
    • Use {@link StreamRange.IdBound#ofExclusive} to specify an exclusive bounded stream + * ID. + *
    • Use {@link StreamRange.InfRangeBound#MAX} to end with the maximum available ID. + *
    + * + * @param count Maximum count of stream entries to return. + * @return Command Response - A Map of key to stream entry data, where entry data is + * an array of item pairings. + */ + public T xrevrange( + @NonNull String key, @NonNull StreamRange end, @NonNull StreamRange start, long count) { + ArgsArray commandArgs = + buildArgs(ArrayUtils.addFirst(StreamRange.toArgs(end, start, count), key)); + protobufTransaction.addCommands(buildCommand(XRevRange, commandArgs)); + return getThis(); + } + /** * Returns the remaining time to live of key that has a timeout, in milliseconds. * diff --git a/java/client/src/test/java/glide/api/RedisClientTest.java b/java/client/src/test/java/glide/api/RedisClientTest.java index 195940e30d..64f4d57a12 100644 --- a/java/client/src/test/java/glide/api/RedisClientTest.java +++ b/java/client/src/test/java/glide/api/RedisClientTest.java @@ -176,6 +176,7 @@ import static redis_request.RedisRequestOuterClass.RequestType.XLen; import static redis_request.RedisRequestOuterClass.RequestType.XRange; import static redis_request.RedisRequestOuterClass.RequestType.XRead; +import static redis_request.RedisRequestOuterClass.RequestType.XRevRange; import static redis_request.RedisRequestOuterClass.RequestType.XTrim; import static redis_request.RedisRequestOuterClass.RequestType.ZAdd; import static redis_request.RedisRequestOuterClass.RequestType.ZCard; @@ -4177,6 +4178,70 @@ public void xrange_withcount_returns_success() { assertEquals(completedResult, payload); } + @Test + @SneakyThrows + public void xrevrange_returns_success() { + // setup + String key = "testKey"; + StreamRange end = IdBound.of(9999L); + StreamRange start = IdBound.ofExclusive("696969-10"); + Map completedResult = + Map.of(key, new String[] {"duration", "12345", "event-id", "2", "user-id", "42"}); + + CompletableFuture> testResponse = new CompletableFuture<>(); + testResponse.complete(completedResult); + + // match on protobuf request + when(commandManager.>submitNewCommand( + eq(XRevRange), eq(new String[] {key, "9999", "(696969-10"}), any())) + .thenReturn(testResponse); + + // exercise + CompletableFuture> response = service.xrevrange(key, end, start); + Map payload = response.get(); + + // verify + assertEquals(testResponse, response); + assertEquals(completedResult, payload); + } + + @Test + @SneakyThrows + public void xrevrange_withcount_returns_success() { + // setup + String key = "testKey"; + StreamRange end = InfRangeBound.MAX; + StreamRange start = InfRangeBound.MIN; + long count = 99L; + Map completedResult = + Map.of(key, new String[] {"duration", "12345", "event-id", "2", "user-id", "42"}); + + CompletableFuture> testResponse = new CompletableFuture<>(); + testResponse.complete(completedResult); + + // match on protobuf request + when(commandManager.>submitNewCommand( + eq(XRevRange), + eq( + new String[] { + key, + MAXIMUM_RANGE_REDIS_API, + MINIMUM_RANGE_REDIS_API, + RANGE_COUNT_REDIS_API, + Long.toString(count) + }), + any())) + .thenReturn(testResponse); + + // exercise + CompletableFuture> response = service.xrevrange(key, end, start, count); + Map payload = response.get(); + + // verify + assertEquals(testResponse, response); + assertEquals(completedResult, 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 2454e210d7..04d4b8f702 100644 --- a/java/client/src/test/java/glide/api/models/TransactionTests.java +++ b/java/client/src/test/java/glide/api/models/TransactionTests.java @@ -156,6 +156,7 @@ import static redis_request.RedisRequestOuterClass.RequestType.XLen; import static redis_request.RedisRequestOuterClass.RequestType.XRange; import static redis_request.RedisRequestOuterClass.RequestType.XRead; +import static redis_request.RedisRequestOuterClass.RequestType.XRevRange; import static redis_request.RedisRequestOuterClass.RequestType.XTrim; import static redis_request.RedisRequestOuterClass.RequestType.ZAdd; import static redis_request.RedisRequestOuterClass.RequestType.ZCard; @@ -715,6 +716,21 @@ InfScoreBound.NEGATIVE_INFINITY, new ScoreBoundary(3, false), new Limit(1, 2)), RANGE_COUNT_REDIS_API, "99"))); + transaction.xrevrange("key", InfRangeBound.MAX, InfRangeBound.MIN); + results.add( + Pair.of(XRevRange, buildArgs("key", MAXIMUM_RANGE_REDIS_API, MINIMUM_RANGE_REDIS_API))); + + transaction.xrevrange("key", InfRangeBound.MAX, InfRangeBound.MIN, 99L); + results.add( + Pair.of( + XRevRange, + buildArgs( + "key", + MAXIMUM_RANGE_REDIS_API, + MINIMUM_RANGE_REDIS_API, + RANGE_COUNT_REDIS_API, + "99"))); + transaction.time(); results.add(Pair.of(Time, buildArgs())); diff --git a/java/integTest/src/test/java/glide/SharedCommandTests.java b/java/integTest/src/test/java/glide/SharedCommandTests.java index 49a35ed4c2..1a0cd3e331 100644 --- a/java/integTest/src/test/java/glide/SharedCommandTests.java +++ b/java/integTest/src/test/java/glide/SharedCommandTests.java @@ -3183,7 +3183,7 @@ public void xdel(BaseClient client) { @SneakyThrows @ParameterizedTest(autoCloseArguments = false) @MethodSource("getClients") - public void xrange(BaseClient client) { + public void xrange_and_xrevrange(BaseClient client) { String key = UUID.randomUUID().toString(); String key2 = UUID.randomUUID().toString(); @@ -3215,11 +3215,23 @@ public void xrange(BaseClient client) { assertNotNull(result.get(streamId1)); assertNotNull(result.get(streamId2)); + // get everything from the stream using a reverse range search + Map revResult = + client.xrevrange(key, InfRangeBound.MAX, InfRangeBound.MIN).get(); + assertEquals(2, revResult.size()); + assertNotNull(revResult.get(streamId1)); + assertNotNull(revResult.get(streamId2)); + // returns empty if + before - Map emptyResult = client.xrange(key, InfRangeBound.MAX, InfRangeBound.MIN).get(); assertEquals(0, emptyResult.size()); + // rev search returns empty if - before + + Map emptyRevResult = + client.xrevrange(key, InfRangeBound.MIN, InfRangeBound.MAX).get(); + assertEquals(0, emptyRevResult.size()); + assertEquals( streamId3, client @@ -3234,24 +3246,44 @@ public void xrange(BaseClient client) { client.xrange(key, IdBound.ofExclusive(streamId2), IdBound.ofExclusive(5), 1L).get(); assertEquals(1, newResult.size()); assertNotNull(newResult.get(streamId3)); + // ...and from xrevrange + Map newRevResult = + client.xrevrange(key, IdBound.ofExclusive(5), IdBound.ofExclusive(streamId2), 1L).get(); + assertEquals(1, newRevResult.size()); + assertNotNull(newRevResult.get(streamId3)); // xrange against an emptied stream assertEquals(3, client.xdel(key, new String[] {streamId1, streamId2, streamId3}).get()); Map emptiedResult = client.xrange(key, InfRangeBound.MIN, InfRangeBound.MAX, 10L).get(); assertEquals(0, emptiedResult.size()); + // ...and xrevrange + Map emptiedRevResult = + client.xrevrange(key, InfRangeBound.MAX, InfRangeBound.MIN, 10L).get(); + assertEquals(0, emptiedRevResult.size()); // xrange against a non-existent stream emptyResult = client.xrange(key2, InfRangeBound.MIN, InfRangeBound.MAX).get(); assertEquals(0, emptyResult.size()); + // ...and xrevrange + emptiedRevResult = client.xrevrange(key2, InfRangeBound.MAX, InfRangeBound.MIN).get(); + assertEquals(0, emptiedRevResult.size()); + // xrange against a non-stream value assertEquals(OK, client.set(key2, "not_a_stream").get()); ExecutionException executionException = assertThrows( ExecutionException.class, () -> client.xrange(key2, InfRangeBound.MIN, InfRangeBound.MAX).get()); assertInstanceOf(RequestException.class, executionException.getCause()); + // ...and xrevrange + executionException = + assertThrows( + ExecutionException.class, + () -> client.xrevrange(key2, InfRangeBound.MAX, InfRangeBound.MIN).get()); + assertInstanceOf(RequestException.class, executionException.getCause()); + // xrange when range bound is not valid ID executionException = assertThrows( ExecutionException.class, @@ -3269,6 +3301,26 @@ public void xrange(BaseClient client) { .xrange(key, InfRangeBound.MIN, IdBound.ofExclusive("not_a_stream_id")) .get()); assertInstanceOf(RequestException.class, executionException.getCause()); + + // ... and xrevrange + + executionException = + assertThrows( + ExecutionException.class, + () -> + client + .xrevrange(key, IdBound.ofExclusive("not_a_stream_id"), InfRangeBound.MIN) + .get()); + assertInstanceOf(RequestException.class, executionException.getCause()); + + executionException = + assertThrows( + ExecutionException.class, + () -> + client + .xrevrange(key, InfRangeBound.MAX, IdBound.ofExclusive("not_a_stream_id")) + .get()); + assertInstanceOf(RequestException.class, executionException.getCause()); } @SneakyThrows diff --git a/java/integTest/src/test/java/glide/TransactionTestUtilities.java b/java/integTest/src/test/java/glide/TransactionTestUtilities.java index a6abc8ce87..a99111e753 100644 --- a/java/integTest/src/test/java/glide/TransactionTestUtilities.java +++ b/java/integTest/src/test/java/glide/TransactionTestUtilities.java @@ -668,6 +668,8 @@ private static Object[] streamCommands(BaseTransaction transaction) { .xread(Map.of(streamKey1, "0-2")) .xrange(streamKey1, IdBound.of("0-1"), IdBound.of("0-1")) .xrange(streamKey1, IdBound.of("0-1"), IdBound.of("0-1"), 1L) + .xrevrange(streamKey1, IdBound.of("0-1"), IdBound.of("0-1")) + .xrevrange(streamKey1, IdBound.of("0-1"), IdBound.of("0-1"), 1L) .xtrim(streamKey1, new MinId(true, "0-2")) .xdel(streamKey1, new String[] {"0-3", "0-5"}); @@ -681,6 +683,8 @@ private static Object[] streamCommands(BaseTransaction transaction) { Map.of("0-3", new String[][] {{"field3", "value3"}})), // xread(Map.of(key9, "0-2")); Map.of("0-1", new String[] {"field1", "value1"}), // .xrange(streamKey1, "0-1", "0-1") Map.of("0-1", new String[] {"field1", "value1"}), // .xrange(streamKey1, "0-1", "0-1", 1l) + Map.of("0-1", new String[] {"field1", "value1"}), // .xrevrange(streamKey1, "0-1", "0-1") + Map.of("0-1", new String[] {"field1", "value1"}), // .xrevrange(streamKey1, "0-1", "0-1", 1l) 1L, // xtrim(streamKey1, new MinId(true, "0-2")) 1L, // .xdel(streamKey1, new String[] {"0-1", "0-5"}); }; From c6fd7a6bf399c5ce648a1d9678c88bafb23f7f31 Mon Sep 17 00:00:00 2001 From: Andrew Carbonetto Date: Mon, 10 Jun 2024 18:32:05 -0700 Subject: [PATCH 2/7] Change XRANGE XREVRANGE to use array of pairs Signed-off-by: Andrew Carbonetto --- glide-core/src/client/value_conversion.rs | 24 ++++++++++++++++++- .../src/main/java/glide/api/BaseClient.java | 8 +++---- .../api/commands/StreamBaseCommands.java | 8 +++---- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/glide-core/src/client/value_conversion.rs b/glide-core/src/client/value_conversion.rs index 8ae39698d8..f63fe54774 100644 --- a/glide-core/src/client/value_conversion.rs +++ b/glide-core/src/client/value_conversion.rs @@ -683,12 +683,16 @@ pub(crate) fn expected_type_for_cmd(cmd: &Cmd) -> Option { // TODO use enum to avoid mistakes match command.as_slice() { - b"HGETALL" | b"CONFIG GET" | b"FT.CONFIG GET" | b"HELLO" | b"XRANGE" | b"XREVRANGE" => { + b"HGETALL" | b"CONFIG GET" | b"FT.CONFIG GET" | b"HELLO" => { Some(ExpectedReturnType::Map { key_type: &None, value_type: &None, }) } + b"XRANGE" | b"XREVRANGE" => Some(ExpectedReturnType::Map { + key_type: &Some(ExpectedReturnType::BulkString), + value_type: &Some(ExpectedReturnType::ArrayOfPairs), + }), b"XREAD" => Some(ExpectedReturnType::Map { key_type: &Some(ExpectedReturnType::BulkString), value_type: &Some(ExpectedReturnType::Map { @@ -988,6 +992,24 @@ mod tests { assert!(converted_4.is_err()); } + #[test] + fn convert_xrange_xrevrange() { + assert!(matches!( + expected_type_for_cmd(redis::cmd("XRANGE").arg("key").arg("start").arg("end")), + Some(ExpectedReturnType::Map { + key_type: &Some(ExpectedReturnType::BulkString), + value_type: &Some(ExpectedReturnType::ArrayOfPairs), + }) + )); + assert!(matches!( + expected_type_for_cmd(redis::cmd("XREVRANGE").arg("key").arg("end").arg("start")), + Some(ExpectedReturnType::Map { + key_type: &Some(ExpectedReturnType::BulkString), + value_type: &Some(ExpectedReturnType::ArrayOfPairs), + }) + )); + } + #[test] fn convert_xread() { assert!(matches!( diff --git a/java/client/src/main/java/glide/api/BaseClient.java b/java/client/src/main/java/glide/api/BaseClient.java index 21e050e416..39786dea69 100644 --- a/java/client/src/main/java/glide/api/BaseClient.java +++ b/java/client/src/main/java/glide/api/BaseClient.java @@ -1323,7 +1323,7 @@ public CompletableFuture xdel(@NonNull String key, @NonNull String[] ids) } @Override - public CompletableFuture> xrange( + public CompletableFuture> xrange( @NonNull String key, @NonNull StreamRange start, @NonNull StreamRange end) { String[] arguments = ArrayUtils.addFirst(StreamRange.toArgs(start, end), key); return commandManager.submitNewCommand( @@ -1331,7 +1331,7 @@ public CompletableFuture> xrange( } @Override - public CompletableFuture> xrange( + public CompletableFuture> xrange( @NonNull String key, @NonNull StreamRange start, @NonNull StreamRange end, long count) { String[] arguments = ArrayUtils.addFirst(StreamRange.toArgs(start, end, count), key); return commandManager.submitNewCommand( @@ -1339,7 +1339,7 @@ public CompletableFuture> xrange( } @Override - public CompletableFuture> xrevrange( + public CompletableFuture> xrevrange( @NonNull String key, @NonNull StreamRange end, @NonNull StreamRange start) { String[] arguments = ArrayUtils.addFirst(StreamRange.toArgs(end, start), key); return commandManager.submitNewCommand( @@ -1349,7 +1349,7 @@ public CompletableFuture> xrevrange( } @Override - public CompletableFuture> xrevrange( + public CompletableFuture> xrevrange( @NonNull String key, @NonNull StreamRange end, @NonNull StreamRange start, long count) { String[] arguments = ArrayUtils.addFirst(StreamRange.toArgs(end, start, count), key); return commandManager.submitNewCommand( diff --git a/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java b/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java index e66d6d4a7c..8c1b380adc 100644 --- a/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java +++ b/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java @@ -201,7 +201,7 @@ CompletableFuture>> xread( * System.out.println("Stream ID: " + streamid + " -> " + Arrays.toString(result.get(streamid))); * }
    */ - CompletableFuture> xrange(String key, StreamRange start, StreamRange end); + CompletableFuture> xrange(String key, StreamRange start, StreamRange end); /** * Returns stream entries matching a given range of IDs. @@ -236,7 +236,7 @@ CompletableFuture>> xread( * }); * } */ - CompletableFuture> xrange( + CompletableFuture> xrange( String key, StreamRange start, StreamRange end, long count); /** @@ -276,7 +276,7 @@ CompletableFuture> xrange( * System.out.println("Stream ID: " + streamid + " -> " + Arrays.toString(result.get(streamid))); * } */ - CompletableFuture> xrevrange( + CompletableFuture> xrevrange( String key, StreamRange end, StreamRange start); /** @@ -314,6 +314,6 @@ CompletableFuture> xrevrange( * }); * } */ - CompletableFuture> xrevrange( + CompletableFuture> xrevrange( String key, StreamRange end, StreamRange start, long count); } From 6570374df705782612d299263232e3ed6afdb6f6 Mon Sep 17 00:00:00 2001 From: Andrew Carbonetto Date: Mon, 10 Jun 2024 18:43:14 -0700 Subject: [PATCH 3/7] Update XRANGE XREVRANGE java client to use pairings return Signed-off-by: Andrew Carbonetto --- .../src/main/java/glide/api/BaseClient.java | 8 ++-- .../api/commands/StreamBaseCommands.java | 40 +++++++--------- .../test/java/glide/api/RedisClientTest.java | 48 +++++++++---------- 3 files changed, 46 insertions(+), 50 deletions(-) diff --git a/java/client/src/main/java/glide/api/BaseClient.java b/java/client/src/main/java/glide/api/BaseClient.java index 39786dea69..fc7fb6889b 100644 --- a/java/client/src/main/java/glide/api/BaseClient.java +++ b/java/client/src/main/java/glide/api/BaseClient.java @@ -1327,7 +1327,7 @@ public CompletableFuture> xrange( @NonNull String key, @NonNull StreamRange start, @NonNull StreamRange end) { String[] arguments = ArrayUtils.addFirst(StreamRange.toArgs(start, end), key); return commandManager.submitNewCommand( - XRange, arguments, response -> castMapOfArrays(handleMapResponse(response), String.class)); + XRange, arguments, response -> castMapOf2DArray(handleMapResponse(response), String.class)); } @Override @@ -1335,7 +1335,7 @@ public CompletableFuture> xrange( @NonNull String key, @NonNull StreamRange start, @NonNull StreamRange end, long count) { String[] arguments = ArrayUtils.addFirst(StreamRange.toArgs(start, end, count), key); return commandManager.submitNewCommand( - XRange, arguments, response -> castMapOfArrays(handleMapResponse(response), String.class)); + XRange, arguments, response -> castMapOf2DArray(handleMapResponse(response), String.class)); } @Override @@ -1345,7 +1345,7 @@ public CompletableFuture> xrevrange( return commandManager.submitNewCommand( XRevRange, arguments, - response -> castMapOfArrays(handleMapResponse(response), String.class)); + response -> castMapOf2DArray(handleMapResponse(response), String.class)); } @Override @@ -1355,7 +1355,7 @@ public CompletableFuture> xrevrange( return commandManager.submitNewCommand( XRevRange, arguments, - response -> castMapOfArrays(handleMapResponse(response), String.class)); + response -> castMapOf2DArray(handleMapResponse(response), String.class)); } @Override diff --git a/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java b/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java index 8c1b380adc..906979269b 100644 --- a/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java +++ b/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java @@ -184,20 +184,19 @@ CompletableFuture>> xread( *
  • Use {@link InfRangeBound#MAX} to end with the maximum available ID. * * - * @return A Map of key to stream entry data, where entry data is an array of item - * pairings. + * @return A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...] * @example *
    {@code
          * // Retrieve all stream entries
    -     * Map result = client.xrange("key", InfRangeBound.MIN, InfRangeBound.MAX).get();
    +     * Map result = client.xrange("key", InfRangeBound.MIN, InfRangeBound.MAX).get();
          * result.forEach((k, v) -> {
          *     System.out.println("Stream ID: " + k);
    -     *     for (int i = 0; i < v.length;) {
    -     *         System.out.println(v[i++] + ": " + v[i++]);
    +     *     for (int i = 0; i < v.length; i++) {
    +     *         System.out.println(v[i][0] + ": " + v[i][1]);
          *     }
          * });
          * // Retrieve exactly one stream entry by id
    -     * Map result = client.xrange("key", IdBound.of(streamId), IdBound.of(streamId)).get();
    +     * Map result = client.xrange("key", IdBound.of(streamId), IdBound.of(streamId)).get();
          * System.out.println("Stream ID: " + streamid + " -> " + Arrays.toString(result.get(streamid)));
          * }
    */ @@ -222,16 +221,15 @@ CompletableFuture>> xread( * * * @param count Maximum count of stream entries to return. - * @return A Map of key to stream entry data, where entry data is an array of item - * pairings. + * @return A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...] * @example *
    {@code
          * // Retrieve the first 2 stream entries
    -     * Map result = client.xrange("key", InfRangeBound.MIN, InfRangeBound.MAX, 2).get();
    +     * Map result = client.xrange("key", InfRangeBound.MIN, InfRangeBound.MAX, 2).get();
          * result.forEach((k, v) -> {
          *     System.out.println("Stream ID: " + k);
    -     *     for (int i = 0; i < v.length;) {
    -     *         System.out.println(v[i++] + ": " + v[i++]);
    +     *     for (int i = 0; i < v.length; i++) {
    +     *         System.out.println(v[i][0] + ": " + v[i][1]);
          *     }
          * });
          * }
    @@ -259,20 +257,19 @@ CompletableFuture> xrange( *
  • Use {@link InfRangeBound#MIN} to start with the minimum available ID. * * - * @return A Map of key to stream entry data, where entry data is an array of item - * pairings. + * @return A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...] * @example *
    {@code
          * // Retrieve all stream entries
    -     * Map result = client.xrevrange("key", InfRangeBound.MAX, InfRangeBound.MIN).get();
    +     * Map result = client.xrevrange("key", InfRangeBound.MAX, InfRangeBound.MIN).get();
          * result.forEach((k, v) -> {
          *     System.out.println("Stream ID: " + k);
    -     *     for (int i = 0; i < v.length;) {
    -     *         System.out.println(v[i++] + ": " + v[i++]);
    +     *     for (int i = 0; i < v.length; i++) {
    +     *         System.out.println(v[i][0] + ": " + v[i][1]);
          *     }
          * });
          * // Retrieve exactly one stream entry by id
    -     * Map result = client.xrevrange("key", IdBound.of(streamId), IdBound.of(streamId)).get();
    +     * Map result = client.xrevrange("key", IdBound.of(streamId), IdBound.of(streamId)).get();
          * System.out.println("Stream ID: " + streamid + " -> " + Arrays.toString(result.get(streamid)));
          * }
    */ @@ -300,16 +297,15 @@ CompletableFuture> xrevrange( * * * @param count Maximum count of stream entries to return. - * @return A Map of key to stream entry data, where entry data is an array of item - * pairings. + * @return A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...] * @example *
    {@code
          * // Retrieve the first 2 stream entries
    -     * Map result = client.xrange("key", InfRangeBound.MAX, InfRangeBound.MIN, 2).get();
    +     * Map result = client.xrange("key", InfRangeBound.MAX, InfRangeBound.MIN, 2).get();
          * result.forEach((k, v) -> {
          *     System.out.println("Stream ID: " + k);
    -     *     for (int i = 0; i < v.length;) {
    -     *         System.out.println(v[i++] + ": " + v[i++]);
    +     *     for (int i = 0; i < v.length; i++) {
    +     *         System.out.println(v[i][0] + ": " + v[i][1]);
          *     }
          * });
          * }
    diff --git a/java/client/src/test/java/glide/api/RedisClientTest.java b/java/client/src/test/java/glide/api/RedisClientTest.java index 64f4d57a12..825290341f 100644 --- a/java/client/src/test/java/glide/api/RedisClientTest.java +++ b/java/client/src/test/java/glide/api/RedisClientTest.java @@ -4121,20 +4121,20 @@ public void xrange_returns_success() { String key = "testKey"; StreamRange start = IdBound.of(9999L); StreamRange end = IdBound.ofExclusive("696969-10"); - Map completedResult = - Map.of(key, new String[] {"duration", "12345", "event-id", "2", "user-id", "42"}); + String[][] fieldValuesResult = {{"duration", "12345"}, {"event-id", "2"}, {"user-id", "42"}}; + Map completedResult = Map.of(key, fieldValuesResult); - CompletableFuture> testResponse = new CompletableFuture<>(); + CompletableFuture> testResponse = new CompletableFuture<>(); testResponse.complete(completedResult); // match on protobuf request - when(commandManager.>submitNewCommand( + when(commandManager.>submitNewCommand( eq(XRange), eq(new String[] {key, "9999", "(696969-10"}), any())) .thenReturn(testResponse); // exercise - CompletableFuture> response = service.xrange(key, start, end); - Map payload = response.get(); + CompletableFuture> response = service.xrange(key, start, end); + Map payload = response.get(); // verify assertEquals(testResponse, response); @@ -4149,14 +4149,14 @@ public void xrange_withcount_returns_success() { StreamRange start = InfRangeBound.MIN; StreamRange end = InfRangeBound.MAX; long count = 99L; - Map completedResult = - Map.of(key, new String[] {"duration", "12345", "event-id", "2", "user-id", "42"}); + String[][] fieldValuesResult = {{"duration", "12345"}, {"event-id", "2"}, {"user-id", "42"}}; + Map completedResult = Map.of(key, fieldValuesResult); - CompletableFuture> testResponse = new CompletableFuture<>(); + CompletableFuture> testResponse = new CompletableFuture<>(); testResponse.complete(completedResult); // match on protobuf request - when(commandManager.>submitNewCommand( + when(commandManager.>submitNewCommand( eq(XRange), eq( new String[] { @@ -4170,8 +4170,8 @@ public void xrange_withcount_returns_success() { .thenReturn(testResponse); // exercise - CompletableFuture> response = service.xrange(key, start, end, count); - Map payload = response.get(); + CompletableFuture> response = service.xrange(key, start, end, count); + Map payload = response.get(); // verify assertEquals(testResponse, response); @@ -4185,20 +4185,20 @@ public void xrevrange_returns_success() { String key = "testKey"; StreamRange end = IdBound.of(9999L); StreamRange start = IdBound.ofExclusive("696969-10"); - Map completedResult = - Map.of(key, new String[] {"duration", "12345", "event-id", "2", "user-id", "42"}); + String[][] fieldValuesResult = {{"duration", "12345"}, {"event-id", "2"}, {"user-id", "42"}}; + Map completedResult = Map.of(key, fieldValuesResult); - CompletableFuture> testResponse = new CompletableFuture<>(); + CompletableFuture> testResponse = new CompletableFuture<>(); testResponse.complete(completedResult); // match on protobuf request - when(commandManager.>submitNewCommand( + when(commandManager.>submitNewCommand( eq(XRevRange), eq(new String[] {key, "9999", "(696969-10"}), any())) .thenReturn(testResponse); // exercise - CompletableFuture> response = service.xrevrange(key, end, start); - Map payload = response.get(); + CompletableFuture> response = service.xrevrange(key, end, start); + Map payload = response.get(); // verify assertEquals(testResponse, response); @@ -4213,14 +4213,14 @@ public void xrevrange_withcount_returns_success() { StreamRange end = InfRangeBound.MAX; StreamRange start = InfRangeBound.MIN; long count = 99L; - Map completedResult = - Map.of(key, new String[] {"duration", "12345", "event-id", "2", "user-id", "42"}); + String[][] fieldValuesResult = {{"duration", "12345"}, {"event-id", "2"}, {"user-id", "42"}}; + Map completedResult = Map.of(key, fieldValuesResult); - CompletableFuture> testResponse = new CompletableFuture<>(); + CompletableFuture> testResponse = new CompletableFuture<>(); testResponse.complete(completedResult); // match on protobuf request - when(commandManager.>submitNewCommand( + when(commandManager.>submitNewCommand( eq(XRevRange), eq( new String[] { @@ -4234,8 +4234,8 @@ public void xrevrange_withcount_returns_success() { .thenReturn(testResponse); // exercise - CompletableFuture> response = service.xrevrange(key, end, start, count); - Map payload = response.get(); + CompletableFuture> response = service.xrevrange(key, end, start, count); + Map payload = response.get(); // verify assertEquals(testResponse, response); From 0d79cb92b6a8f7c803c6933b0ba1313633f9a638 Mon Sep 17 00:00:00 2001 From: Andrew Carbonetto Date: Mon, 10 Jun 2024 18:51:10 -0700 Subject: [PATCH 4/7] Update XRANGE XREVRANGE it tests Signed-off-by: Andrew Carbonetto --- .../src/test/java/glide/SharedCommandTests.java | 16 ++++++++-------- .../java/glide/TransactionTestUtilities.java | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/java/integTest/src/test/java/glide/SharedCommandTests.java b/java/integTest/src/test/java/glide/SharedCommandTests.java index 1a0cd3e331..90c874351a 100644 --- a/java/integTest/src/test/java/glide/SharedCommandTests.java +++ b/java/integTest/src/test/java/glide/SharedCommandTests.java @@ -3210,25 +3210,25 @@ public void xrange_and_xrevrange(BaseClient client) { assertEquals(2L, client.xlen(key).get()); // get everything from the stream - Map result = client.xrange(key, InfRangeBound.MIN, InfRangeBound.MAX).get(); + Map result = client.xrange(key, InfRangeBound.MIN, InfRangeBound.MAX).get(); assertEquals(2, result.size()); assertNotNull(result.get(streamId1)); assertNotNull(result.get(streamId2)); // get everything from the stream using a reverse range search - Map revResult = + Map revResult = client.xrevrange(key, InfRangeBound.MAX, InfRangeBound.MIN).get(); assertEquals(2, revResult.size()); assertNotNull(revResult.get(streamId1)); assertNotNull(revResult.get(streamId2)); // returns empty if + before - - Map emptyResult = + Map emptyResult = client.xrange(key, InfRangeBound.MAX, InfRangeBound.MIN).get(); assertEquals(0, emptyResult.size()); // rev search returns empty if - before + - Map emptyRevResult = + Map emptyRevResult = client.xrevrange(key, InfRangeBound.MIN, InfRangeBound.MAX).get(); assertEquals(0, emptyRevResult.size()); @@ -3242,23 +3242,23 @@ public void xrange_and_xrevrange(BaseClient client) { .get()); // get the newest entry - Map newResult = + Map newResult = client.xrange(key, IdBound.ofExclusive(streamId2), IdBound.ofExclusive(5), 1L).get(); assertEquals(1, newResult.size()); assertNotNull(newResult.get(streamId3)); // ...and from xrevrange - Map newRevResult = + Map newRevResult = client.xrevrange(key, IdBound.ofExclusive(5), IdBound.ofExclusive(streamId2), 1L).get(); assertEquals(1, newRevResult.size()); assertNotNull(newRevResult.get(streamId3)); // xrange against an emptied stream assertEquals(3, client.xdel(key, new String[] {streamId1, streamId2, streamId3}).get()); - Map emptiedResult = + Map emptiedResult = client.xrange(key, InfRangeBound.MIN, InfRangeBound.MAX, 10L).get(); assertEquals(0, emptiedResult.size()); // ...and xrevrange - Map emptiedRevResult = + Map emptiedRevResult = client.xrevrange(key, InfRangeBound.MAX, InfRangeBound.MIN, 10L).get(); assertEquals(0, emptiedRevResult.size()); diff --git a/java/integTest/src/test/java/glide/TransactionTestUtilities.java b/java/integTest/src/test/java/glide/TransactionTestUtilities.java index a99111e753..e468ae86e9 100644 --- a/java/integTest/src/test/java/glide/TransactionTestUtilities.java +++ b/java/integTest/src/test/java/glide/TransactionTestUtilities.java @@ -681,10 +681,10 @@ private static Object[] streamCommands(BaseTransaction transaction) { Map.of( streamKey1, Map.of("0-3", new String[][] {{"field3", "value3"}})), // xread(Map.of(key9, "0-2")); - Map.of("0-1", new String[] {"field1", "value1"}), // .xrange(streamKey1, "0-1", "0-1") - Map.of("0-1", new String[] {"field1", "value1"}), // .xrange(streamKey1, "0-1", "0-1", 1l) - Map.of("0-1", new String[] {"field1", "value1"}), // .xrevrange(streamKey1, "0-1", "0-1") - Map.of("0-1", new String[] {"field1", "value1"}), // .xrevrange(streamKey1, "0-1", "0-1", 1l) + Map.of("0-1", new String[][] {{"field1", "value1"}}), // .xrange(streamKey1, "0-1", "0-1") + Map.of("0-1", new String[][] {{"field1", "value1"}}), // .xrange(streamKey1, "0-1", "0-1", 1l) + Map.of("0-1", new String[][] {{"field1", "value1"}}), // .xrevrange(streamKey1, "0-1", "0-1") + Map.of("0-1", new String[][] {{"field1", "value1"}}), // .xrevrange(streamKey1, "0-1", "0-1", 1l) 1L, // xtrim(streamKey1, new MinId(true, "0-2")) 1L, // .xdel(streamKey1, new String[] {"0-1", "0-5"}); }; From 25b1c1f17d242f687060e434285b21899776e7ce Mon Sep 17 00:00:00 2001 From: Andrew Carbonetto Date: Tue, 11 Jun 2024 09:13:01 -0700 Subject: [PATCH 5/7] SPOTLESS Signed-off-by: Andrew Carbonetto --- .../src/test/java/glide/TransactionTestUtilities.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/integTest/src/test/java/glide/TransactionTestUtilities.java b/java/integTest/src/test/java/glide/TransactionTestUtilities.java index e468ae86e9..51d5037ae3 100644 --- a/java/integTest/src/test/java/glide/TransactionTestUtilities.java +++ b/java/integTest/src/test/java/glide/TransactionTestUtilities.java @@ -684,7 +684,8 @@ private static Object[] streamCommands(BaseTransaction transaction) { Map.of("0-1", new String[][] {{"field1", "value1"}}), // .xrange(streamKey1, "0-1", "0-1") Map.of("0-1", new String[][] {{"field1", "value1"}}), // .xrange(streamKey1, "0-1", "0-1", 1l) Map.of("0-1", new String[][] {{"field1", "value1"}}), // .xrevrange(streamKey1, "0-1", "0-1") - Map.of("0-1", new String[][] {{"field1", "value1"}}), // .xrevrange(streamKey1, "0-1", "0-1", 1l) + Map.of( + "0-1", new String[][] {{"field1", "value1"}}), // .xrevrange(streamKey1, "0-1", "0-1", 1l) 1L, // xtrim(streamKey1, new MinId(true, "0-2")) 1L, // .xdel(streamKey1, new String[] {"0-1", "0-5"}); }; From 5ba5bde659f15bef64d7f035312744b838d03124 Mon Sep 17 00:00:00 2001 From: Andrew Carbonetto Date: Tue, 11 Jun 2024 09:16:02 -0700 Subject: [PATCH 6/7] Update return Signed-off-by: Andrew Carbonetto --- .../java/glide/api/commands/StreamBaseCommands.java | 8 ++++---- .../main/java/glide/api/models/BaseTransaction.java | 12 ++++-------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java b/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java index 906979269b..dbe98bc6b3 100644 --- a/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java +++ b/java/client/src/main/java/glide/api/commands/StreamBaseCommands.java @@ -184,7 +184,7 @@ CompletableFuture>> xread( *
  • Use {@link InfRangeBound#MAX} to end with the maximum available ID. * * - * @return A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...] + * @return A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...]. * @example *
    {@code
          * // Retrieve all stream entries
    @@ -221,7 +221,7 @@ CompletableFuture>> xread(
          *     
          *
          * @param count Maximum count of stream entries to return.
    -     * @return A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...]
    +     * @return A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...].
          * @example
          *     
    {@code
          * // Retrieve the first 2 stream entries
    @@ -257,7 +257,7 @@ CompletableFuture> xrange(
          *       
  • Use {@link InfRangeBound#MIN} to start with the minimum available ID. * * - * @return A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...] + * @return A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...]. * @example *
    {@code
          * // Retrieve all stream entries
    @@ -297,7 +297,7 @@ CompletableFuture> xrevrange(
          *     
          *
          * @param count Maximum count of stream entries to return.
    -     * @return A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...]
    +     * @return A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...].
          * @example
          *     
    {@code
          * // Retrieve the first 2 stream entries
    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 ea7db24adb..98a89acce9 100644
    --- a/java/client/src/main/java/glide/api/models/BaseTransaction.java
    +++ b/java/client/src/main/java/glide/api/models/BaseTransaction.java
    @@ -2743,8 +2743,7 @@ public T xdel(@NonNull String key, @NonNull String[] ids) {
          *       
  • Use {@link StreamRange.InfRangeBound#MAX} to end with the maximum available ID. * * - * @return Command Response - A Map of key to stream entry data, where entry data is - * an array of item pairings. + * @return Command Response - A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...]. */ public T xrange(@NonNull String key, @NonNull StreamRange start, @NonNull StreamRange end) { ArgsArray commandArgs = buildArgs(ArrayUtils.addFirst(StreamRange.toArgs(start, end), key)); @@ -2773,8 +2772,7 @@ public T xrange(@NonNull String key, @NonNull StreamRange start, @NonNull Stream * * * @param count Maximum count of stream entries to return. - * @return Command Response - A Map of key to stream entry data, where entry data is - * an array of item pairings. + * @return Command Response - A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...]. */ public T xrange( @NonNull String key, @NonNull StreamRange start, @NonNull StreamRange end, long count) { @@ -2806,8 +2804,7 @@ public T xrange( *
  • Use {@link StreamRange.InfRangeBound#MIN} to start with the minimum available ID. * * - * @return Command Response - A Map of key to stream entry data, where entry data is - * an array of item pairings. + * @return Command Response - A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...]. */ public T xrevrange(@NonNull String key, @NonNull StreamRange end, @NonNull StreamRange start) { ArgsArray commandArgs = buildArgs(ArrayUtils.addFirst(StreamRange.toArgs(end, start), key)); @@ -2838,8 +2835,7 @@ public T xrevrange(@NonNull String key, @NonNull StreamRange end, @NonNull Strea * * * @param count Maximum count of stream entries to return. - * @return Command Response - A Map of key to stream entry data, where entry data is - * an array of item pairings. + * @return Command Response - A Map of key to stream entry data, where entry data is an array of pairings with format [[field, entry], [field, entry], ...]. */ public T xrevrange( @NonNull String key, @NonNull StreamRange end, @NonNull StreamRange start, long count) { From f542d4720cd3de19f6810113742986f5636c42c4 Mon Sep 17 00:00:00 2001 From: Andrew Carbonetto Date: Tue, 11 Jun 2024 09:19:24 -0700 Subject: [PATCH 7/7] cargo fmt Signed-off-by: Andrew Carbonetto --- glide-core/src/client/value_conversion.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/glide-core/src/client/value_conversion.rs b/glide-core/src/client/value_conversion.rs index f63fe54774..22bd4f7c46 100644 --- a/glide-core/src/client/value_conversion.rs +++ b/glide-core/src/client/value_conversion.rs @@ -683,12 +683,10 @@ pub(crate) fn expected_type_for_cmd(cmd: &Cmd) -> Option { // TODO use enum to avoid mistakes match command.as_slice() { - b"HGETALL" | b"CONFIG GET" | b"FT.CONFIG GET" | b"HELLO" => { - Some(ExpectedReturnType::Map { - key_type: &None, - value_type: &None, - }) - } + b"HGETALL" | b"CONFIG GET" | b"FT.CONFIG GET" | b"HELLO" => Some(ExpectedReturnType::Map { + key_type: &None, + value_type: &None, + }), b"XRANGE" | b"XREVRANGE" => Some(ExpectedReturnType::Map { key_type: &Some(ExpectedReturnType::BulkString), value_type: &Some(ExpectedReturnType::ArrayOfPairs),