Skip to content

Commit

Permalink
Java: Add HSTRLEN command. (#1463)
Browse files Browse the repository at this point in the history
* Java: Add `HSTRLEN` command. (#298)

* Add `HSTRLEN` command.

Signed-off-by: Yury-Fridlyand <[email protected]>

* Update for review comments

Signed-off-by: Andrew Carbonetto <[email protected]>

---------

Signed-off-by: Yury-Fridlyand <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
Co-authored-by: Andrew Carbonetto <[email protected]>
  • Loading branch information
Yury-Fridlyand and acarbonetto authored May 24, 2024
1 parent d880b87 commit 04cdbe3
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 3 deletions.
1 change: 1 addition & 0 deletions glide-core/src/protobuf/redis_request.proto
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ enum RequestType {
ZInter = 146;
BitPos = 147;
BitOp = 148;
HStrlen = 149;
FunctionLoad = 150;
LMPop = 155;
}
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 @@ -158,6 +158,7 @@ pub enum RequestType {
ZInter = 146,
BitPos = 147,
BitOp = 148,
HStrlen = 149,
FunctionLoad = 150,
LMPop = 155,
}
Expand Down Expand Up @@ -323,6 +324,7 @@ impl From<::protobuf::EnumOrUnknown<ProtobufRequestType>> for RequestType {
ProtobufRequestType::FunctionLoad => RequestType::FunctionLoad,
ProtobufRequestType::BitPos => RequestType::BitPos,
ProtobufRequestType::BitOp => RequestType::BitOp,
ProtobufRequestType::HStrlen => RequestType::HStrlen,
}
}
}
Expand Down Expand Up @@ -482,6 +484,7 @@ impl RequestType {
RequestType::FunctionLoad => Some(get_two_word_command("FUNCTION", "LOAD")),
RequestType::BitPos => Some(cmd("BITPOS")),
RequestType::BitOp => Some(cmd("BITOP")),
RequestType::HStrlen => Some(cmd("HSTRLEN")),
}
}
}
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 @@ -43,6 +43,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.HRandField;
import static redis_request.RedisRequestOuterClass.RequestType.HSet;
import static redis_request.RedisRequestOuterClass.RequestType.HSetNX;
import static redis_request.RedisRequestOuterClass.RequestType.HStrlen;
import static redis_request.RedisRequestOuterClass.RequestType.HVals;
import static redis_request.RedisRequestOuterClass.RequestType.Incr;
import static redis_request.RedisRequestOuterClass.RequestType.IncrBy;
Expand Down Expand Up @@ -555,6 +556,12 @@ public CompletableFuture<String[]> hkeys(@NonNull String key) {
response -> castArray(handleArrayResponse(response), String.class));
}

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

@Override
public CompletableFuture<String> hrandfield(@NonNull String key) {
return commandManager.submitNewCommand(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ public interface HashBaseCommands {
/**
* Returns all field names in the hash stored at <code>key</code>.
*
* @see <a href="https://valkey.io/commands/hkeys/">redis.io</a> for details
* @see <a href="https://valkey.io/commands/hkeys/">valkey.io</a> for details.
* @param key The key of the hash.
* @return An <code>array</code> of field names in the hash, or an <code>empty array</code> when
* the key does not exist.
Expand All @@ -237,6 +237,23 @@ public interface HashBaseCommands {
*/
CompletableFuture<String[]> hkeys(String key);

/**
* Returns the string length of the value associated with <code>field</code> in the hash stored at
* <code>key</code>.
*
* @see <a href="https://valkey.io/commands/hstrlen/">valkey.io</a> for details.
* @param key The key of the hash.
* @param field The field in the hash.
* @return The string length or <code>0</code> if <code>field</code> or <code>key</code> does not
* exist.
* @example
* <pre>{@code
* Long strlen = client.hstrlen("my_hash", "my_field").get();
* assert strlen >= 0L;
* }</pre>
*/
CompletableFuture<Long> hstrlen(String key, String field);

/**
* Returns a random field name from the hash value stored at <code>key</code>.
*
Expand Down
16 changes: 16 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 @@ -57,6 +57,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.HRandField;
import static redis_request.RedisRequestOuterClass.RequestType.HSet;
import static redis_request.RedisRequestOuterClass.RequestType.HSetNX;
import static redis_request.RedisRequestOuterClass.RequestType.HStrlen;
import static redis_request.RedisRequestOuterClass.RequestType.HVals;
import static redis_request.RedisRequestOuterClass.RequestType.Incr;
import static redis_request.RedisRequestOuterClass.RequestType.IncrBy;
Expand Down Expand Up @@ -715,6 +716,21 @@ public T hkeys(@NonNull String key) {
return getThis();
}

/**
* Returns the string length of the value associated with <code>field</code> in the hash stored at
* <code>key</code>.
*
* @see <a href="https://valkey.io/commands/hstrlen/">valkey.io</a> for details.
* @param key The key of the hash.
* @param field The field in the hash.
* @return Command Response - The string length or <code>0</code> if <code>field</code> or <code>
* key</code> does not exist.
*/
public T hstrlen(@NonNull String key, @NonNull String field) {
protobufTransaction.addCommands(buildCommand(HStrlen, buildArgs(key, field)));
return getThis();
}

/**
* Returns a random field name from the hash value stored at <code>key</code>.
*
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 @@ -78,6 +78,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.HRandField;
import static redis_request.RedisRequestOuterClass.RequestType.HSet;
import static redis_request.RedisRequestOuterClass.RequestType.HSetNX;
import static redis_request.RedisRequestOuterClass.RequestType.HStrlen;
import static redis_request.RedisRequestOuterClass.RequestType.HVals;
import static redis_request.RedisRequestOuterClass.RequestType.Incr;
import static redis_request.RedisRequestOuterClass.RequestType.IncrBy;
Expand Down Expand Up @@ -1429,6 +1430,31 @@ public void hkeys_returns_success() {
assertEquals(values, payload);
}

@SneakyThrows
@Test
public void hstrlen_returns_success() {
// setup
String key = "testKey";
String field = "field";
String[] args = {key, field};
Long value = 42L;

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

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

// exercise
CompletableFuture<Long> response = service.hstrlen(key, field);
Long payload = response.get();

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

@SneakyThrows
@Test
public void hrandfield_returns_success() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.HRandField;
import static redis_request.RedisRequestOuterClass.RequestType.HSet;
import static redis_request.RedisRequestOuterClass.RequestType.HSetNX;
import static redis_request.RedisRequestOuterClass.RequestType.HStrlen;
import static redis_request.RedisRequestOuterClass.RequestType.HVals;
import static redis_request.RedisRequestOuterClass.RequestType.Incr;
import static redis_request.RedisRequestOuterClass.RequestType.IncrBy;
Expand Down Expand Up @@ -295,6 +296,9 @@ public void transaction_builds_protobuf_request(BaseTransaction<?> transaction)
transaction.hkeys("key");
results.add(Pair.of(HKeys, buildArgs("key")));

transaction.hstrlen("key", "field");
results.add(Pair.of(HStrlen, buildArgs("key", "field")));

transaction
.hrandfield("key")
.hrandfieldWithCount("key", 2)
Expand Down
25 changes: 24 additions & 1 deletion java/integTest/src/test/java/glide/SharedCommandTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -775,13 +775,36 @@ public void hkeys(BaseClient client) {

assertEquals(0, client.hkeys(key2).get().length);

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

@SneakyThrows
@ParameterizedTest(autoCloseArguments = false)
@MethodSource("getClients")
public void hstrlen(BaseClient client) {
String key1 = UUID.randomUUID().toString();
String key2 = UUID.randomUUID().toString();

assertEquals(1, client.hset(key1, Map.of("field", "value")).get());
assertEquals(5L, client.hstrlen(key1, "field").get());

// missing value
assertEquals(0, client.hstrlen(key1, "field 2").get());

// missing key
assertEquals(0, client.hstrlen(key2, "field").get());

// Key exists, but it is not a hash
assertEquals(OK, client.set(key2, "value").get());
Exception executionException =
assertThrows(ExecutionException.class, () -> client.hstrlen(key2, "field").get());
assertInstanceOf(RequestException.class, executionException.getCause());
}

@SneakyThrows
@ParameterizedTest(autoCloseArguments = false)
@MethodSource("getClients")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,8 @@ private static Object[] hashCommands(BaseTransaction<?> transaction) {
.hrandfieldWithCountWithValues(hashKey1, -2)
.hincrBy(hashKey1, field3, 5)
.hincrByFloat(hashKey1, field3, 5.5)
.hkeys(hashKey1);
.hkeys(hashKey1)
.hstrlen(hashKey1, field2);

return new Object[] {
2L, // hset(hashKey1, Map.of(field1, value1, field2, value2))
Expand All @@ -236,6 +237,7 @@ private static Object[] hashCommands(BaseTransaction<?> transaction) {
5L, // hincrBy(hashKey1, field3, 5)
10.5, // hincrByFloat(hashKey1, field3, 5.5)
new String[] {field2, field3}, // hkeys(hashKey1)
(long) value2.length(), // hstrlen(hashKey1, field2)
};
}

Expand Down

0 comments on commit 04cdbe3

Please sign in to comment.