DATAREDIS-378 - Add support for ZRANGEBYLEX.

We now support ZRANGEBYLEX on RedisConnection and StringRedisConnection when using the Jedis driver. The upper and lower bounds can be defined using the Range type which will be converted to the according binary representation including prefix and/or infinite operators.

	range().gt("a")          => (a +
	range().gte("a")         => [a +
	range().lt("z")          => - (z
	range().lte("z")         => - [z
	range().gte("a").lt("z") => [a (z
This commit is contained in:
Christoph Strobl
2015-04-08 12:03:12 +02:00
committed by Thomas Darimont
parent b916ff7549
commit ff37da5197
11 changed files with 587 additions and 11 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2015 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.
@@ -816,5 +816,20 @@ public class RedisConnectionUnitTests {
public void pfMerge(byte[] destinationKey, byte[]... sourceKeys) {
delegate.pfMerge(destinationKey, sourceKeys);
}
@Override
public Set<byte[]> zRangeByLex(byte[] key) {
return delegate.zRangeByLex(key);
}
@Override
public Set<byte[]> zRangeByLex(byte[] key, Range range) {
return delegate.zRangeByLex(key, range);
}
@Override
public Set<byte[]> zRangeByLex(byte[] key, Range range, Limit limit) {
return delegate.zRangeByLex(key, range, limit);
}
}
}

View File

@@ -43,6 +43,7 @@ import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.RedisZSetCommands.Range;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.StringRedisConnection.StringTuple;
import org.springframework.data.redis.test.util.RedisSentinelRule;
@@ -411,9 +412,42 @@ public class JedisConnectionIntegrationTests extends AbstractConnectionIntegrati
connection.zAdd("myzset", 1, "one");
connection.zAdd("myzset", 2, "two");
connection.zAdd("myzset", 3, "three");
Set<byte[]> zRangeByScore = connection.zRangeByScore("myzset", "(1", "2");
assertEquals("two", new String(zRangeByScore.iterator().next()));
}
/**
* @see DATAREDIS-378
*/
@Test
@IfProfileValue(name = "redisVersion", value = "2.8+")
public void zRangeByLexTest() {
connection.zAdd("myzset", 0, "a");
connection.zAdd("myzset", 0, "b");
connection.zAdd("myzset", 0, "c");
connection.zAdd("myzset", 0, "d");
connection.zAdd("myzset", 0, "e");
connection.zAdd("myzset", 0, "f");
connection.zAdd("myzset", 0, "g");
Set<String> values = connection.zRangeByLex("myzset", Range.range().lte("c"));
assertThat(values, hasItems("a", "b", "c"));
assertThat(values, not(hasItems("d", "e", "f", "g")));
values = connection.zRangeByLex("myzset", Range.range().lt("c"));
assertThat(values, hasItems("a", "b"));
assertThat(values, not(hasItem("c")));
values = connection.zRangeByLex("myzset", Range.range().gte("aaa").lt("g"));
assertThat(values, hasItems("b", "c", "d", "e", "f"));
assertThat(values, not(hasItems("a", "g")));
values = connection.zRangeByLex("myzset", Range.range().gte("e"));
assertThat(values, hasItems("e", "f", "g"));
assertThat(values, not(hasItems("a", "b", "c", "d")));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2015 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.
@@ -22,12 +22,14 @@ import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.springframework.data.redis.connection.RedisServer;
import org.springframework.data.redis.connection.RedisZSetCommands.Range;
import org.springframework.data.redis.core.types.RedisClientInfo;
/**
@@ -112,6 +114,79 @@ public class JedisConvertersUnitTests {
assertThat(JedisConverters.toListOfRedisServer(null), notNullValue());
}
/**
* @see DATAREDIS-378
*/
@Test
public void boundaryToBytesForZRangeByLexShouldReturnDefaultValueWhenBoundaryIsNull() {
byte[] defaultValue = "tyrion".getBytes();
assertThat(JedisConverters.boundaryToBytesForZRangeByLex(null, defaultValue), is(defaultValue));
}
/**
* @see DATAREDIS-378
*/
@Test
public void boundaryToBytesForZRangeByLexShouldReturnDefaultValueWhenBoundaryValueIsNull() {
byte[] defaultValue = "tyrion".getBytes();
assertThat(JedisConverters.boundaryToBytesForZRangeByLex(Range.unbounded().getMax(), defaultValue),
is(defaultValue));
}
/**
* @see DATAREDIS-378
*/
@Test
public void boundaryToBytesForZRangeByLexShouldReturnValueCorrectlyWhenBoundaryIsIncluing() {
assertThat(
JedisConverters.boundaryToBytesForZRangeByLex(Range.range().gte(JedisConverters.toBytes("a")).getMin(), null),
is(JedisConverters.toBytes("[a")));
}
/**
* @see DATAREDIS-378
*/
@Test
public void boundaryToBytesForZRangeByLexShouldReturnValueCorrectlyWhenBoundaryIsExcluding() {
assertThat(
JedisConverters.boundaryToBytesForZRangeByLex(Range.range().gt(JedisConverters.toBytes("a")).getMin(), null),
is(JedisConverters.toBytes("(a")));
}
/**
* @see DATAREDIS-378
*/
@Test
public void boundaryToBytesForZRangeByLexShouldReturnValueCorrectlyWhenBoundaryIsAString() {
assertThat(JedisConverters.boundaryToBytesForZRangeByLex(Range.range().gt("a").getMin(), null),
is(JedisConverters.toBytes("(a")));
}
/**
* @see DATAREDIS-378
*/
@Test
public void boundaryToBytesForZRangeByLexShouldReturnValueCorrectlyWhenBoundaryIsANumber() {
assertThat(JedisConverters.boundaryToBytesForZRangeByLex(Range.range().gt(1L).getMin(), null),
is(JedisConverters.toBytes("(1")));
}
/**
* @see DATAREDIS-378
*/
@Test(expected = IllegalArgumentException.class)
public void boundaryToBytesForZRangeByLexShouldThrowExceptionWhenBoundaryHoldsUnknownType() {
JedisConverters.boundaryToBytesForZRangeByLex(Range.range().gt(new Date()).getMin(), null);
}
private void verifyRedisServerInfo(RedisServer server, Map<String, String> values) {
for (Map.Entry<String, String> entry : values.entrySet()) {