diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveNumberCommands.java b/src/main/java/org/springframework/data/redis/connection/ReactiveNumberCommands.java
index a72fb9ee6..a00734041 100644
--- a/src/main/java/org/springframework/data/redis/connection/ReactiveNumberCommands.java
+++ b/src/main/java/org/springframework/data/redis/connection/ReactiveNumberCommands.java
@@ -117,6 +117,7 @@ public interface ReactiveNumberCommands {
* @param value must not be {@literal null}.
* @return
* @see Redis Documentation: INCRBY
+ * @see Redis Documentation: INCRBYFLOAT
*/
default Mono incrBy(ByteBuffer key, T value) {
@@ -132,6 +133,7 @@ public interface ReactiveNumberCommands {
* @param commands must not be {@literal null}.
* @return
* @see Redis Documentation: INCRBY
+ * @see Redis Documentation: INCRBYFLOAT
*/
Flux, T>> incrBy(
Publisher> commands);
diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveNumberCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveNumberCommands.java
index bb011b8c4..29878ffcb 100644
--- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveNumberCommands.java
+++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveNumberCommands.java
@@ -75,7 +75,7 @@ class LettuceReactiveNumberCommands implements ReactiveNumberCommands {
T incrBy = command.getValue();
- Mono extends Number> result = null;
+ Mono extends Number> result;
if (incrBy instanceof Double || incrBy instanceof Float) {
result = cmd.incrbyfloat(command.getKey(), incrBy.doubleValue());
} else {
diff --git a/src/main/java/org/springframework/data/redis/core/BoundValueOperations.java b/src/main/java/org/springframework/data/redis/core/BoundValueOperations.java
index 85895bd5d..207f2bf6f 100644
--- a/src/main/java/org/springframework/data/redis/core/BoundValueOperations.java
+++ b/src/main/java/org/springframework/data/redis/core/BoundValueOperations.java
@@ -87,12 +87,23 @@ public interface BoundValueOperations extends BoundKeyOperations {
@Nullable
V getAndSet(V value);
+ /**
+ * Increment an integer value stored as string value under the bound key by one.
+ *
+ * @param delta
+ * @return {@literal null} when used in pipeline / transaction.
+ * @since 2.1
+ * @see Redis Documentation: INCR
+ */
+ @Nullable
+ Long increment();
+
/**
* Increment an integer value stored as string value under the bound key by {@code delta}.
*
* @param delta
* @return {@literal null} when used in pipeline / transaction.
- * @see Redis Documentation: INCR
+ * @see Redis Documentation: INCRBY
*/
@Nullable
Long increment(long delta);
@@ -107,6 +118,27 @@ public interface BoundValueOperations extends BoundKeyOperations {
@Nullable
Double increment(double delta);
+ /**
+ * Decrement an integer value stored as string value under the bound key by one.
+ *
+ * @return {@literal null} when used in pipeline / transaction.
+ * @since 2.1
+ * @see Redis Documentation: DECR
+ */
+ @Nullable
+ Long decrement();
+
+ /**
+ * Decrement an integer value stored as string value under the bound key by {@code delta}.
+ *
+ * @param delta
+ * @return {@literal null} when used in pipeline / transaction.
+ * @since 2.1
+ * @see Redis Documentation: DECRBY
+ */
+ @Nullable
+ Long decrement(long delta);
+
/**
* Append a {@code value} to the bound key.
*
diff --git a/src/main/java/org/springframework/data/redis/core/DefaultBoundValueOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultBoundValueOperations.java
index 426decabe..31af095d3 100644
--- a/src/main/java/org/springframework/data/redis/core/DefaultBoundValueOperations.java
+++ b/src/main/java/org/springframework/data/redis/core/DefaultBoundValueOperations.java
@@ -22,6 +22,7 @@ import org.springframework.data.redis.connection.DataType;
/**
* @author Costin Leau
* @author Jiahe Cai
+ * @author Mark Paluch
*/
class DefaultBoundValueOperations extends DefaultBoundKeyOperations implements BoundValueOperations {
@@ -57,6 +58,15 @@ class DefaultBoundValueOperations extends DefaultBoundKeyOperations imp
return ops.getAndSet(getKey(), value);
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.core.BoundValueOperations#increment()
+ */
+ @Override
+ public Long increment() {
+ return ops.increment(getKey());
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.redis.core.BoundValueOperations#increment(long)
@@ -75,6 +85,24 @@ class DefaultBoundValueOperations extends DefaultBoundKeyOperations imp
return ops.increment(getKey(), delta);
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.core.BoundValueOperations#decrement()
+ */
+ @Override
+ public Long decrement() {
+ return ops.decrement(getKey());
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.core.BoundValueOperations#decrement(double)
+ */
+ @Override
+ public Long decrement(long delta) {
+ return ops.decrement(getKey(), delta);
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.redis.core.BoundValueOperations#append(java.lang.String)
diff --git a/src/main/java/org/springframework/data/redis/core/DefaultReactiveValueOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultReactiveValueOperations.java
index a50a247fc..f45cb615d 100644
--- a/src/main/java/org/springframework/data/redis/core/DefaultReactiveValueOperations.java
+++ b/src/main/java/org/springframework/data/redis/core/DefaultReactiveValueOperations.java
@@ -194,6 +194,61 @@ class DefaultReactiveValueOperations implements ReactiveValueOperations increment(K key) {
+
+ Assert.notNull(key, "Key must not be null!");
+
+ return template.createMono(connection -> connection.numberCommands().incr(rawKey(key)));
+ }
+
+ /* (non-Javadoc)
+ * @see org.springframework.data.redis.core.ReactiveValueOperations#increment(java.lang.Object, long)
+ */
+ @Override
+ public Mono increment(K key, long delta) {
+
+ Assert.notNull(key, "Key must not be null!");
+
+ return template.createMono(connection -> connection.numberCommands().incrBy(rawKey(key), delta));
+ }
+
+ /* (non-Javadoc)
+ * @see org.springframework.data.redis.core.ReactiveValueOperations#increment(java.lang.Object, double)
+ */
+ @Override
+ public Mono increment(K key, double delta) {
+
+ Assert.notNull(key, "Key must not be null!");
+
+ return template.createMono(connection -> connection.numberCommands().incrBy(rawKey(key), delta));
+ }
+
+ /* (non-Javadoc)
+ * @see org.springframework.data.redis.core.ReactiveValueOperations#decrement(java.lang.Object)
+ */
+ @Override
+ public Mono decrement(K key) {
+
+ Assert.notNull(key, "Key must not be null!");
+
+ return template.createMono(connection -> connection.numberCommands().decr(rawKey(key)));
+ }
+
+ /* (non-Javadoc)
+ * @see org.springframework.data.redis.core.ReactiveValueOperations#decrement(java.lang.Object, long)
+ */
+ @Override
+ public Mono decrement(K key, long delta) {
+
+ Assert.notNull(key, "Key must not be null!");
+
+ return template.createMono(connection -> connection.numberCommands().decrBy(rawKey(key), delta));
+ }
+
/* (non-Javadoc)
* @see org.springframework.data.redis.core.ReactiveValueOperations#append(java.lang.Object, java.lang.String)
*/
@@ -273,61 +328,6 @@ class DefaultReactiveValueOperations implements ReactiveValueOperations connection.keyCommands().del(rawKey(key))).map(l -> l != 0);
}
-
- /* (non-Javadoc)
- * @see org.springframework.data.redis.core.ReactiveValueOperations#increment(java.lang.Object)
- */
- @Override
- public Mono increment(K key) {
-
- Assert.notNull(key, "Key must not be null!");
-
- return incrementBy(key, 1L);
- }
-
- /* (non-Javadoc)
- * @see org.springframework.data.redis.core.ReactiveValueOperations#incrementBy(java.lang.Object, long)
- */
- @Override
- public Mono incrementBy(K key, long delta) {
-
- Assert.notNull(key, "Key must not be null!");
-
- return template.createMono(connection -> connection.numberCommands().incrBy(rawKey(key), delta));
- }
-
- /* (non-Javadoc)
- * @see org.springframework.data.redis.core.ReactiveValueOperations#incrementBy(java.lang.Object, double)
- */
- @Override
- public Mono incrementBy(K key, double delta) {
-
- Assert.notNull(key, "Key must not be null!");
-
- return template.createMono(connection -> connection.numberCommands().incrBy(rawKey(key), delta));
- }
-
- /* (non-Javadoc)
- * @see org.springframework.data.redis.core.ReactiveValueOperations#decrement(java.lang.Object)
- */
- @Override
- public Mono decrement(K key) {
-
- Assert.notNull(key, "Key must not be null!");
-
- return incrementBy(key, -1L);
- }
-
- /* (non-Javadoc)
- * @see org.springframework.data.redis.core.ReactiveValueOperations#decrementBy(java.lang.Object, long)
- */
- @Override
- public Mono decrementBy(K key, long delta) {
-
- Assert.notNull(key, "Key must not be null!");
-
- return incrementBy(key, -delta);
- }
private Mono createMono(Function> function) {
diff --git a/src/main/java/org/springframework/data/redis/core/DefaultValueOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultValueOperations.java
index 69b66a716..6e0912a91 100644
--- a/src/main/java/org/springframework/data/redis/core/DefaultValueOperations.java
+++ b/src/main/java/org/springframework/data/redis/core/DefaultValueOperations.java
@@ -74,6 +74,17 @@ class DefaultValueOperations extends AbstractOperations implements V
}, true);
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.core.ValueOperations#increment(java.lang.Object)
+ */
+ @Override
+ public Long increment(K key) {
+
+ byte[] rawKey = rawKey(key);
+ return execute(connection -> connection.incr(rawKey), true);
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.redis.core.ValueOperations#increment(java.lang.Object, long)
@@ -96,6 +107,28 @@ class DefaultValueOperations extends AbstractOperations implements V
return execute(connection -> connection.incrBy(rawKey, delta), true);
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.core.ValueOperations#decrement(java.lang.Object)
+ */
+ @Override
+ public Long decrement(K key) {
+
+ byte[] rawKey = rawKey(key);
+ return execute(connection -> connection.decr(rawKey), true);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.core.ValueOperations#increment(java.lang.Object, long)
+ */
+ @Override
+ public Long decrement(K key, long delta) {
+
+ byte[] rawKey = rawKey(key);
+ return execute(connection -> connection.decrBy(rawKey, delta), true);
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.redis.core.ValueOperations#append(java.lang.Object, java.lang.String)
diff --git a/src/main/java/org/springframework/data/redis/core/ReactiveValueOperations.java b/src/main/java/org/springframework/data/redis/core/ReactiveValueOperations.java
index 416d12d3e..63a1dcf22 100644
--- a/src/main/java/org/springframework/data/redis/core/ReactiveValueOperations.java
+++ b/src/main/java/org/springframework/data/redis/core/ReactiveValueOperations.java
@@ -131,6 +131,54 @@ public interface ReactiveValueOperations {
*/
Mono> multiGet(Collection keys);
+ /**
+ * Increments the number stored at {@code key} by one.
+ *
+ * @param key must not be {@literal null}.
+ * @since 2.1
+ * @see Redis Documentation: INCR
+ */
+ Mono increment(K key);
+
+ /**
+ * Increments the number stored at {@code key} by {@code delta}.
+ *
+ * @param key must not be {@literal null}.
+ * @param delta
+ * @since 2.1
+ * @see Redis Documentation: INCRBY
+ */
+ Mono increment(K key, long delta);
+
+ /**
+ * Increment the string representing a floating point number stored at {@code key} by {@code delta}.
+ *
+ * @param key must not be {@literal null}.
+ * @param delta
+ * @since 2.1
+ * @see Redis Documentation: INCRBYFLOAT
+ */
+ Mono increment(K key, double delta);
+
+ /**
+ * Decrements the number stored at {@code key} by one.
+ *
+ * @param key must not be {@literal null}.
+ * @since 2.1
+ * @see Redis Documentation: DECR
+ */
+ Mono decrement(K key);
+
+ /**
+ * Decrements the number stored at {@code key} by {@code delta}.
+ *
+ * @param key must not be {@literal null}.
+ * @param delta
+ * @since 2.1
+ * @see Redis Documentation: DECRBY
+ */
+ Mono decrement(K key, long delta);
+
/**
* Append a {@code value} to {@code key}.
*
@@ -183,7 +231,7 @@ public interface ReactiveValueOperations {
*
* @param key must not be {@literal null}.
* @param offset
- * @see Redis Documentation: GETBIT
+ * @see Redis Documentation: GETBIT
*/
Mono getBit(K key, long offset);
@@ -193,44 +241,4 @@ public interface ReactiveValueOperations {
* @param key must not be {@literal null}.
*/
Mono delete(K key);
-
- /**
- * Increments the number stored at {@code key} by one.
- *
- * @param key must not be {@literal null}.
- * @see Redis Documentation: INCR
- */
- Mono increment(K key);
-
- /**
- * Increments the number stored at {@code key} by {@code delta}.
- * @param key must not be {@literal null}.
- * @param delta
- * @see Redis Documentation: INCRBY
- */
- Mono incrementBy(K key, long delta);
-
- /**
- * Increment the string representing a floating point number stored at {@code key} by {@code delta}.
- * @param key must not be {@literal null}.
- * @param delta
- * @see Redis Documentation: INCRBYFLOAT
- */
- Mono incrementBy(K key, double delta);
-
- /**
- * Decrements the number stored at {@code key} by one.
- *
- * @param key must not be {@literal null}.
- * @see Redis Documentation: DECR
- */
- Mono decrement(K key);
-
- /**
- * Decrements the number stored at {@code key} by {@code delta}.
- * @param key must not be {@literal null}.
- * @param delta
- * @see Redis Documentation: DECRBY
- */
- Mono decrementBy(K key, long delta);
}
diff --git a/src/main/java/org/springframework/data/redis/core/ValueOperations.java b/src/main/java/org/springframework/data/redis/core/ValueOperations.java
index 853639931..93e83b70a 100644
--- a/src/main/java/org/springframework/data/redis/core/ValueOperations.java
+++ b/src/main/java/org/springframework/data/redis/core/ValueOperations.java
@@ -126,13 +126,24 @@ public interface ValueOperations {
@Nullable
List multiGet(Collection keys);
+ /**
+ * Increment an integer value stored as string value under {@code key} by one.
+ *
+ * @param key must not be {@literal null}.
+ * @return {@literal null} when used in pipeline / transaction.
+ * @since 2.1
+ * @see Redis Documentation: INCR
+ */
+ @Nullable
+ Long increment(K key);
+
/**
* Increment an integer value stored as string value under {@code key} by {@code delta}.
*
* @param key must not be {@literal null}.
* @param delta
* @return {@literal null} when used in pipeline / transaction.
- * @see Redis Documentation: INCR
+ * @see Redis Documentation: INCRBY
*/
@Nullable
Long increment(K key, long delta);
@@ -148,6 +159,29 @@ public interface ValueOperations {
@Nullable
Double increment(K key, double delta);
+ /**
+ * Decrement an integer value stored as string value under {@code key} by one.
+ *
+ * @param key must not be {@literal null}.
+ * @return {@literal null} when used in pipeline / transaction.
+ * @since 2.1
+ * @see Redis Documentation: DECR
+ */
+ @Nullable
+ Long decrement(K key);
+
+ /**
+ * Decrement an integer value stored as string value under {@code key} by {@code delta}.
+ *
+ * @param key must not be {@literal null}.
+ * @param delta
+ * @return {@literal null} when used in pipeline / transaction.
+ * @since 2.1
+ * @see Redis Documentation: DECRBY
+ */
+ @Nullable
+ Long decrement(K key, long delta);
+
/**
* Append a {@code value} to {@code key}.
*
diff --git a/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicInteger.java b/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicInteger.java
index 64fb35ecd..8844a68be 100644
--- a/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicInteger.java
+++ b/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicInteger.java
@@ -30,7 +30,6 @@ import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
-import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@@ -245,7 +244,7 @@ public class RedisAtomicInteger extends Number implements Serializable, BoundKey
* @return the updated value.
*/
public int incrementAndGet() {
- return operations.increment(key, 1).intValue();
+ return operations.increment(key).intValue();
}
/**
@@ -254,7 +253,7 @@ public class RedisAtomicInteger extends Number implements Serializable, BoundKey
* @return the updated value.
*/
public int decrementAndGet() {
- return operations.increment(key, -1).intValue();
+ return operations.decrement(key).intValue();
}
/**
diff --git a/src/test/java/org/springframework/data/redis/core/DefaultReactiveValueOperationsIntegrationTests.java b/src/test/java/org/springframework/data/redis/core/DefaultReactiveValueOperationsIntegrationTests.java
index 6fe76c079..669d383eb 100644
--- a/src/test/java/org/springframework/data/redis/core/DefaultReactiveValueOperationsIntegrationTests.java
+++ b/src/test/java/org/springframework/data/redis/core/DefaultReactiveValueOperationsIntegrationTests.java
@@ -384,7 +384,7 @@ public class DefaultReactiveValueOperationsIntegrationTests {
StepVerifier.create(valueOperations.size(key)).expectNext(0L).verifyComplete();
}
-
+
@Test // DATAREDIS-784
public void increment() {
@@ -400,11 +400,11 @@ public class DefaultReactiveValueOperationsIntegrationTests {
K key = keyFactory.instance();
- StepVerifier.create(valueOperations.incrementBy(key, 2L)).expectNext(2L).verifyComplete();
+ StepVerifier.create(valueOperations.increment(key, 2L)).expectNext(2L).verifyComplete();
- StepVerifier.create(valueOperations.incrementBy(key, -3L)).expectNext(-1L).verifyComplete();
+ StepVerifier.create(valueOperations.increment(key, -3L)).expectNext(-1L).verifyComplete();
- StepVerifier.create(valueOperations.incrementBy(key, 1L)).expectNext(0L).verifyComplete();
+ StepVerifier.create(valueOperations.increment(key, 1L)).expectNext(0L).verifyComplete();
}
@Test // DATAREDIS-784
@@ -412,11 +412,11 @@ public class DefaultReactiveValueOperationsIntegrationTests {
K key = keyFactory.instance();
- StepVerifier.create(valueOperations.incrementBy(key, 0.1)).expectNext(0.1).verifyComplete();
+ StepVerifier.create(valueOperations.increment(key, 0.1)).expectNext(0.1).verifyComplete();
- StepVerifier.create(valueOperations.incrementBy(key, -0.3)).expectNext(-0.2).verifyComplete();
+ StepVerifier.create(valueOperations.increment(key, -0.3)).expectNext(-0.2).verifyComplete();
- StepVerifier.create(valueOperations.incrementBy(key, 0.2)).expectNext(0.0).verifyComplete();
+ StepVerifier.create(valueOperations.increment(key, 0.2)).expectNext(0.0).verifyComplete();
}
@Test // DATAREDIS-784
@@ -434,10 +434,10 @@ public class DefaultReactiveValueOperationsIntegrationTests {
K key = keyFactory.instance();
- StepVerifier.create(valueOperations.decrementBy(key, 2L)).expectNext(-2L).verifyComplete();
+ StepVerifier.create(valueOperations.decrement(key, 2L)).expectNext(-2L).verifyComplete();
- StepVerifier.create(valueOperations.decrementBy(key, -3L)).expectNext(1L).verifyComplete();
+ StepVerifier.create(valueOperations.decrement(key, -3L)).expectNext(1L).verifyComplete();
- StepVerifier.create(valueOperations.decrementBy(key, 1L)).expectNext(0L).verifyComplete();
+ StepVerifier.create(valueOperations.decrement(key, 1L)).expectNext(0L).verifyComplete();
}
}
diff --git a/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsTests.java b/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsTests.java
index d2d7c1e6f..5659e439c 100644
--- a/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsTests.java
+++ b/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsTests.java
@@ -49,6 +49,7 @@ import org.springframework.data.redis.RedisTestProfileValueSource;
* @author David Liu
* @author Thomas Darimont
* @author Jiahe Cai
+ * @author Mark Paluch
*/
@RunWith(Parameterized.class)
public class DefaultValueOperationsTests {
@@ -94,8 +95,18 @@ public class DefaultValueOperationsTests {
});
}
+ @Test // DATAREDIS-784
+ public void testIncrement() {
+ K key = keyFactory.instance();
+ V v1 = valueFactory.instance();
+ assumeTrue(v1 instanceof Long);
+ valueOps.set(key, v1);
+ assertEquals(Long.valueOf((Long) v1 + 1), valueOps.increment(key));
+ assertEquals(Long.valueOf((Long) v1 + 1), valueOps.get(key));
+ }
+
@Test
- public void testIncrementLong() throws Exception {
+ public void testIncrementLong() {
K key = keyFactory.instance();
V v1 = valueFactory.instance();
assumeTrue(v1 instanceof Long);
@@ -122,6 +133,26 @@ public class DefaultValueOperationsTests {
assertEquals(Double.valueOf(twoDForm.format((Double) v1 + 1.4 - 10d)), valueOps.get(key));
}
+ @Test // DATAREDIS-784
+ public void testDecrement() {
+ K key = keyFactory.instance();
+ V v1 = valueFactory.instance();
+ assumeTrue(v1 instanceof Long);
+ valueOps.set(key, v1);
+ assertEquals(Long.valueOf((Long) v1 - 1), valueOps.decrement(key));
+ assertEquals(Long.valueOf((Long) v1 - 1), valueOps.get(key));
+ }
+
+ @Test // DATAREDIS-784
+ public void testDecrementByLong() {
+ K key = keyFactory.instance();
+ V v1 = valueFactory.instance();
+ assumeTrue(v1 instanceof Long);
+ valueOps.set(key, v1);
+ assertEquals(Long.valueOf((Long) v1 - 5), valueOps.decrement(key, 5));
+ assertEquals(Long.valueOf((Long) v1 - 5), valueOps.get(key));
+ }
+
@Test
public void testMultiSetIfAbsent() {
Map keysAndValues = new HashMap<>();