Support hDel with multiple hash keys
DATAREDIS-99
This commit is contained in:
@@ -305,8 +305,8 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
|
||||
return delegate.getSubscription();
|
||||
}
|
||||
|
||||
public Boolean hDel(byte[] key, byte[] field) {
|
||||
Boolean result = delegate.hDel(key, field);
|
||||
public Long hDel(byte[] key, byte[]... fields) {
|
||||
Long result = delegate.hDel(key, fields);
|
||||
if(isFutureConversion()) {
|
||||
addResultConverter(identityConverter);
|
||||
}
|
||||
@@ -1345,8 +1345,8 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
|
||||
}
|
||||
|
||||
|
||||
public Boolean hDel(String key, String field) {
|
||||
Boolean result = delegate.hDel(serialize(key), serialize(field));
|
||||
public Long hDel(String key, String... fields) {
|
||||
Long result = delegate.hDel(serialize(key), serializeMulti(fields));
|
||||
if(isFutureConversion()) {
|
||||
addResultConverter(identityConverter);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public interface RedisHashCommands {
|
||||
|
||||
Boolean hExists(byte[] key, byte[] field);
|
||||
|
||||
Boolean hDel(byte[] key, byte[] field);
|
||||
Long hDel(byte[] key, byte[]... fields);
|
||||
|
||||
Long hLen(byte[] key);
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@ public interface StringRedisConnection extends RedisConnection {
|
||||
|
||||
Boolean hExists(String key, String field);
|
||||
|
||||
Boolean hDel(String key, String field);
|
||||
Long hDel(String key, String... fields);
|
||||
|
||||
Long hLen(String key);
|
||||
|
||||
|
||||
@@ -2364,17 +2364,21 @@ public class JedisConnection implements RedisConnection {
|
||||
}
|
||||
|
||||
|
||||
public Boolean hDel(byte[] key, byte[] field) {
|
||||
public Long hDel(byte[] key, byte[]... fields) {
|
||||
if((isPipelined() || isQueueing()) && fields.length > 1) {
|
||||
throw new UnsupportedOperationException("hDel of multiple fields not supported " +
|
||||
"in pipeline or transaction");
|
||||
}
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(new JedisResult(pipeline.hdel(key, field), JedisConverters.longToBoolean()));
|
||||
pipeline(new JedisResult(pipeline.hdel(key, fields[0])));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(new JedisResult(transaction.hdel(key, field), JedisConverters.longToBoolean()));
|
||||
transaction(new JedisResult(transaction.hdel(key, fields[0])));
|
||||
return null;
|
||||
}
|
||||
return JedisConverters.toBoolean(jedis.hdel(key, field));
|
||||
return jedis.hdel(key, fields);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
|
||||
@@ -1116,9 +1116,12 @@ public class JredisConnection implements RedisConnection {
|
||||
}
|
||||
|
||||
|
||||
public Boolean hDel(byte[] key, byte[] field) {
|
||||
public Long hDel(byte[] key, byte[]... fields) {
|
||||
if(fields.length > 1) {
|
||||
throw new UnsupportedOperationException("hDel of multiple fields not supported");
|
||||
}
|
||||
try {
|
||||
return jredis.hdel(key, field);
|
||||
return JredisUtils.toLong(jredis.hdel(key, fields[0]));
|
||||
} catch (Exception ex) {
|
||||
throw convertJredisAccessException(ex);
|
||||
}
|
||||
|
||||
@@ -123,4 +123,8 @@ public abstract class JredisUtils {
|
||||
info.putAll(map);
|
||||
return info;
|
||||
}
|
||||
|
||||
static Long toLong(Boolean source) {
|
||||
return source ? 1l : 0l;
|
||||
}
|
||||
}
|
||||
@@ -2460,17 +2460,17 @@ public class LettuceConnection implements RedisConnection {
|
||||
}
|
||||
|
||||
|
||||
public Boolean hDel(byte[] key, byte[] field) {
|
||||
public Long hDel(byte[] key, byte[]... fields) {
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(new LettuceResult(getAsyncConnection().hdel(key, field), LettuceConverters.longToBoolean()));
|
||||
pipeline(new LettuceResult(getAsyncConnection().hdel(key, fields)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(new LettuceTxResult(getConnection().hdel(key, field), LettuceConverters.longToBoolean()));
|
||||
transaction(new LettuceTxResult(getConnection().hdel(key, fields)));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toBoolean(getConnection().hdel(key, field));
|
||||
return getConnection().hdel(key, fields);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
@@ -1887,13 +1887,13 @@ public class SrpConnection implements RedisConnection {
|
||||
}
|
||||
|
||||
|
||||
public Boolean hDel(byte[] key, byte[] field) {
|
||||
public Long hDel(byte[] key, byte[]... fields) {
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(new SrpResult(pipeline.hdel(key, new Object[] { field }), SrpConverters.longToBoolean()));
|
||||
pipeline(new SrpResult(pipeline.hdel(key, (Object[])fields)));
|
||||
return null;
|
||||
}
|
||||
return SrpConverters.toBoolean(client.hdel(key, new Object[] { field }).data());
|
||||
return client.hdel(key, (Object[])fields).data();
|
||||
} catch (Exception ex) {
|
||||
throw convertSrpAccessException(ex);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.util.Assert;
|
||||
* Internal base class used by various RedisTemplate XXXOperations implementations.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Jennifer Hickey
|
||||
*/
|
||||
abstract class AbstractOperations<K, V> {
|
||||
|
||||
@@ -97,6 +98,7 @@ abstract class AbstractOperations<K, V> {
|
||||
return keySerializer().serialize(key);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
byte[] rawString(String key) {
|
||||
return stringSerializer().serialize(key);
|
||||
}
|
||||
@@ -118,6 +120,15 @@ abstract class AbstractOperations<K, V> {
|
||||
return hashKeySerializer().serialize(hashKey);
|
||||
}
|
||||
|
||||
<HK> byte[][] rawHashKeys(HK... hashKeys) {
|
||||
final byte[][] rawHashKeys = new byte[hashKeys.length][];
|
||||
int i = 0;
|
||||
for (HK hashKey : hashKeys) {
|
||||
rawHashKeys[i++] = rawHashKey(hashKey);
|
||||
}
|
||||
return rawHashKeys;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<HV> byte[] rawHashValue(HV value) {
|
||||
if(hashValueSerializer() == null & value instanceof byte[]) {
|
||||
@@ -163,7 +174,7 @@ abstract class AbstractOperations<K, V> {
|
||||
return SerializationUtils.deserialize(rawValues, valueSerializer());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
Set<TypedTuple<V>> deserializeTupleValues(Set<Tuple> rawValues) {
|
||||
if(rawValues == null) {
|
||||
return null;
|
||||
|
||||
@@ -51,7 +51,7 @@ public interface BoundHashOperations<H, HK, HV> extends BoundKeyOperations<H> {
|
||||
|
||||
Long size();
|
||||
|
||||
void delete(Object key);
|
||||
void delete(Object... keys);
|
||||
|
||||
Map<HK, HV> entries();
|
||||
}
|
||||
|
||||
@@ -43,8 +43,8 @@ class DefaultBoundHashOperations<H, HK, HV> extends DefaultBoundKeyOperations<H>
|
||||
}
|
||||
|
||||
|
||||
public void delete(Object key) {
|
||||
ops.delete(getKey(), key);
|
||||
public void delete(Object... keys) {
|
||||
ops.delete(getKey(), keys);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -209,14 +209,14 @@ class DefaultHashOperations<K, HK, HV> extends AbstractOperations<K, Object> imp
|
||||
}
|
||||
|
||||
|
||||
public void delete(K key, Object hashKey) {
|
||||
public void delete(K key, Object... hashKeys) {
|
||||
final byte[] rawKey = rawKey(key);
|
||||
final byte[] rawHashKey = rawHashKey(hashKey);
|
||||
final byte[][] rawHashKeys = rawHashKeys(hashKeys);
|
||||
|
||||
execute(new RedisCallback<Object>() {
|
||||
|
||||
public Object doInRedis(RedisConnection connection) {
|
||||
connection.hDel(rawKey, rawHashKey);
|
||||
connection.hDel(rawKey, rawHashKeys);
|
||||
return null;
|
||||
}
|
||||
}, true);
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.util.Set;
|
||||
*/
|
||||
public interface HashOperations<H, HK, HV> {
|
||||
|
||||
void delete(H key, Object hashKey);
|
||||
void delete(H key, Object... hashKeys);
|
||||
|
||||
Boolean hasKey(H key, Object hashKey);
|
||||
|
||||
|
||||
@@ -1762,7 +1762,17 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
actual.add(connection.hDel("test", "key"));
|
||||
actual.add(connection.hDel("test", "foo"));
|
||||
actual.add(connection.hExists("test", "key"));
|
||||
verifyResults(Arrays.asList(new Object[] { true, true, false, false }));
|
||||
verifyResults(Arrays.asList(new Object[] { true, 1l, 0l, false }));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHDelMultiple() {
|
||||
actual.add(connection.hSet("test", "key", "val"));
|
||||
actual.add(connection.hSet("test", "foo", "bar"));
|
||||
actual.add(connection.hDel("test", "key", "foo"));
|
||||
actual.add(connection.hExists("test", "key"));
|
||||
actual.add(connection.hExists("test", "foo"));
|
||||
verifyResults(Arrays.asList(new Object[] { true, true, 2l, false, false }));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -254,13 +254,13 @@ public class DefaultStringRedisConnectionPipelineTests extends DefaultStringRedi
|
||||
|
||||
@Test
|
||||
public void testHDelBytes() {
|
||||
doReturn(Arrays.asList(new Object[] { true })).when(nativeConnection).closePipeline();
|
||||
doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).closePipeline();
|
||||
super.testHDelBytes();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHDel() {
|
||||
doReturn(Arrays.asList(new Object[] { true })).when(nativeConnection).closePipeline();
|
||||
doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).closePipeline();
|
||||
super.testHDel();
|
||||
}
|
||||
|
||||
|
||||
@@ -222,13 +222,13 @@ public class DefaultStringRedisConnectionPipelineTxTests extends
|
||||
|
||||
@Test
|
||||
public void testHDelBytes() {
|
||||
doReturn(Arrays.asList(new Object[] {Arrays.asList(new Object[] { true })})).when(nativeConnection).closePipeline();
|
||||
doReturn(Arrays.asList(new Object[] {Arrays.asList(new Object[] { 1l })})).when(nativeConnection).closePipeline();
|
||||
super.testHDelBytes();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHDel() {
|
||||
doReturn(Arrays.asList(new Object[] {Arrays.asList(new Object[] { true })})).when(nativeConnection).closePipeline();
|
||||
doReturn(Arrays.asList(new Object[] {Arrays.asList(new Object[] { 1l })})).when(nativeConnection).closePipeline();
|
||||
super.testHDel();
|
||||
}
|
||||
|
||||
|
||||
@@ -326,16 +326,16 @@ public class DefaultStringRedisConnectionTests {
|
||||
|
||||
@Test
|
||||
public void testHDelBytes() {
|
||||
doReturn(true).when(nativeConnection).hDel(fooBytes, barBytes);
|
||||
doReturn(1l).when(nativeConnection).hDel(fooBytes, barBytes);
|
||||
actual.add(connection.hDel(fooBytes, barBytes));
|
||||
verifyResults(Arrays.asList(new Object[] { true }));
|
||||
verifyResults(Arrays.asList(new Object[] { 1l }));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHDel() {
|
||||
doReturn(true).when(nativeConnection).hDel(fooBytes, barBytes);
|
||||
doReturn(1l).when(nativeConnection).hDel(fooBytes, barBytes);
|
||||
actual.add(connection.hDel(foo, bar));
|
||||
verifyResults(Arrays.asList(new Object[] { true }));
|
||||
verifyResults(Arrays.asList(new Object[] { 1l }));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -221,13 +221,13 @@ public class DefaultStringRedisConnectionTxTests extends DefaultStringRedisConne
|
||||
|
||||
@Test
|
||||
public void testHDelBytes() {
|
||||
doReturn(Arrays.asList(new Object[] { true })).when(nativeConnection).exec();
|
||||
doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).exec();
|
||||
super.testHDelBytes();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHDel() {
|
||||
doReturn(Arrays.asList(new Object[] { true })).when(nativeConnection).exec();
|
||||
doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).exec();
|
||||
super.testHDel();
|
||||
}
|
||||
|
||||
|
||||
@@ -426,4 +426,9 @@ public class JedisConnectionPipelineIntegrationTests extends
|
||||
public void testInfoBySection() throws Exception {
|
||||
super.testInfoBySection();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
public void testHDelMultiple() {
|
||||
super.testHDelMultiple();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,4 +362,9 @@ public class JedisConnectionTransactionIntegrationTests extends
|
||||
public void testLastSave() {
|
||||
super.testLastSave();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
public void testHDelMultiple() {
|
||||
super.testHDelMultiple();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -560,6 +560,11 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat
|
||||
super.testInfoBySection();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
public void testHDelMultiple() {
|
||||
super.testHDelMultiple();
|
||||
}
|
||||
|
||||
// Jredis returns null for rPush and lPush
|
||||
@Test
|
||||
public void testLLen() {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.data.redis.matcher.RedisTestMatchers.isEqual;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -117,4 +118,17 @@ public class DefaultHashOperationsTests<K,HK,HV> {
|
||||
expected.put(key2, val2);
|
||||
assertThat(hashOps.entries(key), isEqual(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete() {
|
||||
K key = keyFactory.instance();
|
||||
HK key1 = hashKeyFactory.instance();
|
||||
HV val1 = hashValueFactory.instance();
|
||||
HK key2 = hashKeyFactory.instance();
|
||||
HV val2 = hashValueFactory.instance();
|
||||
hashOps.put(key, key1, val1);
|
||||
hashOps.put(key, key2, val2);
|
||||
hashOps.delete(key, key1, key2);
|
||||
assertTrue(hashOps.keys(key).isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user