Skip to content

Commit

Permalink
Java: Add lindex command. (List Command Group) (valkey-io#1219)
Browse files Browse the repository at this point in the history
* Java: Add lindex command. (List Command Group) (valkey-io#158)

* Minor documentation update + changed param from int to long + minor IT update.
  • Loading branch information
SanHalacogluImproving authored Apr 10, 2024
1 parent d766f51 commit 527e1ec
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 0 deletions.
7 changes: 7 additions & 0 deletions java/client/src/main/java/glide/api/BaseClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.LRange;
import static redis_request.RedisRequestOuterClass.RequestType.LRem;
import static redis_request.RedisRequestOuterClass.RequestType.LTrim;
import static redis_request.RedisRequestOuterClass.RequestType.Lindex;
import static redis_request.RedisRequestOuterClass.RequestType.MGet;
import static redis_request.RedisRequestOuterClass.RequestType.MSet;
import static redis_request.RedisRequestOuterClass.RequestType.PExpire;
Expand Down Expand Up @@ -445,6 +446,12 @@ public CompletableFuture<String[]> lrange(@NonNull String key, long start, long
response -> castArray(handleArrayOrNullResponse(response), String.class));
}

@Override
public CompletableFuture<String> lindex(@NonNull String key, long index) {
return commandManager.submitNewCommand(
Lindex, new String[] {key, Long.toString(index)}, this::handleStringOrNullResponse);
}

@Override
public CompletableFuture<String> ltrim(@NonNull String key, long start, long end) {
return commandManager.submitNewCommand(
Expand Down
24 changes: 24 additions & 0 deletions java/client/src/main/java/glide/api/commands/ListBaseCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,30 @@ public interface ListBaseCommands {
*/
CompletableFuture<String[]> lrange(String key, long start, long end);

/**
* Returns the element at <code>index</code> from the list stored at <code>key</code>.<br>
* The index is zero-based, so <code>0</code> means the first element, <code>1</code> the second
* element and so on. Negative indices can be used to designate elements starting at the tail of
* the list. Here, <code>-1</code> means the last element, <code>-2</code> means the penultimate
* and so forth.
*
* @see <a href="https://redis.io/commands/lindex/">redis.io</a> for details.
* @param key The key of the list.
* @param index The index of the element in the list to retrieve.
* @return The element at <code>index</code> in the list stored at <code>key</code>.<br>
* If <code>index</code> is out of range or if <code>key</code> does not exist, <code>null
* </code> is returned.
* @example
* <pre>{@code
* String payload1 = client.lindex("myList", 0).get();
* assert payload1.equals('value1'); // Returns the first element in the list stored at 'myList'.
*
* String payload2 = client.lindex("myList", -1).get();
* assert payload2.equals('value3'); // Returns the last element in the list stored at 'myList'.
* }</pre>
*/
CompletableFuture<String> lindex(String key, long index);

/**
* Trims an existing list so that it will contain only the specified range of elements specified.
* <br>
Expand Down
23 changes: 23 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 @@ -45,6 +45,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.LRange;
import static redis_request.RedisRequestOuterClass.RequestType.LRem;
import static redis_request.RedisRequestOuterClass.RequestType.LTrim;
import static redis_request.RedisRequestOuterClass.RequestType.Lindex;
import static redis_request.RedisRequestOuterClass.RequestType.MGet;
import static redis_request.RedisRequestOuterClass.RequestType.MSet;
import static redis_request.RedisRequestOuterClass.RequestType.PExpire;
Expand Down Expand Up @@ -677,6 +678,28 @@ public T lrange(@NonNull String key, long start, long end) {
return getThis();
}

/**
* Returns the element at <code>index</code> from the list stored at <code>key</code>.<br>
* The index is zero-based, so <code>0</code> means the first element, <code>1</code> the second
* element and so on. Negative indices can be used to designate elements starting at the tail of
* the list. Here, <code>-1</code> means the last element, <code>-2</code> means the penultimate
* and so forth.
*
* @see <a href="https://redis.io/commands/lindex/">redis.io</a> for details.
* @param key The key of the list.
* @param index The index of the element in the list to retrieve.
* @return Command Response - The element at <code>index</code> in the list stored at <code>key
* </code>.<br>
* If <code>index</code> is out of range or if <code>key</code> does not exist, <code>null
* </code> is returned.
*/
public T lindex(@NonNull String key, long index) {
ArgsArray commandArgs = buildArgs(key, Long.toString(index));

protobufTransaction.addCommands(buildCommand(Lindex, commandArgs));
return getThis();
}

/**
* Trims an existing list so that it will contain only the specified range of elements specified.<br>
* The offsets <code>start</code> and <code>end</code> are zero-based indexes, with <code>0</code> being the
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 @@ -64,6 +64,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.LRange;
import static redis_request.RedisRequestOuterClass.RequestType.LRem;
import static redis_request.RedisRequestOuterClass.RequestType.LTrim;
import static redis_request.RedisRequestOuterClass.RequestType.Lindex;
import static redis_request.RedisRequestOuterClass.RequestType.MGet;
import static redis_request.RedisRequestOuterClass.RequestType.MSet;
import static redis_request.RedisRequestOuterClass.RequestType.PExpire;
Expand Down Expand Up @@ -1348,6 +1349,31 @@ public void lrange_returns_success() {
assertEquals(value, payload);
}

@SneakyThrows
@Test
public void lindex_returns_success() {
// setup
String key = "testKey";
long index = 2;
String[] args = new String[] {key, Long.toString(index)};
String value = "value";

CompletableFuture<String> testResponse = new CompletableFuture<>();
testResponse.complete(value);

// match on protobuf request
when(commandManager.<String>submitNewCommand(eq(Lindex), eq(args), any()))
.thenReturn(testResponse);

// exercise
CompletableFuture<String> response = service.lindex(key, index);
String payload = response.get();

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

@SneakyThrows
@Test
public void ltrim_returns_success() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.LRange;
import static redis_request.RedisRequestOuterClass.RequestType.LRem;
import static redis_request.RedisRequestOuterClass.RequestType.LTrim;
import static redis_request.RedisRequestOuterClass.RequestType.Lindex;
import static redis_request.RedisRequestOuterClass.RequestType.MGet;
import static redis_request.RedisRequestOuterClass.RequestType.MSet;
import static redis_request.RedisRequestOuterClass.RequestType.PExpire;
Expand Down Expand Up @@ -232,6 +233,9 @@ public void transaction_builds_protobuf_request(BaseTransaction<?> transaction)
results.add(
Pair.of(LRange, ArgsArray.newBuilder().addArgs("key").addArgs("1").addArgs("2").build()));

transaction.lindex("key", 1);
results.add(Pair.of(Lindex, ArgsArray.newBuilder().addArgs("key").addArgs("1").build()));

transaction.ltrim("key", 1, 2);
results.add(
Pair.of(LTrim, ArgsArray.newBuilder().addArgs("key").addArgs("1").addArgs("2").build()));
Expand Down
21 changes: 21 additions & 0 deletions java/integTest/src/test/java/glide/SharedCommandTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,27 @@ public void lpush_lpop_lrange_type_error(BaseClient client) {
assertTrue(lrangeException.getCause() instanceof RequestException);
}

@SneakyThrows
@ParameterizedTest
@MethodSource("getClients")
public void lindex(BaseClient client) {
String key1 = UUID.randomUUID().toString();
String key2 = UUID.randomUUID().toString();
String[] valueArray = new String[] {"value1", "value2"};

assertEquals(2, client.lpush(key1, valueArray).get());
assertEquals(valueArray[1], client.lindex(key1, 0).get());
assertEquals(valueArray[0], client.lindex(key1, -1).get());
assertNull(client.lindex(key1, 3).get());
assertNull(client.lindex(key2, 3).get());

// Key exists, but it is not a List
assertEquals(OK, client.set(key2, "value").get());
Exception executionException =
assertThrows(ExecutionException.class, () -> client.lindex(key2, 0).get());
assertTrue(executionException.getCause() instanceof RequestException);
}

@SneakyThrows
@ParameterizedTest
@MethodSource("getClients")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public static BaseTransaction<?> transactionTest(BaseTransaction<?> baseTransact

baseTransaction.lpush(key5, new String[] {value1, value1, value2, value3, value3});
baseTransaction.llen(key5);
baseTransaction.lindex(key5, 0);
baseTransaction.lrem(key5, 1, value1);
baseTransaction.ltrim(key5, 1, -1);
baseTransaction.lrange(key5, 0, -2);
Expand Down Expand Up @@ -172,6 +173,7 @@ public static Object[] transactionTestResult() {
10.5,
5L,
5L,
value3, // lindex(key5, 0)
1L,
OK,
new String[] {value3, value2},
Expand Down

0 comments on commit 527e1ec

Please sign in to comment.