Skip to content

Commit

Permalink
Added Decr and DecrBy to BaseClient and BaseTransaction.(String Comma…
Browse files Browse the repository at this point in the history
…nds) (#80)
  • Loading branch information
SanHalacogluImproving committed Feb 16, 2024
1 parent 10cdf60 commit e625fe6
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 0 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 @@ -2,6 +2,8 @@
package glide.api;

import static glide.ffi.resolvers.SocketListenerResolver.getSocket;
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.Ping;
import static redis_request.RedisRequestOuterClass.RequestType.SAdd;
Expand Down Expand Up @@ -196,6 +198,17 @@ public CompletableFuture<String> set(
return commandManager.submitNewCommand(SetString, arguments, this::handleStringOrNullResponse);
}

@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
25 changes: 25 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 @@ -48,4 +48,29 @@ public interface StringCommands {
* is set, return the old value as a <code>String</code>.
*/
CompletableFuture<String> set(String key, String value, SetOptions options);

/**
* Decrements 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. An error is raised if <code>key
* </code> contains a value of the wrong type or contains a string that cannot be represented
* as integer.
*/
CompletableFuture<Long> decr(String key);

/**
* Decrements 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. An error is raised if <code>key
* </code> contains a value of the wrong type or contains a string that cannot be represented
* as integer.
*/
CompletableFuture<Long> decrBy(String key, long amount);
}
38 changes: 38 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 @@ -2,6 +2,8 @@
package glide.api.models;

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.Info;
import static redis_request.RedisRequestOuterClass.RequestType.Ping;
Expand All @@ -17,6 +19,7 @@
import glide.api.models.commands.SetOptions.ConditionalSet;
import glide.api.models.commands.SetOptions.SetOptionsBuilder;
import lombok.Getter;
import lombok.NonNull;
import org.apache.commons.lang3.ArrayUtils;
import redis_request.RedisRequestOuterClass.Command;
import redis_request.RedisRequestOuterClass.Command.ArgsArray;
Expand Down Expand Up @@ -169,6 +172,41 @@ public T set(String key, String value, SetOptions options) {
return getThis();
}

/**
* Decrements 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. An error is raised if <code>key
* </code> contains a value of the wrong type or contains a string that cannot be represented
* as integer.
*/
public T decr(@NonNull String key) {
ArgsArray commandArgs = buildArgs(key);

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

/**
* Decrements 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. An error is raised if <code>key
* </code> contains a value of the wrong type or contains a string that cannot be represented
* as integer.
*/
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 @@ -12,6 +12,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.Info;
import static redis_request.RedisRequestOuterClass.RequestType.Ping;
Expand Down Expand Up @@ -274,6 +276,54 @@ public void info_with_empty_InfoOptions_returns_success() {
assertEquals(testPayload, 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
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.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
Expand Down Expand Up @@ -253,6 +254,37 @@ public void set_missing_value_and_returnOldValue_is_null(BaseClient client) {
assertNull(data);
}

@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

0 comments on commit e625fe6

Please sign in to comment.