DATAREDIS-1103 - Polishing.
Move keepTTL to Expiration and remove superfluous methods from interfaces. Add tests for reactive variant and work around an open issue in Jedis to support KEEPTTL though the API does not offer that option directly. Original Pull Request: #562
This commit is contained in:
@@ -993,15 +993,6 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
|
||||
return convertAndReturn(delegate.set(key, value, expiration, option), identityConverter);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisStringCommands#set(byte[], byte[], org.springframework.data.redis.core.types.Expiration, org.springframework.data.redis.connection.RedisStringCommands.SetOptions, boolean)
|
||||
*/
|
||||
@Override
|
||||
public Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption option, boolean keepTtl) {
|
||||
return convertAndReturn(delegate.set(key, value, expiration, option, keepTtl), identityConverter);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisStringCommands#setBit(byte[], long, boolean)
|
||||
|
||||
@@ -294,13 +294,6 @@ public interface DefaultedRedisConnection extends RedisConnection {
|
||||
return stringCommands().set(key, value, expiration, option);
|
||||
}
|
||||
|
||||
/** @deprecated in favor of {@link RedisConnection#stringCommands()}}. */
|
||||
@Override
|
||||
@Deprecated
|
||||
default Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption option, boolean keepTtl) {
|
||||
return stringCommands().set(key, value, expiration, option, keepTtl);
|
||||
}
|
||||
|
||||
/** @deprecated in favor of {@link RedisConnection#stringCommands()}}. */
|
||||
@Override
|
||||
@Deprecated
|
||||
|
||||
@@ -169,7 +169,8 @@ public interface ReactiveStringCommands {
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param value must not be {@literal null}.
|
||||
* @param expiration must not be {@literal null}.
|
||||
* @param expiration must not be {@literal null}. Use {@link Expiration#persistent()} for no expiration time or
|
||||
* {@link Expiration#keepTtl()} to keep the existing.
|
||||
* @param option must not be {@literal null}.
|
||||
* @return
|
||||
* @see <a href="https://redis.io/commands/set">Redis Documentation: SET</a>
|
||||
|
||||
@@ -83,7 +83,8 @@ public interface RedisStringCommands {
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param value must not be {@literal null}.
|
||||
* @param expiration must not be {@literal null}. Use {@link Expiration#persistent()} to not set any ttl.
|
||||
* @param expiration must not be {@literal null}. Use {@link Expiration#persistent()} to not set any ttl or
|
||||
* {@link Expiration#keepTtl()} to keep the existing expiration.
|
||||
* @param option must not be {@literal null}. Use {@link SetOption#upsert()} to add non existing.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 1.7
|
||||
@@ -92,22 +93,6 @@ public interface RedisStringCommands {
|
||||
@Nullable
|
||||
Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption option);
|
||||
|
||||
/**
|
||||
* Set {@code value} for {@code key} applying timeouts from {@code expiration} if set and inserting/updating values
|
||||
* depending on {@code option}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param value must not be {@literal null}.
|
||||
* @param expiration must not be {@literal null}. Use {@link Expiration#persistent()} to not set any ttl.
|
||||
* @param option must not be {@literal null}. Use {@link SetOption#upsert()} to add non existing.
|
||||
* @param keepTtl set the value and retain the existing TTL.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 2.4
|
||||
* @see <a href="https://redis.io/commands/set">Redis Documentation: SET</a>
|
||||
*/
|
||||
@Nullable
|
||||
Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption option, boolean keepTtl);
|
||||
|
||||
/**
|
||||
* Set {@code value} for {@code key}, only if {@code key} does not exist.
|
||||
*
|
||||
|
||||
@@ -420,7 +420,8 @@ public interface StringRedisConnection extends RedisConnection {
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param value must not be {@literal null}.
|
||||
* @param expiration can be {@literal null}. Defaulted to {@link Expiration#persistent()}.
|
||||
* @param expiration can be {@literal null}. Defaulted to {@link Expiration#persistent()}. Use
|
||||
* {@link Expiration#keepTtl()} to keep the existing expiration.
|
||||
* @param option can be {@literal null}. Defaulted to {@link SetOption#UPSERT}.
|
||||
* @since 1.7
|
||||
* @see <a href="https://redis.io/commands/set">Redis Documentation: SET</a>
|
||||
|
||||
@@ -127,20 +127,11 @@ class JedisClusterStringCommands implements RedisStringCommands {
|
||||
*/
|
||||
@Override
|
||||
public Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption option) {
|
||||
return set(key, value, expiration, option, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisStringCommands#set(byte[], byte[], org.springframework.data.redis.core.types.Expiration, org.springframework.data.redis.connection.RedisStringCommands.SetOptions, boolean)
|
||||
*/
|
||||
@Override
|
||||
public Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption option, boolean keepTtl) {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(expiration, "Expiration must not be null!");
|
||||
Assert.notNull(option, "Option must not be null!");
|
||||
Assert.isTrue(keepTtl, "KEEPTTL is currently not supported in jedis!");
|
||||
|
||||
SetParams setParams = JedisConverters.toSetCommandExPxArgument(expiration,
|
||||
JedisConverters.toSetCommandNxXxArgument(option));
|
||||
|
||||
@@ -533,6 +533,24 @@ abstract public class JedisConverters extends Converters {
|
||||
|
||||
SetParams paramsToUse = params == null ? SetParams.setParams() : params;
|
||||
|
||||
if (expiration.isKeepTtl()) {
|
||||
|
||||
// TODO: remove once jedis supports KEEPTTL (https://github.com/xetorthio/jedis/issues/2248)
|
||||
return new SetParams() {
|
||||
|
||||
@Override
|
||||
public byte[][] getByteParams(byte[]... args) {
|
||||
|
||||
ArrayList<byte[]> byteParams = new ArrayList<>();
|
||||
for (byte[] arg : paramsToUse.getByteParams(args)) {
|
||||
byteParams.add(arg);
|
||||
}
|
||||
byteParams.add(SafeEncoder.encode("keepttl"));
|
||||
return byteParams.toArray(new byte[byteParams.size()][]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (!expiration.isPersistent()) {
|
||||
if (expiration.getTimeUnit() == TimeUnit.MILLISECONDS) {
|
||||
return paramsToUse.px(expiration.getExpirationTime());
|
||||
|
||||
@@ -153,20 +153,11 @@ class JedisStringCommands implements RedisStringCommands {
|
||||
*/
|
||||
@Override
|
||||
public Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption option) {
|
||||
return set(key, value, expiration, option, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisStringCommands#set(byte[], byte[], org.springframework.data.redis.core.types.Expiration, org.springframework.data.redis.connection.RedisStringCommands.SetOption, boolean)
|
||||
*/
|
||||
@Override
|
||||
public Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption option, boolean keepTtl) {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(expiration, "Expiration must not be null!");
|
||||
Assert.notNull(option, "Option must not be null!");
|
||||
Assert.isTrue(keepTtl, "KEEPTTL is currently not supported in jedis!");
|
||||
|
||||
SetParams params = JedisConverters.toSetCommandExPxArgument(expiration,
|
||||
JedisConverters.toSetCommandNxXxArgument(option));
|
||||
|
||||
@@ -768,36 +768,26 @@ abstract public class LettuceConverters extends Converters {
|
||||
* @since 1.7
|
||||
*/
|
||||
public static SetArgs toSetArgs(@Nullable Expiration expiration, @Nullable SetOption option) {
|
||||
return toSetArgs(expiration, option, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a given {@link Expiration} and {@link SetOption} to the according {@link SetArgs}.<br />
|
||||
*
|
||||
* @param expiration can be {@literal null}.
|
||||
* @param option can be {@literal null}.
|
||||
* @param keepTtl set the value and retain the existing TTL.
|
||||
* @since 2.4
|
||||
*/
|
||||
public static SetArgs toSetArgs(@Nullable Expiration expiration, @Nullable SetOption option, boolean keepTtl) {
|
||||
|
||||
SetArgs args = new SetArgs();
|
||||
if (expiration != null && !expiration.isPersistent()) {
|
||||
|
||||
switch (expiration.getTimeUnit()) {
|
||||
case SECONDS:
|
||||
args.ex(expiration.getExpirationTime());
|
||||
break;
|
||||
default:
|
||||
args.px(expiration.getConverted(TimeUnit.MILLISECONDS));
|
||||
break;
|
||||
if (expiration != null) {
|
||||
|
||||
if (expiration.isKeepTtl()) {
|
||||
args.keepttl();
|
||||
} else if (!expiration.isPersistent()) {
|
||||
|
||||
switch (expiration.getTimeUnit()) {
|
||||
case SECONDS:
|
||||
args.ex(expiration.getExpirationTime());
|
||||
break;
|
||||
default:
|
||||
args.px(expiration.getConverted(TimeUnit.MILLISECONDS));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (keepTtl) {
|
||||
args.keepttl();
|
||||
}
|
||||
|
||||
if (option != null) {
|
||||
|
||||
switch (option) {
|
||||
|
||||
@@ -157,15 +157,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
*/
|
||||
@Override
|
||||
public Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption option) {
|
||||
return set(key, value, expiration, option, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisStringCommands#set(byte[], byte[], org.springframework.data.redis.core.types.Expiration, org.springframework.data.redis.connection.RedisStringCommands.SetOption, boolean)
|
||||
*/
|
||||
@Override
|
||||
public Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption option, boolean keepTtl) {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(expiration, "Expiration must not be null!");
|
||||
@@ -174,18 +166,18 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(
|
||||
getAsyncConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option, keepTtl)),
|
||||
getAsyncConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option)),
|
||||
Converters.stringToBooleanConverter(), () -> false));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(
|
||||
getAsyncConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option, keepTtl)),
|
||||
getAsyncConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option)),
|
||||
Converters.stringToBooleanConverter(), () -> false));
|
||||
return null;
|
||||
}
|
||||
return Converters
|
||||
.stringToBoolean(getConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option, keepTtl)));
|
||||
.stringToBoolean(getConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option)));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
@@ -115,6 +115,19 @@ public class Expiration {
|
||||
return new Expiration(expirationTime, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain an {@link Expiration} that indicates to keep the existing one. Eg. when sending a {@code SET} command.
|
||||
* <p />
|
||||
* <strong>NOTE: </strong>Please follow the documentation of the individual commands to see if {@link #keepTtl()} is
|
||||
* applicable.
|
||||
*
|
||||
* @return never {@literal null}.
|
||||
* @since 2.4
|
||||
*/
|
||||
public static Expiration keepTtl() {
|
||||
return KeepTtl.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link Expiration} with the provided {@link TimeUnit}. Greater units than {@link TimeUnit#SECONDS} are
|
||||
* converted to {@link TimeUnit#SECONDS}. Units smaller than {@link TimeUnit#MILLISECONDS} are converted to
|
||||
@@ -175,4 +188,30 @@ public class Expiration {
|
||||
public boolean isPersistent() {
|
||||
return expirationTime == -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@literal true} if {@link Expiration} of existing key should not be modified.
|
||||
* @since 2.4
|
||||
*/
|
||||
public boolean isKeepTtl() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 2.4
|
||||
*/
|
||||
private static class KeepTtl extends Expiration {
|
||||
|
||||
static KeepTtl INSTANCE = new KeepTtl();
|
||||
|
||||
private KeepTtl() {
|
||||
super(-2, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isKeepTtl() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user