Support sAdd with multiple values

DATAREDIS-99
This commit is contained in:
Jennifer Hickey
2013-08-01 12:23:47 -07:00
parent 6ad3bcf688
commit d4377b4d17
22 changed files with 106 additions and 59 deletions

View File

@@ -661,8 +661,8 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
return result;
}
public Boolean sAdd(byte[] key, byte[] value) {
Boolean result = delegate.sAdd(key, value);
public Long sAdd(byte[] key, byte[]... values) {
Long result = delegate.sAdd(key, values);
if(isFutureConversion()) {
addResultConverter(identityConverter);
}
@@ -1676,8 +1676,8 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
}
public Boolean sAdd(String key, String value) {
Boolean result = delegate.sAdd(serialize(key), serialize(value));
public Long sAdd(String key, String... values) {
Long result = delegate.sAdd(serialize(key), serializeMulti(values));
if(isFutureConversion()) {
addResultConverter(identityConverter);
}

View File

@@ -26,7 +26,7 @@ import java.util.Set;
*/
public interface RedisSetCommands {
Boolean sAdd(byte[] key, byte[] value);
Long sAdd(byte[] key, byte[]... values);
Boolean sRem(byte[] key, byte[] value);

View File

@@ -159,7 +159,7 @@ public interface StringRedisConnection extends RedisConnection {
String bRPopLPush(int timeout, String srcKey, String dstKey);
Boolean sAdd(String key, String value);
Long sAdd(String key, String... values);
Boolean sRem(String key, String value);

View File

@@ -1631,19 +1631,21 @@ public class JedisConnection implements RedisConnection {
//
public Boolean sAdd(byte[] key, byte[] value) {
public Long sAdd(byte[] key, byte[]... values) {
if((isPipelined() || isQueueing()) && values.length > 1) {
throw new UnsupportedOperationException("sAdd of multiple fields not supported " +
"in pipeline or transaction");
}
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.sadd(key, value),
JedisConverters.longToBoolean()));
pipeline(new JedisResult(pipeline.sadd(key, values[0])));
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.sadd(key, value),
JedisConverters.longToBoolean()));
transaction(new JedisResult(transaction.sadd(key, values[0])));
return null;
}
return JedisConverters.toBoolean(jedis.sadd(key, value));
return jedis.sadd(key, values);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}

View File

@@ -785,9 +785,12 @@ public class JredisConnection implements RedisConnection {
//
public Boolean sAdd(byte[] key, byte[] value) {
public Long sAdd(byte[] key, byte[]... values) {
if(values.length > 1) {
throw new UnsupportedOperationException("sAdd of multiple fields not supported");
}
try {
return jredis.sadd(key, value);
return JredisUtils.toLong(jredis.sadd(key, values[0]));
} catch (Exception ex) {
throw convertJredisAccessException(ex);
}

View File

@@ -44,7 +44,6 @@ import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.SortParameters;
import org.springframework.data.redis.connection.Subscription;
import org.springframework.data.redis.connection.convert.TransactionResultConverter;
import org.springframework.data.redis.connection.srp.SrpConverters;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -1707,17 +1706,17 @@ public class LettuceConnection implements RedisConnection {
//
public Boolean sAdd(byte[] key, byte[] value) {
public Long sAdd(byte[] key, byte[]... values) {
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().sadd(key, value), SrpConverters.longToBoolean()));
pipeline(new LettuceResult(getAsyncConnection().sadd(key, values)));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().sadd(key, value), SrpConverters.longToBoolean()));
transaction(new LettuceTxResult(getConnection().sadd(key, values)));
return null;
}
return SrpConverters.toBoolean(getConnection().sadd(key, value));
return getConnection().sadd(key, values);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}

View File

@@ -1335,13 +1335,13 @@ public class SrpConnection implements RedisConnection {
//
public Boolean sAdd(byte[] key, byte[] value) {
public Long sAdd(byte[] key, byte[]... values) {
try {
if (isPipelined()) {
pipeline(new SrpResult(pipeline.sadd(key, new Object[] { value }), SrpConverters.longToBoolean()));
pipeline(new SrpResult(pipeline.sadd(key, (Object[]) values)));
return null;
}
return SrpConverters.toBoolean(client.sadd(key, new Object[] { value }).data());
return client.sadd(key, (Object[]) values).data();
} catch (Exception ex) {
throw convertSrpAccessException(ex);
}

View File

@@ -53,7 +53,7 @@ public interface BoundSetOperations<K, V> extends BoundKeyOperations<K> {
void unionAndStore(Collection<K> keys, K destKey);
Boolean add(V value);
Long add(V... values);
Boolean isMember(Object o);

View File

@@ -44,8 +44,8 @@ class DefaultBoundSetOperations<K, V> extends DefaultBoundKeyOperations<K> imple
}
public Boolean add(V value) {
return ops.add(getKey(), value);
public Long add(V... values) {
return ops.add(getKey(), values);
}

View File

@@ -35,13 +35,13 @@ class DefaultSetOperations<K, V> extends AbstractOperations<K, V> implements Set
}
public Boolean add(K key, V value) {
public Long add(K key, V... values) {
final byte[] rawKey = rawKey(key);
final byte[] rawValue = rawValue(value);
return execute(new RedisCallback<Boolean>() {
final byte[][] rawValues = rawValues(values);
return execute(new RedisCallback<Long>() {
public Boolean doInRedis(RedisConnection connection) {
return connection.sAdd(rawKey, rawValue);
public Long doInRedis(RedisConnection connection) {
return connection.sAdd(rawKey, rawValues);
}
}, true);
}

View File

@@ -51,7 +51,7 @@ public interface SetOperations<K, V> {
Long unionAndStore(K key, Collection<K> otherKeys, K destKey);
Boolean add(K key, V value);
Long add(K key, V... values);
Boolean isMember(K key, Object o);

View File

@@ -139,10 +139,11 @@ public class DefaultRedisSet<E> extends AbstractRedisCollection<E> implements Re
}
@SuppressWarnings("unchecked")
public boolean add(E e) {
Boolean result = boundSetOps.add(e);
Long result = boundSetOps.add(e);
checkResult(result);
return result;
return result == 1;
}

View File

@@ -1281,7 +1281,17 @@ public abstract class AbstractConnectionIntegrationTests {
actual.add(connection.sAdd("myset", "foo"));
actual.add(connection.sAdd("myset", "bar"));
actual.add(connection.sMembers("myset"));
verifyResults(Arrays.asList(new Object[] { true, true, new HashSet<String>(Arrays.asList(new String[] { "foo", "bar" })) }));
verifyResults(Arrays.asList(new Object[] { 1l, 1l, new HashSet<String>(Arrays.asList(new String[] {
"foo", "bar" })) }));
}
@Test
public void testSAddMultiple() {
actual.add(connection.sAdd("myset", "foo", "bar"));
actual.add(connection.sAdd("myset", "baz"));
actual.add(connection.sMembers("myset"));
verifyResults(Arrays.asList(new Object[] { 2l, 1l, new HashSet<String>(Arrays.asList(new String[] {
"foo", "bar", "baz" })) }));
}
@Test
@@ -1289,7 +1299,7 @@ public abstract class AbstractConnectionIntegrationTests {
actual.add(connection.sAdd("myset", "foo"));
actual.add(connection.sAdd("myset", "bar"));
actual.add(connection.sCard("myset"));
verifyResults(Arrays.asList(new Object[] { true, true, 2l }));
verifyResults(Arrays.asList(new Object[] { 1l, 1l, 2l }));
}
@Test
@@ -1299,7 +1309,7 @@ public abstract class AbstractConnectionIntegrationTests {
actual.add(connection.sAdd("otherset", "bar"));
actual.add(connection.sDiff("myset", "otherset"));
verifyResults(
Arrays.asList(new Object[] { true, true, true,
Arrays.asList(new Object[] { 1l, 1l, 1l,
new HashSet<String>(Collections.singletonList("foo")) }));
}
@@ -1311,7 +1321,7 @@ public abstract class AbstractConnectionIntegrationTests {
actual.add(connection.sDiffStore("thirdset", "myset", "otherset"));
actual.add(connection.sMembers("thirdset"));
verifyResults(
Arrays.asList(new Object[] { true, true, true, 1l,
Arrays.asList(new Object[] { 1l, 1l, 1l, 1l,
new HashSet<String>(Collections.singletonList("foo")) }));
}
@@ -1322,7 +1332,7 @@ public abstract class AbstractConnectionIntegrationTests {
actual.add(connection.sAdd("otherset", "bar"));
actual.add(connection.sInter("myset", "otherset"));
verifyResults(
Arrays.asList(new Object[] { true, true, true,
Arrays.asList(new Object[] { 1l, 1l, 1l,
new HashSet<String>(Collections.singletonList("bar")) }));
}
@@ -1334,7 +1344,7 @@ public abstract class AbstractConnectionIntegrationTests {
actual.add(connection.sInterStore("thirdset", "myset", "otherset"));
actual.add(connection.sMembers("thirdset"));
verifyResults(
Arrays.asList(new Object[] { true, true, true, 1l,
Arrays.asList(new Object[] { 1l, 1l, 1l, 1l,
new HashSet<String>(Collections.singletonList("bar")) }));
}
@@ -1344,7 +1354,7 @@ public abstract class AbstractConnectionIntegrationTests {
actual.add(connection.sAdd("myset", "bar"));
actual.add(connection.sIsMember("myset", "foo"));
actual.add(connection.sIsMember("myset", "baz"));
verifyResults(Arrays.asList(new Object[] { true, true, true, false }));
verifyResults(Arrays.asList(new Object[] { 1l, 1l, true, false }));
}
@Test
@@ -1353,7 +1363,7 @@ public abstract class AbstractConnectionIntegrationTests {
actual.add(connection.sAdd("myset", "bar"));
actual.add(connection.sAdd("otherset", "bar"));
actual.add(connection.sMove("myset", "otherset", "foo"));
verifyResults(Arrays.asList(new Object[] { true, true, true, true }));
verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, true }));
}
@Test
@@ -1416,7 +1426,7 @@ public abstract class AbstractConnectionIntegrationTests {
actual.add(connection.sRem("myset", "baz"));
actual.add(connection.sMembers("myset"));
verifyResults(
Arrays.asList(new Object[] { true, true, true, false,
Arrays.asList(new Object[] { 1l, 1l, true, false,
new HashSet<String>(Collections.singletonList("bar")) }));
}
@@ -1427,7 +1437,7 @@ public abstract class AbstractConnectionIntegrationTests {
actual.add(connection.sAdd("otherset", "bar"));
actual.add(connection.sAdd("otherset", "baz"));
actual.add(connection.sUnion("myset", "otherset"));
verifyResults(Arrays.asList(new Object[] { true, true, true, true,
verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, 1l,
new HashSet<String>(Arrays.asList(new String[] { "foo", "bar", "baz" })) }));
}
@@ -1439,7 +1449,7 @@ public abstract class AbstractConnectionIntegrationTests {
actual.add(connection.sAdd("otherset", "baz"));
actual.add(connection.sUnionStore("thirdset", "myset", "otherset"));
actual.add(connection.sMembers("thirdset"));
verifyResults(Arrays.asList(new Object[] { true, true, true, true, 3l,
verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, 1l, 3l,
new HashSet<String>(Arrays.asList(new String[] { "foo", "bar", "baz" })) }));
}

View File

@@ -697,13 +697,13 @@ public class DefaultStringRedisConnectionPipelineTests extends DefaultStringRedi
@Test
public void testSAddBytes() {
doReturn(Arrays.asList(new Object[] { true })).when(nativeConnection).closePipeline();
doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).closePipeline();
super.testSAddBytes();
}
@Test
public void testSAdd() {
doReturn(Arrays.asList(new Object[] { true })).when(nativeConnection).closePipeline();
doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).closePipeline();
super.testSAdd();
}

View File

@@ -665,13 +665,13 @@ public class DefaultStringRedisConnectionPipelineTxTests extends
@Test
public void testSAddBytes() {
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.testSAddBytes();
}
@Test
public void testSAdd() {
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.testSAdd();
}

View File

@@ -842,16 +842,16 @@ public class DefaultStringRedisConnectionTests {
@Test
public void testSAddBytes() {
doReturn(true).when(nativeConnection).sAdd(fooBytes, barBytes);
doReturn(1l).when(nativeConnection).sAdd(fooBytes, barBytes);
actual.add(connection.sAdd(fooBytes, barBytes));
verifyResults(Arrays.asList(new Object[] { true }));
verifyResults(Arrays.asList(new Object[] { 1l }));
}
@Test
public void testSAdd() {
doReturn(true).when(nativeConnection).sAdd(fooBytes, barBytes);
doReturn(1l).when(nativeConnection).sAdd(fooBytes, barBytes);
actual.add(connection.sAdd(foo, bar));
verifyResults(Arrays.asList(new Object[] { true }));
verifyResults(Arrays.asList(new Object[] { 1l }));
}
@Test

View File

@@ -664,13 +664,13 @@ public class DefaultStringRedisConnectionTxTests extends DefaultStringRedisConne
@Test
public void testSAddBytes() {
doReturn(Arrays.asList(new Object[] { true })).when(nativeConnection).exec();
doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).exec();
super.testSAddBytes();
}
@Test
public void testSAdd() {
doReturn(Arrays.asList(new Object[] { true })).when(nativeConnection).exec();
doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).exec();
super.testSAdd();
}

View File

@@ -441,4 +441,9 @@ public class JedisConnectionPipelineIntegrationTests extends
public void testRPushMultiple() {
super.testRPushMultiple();
}
@Test(expected=UnsupportedOperationException.class)
public void testSAddMultiple() {
super.testSAddMultiple();
}
}

View File

@@ -377,4 +377,9 @@ public class JedisConnectionTransactionIntegrationTests extends
public void testRPushMultiple() {
super.testRPushMultiple();
}
@Test(expected=UnsupportedOperationException.class)
public void testSAddMultiple() {
super.testSAddMultiple();
}
}

View File

@@ -575,6 +575,11 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat
super.testRPushMultiple();
}
@Test(expected=UnsupportedOperationException.class)
public void testSAddMultiple() {
super.testSAddMultiple();
}
// Jredis returns null for rPush and lPush
@Test
public void testLLen() {
@@ -705,7 +710,7 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat
actual.add(connection.sDiffStore("thirdset", "myset", "otherset"));
actual.add(connection.sMembers("thirdset"));
// JRedis returns void for sDiffStore, so we always return -1
verifyResults(Arrays.asList(new Object[] { true, true, true, -1l,
verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, -1l,
new HashSet<String>(Collections.singletonList("foo")) }));
}
@@ -717,7 +722,7 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat
actual.add(connection.sInterStore("thirdset", "myset", "otherset"));
actual.add(connection.sMembers("thirdset"));
// JRedis returns void for sInterStore, so we always return -1
verifyResults(Arrays.asList(new Object[] { true, true, true, -1l,
verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, -1l,
new HashSet<String>(Collections.singletonList("bar")) }));
}
@@ -730,7 +735,7 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat
actual.add(connection.sUnionStore("thirdset", "myset", "otherset"));
actual.add(connection.sMembers("thirdset"));
// JRedis returns void for sUnionStore, so we always return -1
verifyResults(Arrays.asList(new Object[] { true, true, true, true, -1l,
verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, 1l, -1l,
new HashSet<String>(Arrays.asList(new String[] { "foo", "bar", "baz" })) }));
}

View File

@@ -105,6 +105,7 @@ public class DefaultSetOperationsTests<K,V> {
assertThat(expected, hasItems((V[])members.toArray()));
}
@SuppressWarnings("unchecked")
@Test
public void testRandomMembersWithDuplicates() {
assumeTrue(RedisTestProfileValueSource.matches("redisVersion", "2.6"));
@@ -138,6 +139,7 @@ public class DefaultSetOperationsTests<K,V> {
}
}
@SuppressWarnings("unchecked")
@Test
public void testMove() {
K key1 = keyFactory.instance();
@@ -153,6 +155,7 @@ public class DefaultSetOperationsTests<K,V> {
isEqual(new HashSet<V>(Collections.singletonList(v1))));
}
@SuppressWarnings("unchecked")
@Test
public void testPop() {
K key = keyFactory.instance();
@@ -162,6 +165,7 @@ public class DefaultSetOperationsTests<K,V> {
assertTrue(setOps.members(key).isEmpty());
}
@SuppressWarnings("unchecked")
@Test
public void testRandomMember() {
K key = keyFactory.instance();
@@ -169,4 +173,17 @@ public class DefaultSetOperationsTests<K,V> {
setOps.add(key, v1);
assertThat(setOps.randomMember(key), isEqual(v1));
}
@SuppressWarnings("unchecked")
@Test
public void testAdd() {
K key = keyFactory.instance();
V v1 = valueFactory.instance();
V v2 = valueFactory.instance();
assertEquals(Long.valueOf(2), setOps.add(key, v1, v2));
Set<V> expected = new HashSet<V>();
expected.add(v1);
expected.add(v2);
assertThat(setOps.members(key), isEqual(expected));
}
}

View File

@@ -190,7 +190,7 @@ public class RedisTemplateTests<K,V> {
Set<V> set = new HashSet<V>(Collections.singletonList(setValue));
Set<TypedTuple<V>> tupleSet = new LinkedHashSet<TypedTuple<V>>(
Collections.singletonList(new DefaultTypedTuple<V>(zsetValue, 1d)));
assertThat(results, isEqual(Arrays.asList(new Object[] {value1, 1l, list, true, set, true, tupleSet})));
assertThat(results, isEqual(Arrays.asList(new Object[] {value1, 1l, list, 1l, set, true, tupleSet})));
}
@Test
@@ -241,7 +241,7 @@ public class RedisTemplateTests<K,V> {
Map<Long, Long> map = new LinkedHashMap<Long,Long>();
map.put(10l, 11l);
assertThat(results,
isEqual(Arrays.asList(new Object[] {5l, 1l, list, true, longSet, true, tupleSet, zSet, true, map})));
isEqual(Arrays.asList(new Object[] {5l, 1l, list, 1l, longSet, true, tupleSet, zSet, true, map})));
}
@Test