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 18e7f2662..1498b3f90 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 @@ -529,8 +529,9 @@ public abstract class JedisConverters extends Converters { if (options.getCount() != null) { sp.count(options.getCount().intValue()); } - if (StringUtils.hasText(options.getPattern())) { - sp.match(options.getPattern()); + byte[] pattern = options.getBytePattern(); + if (pattern != null) { + sp.match(pattern); } } return sp; diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisKeyCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisKeyCommands.java index 969727ce9..cf1e50192 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisKeyCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisKeyCommands.java @@ -168,9 +168,10 @@ class JedisKeyCommands implements RedisKeyCommands { } ScanParams params = JedisConverters.toScanParams(options); - redis.clients.jedis.ScanResult result = connection.getJedis().scan(Long.toString(cursorId), params); + redis.clients.jedis.ScanResult result = connection.getJedis().scan(Long.toString(cursorId).getBytes(), + params); return new ScanIteration<>(Long.parseLong(result.getCursor()), - JedisConverters.stringListToByteList().convert(result.getResult())); + result.getResult()); } protected void doClose() { diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java index 9d9879805..b61cb7a9a 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java @@ -868,8 +868,9 @@ public abstract class LettuceConverters extends Converters { ScanArgs scanArgs = new ScanArgs(); - if (options.getPattern() != null) { - scanArgs.match(options.getPattern()); + byte[] pattern = options.getBytePattern(); + if (pattern != null) { + scanArgs.match(pattern); } if (options.getCount() != null) { diff --git a/src/main/java/org/springframework/data/redis/core/ScanOptions.java b/src/main/java/org/springframework/data/redis/core/ScanOptions.java index a80aa80b5..56a897392 100644 --- a/src/main/java/org/springframework/data/redis/core/ScanOptions.java +++ b/src/main/java/org/springframework/data/redis/core/ScanOptions.java @@ -31,14 +31,16 @@ public class ScanOptions { /** * Constant to apply default {@link ScanOptions} without setting a limit or matching a pattern. */ - public static ScanOptions NONE = new ScanOptions(null, null); + public static ScanOptions NONE = new ScanOptions(null, null, null); private final @Nullable Long count; private final @Nullable String pattern; + private final @Nullable byte[] bytePattern; - private ScanOptions(@Nullable Long count, @Nullable String pattern) { + private ScanOptions(@Nullable Long count, @Nullable String pattern, @Nullable byte[] bytePattern) { this.count = count; this.pattern = pattern; + this.bytePattern = bytePattern; } /** @@ -57,9 +59,24 @@ public class ScanOptions { @Nullable public String getPattern() { + + if (bytePattern != null && pattern == null) { + return new String(bytePattern); + } + return pattern; } + @Nullable + public byte[] getBytePattern() { + + if (bytePattern == null && pattern != null) { + return pattern.getBytes(); + } + + return bytePattern; + } + public String toOptionString() { if (this.equals(ScanOptions.NONE)) { @@ -71,7 +88,8 @@ public class ScanOptions { if (this.count != null) { params += (", 'count', " + count); } - if (StringUtils.hasText(this.pattern)) { + String pattern = getPattern(); + if (StringUtils.hasText(pattern)) { params += (", 'match' , '" + this.pattern + "'"); } @@ -87,6 +105,7 @@ public class ScanOptions { private @Nullable Long count; private @Nullable String pattern; + private @Nullable byte[] bytePattern; /** @@ -111,13 +130,25 @@ public class ScanOptions { return this; } + /** + * Returns the current {@link ScanOptionsBuilder} configured with the given {@code pattern}. + * + * @param pattern + * @return + * @since 2.6 + */ + public ScanOptionsBuilder match(byte[] pattern) { + this.bytePattern = pattern; + return this; + } + /** * Builds a new {@link ScanOptions} objects. * * @return a new {@link ScanOptions} objects. */ public ScanOptions build() { - return new ScanOptions(count, pattern); + return new ScanOptions(count, pattern, bytePattern); } } } diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionUnitTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionUnitTests.java index d8533aba1..204c6f2da 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionUnitTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionUnitTests.java @@ -157,10 +157,10 @@ class JedisConnectionUnitTests { Integer.MAX_VALUE, (long) Integer.MAX_VALUE + 1L)); } - @Test // DATAREDIS-531 + @Test // DATAREDIS-531, GH-2006 public void scanShouldKeepTheConnectionOpen() { - doReturn(new ScanResult<>("0", Collections. emptyList())).when(jedisSpy).scan(anyString(), + doReturn(new ScanResult<>("0", Collections. emptyList())).when(jedisSpy).scan(any(byte[].class), any(ScanParams.class)); connection.scan(ScanOptions.NONE); @@ -168,10 +168,10 @@ class JedisConnectionUnitTests { verify(jedisSpy, never()).quit(); } - @Test // DATAREDIS-531 + @Test // DATAREDIS-531, GH-2006 public void scanShouldCloseTheConnectionWhenCursorIsClosed() throws IOException { - doReturn(new ScanResult<>("0", Collections. emptyList())).when(jedisSpy).scan(anyString(), + doReturn(new ScanResult<>("0", Collections. emptyList())).when(jedisSpy).scan(any(byte[].class), any(ScanParams.class)); Cursor cursor = connection.scan(ScanOptions.NONE);