Support ZADD params for Reactive-/RedisConnection and add addIfAbsent methods.
Closes: #1794 Original pull request: #1988.
This commit is contained in:
committed by
Mark Paluch
parent
102ee017aa
commit
4d77392c9d
@@ -1322,20 +1322,20 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zAdd(byte[], double, byte[])
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zAdd(byte[], double, byte[], org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs)
|
||||
*/
|
||||
@Override
|
||||
public Boolean zAdd(byte[] key, double score, byte[] value) {
|
||||
return convertAndReturn(delegate.zAdd(key, score, value), Converters.identityConverter());
|
||||
public Boolean zAdd(byte[] key, double score, byte[] value, ZAddArgs args) {
|
||||
return convertAndReturn(delegate.zAdd(key, score, value, args), Converters.identityConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zAdd(byte[], java.util.Set)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zAdd(byte[], java.util.Set, org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs)
|
||||
*/
|
||||
@Override
|
||||
public Long zAdd(byte[] key, Set<Tuple> tuples) {
|
||||
return convertAndReturn(delegate.zAdd(key, tuples), Converters.identityConverter());
|
||||
public Long zAdd(byte[] key, Set<Tuple> tuples, ZAddArgs args) {
|
||||
return convertAndReturn(delegate.zAdd(key, tuples, args), Converters.identityConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2686,20 +2686,20 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.StringRedisConnection#zAdd(java.lang.String, double, java.lang.String)
|
||||
* @see org.springframework.data.redis.connection.StringRedisConnection#zAdd(java.lang.String, double, java.lang.String, org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs)
|
||||
*/
|
||||
@Override
|
||||
public Boolean zAdd(String key, double score, String value) {
|
||||
return zAdd(serialize(key), score, serialize(value));
|
||||
public Boolean zAdd(String key, double score, String value, ZAddArgs args) {
|
||||
return zAdd(serialize(key), score, serialize(value), args);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.StringRedisConnection#zAdd(java.lang.String, java.util.Set)
|
||||
* @see org.springframework.data.redis.connection.StringRedisConnection#zAdd(java.lang.String, java.util.Set, org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs)
|
||||
*/
|
||||
@Override
|
||||
public Long zAdd(String key, Set<StringTuple> tuples) {
|
||||
return zAdd(serialize(key), stringTupleToTuple.convert(tuples));
|
||||
public Long zAdd(String key, Set<StringTuple> tuples, ZAddArgs args) {
|
||||
return zAdd(serialize(key), stringTupleToTuple.convert(tuples), args);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -873,15 +873,15 @@ public interface DefaultedRedisConnection extends RedisConnection {
|
||||
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
|
||||
@Override
|
||||
@Deprecated
|
||||
default Boolean zAdd(byte[] key, double score, byte[] value) {
|
||||
return zSetCommands().zAdd(key, score, value);
|
||||
default Boolean zAdd(byte[] key, double score, byte[] value, ZAddArgs args) {
|
||||
return zSetCommands().zAdd(key, score, value, args);
|
||||
}
|
||||
|
||||
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
|
||||
@Override
|
||||
@Deprecated
|
||||
default Long zAdd(byte[] key, Set<Tuple> tuples) {
|
||||
return zSetCommands().zAdd(key, tuples);
|
||||
default Long zAdd(byte[] key, Set<Tuple> tuples, ZAddArgs args) {
|
||||
return zSetCommands().zAdd(key, tuples, args);
|
||||
}
|
||||
|
||||
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
|
||||
|
||||
@@ -63,9 +63,11 @@ public interface ReactiveZSetCommands {
|
||||
private final boolean upsert;
|
||||
private final boolean returnTotalChanged;
|
||||
private final boolean incr;
|
||||
private final boolean gt;
|
||||
private final boolean lt;
|
||||
|
||||
private ZAddCommand(@Nullable ByteBuffer key, List<Tuple> tuples, boolean upsert, boolean returnTotalChanged,
|
||||
boolean incr) {
|
||||
boolean incr, boolean gt, boolean lt) {
|
||||
|
||||
super(key);
|
||||
|
||||
@@ -73,6 +75,8 @@ public interface ReactiveZSetCommands {
|
||||
this.upsert = upsert;
|
||||
this.returnTotalChanged = returnTotalChanged;
|
||||
this.incr = incr;
|
||||
this.gt = gt;
|
||||
this.lt = lt;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,7 +102,7 @@ public interface ReactiveZSetCommands {
|
||||
|
||||
Assert.notNull(tuples, "Tuples must not be null!");
|
||||
|
||||
return new ZAddCommand(null, new ArrayList<>(tuples), false, false, false);
|
||||
return new ZAddCommand(null, new ArrayList<>(tuples), false, false, false, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,7 +115,7 @@ public interface ReactiveZSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return new ZAddCommand(key, tuples, upsert, returnTotalChanged, incr);
|
||||
return new ZAddCommand(key, tuples, upsert, returnTotalChanged, incr, gt, lt);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,7 +125,7 @@ public interface ReactiveZSetCommands {
|
||||
* @return a new {@link ZAddCommand} with {@literal xx} applied.
|
||||
*/
|
||||
public ZAddCommand xx() {
|
||||
return new ZAddCommand(getKey(), tuples, false, returnTotalChanged, incr);
|
||||
return new ZAddCommand(getKey(), tuples, false, returnTotalChanged, incr, gt, lt);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,7 +135,7 @@ public interface ReactiveZSetCommands {
|
||||
* @return a new {@link ZAddCommand} with {@literal nx} applied.
|
||||
*/
|
||||
public ZAddCommand nx() {
|
||||
return new ZAddCommand(getKey(), tuples, true, returnTotalChanged, incr);
|
||||
return new ZAddCommand(getKey(), tuples, true, returnTotalChanged, incr, gt, lt);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,7 +145,7 @@ public interface ReactiveZSetCommands {
|
||||
* @return a new {@link ZAddCommand} with {@literal ch} applied.
|
||||
*/
|
||||
public ZAddCommand ch() {
|
||||
return new ZAddCommand(getKey(), tuples, upsert, true, incr);
|
||||
return new ZAddCommand(getKey(), tuples, upsert, true, incr, gt, lt);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,7 +155,29 @@ public interface ReactiveZSetCommands {
|
||||
* @return a new {@link ZAddCommand} with {@literal incr} applied.
|
||||
*/
|
||||
public ZAddCommand incr() {
|
||||
return new ZAddCommand(getKey(), tuples, upsert, upsert, true);
|
||||
return new ZAddCommand(getKey(), tuples, upsert, upsert, true, gt, lt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies {@literal GT} mode. Constructs a new command
|
||||
* instance with all previously configured properties.
|
||||
*
|
||||
* @return a new {@link ZAddCommand} with {@literal incr} applied.
|
||||
* @since 2.5
|
||||
*/
|
||||
public ZAddCommand gt() {
|
||||
return new ZAddCommand(getKey(), tuples, upsert, upsert, incr, true, lt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies {@literal LT} mode. Constructs a new command
|
||||
* instance with all previously configured properties.
|
||||
*
|
||||
* @return a new {@link ZAddCommand} with {@literal incr} applied.
|
||||
* @since 2.5
|
||||
*/
|
||||
public ZAddCommand lt() {
|
||||
return new ZAddCommand(getKey(), tuples, upsert, upsert, incr, gt, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,6 +201,23 @@ public interface ReactiveZSetCommands {
|
||||
return incr;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return {@literal true} if {@literal GT} is set.
|
||||
* @since 2.5
|
||||
*/
|
||||
public boolean isGt() {
|
||||
return gt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@literal true} if {@literal LT} is set.
|
||||
* @since 2.5
|
||||
*/
|
||||
public boolean isLt() {
|
||||
return lt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.redis.connection;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.DoubleUnaryOperator;
|
||||
@@ -396,6 +397,171 @@ public interface RedisZSetCommands {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code ZADD} specific arguments. <br />
|
||||
* Looking of the {@code INCR} flag? Use the {@code ZINCRBY} operation instead.
|
||||
*
|
||||
* @since 2.3
|
||||
* @see <a href="https://redis.io/commands/zadd">Redis Documentation: ZADD</a>
|
||||
*/
|
||||
class ZAddArgs {
|
||||
|
||||
private static final ZAddArgs NONE = new ZAddArgs(Collections.emptySet());
|
||||
|
||||
private final Set<Flag> flags;
|
||||
|
||||
private ZAddArgs(Set<Flag> flags) {
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return immutable {@link ZAddArgs}.
|
||||
*/
|
||||
public static ZAddArgs none() {
|
||||
return NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return new instance of {@link ZAddArgs} without any flags set.
|
||||
*/
|
||||
public static ZAddArgs empty() {
|
||||
return new ZAddArgs(new LinkedHashSet<>(5));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return new instance of {@link ZAddArgs} without {@link Flag#NX} set.
|
||||
*/
|
||||
public static ZAddArgs ifNotExists() {
|
||||
return empty().nx();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return new instance of {@link ZAddArgs} without {@link Flag#NX} set.
|
||||
*/
|
||||
public static ZAddArgs ifExists() {
|
||||
return empty().xx();
|
||||
}
|
||||
|
||||
/**
|
||||
* Only update elements that already exist.
|
||||
*
|
||||
* @return this.
|
||||
*/
|
||||
public ZAddArgs nx() {
|
||||
|
||||
flags.add(Flag.NX);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't update already existing elements.
|
||||
*
|
||||
* @return this.
|
||||
*/
|
||||
public ZAddArgs xx() {
|
||||
|
||||
flags.add(Flag.XX);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only update existing elements if the new score is less than the current score.
|
||||
*
|
||||
* @return this.
|
||||
*/
|
||||
public ZAddArgs lt() {
|
||||
|
||||
flags.add(Flag.LT);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only update existing elements if the new score is greater than the current score.
|
||||
*
|
||||
* @return this.
|
||||
*/
|
||||
public ZAddArgs gt() {
|
||||
|
||||
flags.add(Flag.GT);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only update elements that already exist.
|
||||
*
|
||||
* @return this.
|
||||
*/
|
||||
public ZAddArgs ch() {
|
||||
|
||||
flags.add(Flag.CH);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only update elements that already exist.
|
||||
*
|
||||
* @return this.
|
||||
*/
|
||||
public boolean contains(Flag flag) {
|
||||
return flags.contains(flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@literal true} if no flags set.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return !flags.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ZAddArgs zAddArgs = (ZAddArgs) o;
|
||||
|
||||
return ObjectUtils.nullSafeEquals(flags, zAddArgs.flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ObjectUtils.nullSafeHashCode(flags);
|
||||
}
|
||||
|
||||
public enum Flag {
|
||||
|
||||
/**
|
||||
* Only update elements that already exist.
|
||||
*/
|
||||
XX,
|
||||
|
||||
/**
|
||||
* Don't update already existing elements.
|
||||
*/
|
||||
NX,
|
||||
|
||||
/**
|
||||
* Only update existing elements if the new score is greater than the current score.
|
||||
*/
|
||||
GT,
|
||||
|
||||
/**
|
||||
* Only update existing elements if the new score is less than the current score.
|
||||
*/
|
||||
LT,
|
||||
|
||||
/**
|
||||
* Modify the return value from the number of new elements added, to the total number of elements changed.
|
||||
*/
|
||||
CH
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@code value} to a sorted set at {@code key}, or update its {@code score} if it already exists.
|
||||
*
|
||||
@@ -406,7 +572,24 @@ public interface RedisZSetCommands {
|
||||
* @see <a href="https://redis.io/commands/zadd">Redis Documentation: ZADD</a>
|
||||
*/
|
||||
@Nullable
|
||||
Boolean zAdd(byte[] key, double score, byte[] value);
|
||||
default Boolean zAdd(byte[] key, double score, byte[] value) {
|
||||
return zAdd(key, score, value, ZAddArgs.none());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@code value} to a sorted set at {@code key}, or update its {@code score} depending on the given
|
||||
* {@link ZAddArgs args}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param score the score.
|
||||
* @param value the value.
|
||||
* @param args must not be {@literal null} use {@link ZAddArgs#none()} instead.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 2.5
|
||||
* @see <a href="https://redis.io/commands/zadd">Redis Documentation: ZADD</a>
|
||||
*/
|
||||
@Nullable
|
||||
Boolean zAdd(byte[] key, double score, byte[] value, ZAddArgs args);
|
||||
|
||||
/**
|
||||
* Add {@code tuples} to a sorted set at {@code key}, or update its {@code score} if it already exists.
|
||||
@@ -417,7 +600,22 @@ public interface RedisZSetCommands {
|
||||
* @see <a href="https://redis.io/commands/zadd">Redis Documentation: ZADD</a>
|
||||
*/
|
||||
@Nullable
|
||||
Long zAdd(byte[] key, Set<Tuple> tuples);
|
||||
default Long zAdd(byte[] key, Set<Tuple> tuples) {
|
||||
return zAdd(key, tuples, ZAddArgs.none());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@code tuples} to a sorted set at {@code key}, or update its {@code score} depending on the given
|
||||
* {@link ZAddArgs args}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param tuples must not be {@literal null}.
|
||||
* @param args must not be {@literal null} use {@link ZAddArgs#none()} instead.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 2.5
|
||||
* @see <a href="https://redis.io/commands/zadd">Redis Documentation: ZADD</a>
|
||||
*/
|
||||
Long zAdd(byte[] key, Set<Tuple> tuples, ZAddArgs args);
|
||||
|
||||
/**
|
||||
* Remove {@code values} from sorted set. Return number of removed elements.
|
||||
|
||||
@@ -1102,7 +1102,24 @@ public interface StringRedisConnection extends RedisConnection {
|
||||
* @see <a href="https://redis.io/commands/zadd">Redis Documentation: ZADD</a>
|
||||
* @see RedisZSetCommands#zAdd(byte[], double, byte[])
|
||||
*/
|
||||
Boolean zAdd(String key, double score, String value);
|
||||
default Boolean zAdd(String key, double score, String value) {
|
||||
return zAdd(key, score, value, ZAddArgs.none());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the {@code value} to a sorted set at {@code key}, or update its {@code score} depending on the given
|
||||
* {@link ZAddArgs args}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param score must not be {@literal null}.
|
||||
* @param value must not be {@literal null}.
|
||||
* @param args must not be {@literal null} use {@link ZAddArgs#none()} instead.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 2.5
|
||||
* @see <a href="https://redis.io/commands/zadd">Redis Documentation: ZADD</a>
|
||||
* @see RedisZSetCommands#zAdd(byte[], double, byte[], ZAddArgs)
|
||||
*/
|
||||
Boolean zAdd(String key, double score, String value, ZAddArgs args);
|
||||
|
||||
/**
|
||||
* Add {@code tuples} to a sorted set at {@code key}, or update its {@code score} if it already exists.
|
||||
@@ -1113,7 +1130,24 @@ public interface StringRedisConnection extends RedisConnection {
|
||||
* @see <a href="https://redis.io/commands/zadd">Redis Documentation: ZADD</a>
|
||||
* @see RedisZSetCommands#zAdd(byte[], Set)
|
||||
*/
|
||||
Long zAdd(String key, Set<StringTuple> tuples);
|
||||
default Long zAdd(String key, Set<StringTuple> tuples) {
|
||||
return zAdd(key, tuples, ZAddArgs.none());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@code tuples} to a sorted set at {@code key}, or update its {@code score} depending on the given
|
||||
* {@link ZAddArgs args}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param tuples must not be {@literal null}.
|
||||
* @param args must not be {@literal null} use {@link ZAddArgs#none()} instead.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 2.5
|
||||
* @see <a href="https://redis.io/commands/zadd">Redis Documentation: ZADD</a>
|
||||
* @see RedisZSetCommands#zAdd(byte[], Set, ZAddArgs)
|
||||
*/
|
||||
@Nullable
|
||||
Long zAdd(String key, Set<StringTuple> tuples, ZAddArgs args);
|
||||
|
||||
/**
|
||||
* Remove {@code values} from sorted set. Return number of removed elements.
|
||||
|
||||
@@ -54,13 +54,13 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zAdd(byte[], double, byte[])
|
||||
*/
|
||||
@Override
|
||||
public Boolean zAdd(byte[] key, double score, byte[] value) {
|
||||
public Boolean zAdd(byte[] key, double score, byte[] value, ZAddArgs args) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
return JedisConverters.toBoolean(connection.getCluster().zadd(key, score, value));
|
||||
return JedisConverters.toBoolean(connection.getCluster().zadd(key, score, value, JedisConverters.toZAddParams(args)));
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
@@ -68,16 +68,16 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zAdd(byte[], java.util.Set)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zAdd(byte[], java.util.Set, org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs)
|
||||
*/
|
||||
@Override
|
||||
public Long zAdd(byte[] key, Set<Tuple> tuples) {
|
||||
public Long zAdd(byte[] key, Set<Tuple> tuples, ZAddArgs args) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(tuples, "Tuples must not be null!");
|
||||
|
||||
try {
|
||||
return connection.getCluster().zadd(key, JedisConverters.toTupleMap(tuples));
|
||||
return connection.getCluster().zadd(key, JedisConverters.toTupleMap(tuples), JedisConverters.toZAddParams(args));
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import redis.clients.jedis.ScanParams;
|
||||
import redis.clients.jedis.SortingParams;
|
||||
import redis.clients.jedis.params.GeoRadiusParam;
|
||||
import redis.clients.jedis.params.SetParams;
|
||||
import redis.clients.jedis.params.ZAddParams;
|
||||
import redis.clients.jedis.util.SafeEncoder;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
@@ -61,6 +62,7 @@ import org.springframework.data.redis.connection.RedisStringCommands.BitOperatio
|
||||
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Range.Boundary;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs;
|
||||
import org.springframework.data.redis.connection.SortParameters;
|
||||
import org.springframework.data.redis.connection.SortParameters.Order;
|
||||
import org.springframework.data.redis.connection.SortParameters.Range;
|
||||
@@ -652,6 +654,42 @@ public abstract class JedisConverters extends Converters {
|
||||
return ObjectUtils.caseInsensitiveValueOf(GeoUnit.values(), metricToUse.getAbbreviation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert {@link ZAddArgs} to {@link ZAddParams}.
|
||||
*
|
||||
* @param source must not be {@literal null}.
|
||||
* @return new instance of {@link ZAddParams}.
|
||||
* @since 2.5
|
||||
*/
|
||||
static ZAddParams toZAddParams(ZAddArgs source) {
|
||||
|
||||
if (!source.isEmpty()) {
|
||||
return new ZAddParams();
|
||||
}
|
||||
|
||||
ZAddParams target = new ZAddParams() {
|
||||
|
||||
{
|
||||
if (source.contains(ZAddArgs.Flag.GT)) {
|
||||
addParam("gt");
|
||||
}
|
||||
if (source.contains(ZAddArgs.Flag.LT)) {
|
||||
addParam("lt");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (source.contains(ZAddArgs.Flag.XX)) {
|
||||
target.xx();
|
||||
}
|
||||
if (source.contains(ZAddArgs.Flag.NX)) {
|
||||
target.nx();
|
||||
}
|
||||
if (source.contains(ZAddArgs.Flag.CH)) {
|
||||
target.ch();
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert {@link GeoRadiusCommandArgs} into {@link GeoRadiusParam}.
|
||||
|
||||
@@ -21,12 +21,14 @@ import redis.clients.jedis.MultiKeyPipelineBase;
|
||||
import redis.clients.jedis.ScanParams;
|
||||
import redis.clients.jedis.ScanResult;
|
||||
import redis.clients.jedis.ZParams;
|
||||
import redis.clients.jedis.params.ZAddParams;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs.Flag;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.KeyBoundCursor;
|
||||
import org.springframework.data.redis.core.ScanIteration;
|
||||
@@ -53,27 +55,27 @@ class JedisZSetCommands implements RedisZSetCommands {
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zAdd(byte[], double, byte[])
|
||||
*/
|
||||
@Override
|
||||
public Boolean zAdd(byte[] key, double score, byte[] value) {
|
||||
public Boolean zAdd(byte[] key, double score, byte[] value, ZAddArgs args) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
return connection.invoke().from(BinaryJedis::zadd, MultiKeyPipelineBase::zadd, key, score, value)
|
||||
return connection.invoke().from(BinaryJedis::zadd, MultiKeyPipelineBase::zadd, key, score, value, JedisConverters.toZAddParams(args))
|
||||
.get(JedisConverters::toBoolean);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zAdd(byte[], java.util.Set)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zAdd(byte[], java.util.Set, org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs)
|
||||
*/
|
||||
@Override
|
||||
public Long zAdd(byte[] key, Set<Tuple> tuples) {
|
||||
public Long zAdd(byte[] key, Set<Tuple> tuples, ZAddArgs args) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(tuples, "Tuples must not be null!");
|
||||
|
||||
return connection.invoke().just(BinaryJedis::zadd, MultiKeyPipelineBase::zadd, key,
|
||||
JedisConverters.toTupleMap(tuples));
|
||||
JedisConverters.toTupleMap(tuples), JedisConverters.toZAddParams(args));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -102,6 +102,12 @@ class LettuceReactiveZSetCommands implements ReactiveZSetCommands {
|
||||
} else {
|
||||
args = ZAddArgs.Builder.xx();
|
||||
}
|
||||
if(command.isGt()) {
|
||||
args = args == null ? ZAddArgs.Builder.gt() : args.gt();
|
||||
}
|
||||
if(command.isLt()) {
|
||||
args = args == null ? ZAddArgs.Builder.lt() : args.lt();
|
||||
}
|
||||
}
|
||||
|
||||
ScoredValue<ByteBuffer>[] values = (ScoredValue<ByteBuffer>[]) command.getTuples().stream()
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs.Flag;
|
||||
import org.springframework.data.redis.connection.convert.Converters;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.KeyBoundCursor;
|
||||
@@ -50,29 +51,29 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zAdd(byte[], double, byte[])
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zAdd(byte[], double, byte[], org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs)
|
||||
*/
|
||||
@Override
|
||||
public Boolean zAdd(byte[] key, double score, byte[] value) {
|
||||
public Boolean zAdd(byte[] key, double score, byte[] value, ZAddArgs args) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
return connection.invoke().from(RedisSortedSetAsyncCommands::zadd, key, score, value)
|
||||
return connection.invoke().from(RedisSortedSetAsyncCommands::zadd, key, LettuceZSetCommands.toZAddArgs(args), score, value)
|
||||
.get(LettuceConverters.longToBoolean());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zAdd(byte[], java.util.Set)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zAdd(byte[], java.util.Set, org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs)
|
||||
*/
|
||||
@Override
|
||||
public Long zAdd(byte[] key, Set<Tuple> tuples) {
|
||||
public Long zAdd(byte[] key, Set<Tuple> tuples, ZAddArgs args) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(tuples, "Tuples must not be null!");
|
||||
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zadd, key,
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zadd, key, LettuceZSetCommands.toZAddArgs(args),
|
||||
LettuceConverters.toObjects(tuples).toArray());
|
||||
}
|
||||
|
||||
@@ -568,4 +569,37 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert {@link ZAddArgs} to {@link io.lettuce.core.ZAddArgs}.
|
||||
*
|
||||
* @param source must not be {@literal null}.
|
||||
* @return never {@literal null}.
|
||||
* @since 2.5
|
||||
*/
|
||||
private static io.lettuce.core.ZAddArgs toZAddArgs(ZAddArgs source) {
|
||||
|
||||
io.lettuce.core.ZAddArgs target = new io.lettuce.core.ZAddArgs();
|
||||
|
||||
if(!source.isEmpty()) {
|
||||
return target;
|
||||
}
|
||||
|
||||
if(source.contains(Flag.XX)) {
|
||||
target.xx();
|
||||
}
|
||||
if(source.contains(Flag.NX)) {
|
||||
target.nx();
|
||||
}
|
||||
if(source.contains(Flag.GT)) {
|
||||
target.gt();
|
||||
}
|
||||
if(source.contains(Flag.LT)) {
|
||||
target.lt();
|
||||
}
|
||||
if(source.contains(Flag.CH)) {
|
||||
target.ch();
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,6 +48,18 @@ public interface BoundZSetOperations<K, V> extends BoundKeyOperations<K> {
|
||||
@Nullable
|
||||
Boolean add(V value, double score);
|
||||
|
||||
/**
|
||||
* Add {@code value} to a sorted set at {@code key} if it does not already exists.
|
||||
*
|
||||
* @param score the score.
|
||||
* @param value the value.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 2.5
|
||||
* @see <a href="https://redis.io/commands/zadd">Redis Documentation: ZADD NX</a>
|
||||
*/
|
||||
@Nullable
|
||||
Boolean addIfAbsent(V value, double score);
|
||||
|
||||
/**
|
||||
* Add {@code tuples} to a sorted set at the bound key, or update its {@code score} if it already exists.
|
||||
*
|
||||
@@ -58,6 +70,17 @@ public interface BoundZSetOperations<K, V> extends BoundKeyOperations<K> {
|
||||
@Nullable
|
||||
Long add(Set<TypedTuple<V>> tuples);
|
||||
|
||||
/**
|
||||
* Add {@code tuples} to a sorted set at {@code key} if it does not already exists.
|
||||
*
|
||||
* @param tuples must not be {@literal null}.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 2.5
|
||||
* @see <a href="https://redis.io/commands/zadd">Redis Documentation: ZADD NX</a>
|
||||
*/
|
||||
@Nullable
|
||||
Long addIfAbsent(Set<TypedTuple<V>> tuples);
|
||||
|
||||
/**
|
||||
* Remove {@code values} from sorted set. Return number of removed elements.
|
||||
*
|
||||
|
||||
@@ -60,6 +60,15 @@ class DefaultBoundZSetOperations<K, V> extends DefaultBoundKeyOperations<K> impl
|
||||
return ops.add(getKey(), value, score);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.BoundZSetOperations#addIfAbsent(java.lang.Object, double)
|
||||
*/
|
||||
@Override
|
||||
public Boolean addIfAbsent(V value, double score) {
|
||||
return ops.addIfAbsent(getKey(), value, score);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.BoundZSetOperations#add(java.util.Set)
|
||||
@@ -69,6 +78,15 @@ class DefaultBoundZSetOperations<K, V> extends DefaultBoundKeyOperations<K> impl
|
||||
return ops.add(getKey(), tuples);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.BoundZSetOperations#addIfAbsent(java.util.Set)
|
||||
*/
|
||||
@Override
|
||||
public Long addIfAbsent(Set<TypedTuple<V>> tuples) {
|
||||
return ops.addIfAbsent(getKey(), tuples);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.BoundZSetOperations#incrementScore(java.lang.Object, double)
|
||||
|
||||
@@ -24,6 +24,8 @@ import org.springframework.data.redis.connection.RedisZSetCommands.Limit;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Range;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Weights;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link ZSetOperations}.
|
||||
@@ -48,10 +50,31 @@ class DefaultZSetOperations<K, V> extends AbstractOperations<K, V> implements ZS
|
||||
*/
|
||||
@Override
|
||||
public Boolean add(K key, V value, double score) {
|
||||
return add(key, value, score, ZAddArgs.none());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ZSetOperations#addIfAbsent(java.lang.Object, java.lang.Object, double)
|
||||
*/
|
||||
@Override
|
||||
public Boolean addIfAbsent(K key, V value, double score) {
|
||||
return add(key, value, score, ZAddArgs.ifNotExists());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key must not be {@literal null}.
|
||||
* @param value must not be {@literal null}.
|
||||
* @param args never {@literal null}.
|
||||
* @return can be {@literal null}.
|
||||
* @since 2.5
|
||||
*/
|
||||
@Nullable
|
||||
protected Boolean add(K key, V value, double score, ZAddArgs args) {
|
||||
|
||||
byte[] rawKey = rawKey(key);
|
||||
byte[] rawValue = rawValue(value);
|
||||
return execute(connection -> connection.zAdd(rawKey, score, rawValue), true);
|
||||
return execute(connection -> connection.zAdd(rawKey, score, rawValue, args), true);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -60,10 +83,31 @@ class DefaultZSetOperations<K, V> extends AbstractOperations<K, V> implements ZS
|
||||
*/
|
||||
@Override
|
||||
public Long add(K key, Set<TypedTuple<V>> tuples) {
|
||||
return add(key, tuples, ZAddArgs.none());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ZSetOperations#addIfAbsent(java.lang.Object, java.util.Set)
|
||||
*/
|
||||
@Override
|
||||
public Long addIfAbsent(K key, Set<TypedTuple<V>> tuples) {
|
||||
return add(key, tuples, ZAddArgs.ifNotExists());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key must not be {@literal null}.
|
||||
* @param tuples must not be {@literal null}.
|
||||
* @param args never {@literal null}.
|
||||
* @return can be {@literal null}.
|
||||
* @since 2.5
|
||||
*/
|
||||
@Nullable
|
||||
protected Long add(K key, Set<TypedTuple<V>> tuples, ZAddArgs args) {
|
||||
|
||||
byte[] rawKey = rawKey(key);
|
||||
Set<Tuple> rawValues = rawTupleValues(tuples);
|
||||
return execute(connection -> connection.zAdd(rawKey, rawValues), true);
|
||||
return execute(connection -> connection.zAdd(rawKey, rawValues, args), true);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -47,6 +47,19 @@ public interface ZSetOperations<K, V> {
|
||||
|
||||
@Nullable
|
||||
Double getScore();
|
||||
|
||||
/**
|
||||
* Create a new {@link TypedTuple}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @param score can be {@literal null}.
|
||||
* @param <V>
|
||||
* @return new instance of {@link TypedTuple}.
|
||||
* @since 2.5
|
||||
*/
|
||||
static <V> TypedTuple<V> of(V value, @Nullable Double score) {
|
||||
return new DefaultTypedTuple<>(value, score);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,6 +74,19 @@ public interface ZSetOperations<K, V> {
|
||||
@Nullable
|
||||
Boolean add(K key, V value, double score);
|
||||
|
||||
/**
|
||||
* Add {@code value} to a sorted set at {@code key} if it does not already exists.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param score the score.
|
||||
* @param value the value.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 2.5
|
||||
* @see <a href="https://redis.io/commands/zadd">Redis Documentation: ZADD NX</a>
|
||||
*/
|
||||
@Nullable
|
||||
Boolean addIfAbsent(K key, V value, double score);
|
||||
|
||||
/**
|
||||
* Add {@code tuples} to a sorted set at {@code key}, or update its {@code score} if it already exists.
|
||||
*
|
||||
@@ -72,6 +98,18 @@ public interface ZSetOperations<K, V> {
|
||||
@Nullable
|
||||
Long add(K key, Set<TypedTuple<V>> tuples);
|
||||
|
||||
/**
|
||||
* Add {@code tuples} to a sorted set at {@code key} if it does not already exists.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param tuples must not be {@literal null}.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 2.5
|
||||
* @see <a href="https://redis.io/commands/zadd">Redis Documentation: ZADD NX</a>
|
||||
*/
|
||||
@Nullable
|
||||
Long addIfAbsent(K key, Set<TypedTuple<V>> tuples);
|
||||
|
||||
/**
|
||||
* Remove {@code values} from sorted set. Return number of removed elements.
|
||||
*
|
||||
|
||||
@@ -288,6 +288,18 @@ public class DefaultRedisZSet<E> extends AbstractRedisCollection<E> implements R
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.support.collections.RedisZSet#addIfAbsent(java.lang.Object, double)
|
||||
*/
|
||||
@Override
|
||||
public boolean addIfAbsent(E e, double score) {
|
||||
|
||||
Boolean result = boundZSetOps.addIfAbsent(e, score);
|
||||
checkResult(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.util.AbstractCollection#clear()
|
||||
|
||||
@@ -144,6 +144,27 @@ public interface RedisZSet<E> extends RedisCollection<E>, Set<E> {
|
||||
*/
|
||||
boolean add(E e);
|
||||
|
||||
/**
|
||||
* Adds an element to the set using the {@link #getDefaultScore() default score} if the element does not already exists.
|
||||
*
|
||||
* @param e element to add
|
||||
* @return true if a new element was added, false otherwise (only the score has been updated)
|
||||
* @since 2.5
|
||||
*/
|
||||
default boolean addIfAbsent(E e) {
|
||||
return addIfAbsent(e, getDefaultScore());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an element to the set with the given score if the element does not already exists.
|
||||
*
|
||||
* @param e element to add
|
||||
* @param score element score
|
||||
* @return true if a new element was added, false otherwise (only the score has been updated)
|
||||
* @since 2.5
|
||||
*/
|
||||
boolean addIfAbsent(E e, double score);
|
||||
|
||||
/**
|
||||
* Count number of elements within sorted set with value between {@code Range#min} and {@code Range#max} applying
|
||||
* lexicographical ordering.
|
||||
|
||||
Reference in New Issue
Block a user