@@ -70,6 +70,7 @@ import org.springframework.util.ObjectUtils;
|
|||||||
* @author Tugdual Grall
|
* @author Tugdual Grall
|
||||||
* @author Andrey Shlykov
|
* @author Andrey Shlykov
|
||||||
* @author dengliming
|
* @author dengliming
|
||||||
|
* @author ihaohong
|
||||||
*/
|
*/
|
||||||
public class DefaultStringRedisConnection implements StringRedisConnection, DecoratedRedisConnection {
|
public class DefaultStringRedisConnection implements StringRedisConnection, DecoratedRedisConnection {
|
||||||
|
|
||||||
@@ -276,6 +277,15 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
|
|||||||
return convertAndReturn(delegate.del(keys), Converters.identityConverter());
|
return convertAndReturn(delegate.del(keys), Converters.identityConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.redis.connection.RedisKeyCommands#copy(byte[], byte[])
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Boolean copy(byte[] sourceKey, byte[] targetKey) {
|
||||||
|
return convertAndReturn(delegate.copy(sourceKey, targetKey), Converters.identityConverter());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.redis.connection.RedisKeyCommands#unlink(byte[][])
|
* @see org.springframework.data.redis.connection.RedisKeyCommands#unlink(byte[][])
|
||||||
@@ -1917,6 +1927,15 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
|
|||||||
return del(serializeMulti(keys));
|
return del(serializeMulti(keys));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.redis.connection.StringRedisConnection#copy(java.lang.String[])
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Boolean copy(String sourceKey, String targetKey) {
|
||||||
|
return copy(serialize(sourceKey), serialize(targetKey));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.redis.connection.StringRedisConnection#unlink(java.lang.String[])
|
* @see org.springframework.data.redis.connection.StringRedisConnection#unlink(java.lang.String[])
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ import org.springframework.lang.Nullable;
|
|||||||
* @author Tugdual Grall
|
* @author Tugdual Grall
|
||||||
* @author Andrey Shlykov
|
* @author Andrey Shlykov
|
||||||
* @author dengliming
|
* @author dengliming
|
||||||
|
* @author ihaohong
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public interface DefaultedRedisConnection extends RedisConnection {
|
public interface DefaultedRedisConnection extends RedisConnection {
|
||||||
@@ -84,6 +85,13 @@ public interface DefaultedRedisConnection extends RedisConnection {
|
|||||||
return keyCommands().del(keys);
|
return keyCommands().del(keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @deprecated in favor of {@link RedisConnection#keyCommands()}. */
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
default Boolean copy(byte[] sourceKey, byte[] targetKey) {
|
||||||
|
return keyCommands().copy(sourceKey, targetKey);
|
||||||
|
}
|
||||||
|
|
||||||
/** @deprecated in favor of {@link RedisConnection#keyCommands()}. */
|
/** @deprecated in favor of {@link RedisConnection#keyCommands()}. */
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import org.springframework.util.Assert;
|
|||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
|
* @author ihaohong
|
||||||
*/
|
*/
|
||||||
public interface RedisKeyCommands {
|
public interface RedisKeyCommands {
|
||||||
|
|
||||||
@@ -71,6 +72,17 @@ public interface RedisKeyCommands {
|
|||||||
@Nullable
|
@Nullable
|
||||||
Long del(byte[]... keys);
|
Long del(byte[]... keys);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy given {@code sourceKey} to {@code targetKey}.
|
||||||
|
*
|
||||||
|
* @param sourceKey must not be {@literal null}.
|
||||||
|
* @param targetKey must not be {@literal null}.
|
||||||
|
* @return
|
||||||
|
* @see <a href="https://redis.io/commands/copy">Redis Documentation: COPY</a>
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
Boolean copy(byte[] sourceKey, byte[] targetKey);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unlink the {@code keys} from the keyspace. Unlike with {@link #del(byte[]...)} the actual memory reclaiming here
|
* Unlink the {@code keys} from the keyspace. Unlike with {@link #del(byte[]...)} the actual memory reclaiming here
|
||||||
* happens asynchronously.
|
* happens asynchronously.
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ import org.springframework.util.CollectionUtils;
|
|||||||
* @author Tugdual Grall
|
* @author Tugdual Grall
|
||||||
* @author Dengliming
|
* @author Dengliming
|
||||||
* @author Andrey Shlykov
|
* @author Andrey Shlykov
|
||||||
|
* @author ihaohong
|
||||||
|
*
|
||||||
* @see RedisCallback
|
* @see RedisCallback
|
||||||
* @see RedisSerializer
|
* @see RedisSerializer
|
||||||
* @see StringRedisTemplate
|
* @see StringRedisTemplate
|
||||||
@@ -132,6 +134,17 @@ public interface StringRedisConnection extends RedisConnection {
|
|||||||
*/
|
*/
|
||||||
Long del(String... keys);
|
Long del(String... keys);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy given {@code sourceKey} to {@code targetKey}.
|
||||||
|
*
|
||||||
|
* @param sourceKey must not be {@literal null}.
|
||||||
|
* @param targetKey must not be {@literal null}.
|
||||||
|
* @return
|
||||||
|
* @see <a href="https://redis.io/commands/copy">Redis Documentation: COPY</a>
|
||||||
|
* @see RedisKeyCommands#copy(byte[], byte[])
|
||||||
|
*/
|
||||||
|
Boolean copy(String sourceKey, String targetKey);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unlink the {@code keys} from the keyspace. Unlike with {@link #del(String...)} the actual memory reclaiming here
|
* Unlink the {@code keys} from the keyspace. Unlike with {@link #del(String...)} the actual memory reclaiming here
|
||||||
* happens asynchronously.
|
* happens asynchronously.
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import org.springframework.util.ObjectUtils;
|
|||||||
/**
|
/**
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
|
* @author ihaohong
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
class JedisClusterKeyCommands implements RedisKeyCommands {
|
class JedisClusterKeyCommands implements RedisKeyCommands {
|
||||||
@@ -87,6 +88,18 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
|
|||||||
.resultsAsList().size();
|
.resultsAsList().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.redis.connection.RedisKeyCommands#copy(byte[], byte[])
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Boolean copy(byte[] sourceKey, byte[] targetKey) {
|
||||||
|
Assert.notNull(sourceKey, "source key must not be null!");
|
||||||
|
Assert.notNull(targetKey, "target key must not be null!");
|
||||||
|
|
||||||
|
return connection.getCluster().copy(sourceKey, targetKey, false);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.redis.connection.RedisKeyCommands#unlink(byte[][])
|
* @see org.springframework.data.redis.connection.RedisKeyCommands#unlink(byte[][])
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import org.springframework.util.Assert;
|
|||||||
/**
|
/**
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
|
* @author ihaohong
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
class JedisKeyCommands implements RedisKeyCommands {
|
class JedisKeyCommands implements RedisKeyCommands {
|
||||||
@@ -90,6 +91,17 @@ class JedisKeyCommands implements RedisKeyCommands {
|
|||||||
return connection.invoke().just(BinaryJedis::del, MultiKeyPipelineBase::del, keys);
|
return connection.invoke().just(BinaryJedis::del, MultiKeyPipelineBase::del, keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.redis.connection.RedisKeyCommands#copy(byte[], byte[])
|
||||||
|
*/
|
||||||
|
public Boolean copy(byte[] sourceKey, byte[] targetKey) {
|
||||||
|
Assert.notNull(sourceKey, "source key must not be null!");
|
||||||
|
Assert.notNull(targetKey, "target key must not be null!");
|
||||||
|
|
||||||
|
return connection.invoke().just(BinaryJedis::copy, MultiKeyPipelineBase::copy, sourceKey, targetKey, false);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.redis.connection.RedisKeyCommands#unlink(byte[][])
|
* @see org.springframework.data.redis.connection.RedisKeyCommands#unlink(byte[][])
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ import org.springframework.util.ObjectUtils;
|
|||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @author Ninad Divadkar
|
* @author Ninad Divadkar
|
||||||
* @author Tamil Selvan
|
* @author Tamil Selvan
|
||||||
|
* @author ihaohong
|
||||||
*/
|
*/
|
||||||
public class LettuceConnection extends AbstractRedisConnection {
|
public class LettuceConnection extends AbstractRedisConnection {
|
||||||
|
|
||||||
@@ -1161,6 +1162,7 @@ public class LettuceConnection extends AbstractRedisConnection {
|
|||||||
COMMAND_OUTPUT_TYPE_MAPPING.put(DECR, IntegerOutput.class);
|
COMMAND_OUTPUT_TYPE_MAPPING.put(DECR, IntegerOutput.class);
|
||||||
COMMAND_OUTPUT_TYPE_MAPPING.put(DECRBY, IntegerOutput.class);
|
COMMAND_OUTPUT_TYPE_MAPPING.put(DECRBY, IntegerOutput.class);
|
||||||
COMMAND_OUTPUT_TYPE_MAPPING.put(DEL, IntegerOutput.class);
|
COMMAND_OUTPUT_TYPE_MAPPING.put(DEL, IntegerOutput.class);
|
||||||
|
COMMAND_OUTPUT_TYPE_MAPPING.put(COPY, IntegerOutput.class);
|
||||||
COMMAND_OUTPUT_TYPE_MAPPING.put(GETBIT, IntegerOutput.class);
|
COMMAND_OUTPUT_TYPE_MAPPING.put(GETBIT, IntegerOutput.class);
|
||||||
COMMAND_OUTPUT_TYPE_MAPPING.put(HDEL, IntegerOutput.class);
|
COMMAND_OUTPUT_TYPE_MAPPING.put(HDEL, IntegerOutput.class);
|
||||||
COMMAND_OUTPUT_TYPE_MAPPING.put(HINCRBY, IntegerOutput.class);
|
COMMAND_OUTPUT_TYPE_MAPPING.put(HINCRBY, IntegerOutput.class);
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import org.springframework.util.Assert;
|
|||||||
/**
|
/**
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
|
* @author ihaohong
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
class LettuceKeyCommands implements RedisKeyCommands {
|
class LettuceKeyCommands implements RedisKeyCommands {
|
||||||
@@ -90,6 +91,18 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
|||||||
return connection.invoke().just(RedisKeyAsyncCommands::del, keys);
|
return connection.invoke().just(RedisKeyAsyncCommands::del, keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.redis.connection.RedisKeyCommands#copy(byte[], byte[])
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Boolean copy(byte[] sourceKey, byte[] targetKey) {
|
||||||
|
Assert.notNull(sourceKey, "source key must not be null!");
|
||||||
|
Assert.notNull(targetKey, "target key must not be null!");
|
||||||
|
|
||||||
|
return connection.invoke().just(RedisKeyAsyncCommands::copy, targetKey, sourceKey);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.redis.connection.RedisKeyCommands#unlink(byte[][])
|
* @see org.springframework.data.redis.connection.RedisKeyCommands#unlink(byte[][])
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import org.springframework.util.Assert;
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @author Ninad Divadkar
|
* @author Ninad Divadkar
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
|
* @author ihaohong
|
||||||
*/
|
*/
|
||||||
public interface RedisOperations<K, V> {
|
public interface RedisOperations<K, V> {
|
||||||
|
|
||||||
@@ -199,6 +200,17 @@ public interface RedisOperations<K, V> {
|
|||||||
@Nullable
|
@Nullable
|
||||||
Long delete(Collection<K> keys);
|
Long delete(Collection<K> keys);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy given {@code sourceKey} to {@code targetKey}.
|
||||||
|
*
|
||||||
|
* @param sourceKey must not be {@literal null}.
|
||||||
|
* @param targetKey must not be {@literal null}.
|
||||||
|
* @return
|
||||||
|
* @see <a href="https://redis.io/commands/copy">Redis Documentation: COPY</a>
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
Boolean copy(K sourceKey, K targetKey);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unlink the {@code key} from the keyspace. Unlike with {@link #delete(Object)} the actual memory reclaiming here
|
* Unlink the {@code key} from the keyspace. Unlike with {@link #delete(Object)} the actual memory reclaiming here
|
||||||
* happens asynchronously.
|
* happens asynchronously.
|
||||||
|
|||||||
@@ -82,6 +82,8 @@ import org.springframework.util.CollectionUtils;
|
|||||||
* @author Anqing Shao
|
* @author Anqing Shao
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @author Denis Zavedeev
|
* @author Denis Zavedeev
|
||||||
|
* @author ihaohong
|
||||||
|
*
|
||||||
* @param <K> the Redis key type against which the template works (usually a String)
|
* @param <K> the Redis key type against which the template works (usually a String)
|
||||||
* @param <V> the Redis value type against which the template works
|
* @param <V> the Redis value type against which the template works
|
||||||
* @see StringRedisTemplate
|
* @see StringRedisTemplate
|
||||||
@@ -710,6 +712,14 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
|||||||
return result != null && result.intValue() == 1;
|
return result != null && result.intValue() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean copy(K source, K target) {
|
||||||
|
byte[] sourceKey = rawKey(source);
|
||||||
|
byte[] targetKey = rawKey(target);
|
||||||
|
|
||||||
|
return execute(connection -> connection.copy(sourceKey, targetKey), true);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.redis.core.RedisOperations#delete(java.util.Collection)
|
* @see org.springframework.data.redis.core.RedisOperations#delete(java.util.Collection)
|
||||||
|
|||||||
@@ -138,6 +138,12 @@ public class DefaultStringRedisConnectionPipelineTests extends DefaultStringRedi
|
|||||||
super.testDel();
|
super.testDel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCopy() {
|
||||||
|
doReturn(Collections.singletonList(Boolean.TRUE)).when(nativeConnection).closePipeline();
|
||||||
|
super.testCopy();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEchoBytes() {
|
public void testEchoBytes() {
|
||||||
doReturn(Arrays.asList(new Object[] { barBytes })).when(nativeConnection).closePipeline();
|
doReturn(Arrays.asList(new Object[] { barBytes })).when(nativeConnection).closePipeline();
|
||||||
|
|||||||
@@ -142,6 +142,13 @@ public class DefaultStringRedisConnectionPipelineTxTests extends DefaultStringRe
|
|||||||
super.testDel();
|
super.testDel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCopy() {
|
||||||
|
doReturn(Collections.singletonList(Collections.singletonList(Boolean.TRUE))).when(nativeConnection).closePipeline();
|
||||||
|
super.testCopy();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEchoBytes() {
|
public void testEchoBytes() {
|
||||||
doReturn(Collections.singletonList(Arrays.asList(new Object[] { barBytes }))).when(nativeConnection)
|
doReturn(Collections.singletonList(Arrays.asList(new Object[] { barBytes }))).when(nativeConnection)
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
|
|||||||
* @author Ninad Divadkar
|
* @author Ninad Divadkar
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @author dengliming
|
* @author dengliming
|
||||||
|
* @author ihaohong
|
||||||
*/
|
*/
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||||
@@ -235,6 +236,13 @@ public class DefaultStringRedisConnectionTests {
|
|||||||
verifyResults(Collections.singletonList(1L));
|
verifyResults(Collections.singletonList(1L));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCopy() {
|
||||||
|
doReturn(Boolean.TRUE).when(nativeConnection).copy(fooBytes, barBytes);
|
||||||
|
actual.add(connection.copy(foo, bar));
|
||||||
|
verifyResults(Collections.singletonList(Boolean.TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEchoBytes() {
|
public void testEchoBytes() {
|
||||||
doReturn(barBytes).when(nativeConnection).echo(fooBytes);
|
doReturn(barBytes).when(nativeConnection).echo(fooBytes);
|
||||||
|
|||||||
@@ -187,6 +187,10 @@ class RedisConnectionUnitTests {
|
|||||||
return delegate.del(keys);
|
return delegate.del(keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean copy(byte[] sourceKey, byte[] targetKey) {
|
||||||
|
return delegate.copy(sourceKey, targetKey);
|
||||||
|
}
|
||||||
|
|
||||||
public void close() throws DataAccessException {
|
public void close() throws DataAccessException {
|
||||||
super.close();
|
super.close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ import org.springframework.data.redis.test.util.CollectionAwareComparator;
|
|||||||
* @author Anqing Shao
|
* @author Anqing Shao
|
||||||
* @author Duobiao Ou
|
* @author Duobiao Ou
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
|
* @author ihaohong
|
||||||
*/
|
*/
|
||||||
@MethodSource("testParams")
|
@MethodSource("testParams")
|
||||||
public class RedisTemplateIntegrationTests<K, V> {
|
public class RedisTemplateIntegrationTests<K, V> {
|
||||||
@@ -390,6 +391,20 @@ public class RedisTemplateIntegrationTests<K, V> {
|
|||||||
assertThat(redisTemplate.hasKey(key1)).isFalse();
|
assertThat(redisTemplate.hasKey(key1)).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParameterizedRedisTest
|
||||||
|
void testCopy() {
|
||||||
|
K key1 = keyFactory.instance();
|
||||||
|
K key2 = keyFactory.instance();
|
||||||
|
V value1 = valueFactory.instance();
|
||||||
|
|
||||||
|
redisTemplate.opsForValue().set(key1, value1);
|
||||||
|
|
||||||
|
assertThat(redisTemplate.hasKey(key2)).isFalse();
|
||||||
|
redisTemplate.copy(key1, key2);
|
||||||
|
assertThat(redisTemplate.hasKey(key2)).isTrue();
|
||||||
|
assertThat(redisTemplate.opsForValue().get(key2)).isEqualTo(value1);
|
||||||
|
}
|
||||||
|
|
||||||
@ParameterizedRedisTest // DATAREDIS-688
|
@ParameterizedRedisTest // DATAREDIS-688
|
||||||
void testDeleteMultiple() {
|
void testDeleteMultiple() {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user