diff --git a/pom.xml b/pom.xml
index e2e0f007c6..474950c8e3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-redis
- 1.7.0.BUILD-SNAPSHOT
+ 1.7.0.DATAREDIS-479-SNAPSHOT
Spring Data Redis
@@ -23,7 +23,7 @@
1.4.8
2.2
3.4.2.Final
- 2.8.0
+ 2.8.1
0.7
06052013
1.01
diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java
index b1c3aaa577..f7a87624b8 100644
--- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 the original author or authors.
+ * Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -74,6 +74,7 @@
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ZParams;
/**
@@ -1532,10 +1533,9 @@ public Cursor sScan(final byte[] key, ScanOptions options) {
@Override
protected ScanIteration doScan(long cursorId, ScanOptions options) {
- redis.clients.jedis.ScanResult result = cluster.sscan(JedisConverters.toString(key),
- Long.toString(cursorId));
- return new ScanIteration(Long.valueOf(result.getCursor()),
- JedisConverters.stringListToByteList().convert(result.getResult()));
+ ScanParams params = JedisConverters.toScanParams(options);
+ redis.clients.jedis.ScanResult result = cluster.sscan(key, JedisConverters.toBytes(cursorId), params);
+ return new ScanIteration(Long.valueOf(result.getStringCursor()), result.getResult());
}
}.open();
}
@@ -2158,8 +2158,19 @@ public Long zInterStore(byte[] destKey, Aggregate aggregate, int[] weights, byte
}
@Override
- public Cursor zScan(byte[] key, ScanOptions options) {
- throw new UnsupportedOperationException("Jedis does currently not support binary zscan command.");
+ public Cursor zScan(final byte[] key, final ScanOptions options) {
+ return new ScanCursor(options) {
+
+ @Override
+ protected ScanIteration doScan(long cursorId, ScanOptions options) {
+
+ ScanParams params = JedisConverters.toScanParams(options);
+
+ redis.clients.jedis.ScanResult result = cluster.zscan(key, JedisConverters.toBytes(cursorId), params);
+ return new ScanIteration(Long.valueOf(result.getStringCursor()), JedisConverters
+ .tuplesToTuples().convert(result.getResult()));
+ }
+ }.open();
}
/*
@@ -2387,7 +2398,11 @@ public Cursor> hScan(final byte[] key, ScanOptions options
@Override
protected ScanIteration> doScan(long cursorId, ScanOptions options) {
- throw new UnsupportedOperationException("Jedis does currently not support binary hscan");
+
+ ScanParams params = JedisConverters.toScanParams(options);
+
+ redis.clients.jedis.ScanResult> result = cluster.hscan(key, JedisConverters.toBytes(cursorId), params);
+ return new ScanIteration>(Long.valueOf(result.getStringCursor()), result.getResult());
}
}.open();
}
diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java
index be7094d98d..94ffd486a1 100644
--- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java
@@ -60,7 +60,6 @@
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
-import org.springframework.util.StringUtils;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.BinaryJedisPubSub;
@@ -92,6 +91,7 @@
* @author Konstantin Shchepanovskyi
* @author David Liu
* @author Milan Agatonovic
+ * @author Mark Paluch
*/
public class JedisConnection extends AbstractRedisConnection {
@@ -3315,7 +3315,7 @@ protected ScanIteration doScan(long cursorId, ScanOptions options) {
throw new UnsupportedOperationException("'SCAN' cannot be called in pipeline / transaction mode.");
}
- ScanParams params = prepareScanParams(options);
+ ScanParams params = JedisConverters.toScanParams(options);
redis.clients.jedis.ScanResult result = jedis.scan(Long.toString(cursorId), params);
return new ScanIteration(Long.valueOf(result.getStringCursor()), JedisConverters.stringListToByteList()
.convert(result.getResult()));
@@ -3352,7 +3352,7 @@ protected ScanIteration doScan(byte[] key, long cursorId, ScanOptions opt
throw new UnsupportedOperationException("'ZSCAN' cannot be called in pipeline / transaction mode.");
}
- ScanParams params = prepareScanParams(options);
+ ScanParams params = JedisConverters.toScanParams(options);
ScanResult result = jedis.zscan(key, JedisConverters.toBytes(cursorId), params);
return new ScanIteration(Long.valueOf(result.getStringCursor()), JedisConverters
@@ -3389,7 +3389,7 @@ protected ScanIteration doScan(byte[] key, long cursorId, ScanOptions op
throw new UnsupportedOperationException("'SSCAN' cannot be called in pipeline / transaction mode.");
}
- ScanParams params = prepareScanParams(options);
+ ScanParams params = JedisConverters.toScanParams(options);
redis.clients.jedis.ScanResult result = jedis.sscan(key, JedisConverters.toBytes(cursorId), params);
return new ScanIteration(Long.valueOf(result.getStringCursor()), result.getResult());
@@ -3424,7 +3424,7 @@ protected ScanIteration> doScan(byte[] key, long cursorId,
throw new UnsupportedOperationException("'HSCAN' cannot be called in pipeline / transaction mode.");
}
- ScanParams params = prepareScanParams(options);
+ ScanParams params = JedisConverters.toScanParams(options);
ScanResult> result = jedis.hscan(key, JedisConverters.toBytes(cursorId), params);
return new ScanIteration>(Long.valueOf(result.getStringCursor()), result.getResult());
@@ -3432,19 +3432,6 @@ protected ScanIteration> doScan(byte[] key, long cursorId,
}.open();
}
- private ScanParams prepareScanParams(ScanOptions options) {
- ScanParams sp = new ScanParams();
- if (!options.equals(ScanOptions.NONE)) {
- if (options.getCount() != null) {
- sp.count(options.getCount().intValue());
- }
- if (StringUtils.hasText(options.getPattern())) {
- sp.match(options.getPattern());
- }
- }
- return sp;
- }
-
/**
* Specifies if pipelined results should be converted to the expected data type. If false, results of
* {@link #closePipeline()} and {@link #exec()} will be of the type returned by the Jedis driver
diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java
index 6913073aee..c241c60a6c 100644
--- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java
+++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java
@@ -42,6 +42,7 @@
import org.springframework.data.redis.connection.convert.MapConverter;
import org.springframework.data.redis.connection.convert.SetConverter;
import org.springframework.data.redis.connection.convert.StringToRedisClientInfoConverter;
+import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.util.Assert;
@@ -51,6 +52,7 @@
import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.jedis.BitOP;
+import redis.clients.jedis.ScanParams;
import redis.clients.jedis.SortingParams;
import redis.clients.util.SafeEncoder;
@@ -432,4 +434,26 @@ private static byte[] boundaryToBytes(Boundary boundary, byte[] inclPrefix, byte
return buffer.array();
}
+
+ /**
+ * Convert {@link ScanOptions} to Jedis {@link ScanParams}.
+ *
+ * @param options
+ * @return
+ */
+ public static ScanParams toScanParams(ScanOptions options) {
+
+ ScanParams sp = new ScanParams();
+
+ if (!options.equals(ScanOptions.NONE)) {
+ if (options.getCount() != null) {
+ sp.count(options.getCount().intValue());
+ }
+ if (StringUtils.hasText(options.getPattern())) {
+ sp.match(options.getPattern());
+ }
+ }
+ return sp;
+ }
+
}
diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java
index da207dab9a..527e3c1a03 100644
--- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java
+++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java
@@ -20,6 +20,7 @@
import static org.hamcrest.number.IsCloseTo.*;
import static org.junit.Assert.*;
import static org.springframework.data.redis.connection.ClusterTestVariables.*;
+import static org.springframework.data.redis.core.ScanOptions.scanOptions;
import java.io.IOException;
import java.util.Arrays;
@@ -1769,6 +1770,33 @@ public void zInterStoreShouldWorkForSameSlotKeys() {
public void zInterStoreShouldThrowExceptionWhenKeysDoNotMapToSameSlots() {
clusterConnection.zInterStore(KEY_3_BYTES, KEY_1_BYTES, KEY_2_BYTES);
}
+
+
+ /**
+ * @see DATAREDIS-479
+ */
+ @Test
+ public void zScanShouldReadEntireValueRange() {
+
+ nativeConnection.zadd(KEY_1_BYTES, 2, VALUE_1_BYTES);
+ nativeConnection.zadd(KEY_1_BYTES, 1, VALUE_2_BYTES);
+ nativeConnection.zadd(KEY_1_BYTES, 4, VALUE_3_BYTES);
+
+ Cursor tuples = clusterConnection.zScan(KEY_1_BYTES, ScanOptions.NONE);
+
+ int count = 0;
+ while (tuples.hasNext()) {
+
+ Tuple tuple = tuples.next();
+
+ assertThat(tuple.getValue(), anyOf(equalTo(VALUE_1_BYTES), equalTo(VALUE_2_BYTES), equalTo(VALUE_3_BYTES)));
+ assertThat(tuple.getScore(), anyOf(equalTo(1D), equalTo(2D), equalTo(4D)));
+
+ count++;
+ }
+
+ assertThat(count, equalTo(3));
+ }
/**
* @see DATAREDIS-315
@@ -1952,6 +1980,32 @@ public void hGetAllShouldRetrieveEntriesCorrectly() {
assertThat(hGetAll.containsKey(KEY_2_BYTES), is(true));
assertThat(hGetAll.containsKey(KEY_3_BYTES), is(true));
}
+
+ /**
+ * @see DATAREDIS-479
+ */
+ @Test
+ public void hScanShouldReadEntireValueRange() {
+
+ clusterConnection.hSet(KEY_1_BYTES, KEY_1_BYTES, VALUE_1_BYTES);
+ clusterConnection.hSet(KEY_1_BYTES, KEY_2_BYTES, VALUE_2_BYTES);
+ clusterConnection.hSet(KEY_1_BYTES, KEY_3_BYTES, VALUE_3_BYTES);
+
+ Cursor> cursor = clusterConnection
+ .hScan(KEY_1_BYTES, scanOptions().match("key*").build());
+
+ int i = 0;
+ while (cursor.hasNext()) {
+
+ byte[] key = cursor.next().getKey();
+
+ assertThat(key, anyOf(equalTo(KEY_1_BYTES), equalTo(KEY_2_BYTES), equalTo(KEY_3_BYTES)));
+
+ i++;
+ }
+
+ assertThat(i, is(3));
+ }
/**
* @see DATAREDIS-315