Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support hset, hget, lindex, linsert, blmove, incr, hlen and lmove wit… #1667

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions java/client/src/main/java/glide/api/BaseClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import static glide.utils.ArrayTransformUtils.castMapOf2DArray;
import static glide.utils.ArrayTransformUtils.castMapOfArrays;
import static glide.utils.ArrayTransformUtils.concatenateArrays;
import static glide.utils.ArrayTransformUtils.convertMapToKeyValueGlideStringArray;
import static glide.utils.ArrayTransformUtils.convertMapToKeyValueStringArray;
import static glide.utils.ArrayTransformUtils.convertMapToValueKeyStringArray;
import static glide.utils.ArrayTransformUtils.mapGeoDataToArray;
Expand Down Expand Up @@ -693,6 +694,11 @@ public CompletableFuture<Long> incr(@NonNull String key) {
return commandManager.submitNewCommand(Incr, new String[] {key}, this::handleLongResponse);
}

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

@Override
public CompletableFuture<Long> incrBy(@NonNull String key, long amount) {
return commandManager.submitNewCommand(
Expand Down Expand Up @@ -761,13 +767,27 @@ public CompletableFuture<String> hget(@NonNull String key, @NonNull String field
HGet, new String[] {key, field}, this::handleStringOrNullResponse);
}

@Override
public CompletableFuture<GlideString> hget(@NonNull GlideString key, @NonNull GlideString field) {
return commandManager.submitNewCommand(
HGet, new GlideString[] {key, field}, this::handleGlideStringOrNullResponse);
}

@Override
public CompletableFuture<Long> hset(
@NonNull String key, @NonNull Map<String, String> fieldValueMap) {
String[] args = ArrayUtils.addFirst(convertMapToKeyValueStringArray(fieldValueMap), key);
return commandManager.submitNewCommand(HSet, args, this::handleLongResponse);
}

@Override
public CompletableFuture<Long> hset(
@NonNull GlideString key, @NonNull Map<GlideString, GlideString> fieldValueMap) {
GlideString[] args =
ArrayUtils.addFirst(convertMapToKeyValueGlideStringArray(fieldValueMap), key);
return commandManager.submitNewCommand(HSet, args, this::handleLongResponse);
}

@Override
public CompletableFuture<Boolean> hsetnx(
@NonNull String key, @NonNull String field, @NonNull String value) {
Expand All @@ -786,6 +806,11 @@ public CompletableFuture<Long> hlen(@NonNull String key) {
return commandManager.submitNewCommand(HLen, new String[] {key}, this::handleLongResponse);
}

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

@Override
public CompletableFuture<String[]> hvals(@NonNull String key) {
return commandManager.submitNewCommand(
Expand Down Expand Up @@ -967,6 +992,14 @@ public CompletableFuture<String> lindex(@NonNull String key, long index) {
LIndex, new String[] {key, Long.toString(index)}, this::handleStringOrNullResponse);
}

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

@Override
public CompletableFuture<String> ltrim(@NonNull String key, long start, long end) {
return commandManager.submitNewCommand(
Expand Down Expand Up @@ -1950,6 +1983,18 @@ public CompletableFuture<Long> linsert(
LInsert, new String[] {key, position.toString(), pivot, element}, this::handleLongResponse);
}

@Override
public CompletableFuture<Long> linsert(
@NonNull GlideString key,
@NonNull InsertPosition position,
@NonNull GlideString pivot,
@NonNull GlideString element) {
return commandManager.submitNewCommand(
LInsert,
new GlideString[] {key, gs(position.toString()), pivot, element},
this::handleLongResponse);
}

@Override
public CompletableFuture<String[]> blpop(@NonNull String[] keys, double timeout) {
String[] arguments = ArrayUtils.add(keys, Double.toString(timeout));
Expand Down Expand Up @@ -2396,6 +2441,17 @@ public CompletableFuture<String> lmove(
return commandManager.submitNewCommand(LMove, arguments, this::handleStringOrNullResponse);
}

@Override
public CompletableFuture<GlideString> lmove(
@NonNull GlideString source,
@NonNull GlideString destination,
@NonNull ListDirection wherefrom,
@NonNull ListDirection whereto) {
GlideString[] arguments =
new GlideString[] {source, destination, gs(wherefrom.toString()), gs(whereto.toString())};
return commandManager.submitNewCommand(LMove, arguments, this::handleGlideStringOrNullResponse);
}

@Override
public CompletableFuture<String> blmove(
@NonNull String source,
Expand All @@ -2410,6 +2466,25 @@ public CompletableFuture<String> blmove(
return commandManager.submitNewCommand(BLMove, arguments, this::handleStringOrNullResponse);
}

@Override
public CompletableFuture<GlideString> blmove(
@NonNull GlideString source,
@NonNull GlideString destination,
@NonNull ListDirection wherefrom,
@NonNull ListDirection whereto,
double timeout) {
GlideString[] arguments =
new GlideString[] {
source,
destination,
gs(wherefrom.toString()),
gs(whereto.toString()),
gs(Double.toString(timeout))
};
return commandManager.submitNewCommand(
BLMove, arguments, this::handleGlideStringOrNullResponse);
}

@Override
public CompletableFuture<String> srandmember(@NonNull String key) {
String[] arguments = new String[] {key};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,25 @@ public interface HashBaseCommands {
*/
CompletableFuture<String> hget(String key, String field);

/**
* Retrieves the value associated with <code>field</code> in the hash stored at <code>key</code>.
*
* @see <a href="https://redis.io/commands/hget/">redis.io</a> for details.
* @param key The key of the hash.
* @param field The field in the hash stored at <code>key</code> to retrieve from the database.
* @return The value associated with <code>field</code>, or <code>null</code> when <code>field
* </code> is not present in the hash or <code>key</code> does not exist.
* @example
* <pre>{@code
* String payload = client.hget(gs("my_hash"), gs("field1")).get();
* assert payload.equals(gs("value"));
*
* String payload = client.hget(gs("my_hash"), gs("nonexistent_field")).get();
* assert payload.equals(null);
* }</pre>
*/
CompletableFuture<GlideString> hget(GlideString key, GlideString field);

/**
* Sets the specified fields to their respective values in the hash stored at <code>key</code>.
*
Expand All @@ -50,6 +69,22 @@ public interface HashBaseCommands {
*/
CompletableFuture<Long> hset(String key, Map<String, String> fieldValueMap);

/**
* Sets the specified fields to their respective values in the hash stored at <code>key</code>.
*
* @see <a href="https://redis.io/commands/hset/">redis.io</a> for details.
* @param key The key of the hash.
* @param fieldValueMap A field-value map consisting of fields and their corresponding values to
* be set in the hash stored at the specified key.
* @return The number of fields that were added.
* @example
* <pre>{@code
* Long num = client.hset(gs("my_hash"), Map.of(gs("field"), gs("value"), gs("field2"), gs("value2"))).get();
* assert num == 2L;
* }</pre>
*/
CompletableFuture<Long> hset(GlideString key, Map<GlideString, GlideString> fieldValueMap);

/**
* Sets <code>field</code> in the hash stored at <code>key</code> to <code>value</code>, only if
* <code>field</code> does not yet exist.<br>
Expand Down Expand Up @@ -109,6 +144,24 @@ public interface HashBaseCommands {
*/
CompletableFuture<Long> hlen(String key);

/**
* Returns the number of fields contained in the hash stored at <code>key</code>.
*
* @see <a href="https://redis.io/commands/hlen/">redis.io</a> for details.
* @param key The key of the hash.
* @return The number of fields in the hash, or <code>0</code> when the key does not exist.<br>
* If <code>key</code> holds a value that is not a hash, an error is returned.
* @example
* <pre>{@code
* Long num1 = client.hlen(gs("myHash")).get();
* assert num1 == 3L;
*
* Long num2 = client.hlen(gs("nonExistingKey")).get();
* assert num2 == 0L;
* }</pre>
*/
CompletableFuture<Long> hlen(GlideString key);

/**
* Returns all values in the hash stored at <code>key</code>.
*
Expand Down
125 changes: 123 additions & 2 deletions java/client/src/main/java/glide/api/commands/ListBaseCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -243,14 +243,38 @@ CompletableFuture<Long[]> lposCount(
* @example
* <pre>{@code
* String payload1 = client.lindex("myList", 0).get();
* assert payload1.equals('value1'); // Returns the first element in the list stored at 'myList'.
* assert payload1.equals("value1"); // Returns the first element in the list stored at 'myList'.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

*
* String payload2 = client.lindex("myList", -1).get();
* assert payload2.equals('value3'); // Returns the last element in the list stored at 'myList'.
* assert payload2.equals("value3"); // Returns the last element in the list stored at 'myList'.
* }</pre>
*/
CompletableFuture<String> lindex(String key, long index);

/**
* 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(gs("myList"), 0).get();
* assert payload1.equals(gs("value1")); // Returns the first element in the list stored at 'myList'.
*
* String payload2 = client.lindex(gs("myList"), -1).get();
* assert payload2.equals(gs("value3")); // Returns the last element in the list stored at 'myList'.
* }</pre>
*/
CompletableFuture<GlideString> lindex(GlideString key, long index);

/**
* Trims an existing list so that it will contain only the specified range of elements specified.
* <br>
Expand Down Expand Up @@ -486,6 +510,28 @@ CompletableFuture<Long[]> lposCount(
CompletableFuture<Long> linsert(
String key, InsertPosition position, String pivot, String element);

/**
* Inserts <code>element</code> in the list at <code>key</code> either before or after the <code>
* pivot</code>.
*
* @see <a href="https://redis.io/commands/linsert/">redis.io</a> for details.
* @param key The key of the list.
* @param position The relative position to insert into - either {@link InsertPosition#BEFORE} or
* {@link InsertPosition#AFTER} the <code>pivot</code>.
* @param pivot An element of the list.
* @param element The new element to insert.
* @return The list length after a successful insert operation.<br>
* If the <code>key</code> doesn't exist returns <code>-1</code>.<br>
* If the <code>pivot</code> wasn't found, returns <code>0</code>.
* @example
* <pre>{@code
* Long length = client.linsert(gs("my_list"), BEFORE, gs("World"), gs("There")).get();
* assert length > 0L;
* }</pre>
*/
CompletableFuture<Long> linsert(
GlideString key, InsertPosition position, GlideString pivot, GlideString element);

/**
* Pops an element from the head of the first list that is non-empty, with the given <code>keys
* </code> being checked in the order that they are given.<br>
Expand Down Expand Up @@ -772,6 +818,35 @@ CompletableFuture<Map<String, String[]>> blmpop(
CompletableFuture<String> lmove(
String source, String destination, ListDirection wherefrom, ListDirection whereto);

/**
* Atomically pops and removes the left/right-most element to the list stored at <code>source
* </code> depending on <code>wherefrom</code>, and pushes the element at the first/last element
* of the list stored at <code>destination</code> depending on <code>wherefrom</code>.
*
* @since Redis 6.2.0 and above.
* @apiNote When in cluster mode, <code>source</code> and <code>destination</code> must map to the
* same hash slot.
* @see <a href="https://valkey.io/commands/lmove/">valkey.io</a> for details.
* @param source The key to the source list.
* @param destination The key to the destination list.
* @param wherefrom The {@link ListDirection} the element should be removed from.
* @param whereto The {@link ListDirection} the element should be added to.
* @return The popped element or <code>null</code> if <code>source</code> does not exist.
* @example
* <pre>{@code
* client.lpush(gs("testKey1"), new GlideString[] {gs("two"), gs("one")}).get();
* client.lpush(gs("testKey2"), new GlideString[] {gs("four"), gs("three")}).get();
* var result = client.lmove(gs("testKey1"), gs("testKey2"), ListDirection.LEFT, ListDirection.LEFT).get();
* assertEquals(result, gs("one"));
* GlideString[] upratedArray1 = client.lrange(gs("testKey1"), 0, -1).get();
* GlideString[] upratedArray2 = client.lrange(gs("testKey2"), 0, -1).get();
* assertArrayEquals(new GlideString[] {gs("two")}, updatedArray1);
* assertArrayEquals(new GlideString[] {gs("one"), gs("three"), gs("four)"}, updatedArray2);
* }</pre>
*/
CompletableFuture<GlideString> lmove(
GlideString source, GlideString destination, ListDirection wherefrom, ListDirection whereto);

/**
* Blocks the connection until it pops atomically and removes the left/right-most element to the
* list stored at <code>source</code> depending on <code>wherefrom</code>, and pushes the element
Expand Down Expand Up @@ -817,4 +892,50 @@ CompletableFuture<String> blmove(
ListDirection wherefrom,
ListDirection whereto,
double timeout);

/**
* Blocks the connection until it pops atomically and removes the left/right-most element to the
* list stored at <code>source</code> depending on <code>wherefrom</code>, and pushes the element
* at the first/last element of the list stored at <code>destination</code> depending on <code>
* wherefrom</code>.<br>
* <code>BLMove</code> is the blocking variant of {@link #lmove(String, String, ListDirection,
* ListDirection)}.
*
* @since Redis 6.2.0 and above.
* @apiNote
* <ol>
* <li>When in cluster mode, all <code>source</code> and <code>destination</code> must map
* to the same hash slot.
* <li><code>BLMove</code> is a client blocking command, see <a
* href="https://github.com/aws/glide-for-redis/wiki/General-Concepts#blocking-commands">Blocking
* Commands</a> for more details and best practices.
* </ol>
*
* @see <a href="https://valkey.io/commands/blmove/">valkey.io</a> for details.
* @param source The key to the source list.
* @param destination The key to the destination list.
* @param wherefrom The {@link ListDirection} the element should be removed from.
* @param whereto The {@link ListDirection} the element should be added to.
* @param timeout The number of seconds to wait for a blocking operation to complete. A value of
* <code>0</code> will block indefinitely.
* @return The popped element or <code>null</code> if <code>source</code> does not exist or if the
* operation timed-out.
* @example
* <pre>{@code
* client.lpush(gs("testKey1"), new GlideString[] {gs("two"), gs("one")}).get();
* client.lpush(gs("testKey2"), new GlideString[] {gs("four"), gs("three")}).get();
* var result = client.blmove(gs("testKey1"), gs("testKey2"), ListDirection.LEFT, ListDirection.LEFT, 0.1).get();
* assertEquals(result, gs("one"));
* GlideString[] upratedArray1 = client.lrange(gs("testKey1"), 0, -1).get();
* GlideString[] upratedArray2 = client.lrange(gs("testKey2"), 0, -1).get();
* assertArrayEquals(new GlideString[] {gs("two")}, updatedArray1);
* assertArrayEquals(new GlideString[] {gs("one"), gs("three"), gs("four")}, updatedArray2);
* }</pre>
*/
CompletableFuture<GlideString> blmove(
GlideString source,
GlideString destination,
ListDirection wherefrom,
ListDirection whereto,
double timeout);
}
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,21 @@ public interface StringBaseCommands {
*/
CompletableFuture<Long> incr(String key);

/**
* Increments the number stored at <code>key</code> by one. If <code>key</code> does not exist, it
* is set to 0 before performing the operation.
*
* @see <a href="https://redis.io/commands/incr/">redis.io</a> for details.
* @param key The key to increment its value.
* @return The value of <code>key</code> after the increment.
* @example
* <pre>{@code
* Long num = client.incr(gs("key")).get();
* assert num == 5L;
* }</pre>
*/
CompletableFuture<Long> incr(GlideString key);

/**
* Increments the number stored at <code>key</code> by <code>amount</code>. If <code>key</code>
* does not exist, it is set to 0 before performing the operation.
Expand Down
Loading
Loading