DATAREDIS-1103 - Support new KEEPTTL option of the SET operation

Original Pull Request: #562
This commit is contained in:
dengliming
2020-09-15 00:52:52 +08:00
committed by Christoph Strobl
parent 3920890c01
commit 232c8a5dd4
8 changed files with 98 additions and 3 deletions

View File

@@ -69,6 +69,7 @@ import org.springframework.util.ObjectUtils;
* @author Ninad Divadkar
* @author Tugdual Grall
* @author Andrey Shlykov
* @author dengliming
*/
public class DefaultStringRedisConnection implements StringRedisConnection, DecoratedRedisConnection {
@@ -992,6 +993,15 @@ 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)

View File

@@ -294,6 +294,13 @@ 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

View File

@@ -92,6 +92,22 @@ 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.
*

View File

@@ -41,6 +41,7 @@ import org.springframework.util.Assert;
* @author Christoph Strobl
* @author Mark Paluch
* @author Xiaohu Zhang
* @author dengliming
* @since 2.0
*/
class JedisClusterStringCommands implements RedisStringCommands {
@@ -126,11 +127,20 @@ 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));

View File

@@ -34,6 +34,7 @@ import org.springframework.util.Assert;
/**
* @author Christoph Strobl
* @author Mark Paluch
* @author dengliming
* @since 2.0
*/
class JedisStringCommands implements RedisStringCommands {
@@ -152,11 +153,20 @@ 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));

View File

@@ -82,6 +82,7 @@ import org.springframework.util.StringUtils;
* @author Thomas Darimont
* @author Mark Paluch
* @author Ninad Divadkar
* @author dengliming
*/
abstract public class LettuceConverters extends Converters {
@@ -767,6 +768,18 @@ 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()) {
@@ -781,6 +794,10 @@ abstract public class LettuceConverters extends Converters {
}
}
if (keepTtl) {
args.keepttl();
}
if (option != null) {
switch (option) {

View File

@@ -36,6 +36,7 @@ import org.springframework.util.Assert;
/**
* @author Christoph Strobl
* @author Mark Paluch
* @author dengliming
* @since 2.0
*/
class LettuceStringCommands implements RedisStringCommands {
@@ -156,7 +157,15 @@ 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!");
@@ -165,18 +174,18 @@ class LettuceStringCommands implements RedisStringCommands {
try {
if (isPipelined()) {
pipeline(connection.newLettuceResult(
getAsyncConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option)),
getAsyncConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option, keepTtl)),
Converters.stringToBooleanConverter(), () -> false));
return null;
}
if (isQueueing()) {
transaction(connection.newLettuceResult(
getAsyncConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option)),
getAsyncConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option, keepTtl)),
Converters.stringToBooleanConverter(), () -> false));
return null;
}
return Converters
.stringToBoolean(getConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option)));
.stringToBoolean(getConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option, keepTtl)));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}