Skip to content

Commit

Permalink
Java: Added Decr and DecrBy to BaseClient and BaseTransaction. (Strin…
Browse files Browse the repository at this point in the history
…g Commands) (valkey-io#957)

* Added Decr and DecrBy to BaseClient and BaseTransaction.(String Commands) (#80)

* Minor fix for documentation.

* Added Transaction Unit Tests.

* Minor documentation refactor

* Removed the message of error in documentation for Decr commands and Added transaction tests.
  • Loading branch information
SanHalacogluImproving authored Feb 20, 2024
1 parent 5ca94f7 commit cda685a
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 8 deletions.
13 changes: 13 additions & 0 deletions java/client/src/main/java/glide/api/BaseClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import static glide.ffi.resolvers.SocketListenerResolver.getSocket;
import static glide.utils.ArrayTransformUtils.castArray;
import static glide.utils.ArrayTransformUtils.convertMapToArgArray;
import static redis_request.RedisRequestOuterClass.RequestType.Decr;
import static redis_request.RedisRequestOuterClass.RequestType.DecrBy;
import static redis_request.RedisRequestOuterClass.RequestType.GetString;
import static redis_request.RedisRequestOuterClass.RequestType.Incr;
import static redis_request.RedisRequestOuterClass.RequestType.IncrBy;
Expand Down Expand Up @@ -248,6 +250,17 @@ public CompletableFuture<Double> incrByFloat(@NonNull String key, double amount)
IncrByFloat, new String[] {key, Double.toString(amount)}, this::handleDoubleResponse);
}

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

@Override
public CompletableFuture<Long> decrBy(@NonNull String key, long amount) {
return commandManager.submitNewCommand(
DecrBy, new String[] {key, Long.toString(amount)}, this::handleLongResponse);
}

@Override
public CompletableFuture<Long> sadd(String key, String[] members) {
String[] arguments = ArrayUtils.addFirst(members, key);
Expand Down
21 changes: 21 additions & 0 deletions java/client/src/main/java/glide/api/commands/StringCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,25 @@ public interface StringCommands {
* @return The value of <code>key</code> after the increment.
*/
CompletableFuture<Double> incrByFloat(String key, double amount);

/**
* Decrement 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/decr/">redis.io</a> for details.
* @param key The key to decrement its value.
* @return The value of <code>key</code> after the decrement.
*/
CompletableFuture<Long> decr(String key);

/**
* Decrement 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.
*
* @see <a href="https://redis.io/commands/decrby/">redis.io</a> for details.
* @param key The key to decrement its value.
* @param amount The amount to decrement.
* @return The value of <code>key</code> after the decrement.
*/
CompletableFuture<Long> decrBy(String key, long amount);
}
33 changes: 33 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 @@ -3,6 +3,8 @@

import static glide.utils.ArrayTransformUtils.convertMapToArgArray;
import static redis_request.RedisRequestOuterClass.RequestType.CustomCommand;
import static redis_request.RedisRequestOuterClass.RequestType.Decr;
import static redis_request.RedisRequestOuterClass.RequestType.DecrBy;
import static redis_request.RedisRequestOuterClass.RequestType.GetString;
import static redis_request.RedisRequestOuterClass.RequestType.Incr;
import static redis_request.RedisRequestOuterClass.RequestType.IncrBy;
Expand Down Expand Up @@ -257,6 +259,37 @@ public T incrByFloat(@NonNull String key, double amount) {
return getThis();
}

/**
* Decrement 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/decr/">redis.io</a> for details.
* @param key The key to decrement its value.
* @return Command Response - The value of <code>key</code> after the decrement.
*/
public T decr(@NonNull String key) {
ArgsArray commandArgs = buildArgs(key);

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

/**
* Decrement 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.
*
* @see <a href="https://redis.io/commands/decrby/">redis.io</a> for details.
* @param key The key to decrement its value.
* @param amount The amount to decrement.
* @return Command Response - The value of <code>key</code> after the decrement.
*/
public T decrBy(@NonNull String key, long amount) {
ArgsArray commandArgs = buildArgs(key, Long.toString(amount));

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

/**
* Add specified members to the set stored at <code>key</code>. Specified members that are already
* a member of this set are ignored.
Expand Down
50 changes: 50 additions & 0 deletions java/client/src/test/java/glide/api/RedisClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static redis_request.RedisRequestOuterClass.RequestType.CustomCommand;
import static redis_request.RedisRequestOuterClass.RequestType.Decr;
import static redis_request.RedisRequestOuterClass.RequestType.DecrBy;
import static redis_request.RedisRequestOuterClass.RequestType.GetString;
import static redis_request.RedisRequestOuterClass.RequestType.Incr;
import static redis_request.RedisRequestOuterClass.RequestType.IncrBy;
Expand Down Expand Up @@ -403,6 +405,54 @@ public void incrByFloat_returns_success() {
assertEquals(value, payload);
}

@SneakyThrows
@Test
public void decr_returns_success() {
// setup
String key = "testKey";
Long value = 10L;

CompletableFuture testResponse = mock(CompletableFuture.class);
when(testResponse.get()).thenReturn(value);

// match on protobuf request
when(commandManager.<String>submitNewCommand(eq(Decr), eq(new String[] {key}), any()))
.thenReturn(testResponse);

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

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

@SneakyThrows
@Test
public void decrBy_returns_success() {
// setup
String key = "testKey";
long amount = 1L;
Long value = 10L;

CompletableFuture testResponse = mock(CompletableFuture.class);
when(testResponse.get()).thenReturn(value);

// match on protobuf request
when(commandManager.<String>submitNewCommand(
eq(DecrBy), eq(new String[] {key, Long.toString(amount)}), any()))
.thenReturn(testResponse);

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

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

@SneakyThrows
@Test
public void sadd_returns_success() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import static glide.api.models.commands.SetOptions.RETURN_OLD_VALUE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static redis_request.RedisRequestOuterClass.RequestType.Decr;
import static redis_request.RedisRequestOuterClass.RequestType.DecrBy;
import static redis_request.RedisRequestOuterClass.RequestType.GetString;
import static redis_request.RedisRequestOuterClass.RequestType.Incr;
import static redis_request.RedisRequestOuterClass.RequestType.IncrBy;
Expand Down Expand Up @@ -58,12 +60,6 @@ public void transaction_builds_protobuf_request() {
transaction.ping("KING PONG");
results.add(Pair.of(Ping, ArgsArray.newBuilder().addArgs("KING PONG").build()));

transaction.mset(Map.of("key", "value"));
results.add(Pair.of(MSet, ArgsArray.newBuilder().addArgs("key").addArgs("value").build()));

transaction.mget(new String[] {"key"});
results.add(Pair.of(MGet, ArgsArray.newBuilder().addArgs("key").build()));

transaction.info();
results.add(Pair.of(Info, ArgsArray.newBuilder().build()));

Expand All @@ -73,6 +69,12 @@ public void transaction_builds_protobuf_request() {
Info,
ArgsArray.newBuilder().addArgs(InfoOptions.Section.EVERYTHING.toString()).build()));

transaction.mset(Map.of("key", "value"));
results.add(Pair.of(MSet, ArgsArray.newBuilder().addArgs("key").addArgs("value").build()));

transaction.mget(new String[] {"key"});
results.add(Pair.of(MGet, ArgsArray.newBuilder().addArgs("key").build()));

transaction.incr("key");
results.add(Pair.of(Incr, ArgsArray.newBuilder().addArgs("key").build()));

Expand All @@ -82,6 +84,12 @@ public void transaction_builds_protobuf_request() {
transaction.incrByFloat("key", 2.5);
results.add(Pair.of(IncrByFloat, ArgsArray.newBuilder().addArgs("key").addArgs("2.5").build()));

transaction.decr("key");
results.add(Pair.of(Decr, ArgsArray.newBuilder().addArgs("key").build()));

transaction.decrBy("key", 2);
results.add(Pair.of(DecrBy, ArgsArray.newBuilder().addArgs("key").addArgs("2").build()));

transaction.sadd("key", new String[] {"value"});
results.add(Pair.of(SAdd, ArgsArray.newBuilder().addArgs("key").addArgs("value").build()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import static glide.api.models.commands.SetOptions.RETURN_OLD_VALUE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static redis_request.RedisRequestOuterClass.RequestType.Decr;
import static redis_request.RedisRequestOuterClass.RequestType.DecrBy;
import static redis_request.RedisRequestOuterClass.RequestType.GetString;
import static redis_request.RedisRequestOuterClass.RequestType.Incr;
import static redis_request.RedisRequestOuterClass.RequestType.IncrBy;
Expand Down Expand Up @@ -81,6 +83,12 @@ public void transaction_builds_protobuf_request() {
transaction.incrByFloat("key", 2.5);
results.add(Pair.of(IncrByFloat, ArgsArray.newBuilder().addArgs("key").addArgs("2.5").build()));

transaction.decr("key");
results.add(Pair.of(Decr, ArgsArray.newBuilder().addArgs("key").build()));

transaction.decrBy("key", 2);
results.add(Pair.of(DecrBy, ArgsArray.newBuilder().addArgs("key").addArgs("2").build()));

transaction.sadd("key", new String[] {"value"});
results.add(Pair.of(SAdd, ArgsArray.newBuilder().addArgs("key").addArgs("value").build()));

Expand Down
32 changes: 32 additions & 0 deletions java/integTest/src/test/java/glide/SharedCommandTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import static glide.api.models.commands.SetOptions.ConditionalSet.ONLY_IF_DOES_NOT_EXIST;
import static glide.api.models.commands.SetOptions.ConditionalSet.ONLY_IF_EXISTS;
import static glide.api.models.commands.SetOptions.Expiry.Milliseconds;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
Expand Down Expand Up @@ -331,6 +332,37 @@ public void test_incr_commands_type_error(BaseClient client) {
assertTrue(incrByFloatException.getCause() instanceof RequestException);
}

@SneakyThrows
@ParameterizedTest
@MethodSource("getClients")
public void decr_and_decrBy_existing_key(BaseClient client) {
String key = UUID.randomUUID().toString();

assertEquals(OK, client.set(key, "10").get());

assertEquals(9, client.decr(key).get());
assertEquals("9", client.get(key).get());

assertEquals(5, client.decrBy(key, 4).get());
assertEquals("5", client.get(key).get());
}

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

assertNull(client.get(key1).get());
assertEquals(-1, client.decr(key1).get());
assertEquals("-1", client.get(key1).get());

assertNull(client.get(key2).get(10, SECONDS));
assertEquals(-3, client.decrBy(key2, 3).get());
assertEquals("-3", client.get(key2).get());
}

@SneakyThrows
@ParameterizedTest
@MethodSource("getClients")
Expand Down
10 changes: 8 additions & 2 deletions java/integTest/src/test/java/glide/TestUtilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ public static BaseTransaction transactionTest(BaseTransaction baseTransaction) {

baseTransaction.incr(key3);
baseTransaction.incrBy(key3, 2);
baseTransaction.incrByFloat(key3, 1.5);

baseTransaction.decr(key3);
baseTransaction.decrBy(key3, 2);

baseTransaction.incrByFloat(key3, 0.5);

baseTransaction.sadd(key4, new String[] {"baz", "foo"});
baseTransaction.srem(key4, new String[] {"foo"});
Expand All @@ -48,7 +52,9 @@ public static Object[] transactionTestResult() {
new String[] {value2, value1},
1L,
3L,
4.5,
2L,
0L,
0.5,
2L,
1L,
1L,
Expand Down

0 comments on commit cda685a

Please sign in to comment.