Skip to content

Commit

Permalink
Added Lpush, Lpop, LpopCount, Lrange, Llen, Ltrim and Lrem Commands. …
Browse files Browse the repository at this point in the history
…(List Commands)
  • Loading branch information
SanHalacogluImproving committed Feb 15, 2024
1 parent 98b1ed7 commit 5cc6df4
Show file tree
Hide file tree
Showing 11 changed files with 756 additions and 10 deletions.
67 changes: 66 additions & 1 deletion java/client/src/main/java/glide/api/BaseClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@
package glide.api;

import static glide.ffi.resolvers.SocketListenerResolver.getSocket;
import static glide.utils.CommandUtils.objectArrayToTypedArray;
import static redis_request.RedisRequestOuterClass.RequestType.GetString;
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;
import static redis_request.RedisRequestOuterClass.RequestType.LRem;
import static redis_request.RedisRequestOuterClass.RequestType.LTrim;
import static redis_request.RedisRequestOuterClass.RequestType.Ping;
import static redis_request.RedisRequestOuterClass.RequestType.SetString;

import glide.api.commands.ConnectionManagementCommands;
import glide.api.commands.ListCommands;
import glide.api.commands.StringCommands;
import glide.api.models.commands.SetOptions;
import glide.api.models.configuration.BaseClientConfiguration;
Expand All @@ -32,7 +40,7 @@
/** Base Client class for Redis */
@AllArgsConstructor
public abstract class BaseClient
implements AutoCloseable, ConnectionManagementCommands, StringCommands {
implements AutoCloseable, ConnectionManagementCommands, StringCommands, ListCommands {
/** Redis simple string response with "OK" */
public static final String OK = ConstantResponse.OK.toString();

Expand Down Expand Up @@ -149,7 +157,15 @@ protected String handleStringOrNullResponse(Response response) throws RedisExcep
return handleRedisResponse(String.class, true, response);
}

protected Long handleLongResponse(Response response) throws RedisException {
return handleRedisResponse(Long.class, false, response);
}

protected Object[] handleArrayResponse(Response response) {
return handleRedisResponse(Object[].class, false, response);
}

protected Object[] handleArrayOrNullResponse(Response response) {
return handleRedisResponse(Object[].class, true, response);
}

Expand Down Expand Up @@ -181,4 +197,53 @@ public CompletableFuture<String> set(
String[] arguments = ArrayUtils.addAll(new String[] {key, value}, options.toArgs());
return commandManager.submitNewCommand(SetString, arguments, this::handleStringOrNullResponse);
}

@Override
public CompletableFuture<Long> lpush(@NonNull String key, @NonNull String[] elements) {
String[] arguments = ArrayUtils.addFirst(elements, key);
return commandManager.submitNewCommand(LPush, arguments, this::handleLongResponse);
}

@Override
public CompletableFuture<String> lpop(@NonNull String key) {
return commandManager.submitNewCommand(
LPop, new String[] {key}, this::handleStringOrNullResponse);
}

@Override
public CompletableFuture<String[]> lpopCount(@NonNull String key, long count) {
return commandManager
.submitNewCommand(
LPop, new String[] {key, Long.toString(count)}, this::handleArrayOrNullResponse)
.thenApply(objectArray -> objectArrayToTypedArray(objectArray, String.class));
}

@Override
public CompletableFuture<String[]> lrange(@NonNull String key, long start, long end) {
return commandManager
.submitNewCommand(
LRange,
new String[] {key, Long.toString(start), Long.toString(end)},
this::handleArrayResponse)
.thenApply(objectArray -> objectArrayToTypedArray(objectArray, String.class));
}

@Override
public CompletableFuture<Long> llen(@NonNull String key) {
return commandManager.submitNewCommand(LLen, new String[] {key}, this::handleLongResponse);
}

@Override
public CompletableFuture<String> ltrim(@NonNull String key, long start, long end) {
return commandManager.submitNewCommand(
LTrim,
new String[] {key, Long.toString(start), Long.toString(end)},
this::handleStringResponse);
}

@Override
public CompletableFuture<Long> lrem(@NonNull String key, long count, @NonNull String element) {
return commandManager.submitNewCommand(
LRem, new String[] {key, Long.toString(count), element}, this::handleLongResponse);
}
}
2 changes: 1 addition & 1 deletion java/client/src/main/java/glide/api/RedisClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public CompletableFuture<Object> customCommand(@NonNull String[] args) {

@Override
public CompletableFuture<Object[]> exec(Transaction transaction) {
return commandManager.submitNewCommand(transaction, this::handleArrayResponse);
return commandManager.submitNewCommand(transaction, this::handleArrayOrNullResponse);
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions java/client/src/main/java/glide/api/RedisClusterClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ public CompletableFuture<ClusterValue<Object>> customCommand(
@Override
public CompletableFuture<Object[]> exec(ClusterTransaction transaction) {
return commandManager.submitNewCommand(
transaction, Optional.empty(), this::handleArrayResponse);
transaction, Optional.empty(), this::handleArrayOrNullResponse);
}

@Override
public CompletableFuture<ClusterValue<Object>[]> exec(
ClusterTransaction transaction, Route route) {
return commandManager
.submitNewCommand(transaction, Optional.ofNullable(route), this::handleArrayResponse)
.submitNewCommand(transaction, Optional.ofNullable(route), this::handleArrayOrNullResponse)
.thenApply(
objects ->
Arrays.stream(objects)
Expand Down
124 changes: 124 additions & 0 deletions java/client/src/main/java/glide/api/commands/ListCommands.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/** Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 */
package glide.api.commands;

import java.util.concurrent.CompletableFuture;

/**
* List Commands interface.
*
* @see <a href="https://redis.io/commands/?group=list">List Commands</a>
*/
public interface ListCommands {
/**
* Inserts all the specified values at the head of the list stored at <code>key</code>. <code>
* elements</code> are inserted one after the other to the head of the list, from the leftmost
* element to the rightmost element. If <code>key</code> does not exist, it is created as an empty
* list before performing the push operations.
*
* @see <a href="https://redis.io/commands/lpush/">redis.io</a> for details.
* @param key The key of the list.
* @param elements The elements to insert at the head of the list stored at <code>key</code>.
* @return The length of the list after the push operations.<br>
* If <code>key</code> holds a value that is not a list, an error is raised.<br>
*/
CompletableFuture<Long> lpush(String key, String[] elements);

/**
* Removes and returns the first elements of the list stored at <code>key</code>. The command pops
* a single element from the beginning of the list.
*
* @see <a href="https://redis.io/commands/lpop/">redis.io</a> for details.
* @param key The key of the list.
* @return The value of the first element. <br>
* If <code>key</code> does not exist null will be returned. <br>
* If <code>key</code> holds a value that is not a list, an error is raised. <br>
*/
CompletableFuture<String> lpop(String key);

/**
* Removes and returns up to <code>count</code> elements of the list stored at <code>key</code>,
* depending on the list's length.
*
* @see <a href="https://redis.io/commands/lpop/">redis.io</a> for details.
* @param key The key of the list.
* @param count The count of the elements to pop from the list.
* @return An array of the popped elements will be returned depending on the list's length.<br>
* If <code>key</code> does not exist null will be returned.<br>
* If <code>key</code> holds a value that is not a list, an error is raised.<br>
*/
CompletableFuture<String[]> lpopCount(String key, long count);

/**
* Returns the specified elements of the list stored at <code>key</code>. The offsets <code>start
* </code> and <code>end</code> are zero-based indexes, with 0 being the first element of the
* list, 1 being the next element and so on. These offsets can also be negative numbers indicating
* offsets starting at the end of the list, with -1 being the last element of the list, -2 being
* the penultimate, and so on.
*
* @see <a href="https://redis.io/commands/lrange/">redis.io</a> for details.
* @param key The key of the list.
* @param start The starting point of the range.
* @param end The end of the range.
* @return Array of elements in the specified range.<br>
* If <code>start</code> exceeds the end of the list, or if <code>start</code> is greater than
* <code>end</code>, an empty array will be returned.<br>
* If <code>end</code> exceeds the actual end of the list, the range will stop at the actual
* end of the list.<br>
* If <code>key</code> does not exist an empty array will be returned.<br>
* If <code>key</code> holds a value that is not a list, an error is raised.<br>
*/
CompletableFuture<String[]> lrange(String key, long start, long end);

/**
* Returns the length of the list stored at <code>key</code>.
*
* @see <a href="https://redis.io/commands/llen/">redis.io</a> for details.
* @param key The key of the list.
* @return The length of the list at <code>key</code>. <br>
* If <code>key</code> does not exist, it is interpreted as an empty list and 0 is returned.
* <br>
* If <code>key</code> holds a value that is not a list, an error is raised. <br>
*/
CompletableFuture<Long> llen(String key);

/**
* Trim an existing list so that it will contain only the specified range of elements specified.
* The offsets <code>start</code> and <code>end</code> are zero-based indexes, with 0 being the
* first element of the list, 1 being the next element and so on. These offsets can also be
* negative numbers indicating offsets starting at the end of the list, with -1 being the last
* element of the list, -2 being the penultimate, and so on.
*
* @see <a href="https://redis.io/commands/ltrim/">redis.io</a> for details.
* @param key The key of the list.
* @param start The starting point of the range.
* @param end The end of the range.
* @return Always <code>OK</code>. <br>
* If <code>start</code> exceeds the end of the list, or if <code>start</code> is greater than
* <code>end</code>, the result will be an empty list (which causes key to be removed). <br>
* If <code>end</code> exceeds the actual end of the list, it will be treated like the last
* element of the list. <br>
* If <code>key</code> does not exist the command will be ignored. <br>
* If <code>key</code> holds a value that is not a list, an error is raised. <br>
*/
CompletableFuture<String> ltrim(String key, long start, long end);

/**
* Removes the first <code>count</code> occurrences of elements equal to <code>element</code> from
* the list stored at <code>key</code>.<br>
* If <code>count</code> is positive: Removes elements equal to <code>element</code> moving from
* head to tail.<br>
* If <code>count</code> is negative: Removes elements equal to <code>element</code> moving from
* tail to head.<br>
* If <code>count</code> is 0 or <code>count</code> is greater than the occurrences of elements
* equal to <code>element</code>: Removes all elements equal to <code>element</code>.<br>
*
* @see <a href="https://redis.io/commands/lrem/">redis.io</a> for details.
* @param key The key of the list.
* @param count The count of the occurrences of elements equal to <code>element</code> to remove.
* @param element The element to remove from the list.
* @return The number of the removed elements.<br>
* If <code>key</code> does not exist, 0 is returned.<br>
* If <code>key</code> holds a value that is not a list, an error is raised.<br>
*/
CompletableFuture<Long> lrem(String key, long count, String element);
}
Loading

0 comments on commit 5cc6df4

Please sign in to comment.