From f732b5f6b99c19078a95732bd4e2b6642fdd801f Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 11 May 2016 00:16:31 +0200 Subject: [PATCH] DATAREDIS-438 - Polishing. RedisGeoCommands now take and return Spring Data domain types like Distance and GeoResults. Updated JavaDoc and Reference documentation. Added and updated author and license headers. Fixed minor formatting and code style issues. Original Pulll Request: #187 --- Makefile | 2 +- src/main/asciidoc/new-features.adoc | 11 + src/main/asciidoc/reference/redis.adoc | 6 + .../DefaultStringRedisConnection.java | 514 +- .../data/redis/connection/RedisCommands.java | 2 +- .../redis/connection/RedisGeoCommands.java | 486 +- .../connection/StringRedisConnection.java | 250 +- .../redis/connection/convert/Converters.java | 96 +- .../jedis/JedisClusterConnection.java | 413 +- .../connection/jedis/JedisConnection.java | 6396 +++++++++-------- .../connection/jedis/JedisConverters.java | 270 +- .../connection/jredis/JredisConnection.java | 170 +- .../connection/lettuce/LettuceConnection.java | 655 +- .../connection/lettuce/LettuceConverters.java | 293 +- .../redis/connection/srp/SrpConnection.java | 188 +- .../data/redis/core/AbstractOperations.java | 21 +- .../data/redis/core/BoundGeoOperations.java | 158 +- .../redis/core/DefaultBoundGeoOperations.java | 197 +- .../data/redis/core/DefaultGeoOperations.java | 363 +- .../data/redis/core/GeoCoordinate.java | 22 - .../data/redis/core/GeoOperations.java | 169 +- .../data/redis/core/GeoOperationsEditor.java | 7 +- .../data/redis/core/GeoRadiusParam.java | 88 - .../data/redis/core/GeoRadiusResponse.java | 34 - .../data/redis/core/GeoUnit.java | 11 - .../data/redis/core/RedisCommand.java | 18 +- .../data/redis/core/RedisOperations.java | 31 +- .../data/redis/core/RedisTemplate.java | 42 +- .../redis/RedisTestProfileValueSource.java | 7 +- .../AbstractConnectionIntegrationTests.java | 440 +- .../connection/ClusterConnectionTests.java | 80 + ...ultStringRedisConnectionPipelineTests.java | 239 +- ...tStringRedisConnectionPipelineTxTests.java | 436 +- .../DefaultStringRedisConnectionTests.java | 550 +- .../DefaultStringRedisConnectionTxTests.java | 404 +- .../connection/RedisConnectionUnitTests.java | 103 +- .../jedis/JedisClusterConnectionTests.java | 266 + .../jedis/JedisSentinelIntegrationTests.java | 29 +- .../LettuceClusterConnectionTests.java | 276 + ...eConnectionPipelineTxIntegrationTests.java | 2 +- ...ConnectionTransactionIntegrationTests.java | 80 + .../LettuceSentinelIntegrationTests.java | 25 +- .../redis/core/DefaultGeoOperationsTests.java | 527 +- .../core/DefaultHashOperationsTests.java | 11 +- .../DefaultHyperLogLogOperationsTests.java | 12 +- .../core/DefaultListOperationsTests.java | 12 +- .../redis/core/DefaultSetOperationsTests.java | 10 + .../core/DefaultValueOperationsTests.java | 32 +- .../core/DefaultZSetOperationsTests.java | 38 +- 49 files changed, 9106 insertions(+), 5386 deletions(-) delete mode 100644 src/main/java/org/springframework/data/redis/core/GeoCoordinate.java delete mode 100644 src/main/java/org/springframework/data/redis/core/GeoRadiusParam.java delete mode 100644 src/main/java/org/springframework/data/redis/core/GeoRadiusResponse.java delete mode 100644 src/main/java/org/springframework/data/redis/core/GeoUnit.java diff --git a/Makefile b/Makefile index 900fafad6..7f3160abd 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -REDIS_VERSION:=3.2.0-rc3 +REDIS_VERSION:=3.2.0 SPRING_PROFILE?=ci ####### diff --git a/src/main/asciidoc/new-features.adoc b/src/main/asciidoc/new-features.adoc index dd75f6e01..af2539287 100644 --- a/src/main/asciidoc/new-features.adoc +++ b/src/main/asciidoc/new-features.adoc @@ -3,6 +3,17 @@ New and noteworthy in the latest releases. +[[new-in-1.8.0]] +== New in Spring Data Redis 1.8 + +* Support for Redis http://redis.io/commands#geo[GEO] commands. + +[[new-in-1.7.0]] +== New in Spring Data Redis 1.7 + +* Support for http://redis.io/topics/cluster-tutorial[RedisCluster]. +* Support for Spring Data Repository abstractions (see <>). + [[new-in-1-6-0]] == New in Spring Data Redis 1.6 diff --git a/src/main/asciidoc/reference/redis.adoc b/src/main/asciidoc/reference/redis.adoc index b7d8a6b30..56cdc8cc7 100644 --- a/src/main/asciidoc/reference/redis.adoc +++ b/src/main/asciidoc/reference/redis.adoc @@ -235,6 +235,9 @@ Moreover, the template provides operations views (following the grouping from Re |HyperLogLogOperations |Redis HyperLogLog operations like (pfadd, pfcount,...) +|GeoOperations +|Redis geospatial operations like `GEOADD`, `GEORADIUS`,...) + 2+^|_Key Bound Operations_ |BoundValueOperations @@ -251,6 +254,9 @@ Moreover, the template provides operations views (following the grouping from Re |BoundHashOperations |Redis hash key bound operations + +|BoundGeoOperations +|Redis key bound geospatial operations. |==== Once configured, the template is thread-safe and can be reused across multiple instances. diff --git a/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java index 341423eb8..68197780c 100644 --- a/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java @@ -15,17 +15,34 @@ */ package org.springframework.data.redis.connection; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Properties; +import java.util.Queue; +import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.core.convert.converter.Converter; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Point; import org.springframework.data.redis.RedisSystemException; +import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.connection.convert.ListConverter; import org.springframework.data.redis.connection.convert.MapConverter; import org.springframework.data.redis.connection.convert.SetConverter; -import org.springframework.data.redis.core.*; +import org.springframework.data.redis.core.ConvertingCursor; +import org.springframework.data.redis.core.Cursor; +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.data.redis.serializer.RedisSerializer; @@ -40,6 +57,7 @@ import org.springframework.util.Assert; * @author Christoph Strobl * @author Thomas Darimont * @author Mark Paluch + * @author Ninad Divadkar */ public class DefaultStringRedisConnection implements StringRedisConnection, DecoratedRedisConnection { @@ -56,6 +74,8 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco private ListConverter byteListToStringList = new ListConverter(bytesToString); private MapConverter byteMapToStringMap = new MapConverter(bytesToString); private SetConverter byteSetToStringSet = new SetConverter(bytesToString); + private Converter>, GeoResults>> byteGeoResultsToStringGeoResults; + @SuppressWarnings("rawtypes") private Queue pipelineConverters = new LinkedList(); @SuppressWarnings("rawtypes") private Queue txConverters = new LinkedList(); private boolean deserializePipelineAndTxResults = false; @@ -105,9 +125,7 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco * @param connection Redis connection */ public DefaultStringRedisConnection(RedisConnection connection) { - Assert.notNull(connection, "connection is required"); - this.delegate = connection; - this.serializer = new StringRedisSerializer(); + this(connection, new StringRedisSerializer()); } /** @@ -117,10 +135,13 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco * @param serializer String serializer */ public DefaultStringRedisConnection(RedisConnection connection, RedisSerializer serializer) { + Assert.notNull(connection, "connection is required"); - Assert.notNull(connection, "serializer is required"); + Assert.notNull(serializer, "serializer is required"); + this.delegate = connection; this.serializer = serializer; + this.byteGeoResultsToStringGeoResults = Converters.deserializingGeoResultsConverter(serializer); } public Long append(byte[] key, byte[] value) { @@ -270,7 +291,7 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco delegate.flushDb(); } - public byte[] get(byte[] key) { + public byte[] get(byte[] key) { byte[] result = delegate.get(key); if (isFutureConversion()) { addResultConverter(identityConverter); @@ -2270,194 +2291,362 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco return result; } - @Override - public Long geoAdd(byte[] key, double longitude, double latitude, byte[] member){ - Long result = delegate.geoAdd(key, longitude, latitude, member); - if (isFutureConversion()){ - addResultConverter(identityConverter); - } - return result; - } - - @Override - public Long geoAdd(String key, double longitude, double latitude, String member){ - Long result = delegate.geoAdd(serialize(key), longitude, latitude, serialize(member)); - if (isFutureConversion()){ - addResultConverter(identityConverter); - } - return result; - } - - @Override - public Long geoAdd(byte[] key, Map memberCoordinateMap) { - Long result = delegate.geoAdd(key, memberCoordinateMap); - if (isFutureConversion()){ - addResultConverter(identityConverter); - } - return result; - } - - @Override - public Long geoAdd(String key, Map memberCoordinateMap) { - Map byteMap = new HashMap(); - for (String k : memberCoordinateMap.keySet()){ - byteMap.put(serialize(k), memberCoordinateMap.get(k)); - } - Long result = delegate.geoAdd(serialize(key), byteMap); - if (isFutureConversion()){ - addResultConverter(identityConverter); - } - return result; - } - - @Override - public Double geoDist(byte[] key, byte[] member1, byte[] member2) { - Double result = delegate.geoDist(key, member1, member2); - if (isFutureConversion()){ - addResultConverter(identityConverter); - } - return result; - } - - @Override - public Double geoDist(String key, String member1, String member2) { - return geoDist(key, member1, member2, GeoUnit.Meters); - } - - @Override - public Double geoDist(byte[] key, byte[] member1, byte[] member2, GeoUnit unit) { - Double result = delegate.geoDist(key, member1, member2, unit); - if (isFutureConversion()){ - addResultConverter(identityConverter); - } - return result; - } - - @Override - public Double geoDist(String key, String member1, String member2, GeoUnit geoUnit) { - Double result = delegate.geoDist(serialize(key), serialize(member1), serialize(member2), geoUnit); - if (isFutureConversion()){ - addResultConverter(identityConverter); - } - return result; - } - - @Override - public List geoHash(byte[] key, byte[]... members) { - List result = delegate.geoHash(key, members); - if (isFutureConversion()){ - addResultConverter(identityConverter); - } - return result; - } - - @Override - public List geoHash(String key, String... members) { - List result = delegate.geoHash(serialize(key), serializeMulti(members)); - if (isFutureConversion()){ - addResultConverter(byteListToStringList); - } - return byteListToStringList.convert(result); - } - - @Override - public List geoPos(byte[] key, byte[]... members) { - List result = delegate.geoPos(key, members); - if (isFutureConversion()){ - addResultConverter(identityConverter); - } - return result; - } - - @Override - public List geoPos(String key, String... members) { - List result = delegate.geoPos(serialize(key), serializeMulti(members)); - if (isFutureConversion()){ - addResultConverter(identityConverter); - } - return result; - } - + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], org.springframework.data.geo.Point, byte[]) + */ @Override - public List georadius(String key, double longitude, double latitude, double radius, GeoUnit unit) { - List result = delegate.georadius(serialize(key), longitude, latitude, radius, unit); - if (isFutureConversion()){ + public Long geoAdd(byte[] key, Point point, byte[] member) { + + Long result = delegate.geoAdd(key, point, member); + if (isFutureConversion()) { addResultConverter(identityConverter); } return result; } - @Override - public List georadius(String key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { - List result = delegate.georadius(serialize(key), longitude, latitude, radius, unit, param); - if (isFutureConversion()){ + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation) + */ + public Long geoAdd(byte[] key, GeoLocation location) { + + Long result = delegate.geoAdd(key, location); + if (isFutureConversion()) { addResultConverter(identityConverter); } return result; } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.StringRedisConnection#geoAdd(java.lang.String, org.springframework.data.geo.Point, java.lang.String) + */ @Override - public List georadiusByMember(String key, String member, double radius, GeoUnit unit) { - List result = delegate.georadiusByMember(serialize(key), serialize(member), radius, unit); - if (isFutureConversion()){ + public Long geoAdd(String key, Point point, String member) { + return geoAdd(serialize(key), point, serialize(member)); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.StringRedisConnection#geoAdd(java.lang.String, org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation) + */ + @Override + public Long geoAdd(String key, GeoLocation location) { + + Assert.notNull(location, "Location must not be null!"); + return geoAdd(key, location.getPoint(), location.getName()); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], java.util.Map) + */ + @Override + public Long geoAdd(byte[] key, Map memberCoordinateMap) { + + Long result = delegate.geoAdd(key, memberCoordinateMap); + if (isFutureConversion()) { addResultConverter(identityConverter); } return result; } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], java.lang.Iterable) + */ @Override - public List georadiusByMember(String key, String member, double radius, GeoUnit unit, GeoRadiusParam param) { - List result = delegate.georadiusByMember(serialize(key), serialize(member), radius, unit, param); - if (isFutureConversion()){ + public Long geoAdd(byte[] key, Iterable> locations) { + + Long result = delegate.geoAdd(key, locations); + if (isFutureConversion()) { addResultConverter(identityConverter); } return result; } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.StringRedisConnection#geoAdd(java.lang.String, java.util.Map) + */ @Override - public List georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit) { - List result = delegate.georadius(key, longitude, latitude, radius, unit); - if (isFutureConversion()){ + public Long geoAdd(String key, Map memberCoordinateMap) { + + Assert.notNull(memberCoordinateMap, "MemberCoordinateMap must not be null!"); + + Map byteMap = new HashMap(); + for (Entry entry : memberCoordinateMap.entrySet()) { + byteMap.put(serialize(entry.getKey()), memberCoordinateMap.get(entry.getValue())); + } + + return geoAdd(serialize(key), byteMap); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.StringRedisConnection#geoAdd(java.lang.String, java.lang.Iterable) + */ + @Override + public Long geoAdd(String key, Iterable> locations) { + + Assert.notNull(locations, "Locations must not be null!"); + + Map byteMap = new HashMap(); + for (GeoLocation location : locations) { + byteMap.put(serialize(location.getName()), location.getPoint()); + } + + return geoAdd(serialize(key), byteMap); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoDist(byte[], byte[], byte[]) + */ + @Override + public Distance geoDist(byte[] key, byte[] member1, byte[] member2) { + + Distance result = delegate.geoDist(key, member1, member2); + if (isFutureConversion()) { addResultConverter(identityConverter); } return result; } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.StringRedisConnection#geoDist(java.lang.String, java.lang.String, java.lang.String) + */ @Override - public List georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { - List result = delegate.georadius(key, longitude, latitude, radius, unit, param); - if (isFutureConversion()){ + public Distance geoDist(String key, String member1, String member2) { + return geoDist(serialize(key), serialize(member1), serialize(member2)); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoDist(byte[], byte[], byte[], org.springframework.data.geo.Metric) + */ + @Override + public Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric metric) { + + Distance result = delegate.geoDist(key, member1, member2, metric); + if (isFutureConversion()) { addResultConverter(identityConverter); } return result; } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.StringRedisConnection#geoDist(java.lang.String, java.lang.String, java.lang.String, org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit) + */ @Override - public List georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit) { - List result = delegate.georadiusByMember(key, member, radius, unit); - if (isFutureConversion()){ + public Distance geoDist(String key, String member1, String member2, Metric metric) { + return geoDist(serialize(key), serialize(member1), serialize(member2), metric); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoHash(byte[], byte[][]) + */ + @Override + public List geoHash(byte[] key, byte[]... members) { + + List result = delegate.geoHash(key, members); + if (isFutureConversion()) { addResultConverter(identityConverter); } return result; } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.StringRedisConnection#geoHash(java.lang.String, java.lang.String[]) + */ @Override - public List georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param) { - List result = delegate.georadiusByMember(key, member, radius, unit, param); - if (isFutureConversion()){ + public List geoHash(String key, String... members) { + + List result = delegate.geoHash(serialize(key), serializeMulti(members)); + if (isFutureConversion()) { addResultConverter(identityConverter); } return result; } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoPos(byte[], byte[][]) + */ @Override - public Long geoRemove(byte[] key, byte[]... values) { - return zRem(key, values); + public List geoPos(byte[] key, byte[]... members) { + + List result = delegate.geoPos(key, members); + if (isFutureConversion()) { + addResultConverter(identityConverter); + } + return result; } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.StringRedisConnection#geoPos(java.lang.String, java.lang.String[]) + */ + @Override + public List geoPos(String key, String... members) { + return geoPos(serialize(key), serializeMulti(members)); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.StringRedisConnection#georadius(java.lang.String, org.springframework.data.geo.Circle) + */ + @Override + public GeoResults> georadius(String key, Circle within) { + + GeoResults> result = delegate.geoRadius(serialize(key), within); + if (isFutureConversion()) { + addResultConverter(byteGeoResultsToStringGeoResults); + } + + return byteGeoResultsToStringGeoResults.convert(result); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.StringRedisConnection#georadius(java.lang.String, org.springframework.data.geo.Circle, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> georadius(String key, Circle within, GeoRadiusCommandArgs args) { + + GeoResults> result = delegate.geoRadius(serialize(key), within, args); + if (isFutureConversion()) { + addResultConverter(byteGeoResultsToStringGeoResults); + } + return byteGeoResultsToStringGeoResults.convert(result); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.StringRedisConnection#georadiusByMember(java.lang.String, java.lang.String, double) + */ + @Override + public GeoResults> georadiusByMember(String key, String member, double radius) { + return georadiusByMember(key, member, new Distance(radius, DistanceUnit.METERS)); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.StringRedisConnection#georadiusByMember(java.lang.String, java.lang.String, org.springframework.data.geo.Distance) + */ + @Override + public GeoResults> georadiusByMember(String key, String member, Distance radius) { + + GeoResults> result = delegate.geoRadiusByMember(serialize(key), serialize(member), radius); + if (isFutureConversion()) { + addResultConverter(byteGeoResultsToStringGeoResults); + } + return byteGeoResultsToStringGeoResults.convert(result); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.StringRedisConnection#georadiusByMember(java.lang.String, java.lang.String, org.springframework.data.geo.Distance, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> georadiusByMember(String key, String member, Distance radius, + GeoRadiusCommandArgs args) { + + GeoResults> result = delegate.geoRadiusByMember(serialize(key), serialize(member), radius, + args); + if (isFutureConversion()) { + addResultConverter(byteGeoResultsToStringGeoResults); + } + return byteGeoResultsToStringGeoResults.convert(result); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadius(byte[], org.springframework.data.geo.Circle) + */ + @Override + public GeoResults> geoRadius(byte[] key, Circle within) { + + GeoResults> result = delegate.geoRadius(key, within); + if (isFutureConversion()) { + addResultConverter(identityConverter); + } + return result; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadius(byte[], org.springframework.data.geo.Circle, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> geoRadius(byte[] key, Circle within, GeoRadiusCommandArgs args) { + + GeoResults> result = delegate.geoRadius(key, within, args); + if (isFutureConversion()) { + addResultConverter(identityConverter); + } + return result; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], double) + */ + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, double radius) { + return geoRadiusByMember(key, member, new Distance(radius, DistanceUnit.METERS)); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], org.springframework.data.geo.Distance) + */ + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius) { + + GeoResults> result = delegate.geoRadiusByMember(key, member, radius); + if (isFutureConversion()) { + addResultConverter(identityConverter); + } + return result; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], org.springframework.data.geo.Distance, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius, + GeoRadiusCommandArgs args) { + + GeoResults> result = delegate.geoRadiusByMember(key, member, radius, args); + if (isFutureConversion()) { + addResultConverter(identityConverter); + } + return result; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoRemove(byte[], byte[][]) + */ + @Override + public Long geoRemove(byte[] key, byte[]... members) { + return zRem(key, members); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.StringRedisConnection#geoRemove(java.lang.String, java.lang.String[]) + */ @Override public Long geoRemove(String key, String... members) { - return zRem(key, members); + return geoRemove(serialize(key), serializeMulti(members)); } public List closePipeline() { @@ -2684,30 +2873,31 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco @Override public Cursor> hScan(String key, ScanOptions options) { - return new ConvertingCursor, Map.Entry>(this.delegate.hScan( - this.serialize(key), options), new Converter, Map.Entry>() { - - @Override - public Entry convert(final Entry source) { - return new Map.Entry() { + return new ConvertingCursor, Map.Entry>( + this.delegate.hScan(this.serialize(key), options), + new Converter, Map.Entry>() { @Override - public String getKey() { - return bytesToString.convert(source.getKey()); - } + public Entry convert(final Entry source) { + return new Map.Entry() { - @Override - public String getValue() { - return bytesToString.convert(source.getValue()); - } + @Override + public String getKey() { + return bytesToString.convert(source.getKey()); + } - @Override - public String setValue(String value) { - throw new UnsupportedOperationException("Cannot set value for entry in cursor"); + @Override + public String getValue() { + return bytesToString.convert(source.getValue()); + } + + @Override + public String setValue(String value) { + throw new UnsupportedOperationException("Cannot set value for entry in cursor"); + } + }; } - }; - } - }); + }); } /* diff --git a/src/main/java/org/springframework/data/redis/connection/RedisCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisCommands.java index 47a9579fe..ee3725617 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisCommands.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2014 the original author or authors. + * Copyright 2011-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. diff --git a/src/main/java/org/springframework/data/redis/connection/RedisGeoCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisGeoCommands.java index 6109f16a3..6d7ee8582 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisGeoCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisGeoCommands.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013 the original author or authors. + * Copyright 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. @@ -15,174 +15,356 @@ */ package org.springframework.data.redis.connection; - -import org.springframework.data.redis.core.GeoCoordinate; -import org.springframework.data.redis.core.GeoRadiusParam; -import org.springframework.data.redis.core.GeoRadiusResponse; -import org.springframework.data.redis.core.GeoUnit; - +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; + +import org.springframework.data.domain.Sort.Direction; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Point; +import org.springframework.util.Assert; + +import lombok.Data; +import lombok.RequiredArgsConstructor; /** * Geo-specific Redis commands. * * @author Ninad Divadkar + * @author Christoph Strobl + * @since 1.8 */ public interface RedisGeoCommands { - /** - * Add latitude and longitude for a given key with a name. - * Returns the number of elements added to the sorted set, not including elements already existing for which the - * score was updated. - *

- * @link http://redis.io/commands/geoadd - * - * @param key - * @param member - * @param longitude - * @param latitude - * @return - */ - Long geoAdd(byte[] key, double longitude, double latitude, byte[] member); - /** - * Add latitude and longitude for a given key with a name. - * Returns the number of elements added to the sorted set, not including elements already existing for which the - * score was updated. - *

- * @link http://redis.io/commands/geoadd - * - * @param key - * @param memberCoordinateMap - * @return - */ - Long geoAdd(byte[] key, Map memberCoordinateMap); + /** + * Add {@link Point} with given member {@literal name} to {@literal key}. + * + * @param key must not be {@literal null}. + * @param point must not be {@literal null}. + * @param member must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + */ + Long geoAdd(byte[] key, Point point, byte[] member); - /** - * Return the distance between two members in the geospatial index represented by the sorted set. - *

- * @link http://redis.io/commands/geodist - * - * @param key - * @param member1 - * @param member2 - * @return - */ - Double geoDist(byte[] key, byte[] member1, byte[] member2); + /** + * Add {@link GeoLocation} to {@literal key}. + * + * @param key must not be {@literal null}. + * @param location must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + */ + Long geoAdd(byte[] key, GeoLocation location); - /** - * Return the distance between two members in the geospatial index represented by the sorted set. - *

- * @link http://redis.io/commands/geodist - * - * @param key - * @param member1 - * @param member2 - * @param unit - * @return - */ - Double geoDist(byte[] key, byte[] member1, byte[] member2, GeoUnit unit); + /** + * Add {@link Map} of member / {@link Point} pairs to {@literal key}. + * + * @param key must not be {@literal null}. + * @param memberCoordinateMap must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + */ + Long geoAdd(byte[] key, Map memberCoordinateMap); - /** - * Return valid Geohash strings representing the position of one or more elements in a sorted set value - * representing a geospatial index (where elements were added using GEOADD). - *

- * @link http://redis.io/commands/geohash - * - * @param key - * @param members - * @return - */ - List geoHash(byte[] key, byte[]... members); + /** + * Add {@link GeoLocation}s to {@literal key} + * + * @param key must not be {@literal null}. + * @param locations must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + */ + Long geoAdd(byte[] key, Iterable> locations); - /** - * Return the positions (longitude,latitude) of all the specified members of the geospatial index represented by - * the sorted set at key. - *

- * @link http://redis.io/commands/geopos - * - * @param key - * @param members - * @return - */ - List geoPos(byte[] key, byte[]... members); + /** + * Get the {@link Distance} between {@literal member1} and {@literal member2}. + * + * @param key must not be {@literal null}. + * @param member1 must not be {@literal null}. + * @param member2 must not be {@literal null}. + * @return can be {@literal null}. + * @see http://redis.io/commands/geodist + */ + Distance geoDist(byte[] key, byte[] member1, byte[] member2); - /** - * Return the members of a sorted set populated with geospatial information using GEOADD, which are within - * the borders of the area specified with the center location and the maximum distance from the radius. - *

- * @link http://redis.io/commands/georadius - * - * @param key - * @param longitude - * @param latitude - * @param radius - * @param unit - * @return - */ - List georadius(byte[] key, double longitude, double latitude, - double radius, GeoUnit unit); + /** + * Get the {@link Distance} between {@literal member1} and {@literal member2} in the given {@link Metric}. + * + * @param key must not be {@literal null}. + * @param member1 must not be {@literal null}. + * @param member2 must not be {@literal null}. + * @param metric must not be {@literal null}. + * @return can be {@literal null}. + * @see http://redis.io/commands/geodist + */ + Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric metric); - /** - * Return the members of a sorted set populated with geospatial information using GEOADD, which are within - * the borders of the area specified with the center location and the maximum distance from the radius. - *

- * @link http://redis.io/commands/georadius - * - * @param key - * @param longitude - * @param latitude - * @param radius - * @param unit - * @param param - * @return - */ - List georadius(byte[] key, double longitude, double latitude, - double radius, GeoUnit unit, GeoRadiusParam param); + /** + * Get Geohash representation of the position for one or more {@literal member}s. + * + * @param key must not be {@literal null}. + * @param members must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/geohash + */ + List geoHash(byte[] key, byte[]... members); - /** - * This command is exactly like GEORADIUS with the sole difference that instead of taking, as the center of - * the area to query, a longitude and latitude value, it takes the name of a member already existing inside - * the geospatial index represented by the sorted set. - *

- * @link http://redis.io/commands/georadiusbymember - * - * @param key - * @param member - * @param radius - * @param unit - * - * @return - */ - List georadiusByMember(byte[] key, byte[] member, double radius, - GeoUnit unit); + /** + * Get the {@link Point} representation of positions for one or more {@literal member}s. + * + * @param key must not be {@literal null}. + * @param members must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/geopos + */ + List geoPos(byte[] key, byte[]... members); - /** - * This command is exactly like GEORADIUS with the sole difference that instead of taking, as the center of - * the area to query, a longitude and latitude value, it takes the name of a member already existing inside - * the geospatial index represented by the sorted set. - *

- * @link http://redis.io/commands/georadiusbymember - * - * @param key - * @param member - * @param radius - * @param unit - * @param param - * - * @return - */ - List georadiusByMember(byte[] key, byte[] member, double radius, - GeoUnit unit, GeoRadiusParam param); + /** + * Get the {@literal member}s within the boundaries of a given {@link Circle}. + * + * @param key must not be {@literal null}. + * @param within must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadius + */ + GeoResults> geoRadius(byte[] key, Circle within); - /** - * Redis does not have a georem command, so this command just maps to zrem - *

- * @link http://redis.io/commands/geoadd - * - * @param key - * @param values - * @return - */ - Long geoRemove(byte[] key, byte[]... values); + /** + * Get the {@literal member}s within the boundaries of a given {@link Circle} applying {@link GeoRadiusCommandArgs}. + * + * @param key must not be {@literal null}. + * @param within must not be {@literal null}. + * @param args must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadius + */ + GeoResults> geoRadius(byte[] key, Circle within, GeoRadiusCommandArgs args); + + /** + * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given + * {@literal radius}. + * + * @param key must not be {@literal null}. + * @param member must not be {@literal null}. + * @param radius + * @return never {@literal null}. + * @see http://redis.io/commands/georadiusbymember + */ + GeoResults> geoRadiusByMember(byte[] key, byte[] member, double radius); + + /** + * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given + * {@link Distance}. + * + * @param key must not be {@literal null}. + * @param member must not be {@literal null}. + * @param radius must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadiusbymember + */ + GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius); + + /** + * Get the {@literal member}s within the circle defined by the {@literal members} coordinates, given {@link Distance} + * and {@link GeoRadiusCommandArgs}. + * + * @param key must not be {@literal null}. + * @param member must not be {@literal null}. + * @param radius must not be {@literal null}. + * @param args must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadiusbymember + */ + GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius, + GeoRadiusCommandArgs args); + + /** + * Remove the {@literal member}s. + * + * @param key must not be {@literal null}. + * @param members must not be {@literal null}. + * @return Number of elements removed. + */ + Long geoRemove(byte[] key, byte[]... members); + + /** + * Additional arguments (like count/sort/...) to be used with {@link RedisGeoCommands}. + * + * @author Ninad Divadkar + * @author Christoph Strobl + * @since 1.8 + */ + public class GeoRadiusCommandArgs { + + Set flags = new LinkedHashSet(2, 1); + Long limit; + Direction sortDirection; + + private GeoRadiusCommandArgs() {} + + /** + * Create new {@link GeoRadiusCommandArgs}. + * + * @return never {@literal null}. + */ + public static GeoRadiusCommandArgs newGeoRadiusArgs() { + return new GeoRadiusCommandArgs(); + } + + /** + * Sets the {@link Flag#WITHCOORD} flag to also return the longitude, latitude coordinates of the matching items. + * + * @return + */ + public GeoRadiusCommandArgs includeCoordinates() { + + flags.add(Flag.WITHCOORD); + return this; + } + + /** + * Sets the {@link Flag#WITHDIST} flag to also return the distance of the returned items from the specified center. + * + * @return never {@literal null}. + */ + public GeoRadiusCommandArgs includeDistance() { + + flags.add(Flag.WITHDIST); + return this; + } + + /** + * Sort returned items from the nearest to the furthest, relative to the center. + * + * @return never {@literal null}. + */ + public GeoRadiusCommandArgs sortAscending() { + + sortDirection = Direction.ASC; + return this; + } + + /** + * Sort returned items from the furthest to the nearest, relative to the center. + * + * @return never {@literal null}. + */ + public GeoRadiusCommandArgs sortDescending() { + + sortDirection = Direction.DESC; + return this; + } + + /** + * Limit the results to the first N matching items. + * + * @param count + * @return never {@literal null}. + */ + public GeoRadiusCommandArgs limit(long count) { + + Assert.isTrue(count > 0, "Count has to positive value."); + limit = count; + return this; + } + + /** + * @return never {@literal null}. + */ + public Set getFlags() { + return flags; + } + + /** + * @return can be {@literal null}. + */ + public Long getLimit() { + return limit; + } + + /** + * @return can be {@literal null}. + */ + public Direction getSortDirection() { + return sortDirection; + } + + public boolean hasFlags() { + return !flags.isEmpty(); + } + + public boolean hasSortDirection() { + return sortDirection != null; + } + + public boolean hasLimit() { + return limit != null; + } + + public static enum Flag { + WITHCOORD, WITHDIST + } + } + + /** + * {@link GeoLocation} representing a {@link Point} associated with a {@literal name}. + * + * @author Christoph Strobl + * @param + * @since 1.8 + */ + @Data + @RequiredArgsConstructor + public static class GeoLocation { + + private final T name; + private final Point point; + } + + /** + * {@link Metric}s supported by Redis. + * + * @author Christoph Strobl + * @since 1.8 + */ + public static enum DistanceUnit implements Metric { + + METERS(6378137, "m"), KILOMETERS(6378.137, "km"), MILES(3963.191, "mi"), FEET(20925646.325, "ft"); + + private final double multiplier; + private final String abbreviation; + + /** + * Creates a new {@link DistanceUnit} using the given muliplier. + * + * @param multiplier the earth radius at equator. + */ + private DistanceUnit(double multiplier, String abbreviation) { + + this.multiplier = multiplier; + this.abbreviation = abbreviation; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.geo.Metric#getMultiplier() + */ + public double getMultiplier() { + return multiplier; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.geo.Metric#getAbbreviation() + */ + @Override + public String getAbbreviation() { + return abbreviation; + } + } } diff --git a/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java index 9f2063205..0d95891f3 100644 --- a/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java @@ -20,7 +20,15 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.springframework.data.redis.core.*; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Point; +import org.springframework.data.redis.core.Cursor; +import org.springframework.data.redis.core.RedisCallback; +import org.springframework.data.redis.core.ScanOptions; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.types.Expiration; import org.springframework.data.redis.core.types.RedisClientInfo; import org.springframework.data.redis.serializer.RedisSerializer; @@ -34,6 +42,7 @@ import org.springframework.data.redis.serializer.RedisSerializer; * @author Thomas Darimont * @author David Liu * @author Mark Paluch + * @author Ninad Divadkar * @see RedisCallback * @see RedisSerializer * @see StringRedisTemplate @@ -623,151 +632,168 @@ public interface StringRedisConnection extends RedisConnection { Set zRangeByLex(String key, Range range, Limit limit); /** - * Add latitude and longitude for a {@member} with a given {@key}. - * Returns the number of elements added to the sorted set, not including elements already existing for which the - * score was updated. - *

- * @link http://redis.io/commands/geoadd - * - * @param key - * @param member - * @param longitude - * @param latitude - * @return + * Add {@link Point} with given member {@literal name} to {@literal key}. + * + * @param key must not be {@literal null}. + * @param point must not be {@literal null}. + * @param member must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + * @since 1.8 */ - Long geoAdd(String key, double longitude, double latitude, String member); + Long geoAdd(String key, Point point, String member); /** - * Add memberCoordinateMap with a given {@key}. - * Returns the number of elements added to the sorted set, not including elements already existing for which the - * score was updated. - *

- * @link http://redis.io/commands/geoadd - * - * @param key - * @param memberCoordinateMap - * @return + * Add {@link GeoLocation} to {@literal key}. + * + * @param key must not be {@literal null}. + * @param location must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + * @since 1.8 */ - Long geoAdd(String key, Map memberCoordinateMap); + Long geoAdd(String key, GeoLocation location); /** - * Return the distance between {@member1} and {@member2} in the geospatial index represented by the sorted set. - * The unit in which the distance is returned is meters. - *

- * @link http://redis.io/commands/geodist - * - * @param key - * @param member1 - * @param member2 - * @return + * Add {@link Map} of member / {@link Point} pairs to {@literal key}. + * + * @param key must not be {@literal null}. + * @param memberCoordinateMap must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + * @since 1.8 */ - Double geoDist(String key, String member1, String member2); + Long geoAdd(String key, Map memberCoordinateMap); /** - * Return the distance in {@unit} between {@member1} and {@member2} in the geospatial index represented by the sorted set. - *

- * @link http://redis.io/commands/geodist - * - * @param key - * @param member1 - * @param member2 - * @return + * Add {@link GeoLocation}s to {@literal key} + * + * @param key must not be {@literal null}. + * @param locations must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + * @since 1.8 */ - Double geoDist(String key, String member1, String member2, GeoUnit unit); + Long geoAdd(String key, Iterable> locations); /** - * Return valid Geohash strings representing the position of one or more {@values} - * representing a geospatial index (where elements were added using GEOADD). - *

- * @link http://redis.io/commands/geohash + * Get the {@link Distance} between {@literal member1} and {@literal member2}. * - * @param key - * @param values - * @return + * @param key must not be {@literal null}. + * @param member1 must not be {@literal null}. + * @param member2 must not be {@literal null}. + * @return can be {@literal null}. + * @see http://redis.io/commands/geodist + * @since 1.8 */ - List geoHash(String key, String... values); + Distance geoDist(String key, String member1, String member2); /** - * Return the positions (longitude,latitude) in GeoCoordinate of all the specified {@members} of the geospatial index represented by - * the sorted set at key. - *

- * @link http://redis.io/commands/geopos + * Get the {@link Distance} between {@literal member1} and {@literal member2} in the given {@link Metric}. * - * @param key - * @param members - * @return + * @param key must not be {@literal null}. + * @param member1 must not be {@literal null}. + * @param member2 must not be {@literal null}. + * @param metric must not be {@literal null}. + * @return can be {@literal null}. + * @see http://redis.io/commands/geodist + * @since 1.8 */ - List geoPos(String key, String... members); + Distance geoDist(String key, String member1, String member2, Metric metric); /** - * Return the members of a sorted set populated with geospatial information using GEOADD, which are within - * the borders of the area specified with the center location given by {@longitude} and {@latitude} and - * the maximum distance from the {@radius}. - *

- * @link http://redis.io/commands/georadius + * Get geohash representation of the position for one or more {@literal member}s. * - * @param key - * @param longitude - * @param latitude + * @param key must not be {@literal null}. + * @param members must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/geohash + * @since 1.8 + */ + List geoHash(String key, String... members); + + /** + * Get the {@link Point} representation of positions for one or more {@literal member}s. + * + * @param key must not be {@literal null}. + * @param members must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/geopos + * @since 1.8 + */ + List geoPos(String key, String... members); + + /** + * Get the {@literal member}s within the boundaries of a given {@link Circle}. + * + * @param key must not be {@literal null}. + * @param within must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadius + * @since 1.8 + */ + GeoResults> georadius(String key, Circle within); + + /** + * Get the {@literal member}s within the boundaries of a given {@link Circle} applying {@link GeoRadiusCommandArgs}. + * + * @param key must not be {@literal null}. + * @param within must not be {@literal null}. + * @param args must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadius + * @since 1.8 + */ + GeoResults> georadius(String key, Circle within, GeoRadiusCommandArgs args); + + /** + * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given + * {@literal radius}. + * + * @param key must not be {@literal null}. + * @param member must not be {@literal null}. * @param radius - * @param unit - * @return + * @return never {@literal null}. + * @see http://redis.io/commands/georadiusbymember + * @since 1.8 */ - List georadius(String key, double longitude, double latitude, - double radius, GeoUnit unit); + GeoResults> georadiusByMember(String key, String member, double radius); /** - * Return the members of a sorted set populated with geospatial information using GEOADD, which are within - * the borders of the area specified with the center location given by {@longitude} and {@latitude} and - * the maximum distance from the {@radius}. {@param} can be passed to get coordinates, distance and sort the values - *

- * @link http://redis.io/commands/georadius + * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given + * {@link Distance}. * - * @param key - * @param longitude - * @param latitude - * @param radius - * @param unit - * @param param - * @return + * @param key must not be {@literal null}. + * @param member must not be {@literal null}. + * @param radius must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadiusbymember + * @since 1.8 */ - List georadius(String key, double longitude, double latitude, - double radius, GeoUnit unit, GeoRadiusParam param); + GeoResults> georadiusByMember(String key, String member, Distance radius); /** - * This command is exactly like GEORADIUS with the sole difference that instead of taking, as the center of - * the area to query, a longitude and latitude value, it takes the name of a member already existing inside - * the geospatial index represented by the sorted set. - *

- * @link http://redis.io/commands/georadiusbymember + * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given + * {@link Distance} and {@link GeoRadiusCommandArgs}. * - * @param key - * @param member - * @param radius - * @param unit - * - * @return + * @param key must not be {@literal null}. + * @param member must not be {@literal null}. + * @param radius must not be {@literal null}. + * @param args must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadiusbymember + * @since 1.8 */ - List georadiusByMember(String key, String member, double radius, - GeoUnit unit); + GeoResults> georadiusByMember(String key, String member, Distance radius, + GeoRadiusCommandArgs args); /** - * This command is exactly like GEORADIUS with the sole difference that instead of taking, as the center of - * the area to query, a longitude and latitude value, it takes the name of a member already existing inside - * the geospatial index represented by the sorted set. - *

- * @link http://redis.io/commands/georadiusbymember + * Remove the {@literal member}s. * - * @param key - * @param member - * @param radius - * @param unit - * @param param - * - * @return + * @param key must not be {@literal null}. + * @param members must not be {@literal null}. + * @return Number of members elements removed. + * @since 1.8 */ - List georadiusByMember(String key, String member, double radius, - GeoUnit unit, GeoRadiusParam param); - Long geoRemove(String key, String... members); } diff --git a/src/main/java/org/springframework/data/redis/connection/convert/Converters.java b/src/main/java/org/springframework/data/redis/connection/convert/Converters.java index f6cf551dc..b462bc091 100644 --- a/src/main/java/org/springframework/data/redis/connection/convert/Converters.java +++ b/src/main/java/org/springframework/data/redis/connection/convert/Converters.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-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. @@ -27,24 +27,36 @@ import java.util.Properties; import java.util.Set; import org.springframework.core.convert.converter.Converter; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResult; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Metrics; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.connection.RedisClusterNode; import org.springframework.data.redis.connection.RedisClusterNode.Flag; import org.springframework.data.redis.connection.RedisClusterNode.LinkState; import org.springframework.data.redis.connection.RedisClusterNode.RedisClusterNodeBuilder; import org.springframework.data.redis.connection.RedisClusterNode.SlotRange; +import org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; import org.springframework.data.redis.connection.RedisNode.NodeType; import org.springframework.data.redis.connection.RedisZSetCommands.Tuple; +import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.util.CollectionUtils; import org.springframework.util.NumberUtils; +import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; +import lombok.RequiredArgsConstructor; + /** * Common type converters * * @author Jennifer Hickey * @author Thomas Darimont * @author Mark Paluch + * @author Christoph Strobl */ abstract public class Converters { @@ -263,4 +275,86 @@ abstract public class Converters { + NumberUtils.parseNumber(microseconds, Long.class) / 1000L; } + /** + * {@link Converter} capable of deserializing {@link GeoResults}. + * + * @param serializer + * @return + * @since 1.8 + */ + public static Converter>, GeoResults>> deserializingGeoResultsConverter( + RedisSerializer serializer) { + return new DeserializingGeoResultsConverter(serializer); + } + + /** + * {@link Converter} capable of converting Double into {@link Distance} using given {@link Metric}. + * + * @param metric + * @return + * @since 1.8 + */ + public static Converter distanceConverterForMetric(Metric metric) { + return DistanceConverterFactory.INSTANCE.forMetric(metric); + } + + /** + * @author Christoph Strobl + * @since 1.8 + */ + static enum DistanceConverterFactory { + + INSTANCE; + + DistanceConverter forMetric(Metric metric) { + return new DistanceConverter( + metric == null || ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, metric) ? DistanceUnit.METERS : metric); + } + + static class DistanceConverter implements Converter { + + private Metric metric; + + public DistanceConverter(Metric metric) { + this.metric = metric == null || ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, metric) ? DistanceUnit.METERS + : metric; + } + + @Override + public Distance convert(Double source) { + return source == null ? null : new Distance(source, metric); + } + } + } + + /** + * @author Christoph Strobl + * @param + * @since 1.8 + */ + @RequiredArgsConstructor + static class DeserializingGeoResultsConverter + implements Converter>, GeoResults>> { + + final RedisSerializer serializer; + + @Override + public GeoResults> convert(GeoResults> source) { + + if (source == null) { + return new GeoResults>(Collections.>> emptyList()); + } + + List>> values = new ArrayList>>(source.getContent().size()); + for (GeoResult> value : source.getContent()) { + + values.add(new GeoResult>( + new GeoLocation(serializer.deserialize(value.getContent().getName()), value.getContent().getPoint()), + value.getDistance())); + } + + return new GeoResults>(values, source.getAverageDistance().getMetric()); + } + } + } 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 d38a8678c..7fdfd6979 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 @@ -15,13 +15,30 @@ */ package org.springframework.data.redis.connection.jedis; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Properties; +import java.util.Random; +import java.util.Set; import java.util.concurrent.TimeUnit; import org.springframework.beans.DirectFieldAccessor; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Point; import org.springframework.data.redis.ClusterStateFailureException; import org.springframework.data.redis.ExceptionTranslationStrategy; import org.springframework.data.redis.PassThroughExceptionTranslationStrategy; @@ -48,8 +65,10 @@ import org.springframework.data.redis.connection.SortParameters; import org.springframework.data.redis.connection.Subscription; import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.connection.util.ByteArraySet; -import org.springframework.data.redis.core.*; -import org.springframework.data.redis.core.GeoRadiusResponse; +import org.springframework.data.redis.core.Cursor; +import org.springframework.data.redis.core.ScanCursor; +import org.springframework.data.redis.core.ScanIteration; +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.data.redis.util.ByteUtils; @@ -57,9 +76,15 @@ import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; -import redis.clients.jedis.*; +import redis.clients.jedis.BinaryJedisPubSub; import redis.clients.jedis.GeoCoordinate; import redis.clients.jedis.GeoUnit; +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; +import redis.clients.jedis.params.geo.GeoRadiusParam; /** * {@link RedisClusterConnection} implementation on top of {@link JedisCluster}.
@@ -68,6 +93,7 @@ import redis.clients.jedis.GeoUnit; * * @author Christoph Strobl * @author Mark Paluch + * @author Ninad Divadkar * @since 1.7 */ public class JedisClusterConnection implements RedisClusterConnection { @@ -2149,10 +2175,11 @@ public class JedisClusterConnection implements RedisClusterConnection { 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())); + + 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(); } @@ -2382,10 +2409,11 @@ public class JedisClusterConnection implements RedisClusterConnection { @Override protected ScanIteration> doScan(long cursorId, ScanOptions options) { - + ScanParams params = JedisConverters.toScanParams(options); - - redis.clients.jedis.ScanResult> result = cluster.hscan(key, JedisConverters.toBytes(cursorId), params); + + redis.clients.jedis.ScanResult> result = cluster.hscan(key, + JedisConverters.toBytes(cursorId), params); return new ScanIteration>(Long.valueOf(result.getStringCursor()), result.getResult()); } }.open(); @@ -2495,126 +2523,265 @@ public class JedisClusterConnection implements RedisClusterConnection { } } - @Override - public Long geoAdd(byte[] key, double longitude, double latitude, byte[] member){ - try { - return cluster.geoadd(key, longitude, latitude, member); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public Long geoAdd(byte[] key, Map memberCoordinateMap) { - Map redisGeoCoordinateMap = new HashMap(); - for(byte[] mapKey : memberCoordinateMap.keySet()){ - redisGeoCoordinateMap.put(mapKey, JedisConverters.toGeoCoordinate(memberCoordinateMap.get(mapKey))); - } - try { - return cluster.geoadd(key, redisGeoCoordinateMap); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - - @Override - public Double geoDist(byte[] key, byte[] member1, byte[] member2) { - try { - return cluster.geodist(key, member1, member2); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public Double geoDist(byte[] key, byte[] member1, byte[] member2, org.springframework.data.redis.core.GeoUnit unit) { - GeoUnit geoUnit = JedisConverters.toGeoUnit(unit); - try { - return cluster.geodist(key, member1, member2, geoUnit); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public List geoHash(byte[] key, byte[]... members) { - try { - return cluster.geohash(key, members); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public List geoPos(byte[] key, byte[]... members) { - try { - return JedisConverters.geoCoordinateListToGeoCoordinateList().convert(cluster.geopos(key, members)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], org.springframework.data.geo.Point, byte[]) + */ @Override - public List georadius(byte[] key, double longitude, double latitude, - double radius, org.springframework.data.redis.core.GeoUnit unit) { - GeoUnit geoUnit = JedisConverters.toGeoUnit(unit); + public Long geoAdd(byte[] key, Point point, byte[] member) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(point, "Point must not be null!"); + Assert.notNull(member, "Member must not be null!"); + try { - return JedisConverters.geoRadiusResponseGeoRadiusResponseList(). - convert(cluster.georadius(key, longitude, latitude, radius, geoUnit)); + return cluster.geoadd(key, point.getX(), point.getY(), member); } catch (Exception ex) { throw convertJedisAccessException(ex); } } - @Override - public List georadius(byte[] key, double longitude, double latitude, - double radius, org.springframework.data.redis.core.GeoUnit unit, GeoRadiusParam param) { - GeoUnit geoUnit = JedisConverters.toGeoUnit(unit); - redis.clients.jedis.params.geo.GeoRadiusParam geoRadiusParam = JedisConverters.toGeoRadiusParam(param); - try { - return JedisConverters.geoRadiusResponseGeoRadiusResponseList(). - convert(cluster.georadius(key, longitude, latitude, radius, geoUnit, geoRadiusParam)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public List georadiusByMember(byte[] key, byte[] member, double radius, - org.springframework.data.redis.core.GeoUnit unit) { - GeoUnit geoUnit = JedisConverters.toGeoUnit(unit); - try { - return JedisConverters.geoRadiusResponseGeoRadiusResponseList(). - convert(cluster.georadiusByMember(key, member, radius, geoUnit)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public List georadiusByMember(byte[] key, byte[] member, double radius, - org.springframework.data.redis.core.GeoUnit unit, GeoRadiusParam param) { - GeoUnit geoUnit = JedisConverters.toGeoUnit(unit); - redis.clients.jedis.params.geo.GeoRadiusParam geoRadiusParam = JedisConverters.toGeoRadiusParam(param); - try { - return JedisConverters.geoRadiusResponseGeoRadiusResponseList(). - convert(cluster.georadiusByMember(key, member, radius, geoUnit, geoRadiusParam)); - - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public Long geoRemove(byte[] key, byte[]... values) { - return zRem(key, values); - } - /* - * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisConnectionCommands#select(int) - */ + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation) + */ + public Long geoAdd(byte[] key, GeoLocation location) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(location, "Location must not be null!"); + + return geoAdd(key, location.getPoint(), location.getName()); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], java.util.Map) + */ + @Override + public Long geoAdd(byte[] key, Map memberCoordinateMap) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(memberCoordinateMap, "MemberCoordinateMap must not be null!"); + + Map redisGeoCoordinateMap = new HashMap(); + for (byte[] mapKey : memberCoordinateMap.keySet()) { + redisGeoCoordinateMap.put(mapKey, JedisConverters.toGeoCoordinate(memberCoordinateMap.get(mapKey))); + } + + try { + return cluster.geoadd(key, redisGeoCoordinateMap); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], java.lang.Iterable) + */ + @Override + public Long geoAdd(byte[] key, Iterable> locations) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(locations, "Locations must not be null!"); + + Map redisGeoCoordinateMap = new HashMap(); + for (GeoLocation location : locations) { + redisGeoCoordinateMap.put(location.getName(), JedisConverters.toGeoCoordinate(location.getPoint())); + } + + try { + return cluster.geoadd(key, redisGeoCoordinateMap); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoDist(byte[], byte[], byte[]) + */ + @Override + public Distance geoDist(byte[] key, byte[] member1, byte[] member2) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(member1, "Member1 must not be null!"); + Assert.notNull(member2, "Member2 must not be null!"); + + try { + return JedisConverters.distanceConverterForMetric(DistanceUnit.METERS) + .convert(cluster.geodist(key, member1, member2)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoDist(byte[], byte[], byte[], org.springframework.data.geo.Metric) + */ + @Override + public Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric metric) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(member1, "Member1 must not be null!"); + Assert.notNull(member2, "Member2 must not be null!"); + Assert.notNull(metric, "Metric must not be null!"); + + GeoUnit geoUnit = JedisConverters.toGeoUnit(metric); + try { + return JedisConverters.distanceConverterForMetric(metric) + .convert(cluster.geodist(key, member1, member2, geoUnit)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoHash(byte[], byte[][]) + */ + @Override + public List geoHash(byte[] key, byte[]... members) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(members, "Members must not be null!"); + Assert.noNullElements(members, "Members must not contain null!"); + + try { + return JedisConverters.toStrings(cluster.geohash(key, members)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoPos(byte[], byte[][]) + */ + @Override + public List geoPos(byte[] key, byte[]... members) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(members, "Members must not be null!"); + Assert.noNullElements(members, "Members must not contain null!"); + + try { + return JedisConverters.geoCoordinateToPointConverter().convert(cluster.geopos(key, members)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadius(byte[], org.springframework.data.geo.Circle) + */ + @Override + public GeoResults> geoRadius(byte[] key, Circle within) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(within, "Within must not be null!"); + + try { + return JedisConverters.geoRadiusResponseToGeoResultsConverter(within.getRadius().getMetric()) + .convert(cluster.georadius(key, within.getCenter().getX(), within.getCenter().getY(), + within.getRadius().getValue(), JedisConverters.toGeoUnit(within.getRadius().getMetric()))); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadius(byte[], org.springframework.data.geo.Circle, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> geoRadius(byte[] key, Circle within, GeoRadiusCommandArgs args) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(within, "Within must not be null!"); + Assert.notNull(args, "Args must not be null!"); + + GeoRadiusParam geoRadiusParam = JedisConverters.toGeoRadiusParam(args); + + try { + return JedisConverters.geoRadiusResponseToGeoResultsConverter(within.getRadius().getMetric()) + .convert(cluster.georadius(key, within.getCenter().getX(), within.getCenter().getY(), + within.getRadius().getValue(), JedisConverters.toGeoUnit(within.getRadius().getMetric()), + geoRadiusParam)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], double) + */ + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, double radius) { + return geoRadiusByMember(key, member, new Distance(radius, DistanceUnit.METERS)); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], org.springframework.data.geo.Distance) + */ + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(member, "Member must not be null!"); + Assert.notNull(radius, "Radius must not be null!"); + + GeoUnit geoUnit = JedisConverters.toGeoUnit(radius.getMetric()); + try { + return JedisConverters.geoRadiusResponseToGeoResultsConverter(radius.getMetric()) + .convert(cluster.georadiusByMember(key, member, radius.getValue(), geoUnit)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], org.springframework.data.geo.Distance, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius, + GeoRadiusCommandArgs args) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(member, "Member must not be null!"); + Assert.notNull(radius, "Radius must not be null!"); + Assert.notNull(args, "Args must not be null!"); + + GeoUnit geoUnit = JedisConverters.toGeoUnit(radius.getMetric()); + redis.clients.jedis.params.geo.GeoRadiusParam geoRadiusParam = JedisConverters.toGeoRadiusParam(args); + + try { + return JedisConverters.geoRadiusResponseToGeoResultsConverter(radius.getMetric()) + .convert(cluster.georadiusByMember(key, member, radius.getValue(), geoUnit, geoRadiusParam)); + + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoRemove(byte[], byte[][]) + */ + @Override + public Long geoRemove(byte[] key, byte[]... members) { + return zRem(key, members); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisConnectionCommands#select(int) + */ @Override public void select(final int dbIndex) { 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 41910f815..41463c3f5 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 @@ -17,13 +17,28 @@ package org.springframework.data.redis.connection.jedis; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Properties; +import java.util.Queue; +import java.util.Set; import java.util.concurrent.TimeUnit; import org.springframework.core.convert.converter.Converter; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Point; import org.springframework.data.redis.ExceptionTranslationStrategy; import org.springframework.data.redis.FallbackExceptionTranslationStrategy; import org.springframework.data.redis.RedisConnectionFailureException; @@ -39,10 +54,13 @@ 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.Converters; +import org.springframework.data.redis.connection.convert.ListConverter; import org.springframework.data.redis.connection.convert.TransactionResultConverter; -import org.springframework.data.redis.core.*; -import org.springframework.data.redis.core.GeoCoordinate; -import org.springframework.data.redis.core.GeoRadiusResponse; +import org.springframework.data.redis.core.Cursor; +import org.springframework.data.redis.core.KeyBoundCursor; +import org.springframework.data.redis.core.ScanCursor; +import org.springframework.data.redis.core.ScanIteration; +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; @@ -50,9 +68,24 @@ import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; -import redis.clients.jedis.*; +import redis.clients.jedis.BinaryJedis; +import redis.clients.jedis.BinaryJedisPubSub; +import redis.clients.jedis.Builder; +import redis.clients.jedis.Client; +import redis.clients.jedis.Connection; +import redis.clients.jedis.GeoCoordinate; import redis.clients.jedis.GeoUnit; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.Pipeline; +import redis.clients.jedis.Protocol; import redis.clients.jedis.Protocol.Command; +import redis.clients.jedis.Queable; +import redis.clients.jedis.Response; +import redis.clients.jedis.ScanParams; +import redis.clients.jedis.ScanResult; +import redis.clients.jedis.SortingParams; +import redis.clients.jedis.Transaction; +import redis.clients.jedis.ZParams; import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.util.Pool; @@ -68,701 +101,704 @@ import redis.clients.util.Pool; * @author David Liu * @author Milan Agatonovic * @author Mark Paluch + * @author Ninad Divadkar */ public class JedisConnection extends AbstractRedisConnection { - private static final Field CLIENT_FIELD; - private static final Method SEND_COMMAND; - private static final Method GET_RESPONSE; + private static final Field CLIENT_FIELD; + private static final Method SEND_COMMAND; + private static final Method GET_RESPONSE; - private static final String SHUTDOWN_SCRIPT = "return redis.call('SHUTDOWN','%s')"; + private static final String SHUTDOWN_SCRIPT = "return redis.call('SHUTDOWN','%s')"; - private static final ExceptionTranslationStrategy EXCEPTION_TRANSLATION = new FallbackExceptionTranslationStrategy( - JedisConverters.exceptionConverter()); + private static final ExceptionTranslationStrategy EXCEPTION_TRANSLATION = new FallbackExceptionTranslationStrategy( + JedisConverters.exceptionConverter()); - static { + static { - CLIENT_FIELD = ReflectionUtils.findField(BinaryJedis.class, "client", Client.class); - ReflectionUtils.makeAccessible(CLIENT_FIELD); + CLIENT_FIELD = ReflectionUtils.findField(BinaryJedis.class, "client", Client.class); + ReflectionUtils.makeAccessible(CLIENT_FIELD); - try { - Class commandType = ClassUtils.isPresent("redis.clients.jedis.ProtocolCommand", null) ? ClassUtils.forName( - "redis.clients.jedis.ProtocolCommand", null) : ClassUtils.forName("redis.clients.jedis.Protocol$Command", - null); + try { + Class commandType = ClassUtils.isPresent("redis.clients.jedis.ProtocolCommand", null) + ? ClassUtils.forName("redis.clients.jedis.ProtocolCommand", null) + : ClassUtils.forName("redis.clients.jedis.Protocol$Command", null); - SEND_COMMAND = ReflectionUtils.findMethod(Connection.class, "sendCommand", new Class[]{commandType, - byte[][].class}); - } catch (Exception e) { - throw new NoClassDefFoundError( - "Could not find required flavor of command required by 'redis.clients.jedis.Connection#sendCommand'."); - } + SEND_COMMAND = ReflectionUtils.findMethod(Connection.class, "sendCommand", + new Class[] { commandType, byte[][].class }); + } catch (Exception e) { + throw new NoClassDefFoundError( + "Could not find required flavor of command required by 'redis.clients.jedis.Connection#sendCommand'."); + } - ReflectionUtils.makeAccessible(SEND_COMMAND); + ReflectionUtils.makeAccessible(SEND_COMMAND); - GET_RESPONSE = ReflectionUtils.findMethod(Queable.class, "getResponse", Builder.class); - ReflectionUtils.makeAccessible(GET_RESPONSE); - } + GET_RESPONSE = ReflectionUtils.findMethod(Queable.class, "getResponse", Builder.class); + ReflectionUtils.makeAccessible(GET_RESPONSE); + } - private final Jedis jedis; - private final Client client; - private Transaction transaction; - private final Pool pool; - /** - * flag indicating whether the connection needs to be dropped or not - */ - private boolean broken = false; - private volatile JedisSubscription subscription; - private volatile Pipeline pipeline; - private final int dbIndex; - private boolean convertPipelineAndTxResults = true; - private List>> pipelinedResults = new ArrayList>>(); - private Queue>> txResults = new LinkedList>>(); - - private class JedisResult extends FutureResult> { - public JedisResult(Response resultHolder, Converter converter) { - super(resultHolder, converter); - } - - public JedisResult(Response resultHolder) { - super(resultHolder); - } - - @SuppressWarnings("unchecked") - public Object get() { - if (convertPipelineAndTxResults && converter != null) { - return converter.convert(resultHolder.get()); - } - return resultHolder.get(); - } - } - - private class JedisStatusResult extends JedisResult { - public JedisStatusResult(Response resultHolder) { - super(resultHolder); - setStatus(true); - } - } - - /** - * Constructs a new JedisConnection instance. - * - * @param jedis Jedis entity - */ - public JedisConnection(Jedis jedis) { - this(jedis, null, 0); - } - - /** - * Constructs a new JedisConnection instance backed by a jedis pool. - * - * @param jedis - * @param pool can be null, if no pool is used - */ - public JedisConnection(Jedis jedis, Pool pool, int dbIndex) { - this.jedis = jedis; - // extract underlying connection for batch operations - client = (Client) ReflectionUtils.getField(CLIENT_FIELD, jedis); - - this.pool = pool; - - this.dbIndex = dbIndex; - - // select the db - // if this fail, do manual clean-up before propagating the exception - // as we're inside the constructor - if (dbIndex > 0) { - try { - select(dbIndex); - } catch (DataAccessException ex) { - close(); - throw ex; - } - } - } - - protected DataAccessException convertJedisAccessException(Exception ex) { - - if (ex instanceof NullPointerException) { - // An NPE before flush will leave data in the OutputStream of a pooled connection - broken = true; - } - - DataAccessException exception = EXCEPTION_TRANSLATION.translate(ex); - if (exception instanceof RedisConnectionFailureException) { - broken = true; - } - - return exception; - } - - public Object execute(String command, byte[]... args) { - Assert.hasText(command, "a valid command needs to be specified"); - try { - List mArgs = new ArrayList(); - if (!ObjectUtils.isEmpty(args)) { - Collections.addAll(mArgs, args); - } - - ReflectionUtils.invokeMethod(SEND_COMMAND, client, Command.valueOf(command.trim().toUpperCase()), - mArgs.toArray(new byte[mArgs.size()][])); - if (isQueueing() || isPipelined()) { - Object target = (isPipelined() ? pipeline : transaction); - @SuppressWarnings("unchecked") - Response result = (Response) ReflectionUtils.invokeMethod(GET_RESPONSE, target, - new Builder() { - public Object build(Object data) { - return data; - } - - public String toString() { - return "Object"; - } - }); - if (isPipelined()) { - pipeline(new JedisResult(result)); - } else { - transaction(new JedisResult(result)); - } - return null; - } - return client.getOne(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public void close() throws DataAccessException { - super.close(); - // return the connection to the pool - if (pool != null) { - if (!broken) { - // reset the connection - try { - if (dbIndex > 0) { - jedis.select(0); - } - pool.returnResource(jedis); - return; - } catch (Exception ex) { - DataAccessException dae = convertJedisAccessException(ex); - if (broken) { - pool.returnBrokenResource(jedis); - } else { - pool.returnResource(jedis); - } - throw dae; - } - } else { - pool.returnBrokenResource(jedis); - return; - } - } - // else close the connection normally (doing the try/catch dance) - Exception exc = null; - if (isQueueing()) { - try { - client.quit(); - } catch (Exception ex) { - exc = ex; - } - try { - client.disconnect(); - } catch (Exception ex) { - exc = ex; - } - return; - } - try { - jedis.quit(); - } catch (Exception ex) { - exc = ex; - } - try { - jedis.disconnect(); - } catch (Exception ex) { - exc = ex; - } - if (exc != null) - throw convertJedisAccessException(exc); - } - - public Jedis getNativeConnection() { - return jedis; - } - - public boolean isClosed() { - try { - return !jedis.isConnected(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public boolean isQueueing() { - return client.isInMulti(); - } - - public boolean isPipelined() { - return (pipeline != null); - } - - public void openPipeline() { - if (pipeline == null) { - pipeline = jedis.pipelined(); - } - } - - public List closePipeline() { - if (pipeline != null) { - try { - return convertPipelineResults(); - } finally { - pipeline = null; - pipelinedResults.clear(); - } - } - return Collections.emptyList(); - } - - private List convertPipelineResults() { - List results = new ArrayList(); - pipeline.sync(); - Exception cause = null; - for (FutureResult> result : pipelinedResults) { - try { - Object data = result.get(); - if (!convertPipelineAndTxResults || !(result.isStatus())) { - results.add(data); - } - } catch (JedisDataException e) { - DataAccessException dataAccessException = convertJedisAccessException(e); - if (cause == null) { - cause = dataAccessException; - } - results.add(dataAccessException); - } catch (DataAccessException e) { - if (cause == null) { - cause = e; - } - results.add(e); - } - } - if (cause != null) { - throw new RedisPipelineException(cause, results); - } - return results; - } - - private void doPipelined(Response response) { - pipeline(new JedisStatusResult(response)); - } - - private void pipeline(FutureResult> result) { - if (isQueueing()) { - transaction(result); - } else { - pipelinedResults.add(result); - } - } - - private void doQueued(Response response) { - transaction(new JedisStatusResult(response)); - } - - private void transaction(FutureResult> result) { - txResults.add(result); - } - - public List sort(byte[] key, SortParameters params) { - - SortingParams sortParams = JedisConverters.toSortingParams(params); - - try { - if (isPipelined()) { - if (sortParams != null) { - pipeline(new JedisResult(pipeline.sort(key, sortParams))); - } else { - pipeline(new JedisResult(pipeline.sort(key))); - } - - return null; - } - if (isQueueing()) { - if (sortParams != null) { - transaction(new JedisResult(transaction.sort(key, sortParams))); - } else { - transaction(new JedisResult(transaction.sort(key))); - } - - return null; - } - return (sortParams != null ? jedis.sort(key, sortParams) : jedis.sort(key)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long sort(byte[] key, SortParameters params, byte[] storeKey) { - - SortingParams sortParams = JedisConverters.toSortingParams(params); - - try { - if (isPipelined()) { - if (sortParams != null) { - pipeline(new JedisResult(pipeline.sort(key, sortParams, storeKey))); - } else { - pipeline(new JedisResult(pipeline.sort(key, storeKey))); - } - - return null; - } - if (isQueueing()) { - if (sortParams != null) { - transaction(new JedisResult(transaction.sort(key, sortParams, storeKey))); - } else { - transaction(new JedisResult(transaction.sort(key, storeKey))); - } - - return null; - } - return (sortParams != null ? jedis.sort(key, sortParams, storeKey) : jedis.sort(key, storeKey)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long dbSize() { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.dbSize())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.dbSize())); - return null; - } - return jedis.dbSize(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public void flushDb() { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.flushDB())); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.flushDB())); - return; - } - jedis.flushDB(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public void flushAll() { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.flushAll())); - return; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.flushAll())); - return; - } - jedis.flushAll(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public void bgSave() { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.bgsave())); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.bgsave())); - return; - } - jedis.bgsave(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public void bgReWriteAof() { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.bgrewriteaof())); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.bgrewriteaof())); - return; - } - jedis.bgrewriteaof(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - /** - * @deprecated As of 1.3, use {@link #bgReWriteAof}. - */ - @Deprecated - public void bgWriteAof() { - bgReWriteAof(); - } - - public void save() { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.save())); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.save())); - return; - } - jedis.save(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public List getConfig(String param) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.configGet(param))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.configGet(param))); - return null; - } - return jedis.configGet(param); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Properties info() { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.info(), JedisConverters.stringToProps())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.info(), JedisConverters.stringToProps())); - return null; - } - return JedisConverters.toProperties(jedis.info()); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Properties info(String section) { - if (isPipelined()) { - throw new UnsupportedOperationException(); - } - if (isQueueing()) { - throw new UnsupportedOperationException(); - } - try { - return JedisConverters.toProperties(jedis.info(section)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long lastSave() { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.lastsave())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.lastsave())); - return null; - } - return jedis.lastsave(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public void setConfig(String param, String value) { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.configSet(param, value))); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.configSet(param, value))); - return; - } - jedis.configSet(param, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public void resetConfigStats() { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.configResetStat())); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.configResetStat())); - return; - } - jedis.configResetStat(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public void shutdown() { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.shutdown())); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.shutdown())); - return; - } - jedis.shutdown(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - /* - * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisServerCommands#shutdown(org.springframework.data.redis.connection.RedisServerCommands.ShutdownOption) + private final Jedis jedis; + private final Client client; + private Transaction transaction; + private final Pool pool; + /** + * flag indicating whether the connection needs to be dropped or not */ - @Override - public void shutdown(ShutdownOption option) { + private boolean broken = false; + private volatile JedisSubscription subscription; + private volatile Pipeline pipeline; + private final int dbIndex; + private boolean convertPipelineAndTxResults = true; + private List>> pipelinedResults = new ArrayList>>(); + private Queue>> txResults = new LinkedList>>(); - if (option == null) { - shutdown(); - return; - } + private class JedisResult extends FutureResult> { + public JedisResult(Response resultHolder, Converter converter) { + super(resultHolder, converter); + } - eval(String.format(SHUTDOWN_SCRIPT, option.name()).getBytes(), ReturnType.STATUS, 0); - } + public JedisResult(Response resultHolder) { + super(resultHolder); + } - public byte[] echo(byte[] message) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.echo(message))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.echo(message))); - return null; - } - return jedis.echo(message); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + @SuppressWarnings("unchecked") + public Object get() { + if (convertPipelineAndTxResults && converter != null) { + return converter.convert(resultHolder.get()); + } + return resultHolder.get(); + } + } - public String ping() { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.ping())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.ping())); - return null; - } - return jedis.ping(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + private class JedisStatusResult extends JedisResult { + public JedisStatusResult(Response resultHolder) { + super(resultHolder); + setStatus(true); + } + } - public Long del(byte[]... keys) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.del(keys))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.del(keys))); - return null; - } - return jedis.del(keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + /** + * Constructs a new JedisConnection instance. + * + * @param jedis Jedis entity + */ + public JedisConnection(Jedis jedis) { + this(jedis, null, 0); + } - public void discard() { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.discard())); - return; - } - transaction.discard(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } finally { - txResults.clear(); - transaction = null; - } - } + /** + * Constructs a new JedisConnection instance backed by a jedis pool. + * + * @param jedis + * @param pool can be null, if no pool is used + */ + public JedisConnection(Jedis jedis, Pool pool, int dbIndex) { + this.jedis = jedis; + // extract underlying connection for batch operations + client = (Client) ReflectionUtils.getField(CLIENT_FIELD, jedis); - public List exec() { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.exec(), new TransactionResultConverter>( - new LinkedList>>(txResults), JedisConverters.exceptionConverter()))); - return null; - } + this.pool = pool; - if (transaction == null) { - throw new InvalidDataAccessApiUsageException("No ongoing transaction. Did you forget to call multi?"); - } - List results = transaction.exec(); - return convertPipelineAndTxResults ? new TransactionResultConverter>(txResults, - JedisConverters.exceptionConverter()).convert(results) : results; - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } finally { - txResults.clear(); - transaction = null; - } - } + this.dbIndex = dbIndex; - public Boolean exists(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.exists(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.exists(key))); - return null; - } - return jedis.exists(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + // select the db + // if this fail, do manual clean-up before propagating the exception + // as we're inside the constructor + if (dbIndex > 0) { + try { + select(dbIndex); + } catch (DataAccessException ex) { + close(); + throw ex; + } + } + } - public Boolean expire(byte[] key, long seconds) { + protected DataAccessException convertJedisAccessException(Exception ex) { + + if (ex instanceof NullPointerException) { + // An NPE before flush will leave data in the OutputStream of a pooled connection + broken = true; + } + + DataAccessException exception = EXCEPTION_TRANSLATION.translate(ex); + if (exception instanceof RedisConnectionFailureException) { + broken = true; + } + + return exception; + } + + public Object execute(String command, byte[]... args) { + Assert.hasText(command, "a valid command needs to be specified"); + try { + List mArgs = new ArrayList(); + if (!ObjectUtils.isEmpty(args)) { + Collections.addAll(mArgs, args); + } + + ReflectionUtils.invokeMethod(SEND_COMMAND, client, Command.valueOf(command.trim().toUpperCase()), + mArgs.toArray(new byte[mArgs.size()][])); + if (isQueueing() || isPipelined()) { + Object target = (isPipelined() ? pipeline : transaction); + @SuppressWarnings("unchecked") + Response result = (Response) ReflectionUtils.invokeMethod(GET_RESPONSE, target, + new Builder() { + public Object build(Object data) { + return data; + } + + public String toString() { + return "Object"; + } + }); + if (isPipelined()) { + pipeline(new JedisResult(result)); + } else { + transaction(new JedisResult(result)); + } + return null; + } + return client.getOne(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public void close() throws DataAccessException { + super.close(); + // return the connection to the pool + if (pool != null) { + if (!broken) { + // reset the connection + try { + if (dbIndex > 0) { + jedis.select(0); + } + pool.returnResource(jedis); + return; + } catch (Exception ex) { + DataAccessException dae = convertJedisAccessException(ex); + if (broken) { + pool.returnBrokenResource(jedis); + } else { + pool.returnResource(jedis); + } + throw dae; + } + } else { + pool.returnBrokenResource(jedis); + return; + } + } + // else close the connection normally (doing the try/catch dance) + Exception exc = null; + if (isQueueing()) { + try { + client.quit(); + } catch (Exception ex) { + exc = ex; + } + try { + client.disconnect(); + } catch (Exception ex) { + exc = ex; + } + return; + } + try { + jedis.quit(); + } catch (Exception ex) { + exc = ex; + } + try { + jedis.disconnect(); + } catch (Exception ex) { + exc = ex; + } + if (exc != null) + throw convertJedisAccessException(exc); + } + + public Jedis getNativeConnection() { + return jedis; + } + + public boolean isClosed() { + try { + return !jedis.isConnected(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public boolean isQueueing() { + return client.isInMulti(); + } + + public boolean isPipelined() { + return (pipeline != null); + } + + public void openPipeline() { + if (pipeline == null) { + pipeline = jedis.pipelined(); + } + } + + public List closePipeline() { + if (pipeline != null) { + try { + return convertPipelineResults(); + } finally { + pipeline = null; + pipelinedResults.clear(); + } + } + return Collections.emptyList(); + } + + private List convertPipelineResults() { + List results = new ArrayList(); + pipeline.sync(); + Exception cause = null; + for (FutureResult> result : pipelinedResults) { + try { + Object data = result.get(); + if (!convertPipelineAndTxResults || !(result.isStatus())) { + results.add(data); + } + } catch (JedisDataException e) { + DataAccessException dataAccessException = convertJedisAccessException(e); + if (cause == null) { + cause = dataAccessException; + } + results.add(dataAccessException); + } catch (DataAccessException e) { + if (cause == null) { + cause = e; + } + results.add(e); + } + } + if (cause != null) { + throw new RedisPipelineException(cause, results); + } + return results; + } + + private void doPipelined(Response response) { + pipeline(new JedisStatusResult(response)); + } + + private void pipeline(FutureResult> result) { + if (isQueueing()) { + transaction(result); + } else { + pipelinedResults.add(result); + } + } + + private void doQueued(Response response) { + transaction(new JedisStatusResult(response)); + } + + private void transaction(FutureResult> result) { + txResults.add(result); + } + + public List sort(byte[] key, SortParameters params) { + + SortingParams sortParams = JedisConverters.toSortingParams(params); + + try { + if (isPipelined()) { + if (sortParams != null) { + pipeline(new JedisResult(pipeline.sort(key, sortParams))); + } else { + pipeline(new JedisResult(pipeline.sort(key))); + } + + return null; + } + if (isQueueing()) { + if (sortParams != null) { + transaction(new JedisResult(transaction.sort(key, sortParams))); + } else { + transaction(new JedisResult(transaction.sort(key))); + } + + return null; + } + return (sortParams != null ? jedis.sort(key, sortParams) : jedis.sort(key)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long sort(byte[] key, SortParameters params, byte[] storeKey) { + + SortingParams sortParams = JedisConverters.toSortingParams(params); + + try { + if (isPipelined()) { + if (sortParams != null) { + pipeline(new JedisResult(pipeline.sort(key, sortParams, storeKey))); + } else { + pipeline(new JedisResult(pipeline.sort(key, storeKey))); + } + + return null; + } + if (isQueueing()) { + if (sortParams != null) { + transaction(new JedisResult(transaction.sort(key, sortParams, storeKey))); + } else { + transaction(new JedisResult(transaction.sort(key, storeKey))); + } + + return null; + } + return (sortParams != null ? jedis.sort(key, sortParams, storeKey) : jedis.sort(key, storeKey)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long dbSize() { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.dbSize())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.dbSize())); + return null; + } + return jedis.dbSize(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public void flushDb() { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.flushDB())); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.flushDB())); + return; + } + jedis.flushDB(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public void flushAll() { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.flushAll())); + return; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.flushAll())); + return; + } + jedis.flushAll(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public void bgSave() { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.bgsave())); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.bgsave())); + return; + } + jedis.bgsave(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + @Override + public void bgReWriteAof() { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.bgrewriteaof())); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.bgrewriteaof())); + return; + } + jedis.bgrewriteaof(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /** + * @deprecated As of 1.3, use {@link #bgReWriteAof}. + */ + @Deprecated + public void bgWriteAof() { + bgReWriteAof(); + } + + public void save() { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.save())); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.save())); + return; + } + jedis.save(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public List getConfig(String param) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.configGet(param))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.configGet(param))); + return null; + } + return jedis.configGet(param); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Properties info() { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.info(), JedisConverters.stringToProps())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.info(), JedisConverters.stringToProps())); + return null; + } + return JedisConverters.toProperties(jedis.info()); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Properties info(String section) { + if (isPipelined()) { + throw new UnsupportedOperationException(); + } + if (isQueueing()) { + throw new UnsupportedOperationException(); + } + try { + return JedisConverters.toProperties(jedis.info(section)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long lastSave() { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.lastsave())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.lastsave())); + return null; + } + return jedis.lastsave(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public void setConfig(String param, String value) { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.configSet(param, value))); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.configSet(param, value))); + return; + } + jedis.configSet(param, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public void resetConfigStats() { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.configResetStat())); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.configResetStat())); + return; + } + jedis.configResetStat(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public void shutdown() { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.shutdown())); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.shutdown())); + return; + } + jedis.shutdown(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisServerCommands#shutdown(org.springframework.data.redis.connection.RedisServerCommands.ShutdownOption) + */ + @Override + public void shutdown(ShutdownOption option) { + + if (option == null) { + shutdown(); + return; + } + + eval(String.format(SHUTDOWN_SCRIPT, option.name()).getBytes(), ReturnType.STATUS, 0); + } + + public byte[] echo(byte[] message) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.echo(message))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.echo(message))); + return null; + } + return jedis.echo(message); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public String ping() { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.ping())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.ping())); + return null; + } + return jedis.ping(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long del(byte[]... keys) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.del(keys))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.del(keys))); + return null; + } + return jedis.del(keys); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public void discard() { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.discard())); + return; + } + transaction.discard(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } finally { + txResults.clear(); + transaction = null; + } + } + + public List exec() { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.exec(), new TransactionResultConverter>( + new LinkedList>>(txResults), JedisConverters.exceptionConverter()))); + return null; + } + + if (transaction == null) { + throw new InvalidDataAccessApiUsageException("No ongoing transaction. Did you forget to call multi?"); + } + List results = transaction.exec(); + return convertPipelineAndTxResults + ? new TransactionResultConverter>(txResults, JedisConverters.exceptionConverter()) + .convert(results) + : results; + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } finally { + txResults.clear(); + transaction = null; + } + } + + public Boolean exists(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.exists(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.exists(key))); + return null; + } + return jedis.exists(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Boolean expire(byte[] key, long seconds) { /* * @see DATAREDIS-286 to avoid overflow in Jedis @@ -770,2505 +806,2673 @@ public class JedisConnection extends AbstractRedisConnection { * TODO Remove this workaround when we upgrade to a Jedis version that contains a * fix for: https://github.com/xetorthio/jedis/pull/575 */ - if (seconds > Integer.MAX_VALUE) { + if (seconds > Integer.MAX_VALUE) { - return pExpireAt(key, time() + TimeUnit.SECONDS.toMillis(seconds)); - } + return pExpireAt(key, time() + TimeUnit.SECONDS.toMillis(seconds)); + } - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.expire(key, (int) seconds), JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.expire(key, (int) seconds), JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(jedis.expire(key, (int) seconds)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.expire(key, (int) seconds), JedisConverters.longToBoolean())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.expire(key, (int) seconds), JedisConverters.longToBoolean())); + return null; + } + return JedisConverters.toBoolean(jedis.expire(key, (int) seconds)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public Boolean expireAt(byte[] key, long unixTime) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.expireAt(key, unixTime), JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.expireAt(key, unixTime), JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(jedis.expireAt(key, unixTime)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public Boolean expireAt(byte[] key, long unixTime) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.expireAt(key, unixTime), JedisConverters.longToBoolean())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.expireAt(key, unixTime), JedisConverters.longToBoolean())); + return null; + } + return JedisConverters.toBoolean(jedis.expireAt(key, unixTime)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public Set keys(byte[] pattern) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.keys(pattern))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.keys(pattern))); - return null; - } - return (jedis.keys(pattern)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public Set keys(byte[] pattern) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.keys(pattern))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.keys(pattern))); + return null; + } + return (jedis.keys(pattern)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public void multi() { - if (isQueueing()) { - return; - } - try { - if (isPipelined()) { - pipeline.multi(); - return; - } - this.transaction = jedis.multi(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public void multi() { + if (isQueueing()) { + return; + } + try { + if (isPipelined()) { + pipeline.multi(); + return; + } + this.transaction = jedis.multi(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public Boolean persist(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.persist(key), JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.persist(key), JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(jedis.persist(key)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public Boolean persist(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.persist(key), JedisConverters.longToBoolean())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.persist(key), JedisConverters.longToBoolean())); + return null; + } + return JedisConverters.toBoolean(jedis.persist(key)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public Boolean move(byte[] key, int dbIndex) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.move(key, dbIndex), JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.move(key, dbIndex), JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(jedis.move(key, dbIndex)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public Boolean move(byte[] key, int dbIndex) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.move(key, dbIndex), JedisConverters.longToBoolean())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.move(key, dbIndex), JedisConverters.longToBoolean())); + return null; + } + return JedisConverters.toBoolean(jedis.move(key, dbIndex)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public byte[] randomKey() { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.randomKeyBinary())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.randomKeyBinary())); - return null; - } - return jedis.randomBinaryKey(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public byte[] randomKey() { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.randomKeyBinary())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.randomKeyBinary())); + return null; + } + return jedis.randomBinaryKey(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public void rename(byte[] oldName, byte[] newName) { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.rename(oldName, newName))); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.rename(oldName, newName))); - return; - } - jedis.rename(oldName, newName); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public void rename(byte[] oldName, byte[] newName) { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.rename(oldName, newName))); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.rename(oldName, newName))); + return; + } + jedis.rename(oldName, newName); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public Boolean renameNX(byte[] oldName, byte[] newName) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.renamenx(oldName, newName), JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.renamenx(oldName, newName), JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(jedis.renamenx(oldName, newName)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public Boolean renameNX(byte[] oldName, byte[] newName) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.renamenx(oldName, newName), JedisConverters.longToBoolean())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.renamenx(oldName, newName), JedisConverters.longToBoolean())); + return null; + } + return JedisConverters.toBoolean(jedis.renamenx(oldName, newName)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public void select(int dbIndex) { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.select(dbIndex))); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.select(dbIndex))); - return; - } - jedis.select(dbIndex); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public void select(int dbIndex) { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.select(dbIndex))); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.select(dbIndex))); + return; + } + jedis.select(dbIndex); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public Long ttl(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.ttl(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.ttl(key))); - return null; - } - return jedis.ttl(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public Long ttl(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.ttl(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.ttl(key))); + return null; + } + return jedis.ttl(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public Boolean pExpire(byte[] key, long millis) { + public Boolean pExpire(byte[] key, long millis) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.pexpire(key, millis), JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.pexpire(key, millis), JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(jedis.pexpire(key, millis)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.pexpire(key, millis), JedisConverters.longToBoolean())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.pexpire(key, millis), JedisConverters.longToBoolean())); + return null; + } + return JedisConverters.toBoolean(jedis.pexpire(key, millis)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public Boolean pExpireAt(byte[] key, long unixTimeInMillis) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.pexpireAt(key, unixTimeInMillis), JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.pexpireAt(key, unixTimeInMillis), JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(jedis.pexpireAt(key, unixTimeInMillis)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public Boolean pExpireAt(byte[] key, long unixTimeInMillis) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.pexpireAt(key, unixTimeInMillis), JedisConverters.longToBoolean())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.pexpireAt(key, unixTimeInMillis), JedisConverters.longToBoolean())); + return null; + } + return JedisConverters.toBoolean(jedis.pexpireAt(key, unixTimeInMillis)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public Long pTtl(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.pttl(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.pttl(key))); - return null; - } - return jedis.pttl(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public Long pTtl(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.pttl(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.pttl(key))); + return null; + } + return jedis.pttl(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public byte[] dump(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.dump(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.dump(key))); - return null; - } - return jedis.dump(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public byte[] dump(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.dump(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.dump(key))); + return null; + } + return jedis.dump(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public void restore(byte[] key, long ttlInMillis, byte[] serializedValue) { + public void restore(byte[] key, long ttlInMillis, byte[] serializedValue) { - if (ttlInMillis > Integer.MAX_VALUE) { - throw new IllegalArgumentException("TtlInMillis must be less than Integer.MAX_VALUE for restore in Jedis."); - } - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.restore(key, (int) ttlInMillis, serializedValue))); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.restore(key, (int) ttlInMillis, serializedValue))); - return; - } - jedis.restore(key, (int) ttlInMillis, serializedValue); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + if (ttlInMillis > Integer.MAX_VALUE) { + throw new IllegalArgumentException("TtlInMillis must be less than Integer.MAX_VALUE for restore in Jedis."); + } + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.restore(key, (int) ttlInMillis, serializedValue))); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.restore(key, (int) ttlInMillis, serializedValue))); + return; + } + jedis.restore(key, (int) ttlInMillis, serializedValue); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public DataType type(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.type(key), JedisConverters.stringToDataType())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.type(key), JedisConverters.stringToDataType())); - return null; - } - return JedisConverters.toDataType(jedis.type(key)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public DataType type(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.type(key), JedisConverters.stringToDataType())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.type(key), JedisConverters.stringToDataType())); + return null; + } + return JedisConverters.toDataType(jedis.type(key)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public void unwatch() { - try { - jedis.unwatch(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public void unwatch() { + try { + jedis.unwatch(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public void watch(byte[]... keys) { - if (isQueueing()) { - throw new UnsupportedOperationException(); - } - try { - for (byte[] key : keys) { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.watch(key))); - } else { - jedis.watch(key); - } - } - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public void watch(byte[]... keys) { + if (isQueueing()) { + throw new UnsupportedOperationException(); + } + try { + for (byte[] key : keys) { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.watch(key))); + } else { + jedis.watch(key); + } + } + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - // - // String commands - // + // + // String commands + // - public byte[] get(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.get(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.get(key))); - return null; - } + public byte[] get(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.get(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.get(key))); + return null; + } - return jedis.get(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + return jedis.get(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - public void set(byte[] key, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.set(key, value))); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.set(key, value))); - return; - } - jedis.set(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + public void set(byte[] key, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.set(key, value))); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.set(key, value))); + return; + } + jedis.set(key, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - /* + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisStringCommands#set(byte[], byte[], org.springframework.data.redis.core.types.Expiration, org.springframework.data.redis.connection.RedisStringCommands.SetOption) + */ + @Override + public void set(byte[] key, byte[] value, Expiration expiration, SetOption option) { + + if (expiration == null || expiration.isPersistent()) { + + if (option == null || ObjectUtils.nullSafeEquals(SetOption.UPSERT, option)) { + set(key, value); + } else { + + try { + + byte[] nxxx = JedisConverters.toSetCommandNxXxArgument(option); + + if (isPipelined()) { + + pipeline(new JedisStatusResult(pipeline.set(key, value, nxxx))); + return; + } + if (isQueueing()) { + + transaction(new JedisStatusResult(transaction.set(key, value, nxxx))); + return; + } + + jedis.set(key, value, nxxx); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + } else { + + if (option == null || ObjectUtils.nullSafeEquals(SetOption.UPSERT, option)) { + + if (ObjectUtils.nullSafeEquals(TimeUnit.MILLISECONDS, expiration.getTimeUnit())) { + pSetEx(key, expiration.getExpirationTime(), value); + } else { + setEx(key, expiration.getExpirationTime(), value); + } + } else { + + byte[] nxxx = JedisConverters.toSetCommandNxXxArgument(option); + byte[] expx = JedisConverters.toSetCommandExPxArgument(expiration); + + try { + if (isPipelined()) { + + if (expiration.getExpirationTime() > Integer.MAX_VALUE) { + + throw new IllegalArgumentException( + "Expiration.expirationTime must be less than Integer.MAX_VALUE for pipeline in Jedis."); + } + + pipeline(new JedisStatusResult(pipeline.set(key, value, nxxx, expx, (int) expiration.getExpirationTime()))); + return; + } + if (isQueueing()) { + + if (expiration.getExpirationTime() > Integer.MAX_VALUE) { + throw new IllegalArgumentException( + "Expiration.expirationTime must be less than Integer.MAX_VALUE for transactions in Jedis."); + } + + transaction( + new JedisStatusResult(transaction.set(key, value, nxxx, expx, (int) expiration.getExpirationTime()))); + return; + } + + jedis.set(key, value, nxxx, expx, expiration.getExpirationTime()); + + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + } + } + + public byte[] getSet(byte[] key, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.getSet(key, value))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.getSet(key, value))); + return null; + } + return jedis.getSet(key, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long append(byte[] key, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.append(key, value))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.append(key, value))); + return null; + } + return jedis.append(key, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public List mGet(byte[]... keys) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.mget(keys))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.mget(keys))); + return null; + } + return jedis.mget(keys); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public void mSet(Map tuples) { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.mset(JedisConverters.toByteArrays(tuples)))); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.mset(JedisConverters.toByteArrays(tuples)))); + return; + } + jedis.mset(JedisConverters.toByteArrays(tuples)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Boolean mSetNX(Map tuples) { + try { + if (isPipelined()) { + pipeline( + new JedisResult(pipeline.msetnx(JedisConverters.toByteArrays(tuples)), JedisConverters.longToBoolean())); + return null; + } + if (isQueueing()) { + transaction( + new JedisResult(transaction.msetnx(JedisConverters.toByteArrays(tuples)), JedisConverters.longToBoolean())); + return null; + } + return JedisConverters.toBoolean(jedis.msetnx(JedisConverters.toByteArrays(tuples))); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public void setEx(byte[] key, long time, byte[] value) { + + if (time > Integer.MAX_VALUE) { + throw new IllegalArgumentException("Time must be less than Integer.MAX_VALUE for setEx in Jedis."); + } + + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.setex(key, (int) time, value))); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.setex(key, (int) time, value))); + return; + } + jedis.setex(key, (int) time, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisStringCommands#pSetEx(byte[], long, byte[]) + */ + @Override + public void pSetEx(byte[] key, long milliseconds, byte[] value) { + + try { + if (isPipelined()) { + doPipelined(pipeline.psetex(key, milliseconds, value)); + return; + } + if (isQueueing()) { + doQueued(transaction.psetex(key, milliseconds, value)); + return; + } + jedis.psetex(key, milliseconds, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Boolean setNX(byte[] key, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.setnx(key, value), JedisConverters.longToBoolean())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.setnx(key, value), JedisConverters.longToBoolean())); + return null; + } + return JedisConverters.toBoolean(jedis.setnx(key, value)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public byte[] getRange(byte[] key, long start, long end) { + + if (start > Integer.MAX_VALUE || end > Integer.MAX_VALUE) { + throw new IllegalArgumentException("Start and end must be less than Integer.MAX_VALUE for getRange in Jedis."); + } + + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.substr(key, (int) start, (int) end), JedisConverters.stringToBytes())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.substr(key, (int) start, (int) end), JedisConverters.stringToBytes())); + return null; + } + return jedis.substr(key, (int) start, (int) end); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long decr(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.decr(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.decr(key))); + return null; + } + return jedis.decr(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long decrBy(byte[] key, long value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.decrBy(key, value))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.decrBy(key, value))); + return null; + } + return jedis.decrBy(key, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long incr(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.incr(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.incr(key))); + return null; + } + return jedis.incr(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long incrBy(byte[] key, long value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.incrBy(key, value))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.incrBy(key, value))); + return null; + } + return jedis.incrBy(key, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Double incrBy(byte[] key, double value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.incrByFloat(key, value))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.incrByFloat(key, value))); + return null; + } + return jedis.incrByFloat(key, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Boolean getBit(byte[] key, long offset) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.getbit(key, offset))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.getbit(key, offset))); + return null; + } + // compatibility check for Jedis 2.0.0 + Object getBit = jedis.getbit(key, offset); + // Jedis 2.0 + if (getBit instanceof Long) { + return (((Long) getBit) == 0 ? Boolean.FALSE : Boolean.TRUE); + } + // Jedis 2.1 + return ((Boolean) getBit); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Boolean setBit(byte[] key, long offset, boolean value) { + try { + if (isPipelined()) { + + pipeline(new JedisResult(pipeline.setbit(key, offset, JedisConverters.toBit(value)))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.setbit(key, offset, JedisConverters.toBit(value)))); + return null; + } + return jedis.setbit(key, offset, JedisConverters.toBit(value)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public void setRange(byte[] key, byte[] value, long start) { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.setrange(key, start, value))); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.setrange(key, start, value))); + return; + } + jedis.setrange(key, start, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long strLen(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.strlen(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.strlen(key))); + return null; + } + return jedis.strlen(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long bitCount(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.bitcount(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.bitcount(key))); + return null; + } + return jedis.bitcount(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long bitCount(byte[] key, long begin, long end) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.bitcount(key, begin, end))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.bitcount(key, begin, end))); + return null; + } + return jedis.bitcount(key, begin, end); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long bitOp(BitOperation op, byte[] destination, byte[]... keys) { + if (op == BitOperation.NOT && keys.length > 1) { + throw new UnsupportedOperationException("Bitop NOT should only be performed against one key"); + } + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.bitop(JedisConverters.toBitOp(op), destination, keys))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.bitop(JedisConverters.toBitOp(op), destination, keys))); + return null; + } + return jedis.bitop(JedisConverters.toBitOp(op), destination, keys); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + // + // List commands + // + + public Long lPush(byte[] key, byte[]... values) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.lpush(key, values))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.lpush(key, values))); + return null; + } + return jedis.lpush(key, values); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long rPush(byte[] key, byte[]... values) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.rpush(key, values))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.rpush(key, values))); + return null; + } + return jedis.rpush(key, values); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public List bLPop(int timeout, byte[]... keys) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.blpop(bXPopArgs(timeout, keys)))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.blpop(bXPopArgs(timeout, keys)))); + return null; + } + return jedis.blpop(timeout, keys); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public List bRPop(int timeout, byte[]... keys) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.brpop(bXPopArgs(timeout, keys)))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.brpop(bXPopArgs(timeout, keys)))); + return null; + } + return jedis.brpop(timeout, keys); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public byte[] lIndex(byte[] key, long index) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.lindex(key, index))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.lindex(key, index))); + return null; + } + return jedis.lindex(key, index); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long lInsert(byte[] key, Position where, byte[] pivot, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.linsert(key, JedisConverters.toListPosition(where), pivot, value))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.linsert(key, JedisConverters.toListPosition(where), pivot, value))); + return null; + } + return jedis.linsert(key, JedisConverters.toListPosition(where), pivot, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long lLen(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.llen(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.llen(key))); + return null; + } + return jedis.llen(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public byte[] lPop(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.lpop(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.lpop(key))); + return null; + } + return jedis.lpop(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public List lRange(byte[] key, long start, long end) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.lrange(key, start, end))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.lrange(key, start, end))); + return null; + } + return jedis.lrange(key, start, end); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long lRem(byte[] key, long count, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.lrem(key, count, value))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.lrem(key, count, value))); + return null; + } + return jedis.lrem(key, count, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public void lSet(byte[] key, long index, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.lset(key, index, value))); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.lset(key, index, value))); + return; + } + jedis.lset(key, index, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public void lTrim(byte[] key, long start, long end) { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.ltrim(key, start, end))); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.ltrim(key, start, end))); + return; + } + jedis.ltrim(key, start, end); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public byte[] rPop(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.rpop(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.rpop(key))); + return null; + } + return jedis.rpop(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public byte[] rPopLPush(byte[] srcKey, byte[] dstKey) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.rpoplpush(srcKey, dstKey))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.rpoplpush(srcKey, dstKey))); + return null; + } + return jedis.rpoplpush(srcKey, dstKey); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public byte[] bRPopLPush(int timeout, byte[] srcKey, byte[] dstKey) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.brpoplpush(srcKey, dstKey, timeout))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.brpoplpush(srcKey, dstKey, timeout))); + return null; + } + return jedis.brpoplpush(srcKey, dstKey, timeout); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long lPushX(byte[] key, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.lpushx(key, value))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.lpushx(key, value))); + return null; + } + return jedis.lpushx(key, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long rPushX(byte[] key, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.rpushx(key, value))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.rpushx(key, value))); + return null; + } + return jedis.rpushx(key, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + // + // Set commands + // + + public Long sAdd(byte[] key, byte[]... values) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.sadd(key, values))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.sadd(key, values))); + return null; + } + return jedis.sadd(key, values); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long sCard(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.scard(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.scard(key))); + return null; + } + return jedis.scard(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Set sDiff(byte[]... keys) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.sdiff(keys))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.sdiff(keys))); + return null; + } + return jedis.sdiff(keys); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long sDiffStore(byte[] destKey, byte[]... keys) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.sdiffstore(destKey, keys))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.sdiffstore(destKey, keys))); + return null; + } + return jedis.sdiffstore(destKey, keys); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Set sInter(byte[]... keys) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.sinter(keys))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.sinter(keys))); + return null; + } + return jedis.sinter(keys); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long sInterStore(byte[] destKey, byte[]... keys) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.sinterstore(destKey, keys))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.sinterstore(destKey, keys))); + return null; + } + return jedis.sinterstore(destKey, keys); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Boolean sIsMember(byte[] key, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.sismember(key, value))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.sismember(key, value))); + return null; + } + return jedis.sismember(key, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Set sMembers(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.smembers(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.smembers(key))); + return null; + } + return jedis.smembers(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Boolean sMove(byte[] srcKey, byte[] destKey, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.smove(srcKey, destKey, value), JedisConverters.longToBoolean())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.smove(srcKey, destKey, value), JedisConverters.longToBoolean())); + return null; + } + return JedisConverters.toBoolean(jedis.smove(srcKey, destKey, value)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public byte[] sPop(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.spop(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.spop(key))); + return null; + } + return jedis.spop(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public byte[] sRandMember(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.srandmember(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.srandmember(key))); + return null; + } + return jedis.srandmember(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public List sRandMember(byte[] key, long count) { + + if (count > Integer.MAX_VALUE) { + throw new IllegalArgumentException("Count must be less than Integer.MAX_VALUE for sRandMember in Jedis."); + } + + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.srandmember(key, (int) count))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.srandmember(key, (int) count))); + return null; + } + return jedis.srandmember(key, (int) count); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long sRem(byte[] key, byte[]... values) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.srem(key, values))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.srem(key, values))); + return null; + } + return jedis.srem(key, values); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Set sUnion(byte[]... keys) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.sunion(keys))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.sunion(keys))); + return null; + } + return jedis.sunion(keys); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long sUnionStore(byte[] destKey, byte[]... keys) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.sunionstore(destKey, keys))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.sunionstore(destKey, keys))); + return null; + } + return jedis.sunionstore(destKey, keys); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + // + // ZSet commands + // + + public Boolean zAdd(byte[] key, double score, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zadd(key, score, value), JedisConverters.longToBoolean())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zadd(key, score, value), JedisConverters.longToBoolean())); + return null; + } + return JedisConverters.toBoolean(jedis.zadd(key, score, value)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long zAdd(byte[] key, Set tuples) { + if (isPipelined() || isQueueing()) { + throw new UnsupportedOperationException("zAdd of multiple fields not supported " + "in pipeline or transaction"); + } + Map args = zAddArgs(tuples); + try { + return jedis.zadd(key, args); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long zCard(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zcard(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zcard(key))); + return null; + } + return jedis.zcard(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long zCount(byte[] key, double min, double max) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zcount(key, min, max))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zcount(key, min, max))); + return null; + } + return jedis.zcount(key, min, max); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zCount(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range) + */ + @Override + public Long zCount(byte[] key, Range range) { + + if (isPipelined() || isQueueing()) { + throw new UnsupportedOperationException( + "ZCOUNT not implemented in jedis for binary protocol on transaction and pipeline"); + } + + byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); + byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); + + return jedis.zcount(key, min, max); + } + + public Double zIncrBy(byte[] key, double increment, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zincrby(key, increment, value))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zincrby(key, increment, value))); + return null; + } + return jedis.zincrby(key, increment, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long zInterStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets) { + try { + ZParams zparams = new ZParams().weights(weights).aggregate(ZParams.Aggregate.valueOf(aggregate.name())); + + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zinterstore(destKey, zparams, sets))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zinterstore(destKey, zparams, sets))); + return null; + } + return jedis.zinterstore(destKey, zparams, sets); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long zInterStore(byte[] destKey, byte[]... sets) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zinterstore(destKey, sets))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zinterstore(destKey, sets))); + return null; + } + return jedis.zinterstore(destKey, sets); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Set zRange(byte[] key, long start, long end) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zrange(key, start, end))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zrange(key, start, end))); + return null; + } + return jedis.zrange(key, start, end); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Set zRangeWithScores(byte[] key, long start, long end) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zrangeWithScores(key, start, end), JedisConverters.tupleSetToTupleSet())); + return null; + } + if (isQueueing()) { + transaction( + new JedisResult(transaction.zrangeWithScores(key, start, end), JedisConverters.tupleSetToTupleSet())); + return null; + } + return JedisConverters.toTupleSet(jedis.zrangeWithScores(key, start, end)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByLex(byte[]) + */ + public Set zRangeByLex(byte[] key) { + return zRangeByLex(key, Range.unbounded()); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByLex(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range) + */ + public Set zRangeByLex(byte[] key, Range range) { + return zRangeByLex(key, range, null); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByLex(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit) + */ + public Set zRangeByLex(byte[] key, Range range, Limit limit) { + + Assert.notNull(range, "Range cannot be null for ZRANGEBYLEX."); + + byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.MINUS_BYTES); + byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES); + + try { + if (isPipelined()) { + if (limit != null) { + pipeline(new JedisResult(pipeline.zrangeByLex(key, min, max, limit.getOffset(), limit.getCount()))); + } else { + pipeline(new JedisResult(pipeline.zrangeByLex(key, min, max))); + } + return null; + } + + if (isQueueing()) { + if (limit != null) { + transaction(new JedisResult(transaction.zrangeByLex(key, min, max, limit.getOffset(), limit.getCount()))); + } else { + transaction(new JedisResult(transaction.zrangeByLex(key, min, max))); + } + return null; + } + + if (limit != null) { + return jedis.zrangeByLex(key, min, max, limit.getOffset(), limit.getCount()); + } + return jedis.zrangeByLex(key, min, max); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScore(byte[], double, double) + */ + public Set zRangeByScore(byte[] key, double min, double max) { + return zRangeByScore(key, new Range().gte(min).lte(max)); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range) + */ + @Override + public Set zRangeByScore(byte[] key, Range range) { + return zRangeByScore(key, range, null); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit) + */ + @Override + public Set zRangeByScore(byte[] key, Range range, Limit limit) { + + Assert.notNull(range, "Range cannot be null for ZRANGEBYSCORE."); + + byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); + byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); + + try { + if (isPipelined()) { + if (limit != null) { + pipeline(new JedisResult(pipeline.zrangeByScore(key, min, max, limit.getOffset(), limit.getCount()))); + } else { + pipeline(new JedisResult(pipeline.zrangeByScore(key, min, max))); + } + return null; + } + + if (isQueueing()) { + if (limit != null) { + transaction(new JedisResult(transaction.zrangeByScore(key, min, max, limit.getOffset(), limit.getCount()))); + } else { + transaction(new JedisResult(transaction.zrangeByScore(key, min, max))); + } + return null; + } + + if (limit != null) { + return jedis.zrangeByScore(key, min, max, limit.getOffset(), limit.getCount()); + } + return jedis.zrangeByScore(key, min, max); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScoreWithScores(byte[], double, double) + */ + public Set zRangeByScoreWithScores(byte[] key, double min, double max) { + return zRangeByScoreWithScores(key, new Range().gte(min).lte(max)); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range) + */ + @Override + public Set zRangeByScoreWithScores(byte[] key, Range range) { + return zRangeByScoreWithScores(key, range, null); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit) + */ + @Override + public Set zRangeByScoreWithScores(byte[] key, Range range, Limit limit) { + + Assert.notNull(range, "Range cannot be null for ZRANGEBYSCOREWITHSCORES."); + + byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); + byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); + + try { + if (isPipelined()) { + if (limit != null) { + pipeline(new JedisResult(pipeline.zrangeByScoreWithScores(key, min, max, limit.getOffset(), limit.getCount()), + JedisConverters.tupleSetToTupleSet())); + } else { + pipeline( + new JedisResult(pipeline.zrangeByScoreWithScores(key, min, max), JedisConverters.tupleSetToTupleSet())); + } + return null; + } + + if (isQueueing()) { + if (limit != null) { + transaction( + new JedisResult(transaction.zrangeByScoreWithScores(key, min, max, limit.getOffset(), limit.getCount()), + JedisConverters.tupleSetToTupleSet())); + } else { + transaction(new JedisResult(transaction.zrangeByScoreWithScores(key, min, max), + JedisConverters.tupleSetToTupleSet())); + } + return null; + } + + if (limit != null) { + return JedisConverters + .toTupleSet(jedis.zrangeByScoreWithScores(key, min, max, limit.getOffset(), limit.getCount())); + } + return JedisConverters.toTupleSet(jedis.zrangeByScoreWithScores(key, min, max)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Set zRevRangeWithScores(byte[] key, long start, long end) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zrevrangeWithScores(key, start, end), JedisConverters.tupleSetToTupleSet())); + return null; + } + if (isQueueing()) { + transaction( + new JedisResult(transaction.zrevrangeWithScores(key, start, end), JedisConverters.tupleSetToTupleSet())); + return null; + } + return JedisConverters.toTupleSet(jedis.zrevrangeWithScores(key, start, end)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScore(byte[], double, double, long, long) + */ + @Override + public Set zRangeByScore(byte[] key, double min, double max, long offset, long count) { + + return zRangeByScore(key, new Range().gte(min).lte(max), + new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue())); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScoreWithScores(byte[], double, double, long, long) + */ + @Override + public Set zRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { + + return zRangeByScoreWithScores(key, new Range().gte(min).lte(max), + new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue())); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScore(byte[], double, double, long, long) + */ + @Override + public Set zRevRangeByScore(byte[] key, double min, double max, long offset, long count) { + + return zRevRangeByScore(key, new Range().gte(min).lte(max), + new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue())); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScore(byte[], double, double) + */ + @Override + public Set zRevRangeByScore(byte[] key, double min, double max) { + return zRevRangeByScore(key, new Range().gte(min).lte(max)); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range) + */ + @Override + public Set zRevRangeByScore(byte[] key, Range range) { + return zRevRangeByScore(key, range, null); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit) + */ + @Override + public Set zRevRangeByScore(byte[] key, Range range, Limit limit) { + + Assert.notNull(range, "Range cannot be null for ZREVRANGEBYSCORE."); + + byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); + byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); + + try { + if (isPipelined()) { + if (limit != null) { + pipeline(new JedisResult(pipeline.zrevrangeByScore(key, max, min, limit.getOffset(), limit.getCount()))); + } else { + pipeline(new JedisResult(pipeline.zrevrangeByScore(key, max, min))); + } + return null; + } + + if (isQueueing()) { + if (limit != null) { + transaction( + new JedisResult(transaction.zrevrangeByScore(key, max, min, limit.getOffset(), limit.getCount()))); + } else { + transaction(new JedisResult(transaction.zrevrangeByScore(key, max, min))); + } + return null; + } + + if (limit != null) { + return jedis.zrevrangeByScore(key, max, min, limit.getOffset(), limit.getCount()); + } + return jedis.zrevrangeByScore(key, max, min); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScoreWithScores(byte[], double, double, long, long) + */ + @Override + public Set zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { + + return zRevRangeByScoreWithScores(key, new Range().gte(min).lte(max), + new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue())); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range) + */ + @Override + public Set zRevRangeByScoreWithScores(byte[] key, Range range) { + return zRevRangeByScoreWithScores(key, range, null); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit) + */ + @Override + public Set zRevRangeByScoreWithScores(byte[] key, Range range, Limit limit) { + + Assert.notNull(range, "Range cannot be null for ZREVRANGEBYSCOREWITHSCORES."); + + byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); + byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); + + try { + if (isPipelined()) { + if (limit != null) { + pipeline( + new JedisResult(pipeline.zrevrangeByScoreWithScores(key, max, min, limit.getOffset(), limit.getCount()), + JedisConverters.tupleSetToTupleSet())); + } else { + pipeline(new JedisResult(pipeline.zrevrangeByScoreWithScores(key, max, min), + JedisConverters.tupleSetToTupleSet())); + } + return null; + } + + if (isQueueing()) { + if (limit != null) { + transaction(new JedisResult( + transaction.zrevrangeByScoreWithScores(key, max, min, limit.getOffset(), limit.getCount()), + JedisConverters.tupleSetToTupleSet())); + } else { + transaction(new JedisResult(transaction.zrevrangeByScoreWithScores(key, max, min), + JedisConverters.tupleSetToTupleSet())); + } + return null; + } + + if (limit != null) { + return JedisConverters + .toTupleSet(jedis.zrevrangeByScoreWithScores(key, max, min, limit.getOffset(), limit.getCount())); + } + return JedisConverters.toTupleSet(jedis.zrevrangeByScoreWithScores(key, max, min)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScoreWithScores(byte[], double, double) + */ + public Set zRevRangeByScoreWithScores(byte[] key, double min, double max) { + return zRevRangeByScoreWithScores(key, new Range().gte(min).lte(max), null); + } + + public Long zRank(byte[] key, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zrank(key, value))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zrank(key, value))); + return null; + } + return jedis.zrank(key, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long zRem(byte[] key, byte[]... values) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zrem(key, values))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zrem(key, values))); + return null; + } + return jedis.zrem(key, values); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long zRemRange(byte[] key, long start, long end) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zremrangeByRank(key, start, end))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zremrangeByRank(key, start, end))); + return null; + } + return jedis.zremrangeByRank(key, start, end); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRangeByScore(byte[], double, double) + */ + @Override + public Long zRemRangeByScore(byte[] key, double min, double max) { + return zRemRangeByScore(key, new Range().gte(min).lte(max)); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range) + */ + @Override + public Long zRemRangeByScore(byte[] key, Range range) { + + Assert.notNull(range, "Range cannot be null for ZREMRANGEBYSCORE."); + + byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); + byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); + + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zremrangeByScore(key, min, max))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zremrangeByScore(key, min, max))); + return null; + } + return jedis.zremrangeByScore(key, min, max); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Set zRevRange(byte[] key, long start, long end) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zrevrange(key, start, end))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zrevrange(key, start, end))); + return null; + } + return jedis.zrevrange(key, start, end); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long zRevRank(byte[] key, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zrevrank(key, value))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zrevrank(key, value))); + return null; + } + return jedis.zrevrank(key, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Double zScore(byte[] key, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zscore(key, value))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zscore(key, value))); + return null; + } + return jedis.zscore(key, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long zUnionStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets) { + try { + ZParams zparams = new ZParams().weights(weights).aggregate(ZParams.Aggregate.valueOf(aggregate.name())); + + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zunionstore(destKey, zparams, sets))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zunionstore(destKey, zparams, sets))); + return null; + } + return jedis.zunionstore(destKey, zparams, sets); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long zUnionStore(byte[] destKey, byte[]... sets) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.zunionstore(destKey, sets))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.zunionstore(destKey, sets))); + return null; + } + return jedis.zunionstore(destKey, sets); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + // + // Hash commands + // + + public Boolean hSet(byte[] key, byte[] field, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.hset(key, field, value), JedisConverters.longToBoolean())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.hset(key, field, value), JedisConverters.longToBoolean())); + return null; + } + return JedisConverters.toBoolean(jedis.hset(key, field, value)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Boolean hSetNX(byte[] key, byte[] field, byte[] value) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.hsetnx(key, field, value), JedisConverters.longToBoolean())); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.hsetnx(key, field, value), JedisConverters.longToBoolean())); + return null; + } + return JedisConverters.toBoolean(jedis.hsetnx(key, field, value)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long hDel(byte[] key, byte[]... fields) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.hdel(key, fields))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.hdel(key, fields))); + return null; + } + return jedis.hdel(key, fields); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Boolean hExists(byte[] key, byte[] field) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.hexists(key, field))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.hexists(key, field))); + return null; + } + return jedis.hexists(key, field); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public byte[] hGet(byte[] key, byte[] field) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.hget(key, field))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.hget(key, field))); + return null; + } + return jedis.hget(key, field); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Map hGetAll(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.hgetAll(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.hgetAll(key))); + return null; + } + return jedis.hgetAll(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long hIncrBy(byte[] key, byte[] field, long delta) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.hincrBy(key, field, delta))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.hincrBy(key, field, delta))); + return null; + } + return jedis.hincrBy(key, field, delta); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Double hIncrBy(byte[] key, byte[] field, double delta) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.hincrByFloat(key, field, delta))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.hincrByFloat(key, field, delta))); + return null; + } + return jedis.hincrByFloat(key, field, delta); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Set hKeys(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.hkeys(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.hkeys(key))); + return null; + } + return jedis.hkeys(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Long hLen(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.hlen(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.hlen(key))); + return null; + } + return jedis.hlen(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public List hMGet(byte[] key, byte[]... fields) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.hmget(key, fields))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.hmget(key, fields))); + return null; + } + return jedis.hmget(key, fields); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public void hMSet(byte[] key, Map tuple) { + try { + if (isPipelined()) { + pipeline(new JedisStatusResult(pipeline.hmset(key, tuple))); + return; + } + if (isQueueing()) { + transaction(new JedisStatusResult(transaction.hmset(key, tuple))); + return; + } + jedis.hmset(key, tuple); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public List hVals(byte[] key) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.hvals(key))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.hvals(key))); + return null; + } + return jedis.hvals(key); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + // + // Pub/Sub functionality + // + + public Long publish(byte[] channel, byte[] message) { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.publish(channel, message))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.publish(channel, message))); + return null; + } + return jedis.publish(channel, message); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public Subscription getSubscription() { + return subscription; + } + + public boolean isSubscribed() { + return (subscription != null && subscription.isAlive()); + } + + public void pSubscribe(MessageListener listener, byte[]... patterns) { + if (isSubscribed()) { + throw new RedisSubscribedConnectionException( + "Connection already subscribed; use the connection Subscription to cancel or add new channels"); + } + if (isQueueing()) { + throw new UnsupportedOperationException(); + } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } + + try { + BinaryJedisPubSub jedisPubSub = new JedisMessageListener(listener); + + subscription = new JedisSubscription(listener, jedisPubSub, null, patterns); + jedis.psubscribe(jedisPubSub, patterns); + + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + public void subscribe(MessageListener listener, byte[]... channels) { + if (isSubscribed()) { + throw new RedisSubscribedConnectionException( + "Connection already subscribed; use the connection Subscription to cancel or add new channels"); + } + + if (isQueueing()) { + throw new UnsupportedOperationException(); + } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } + + try { + BinaryJedisPubSub jedisPubSub = new JedisMessageListener(listener); + + subscription = new JedisSubscription(listener, jedisPubSub, channels, null); + jedis.subscribe(jedisPubSub, channels); + + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + // + // Geo commands + // + + /* * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisStringCommands#set(byte[], byte[], org.springframework.data.redis.core.types.Expiration, org.springframework.data.redis.connection.RedisStringCommands.SetOption) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], org.springframework.data.geo.Point, byte[]) */ - @Override - public void set(byte[] key, byte[] value, Expiration expiration, SetOption option) { + @Override + public Long geoAdd(byte[] key, Point point, byte[] member) { - if (expiration == null || expiration.isPersistent()) { + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(point, "Point must not be null!"); + Assert.notNull(member, "Member must not be null!"); - if (option == null || ObjectUtils.nullSafeEquals(SetOption.UPSERT, option)) { - set(key, value); - } else { + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.geoadd(key, point.getX(), point.getY(), member))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.geoadd(key, point.getX(), point.getY(), member))); + return null; + } - try { + return jedis.geoadd(key, point.getX(), point.getY(), member); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - byte[] nxxx = JedisConverters.toSetCommandNxXxArgument(option); - - if (isPipelined()) { - - pipeline(new JedisStatusResult(pipeline.set(key, value, nxxx))); - return; - } - if (isQueueing()) { - - transaction(new JedisStatusResult(transaction.set(key, value, nxxx))); - return; - } - - jedis.set(key, value, nxxx); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - } else { - - if (option == null || ObjectUtils.nullSafeEquals(SetOption.UPSERT, option)) { - - if (ObjectUtils.nullSafeEquals(TimeUnit.MILLISECONDS, expiration.getTimeUnit())) { - pSetEx(key, expiration.getExpirationTime(), value); - } else { - setEx(key, expiration.getExpirationTime(), value); - } - } else { - - byte[] nxxx = JedisConverters.toSetCommandNxXxArgument(option); - byte[] expx = JedisConverters.toSetCommandExPxArgument(expiration); - - try { - if (isPipelined()) { - - if (expiration.getExpirationTime() > Integer.MAX_VALUE) { - - throw new IllegalArgumentException( - "Expiration.expirationTime must be less than Integer.MAX_VALUE for pipeline in Jedis."); - } - - pipeline(new JedisStatusResult(pipeline.set(key, value, nxxx, expx, (int) expiration.getExpirationTime()))); - return; - } - if (isQueueing()) { - - if (expiration.getExpirationTime() > Integer.MAX_VALUE) { - throw new IllegalArgumentException( - "Expiration.expirationTime must be less than Integer.MAX_VALUE for transactions in Jedis."); - } - - transaction(new JedisStatusResult(transaction.set(key, value, nxxx, expx, - (int) expiration.getExpirationTime()))); - return; - } - - jedis.set(key, value, nxxx, expx, expiration.getExpirationTime()); - - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - } - } - - public byte[] getSet(byte[] key, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.getSet(key, value))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.getSet(key, value))); - return null; - } - return jedis.getSet(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long append(byte[] key, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.append(key, value))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.append(key, value))); - return null; - } - return jedis.append(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public List mGet(byte[]... keys) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.mget(keys))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.mget(keys))); - return null; - } - return jedis.mget(keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public void mSet(Map tuples) { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.mset(JedisConverters.toByteArrays(tuples)))); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.mset(JedisConverters.toByteArrays(tuples)))); - return; - } - jedis.mset(JedisConverters.toByteArrays(tuples)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Boolean mSetNX(Map tuples) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.msetnx(JedisConverters.toByteArrays(tuples)), JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.msetnx(JedisConverters.toByteArrays(tuples)), - JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(jedis.msetnx(JedisConverters.toByteArrays(tuples))); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public void setEx(byte[] key, long time, byte[] value) { - - if (time > Integer.MAX_VALUE) { - throw new IllegalArgumentException("Time must be less than Integer.MAX_VALUE for setEx in Jedis."); - } - - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.setex(key, (int) time, value))); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.setex(key, (int) time, value))); - return; - } - jedis.setex(key, (int) time, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - /* + /* * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisStringCommands#pSetEx(byte[], long, byte[]) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation) */ - @Override - public void pSetEx(byte[] key, long milliseconds, byte[] value) { + public Long geoAdd(byte[] key, GeoLocation location) { - try { - if (isPipelined()) { - doPipelined(pipeline.psetex(key, milliseconds, value)); - return; - } - if (isQueueing()) { - doQueued(transaction.psetex(key, milliseconds, value)); - return; - } - jedis.psetex(key, milliseconds, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(location, "Location must not be null!"); - public Boolean setNX(byte[] key, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.setnx(key, value), JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.setnx(key, value), JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(jedis.setnx(key, value)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + return geoAdd(key, location.getPoint(), location.getName()); + } - public byte[] getRange(byte[] key, long start, long end) { - - if (start > Integer.MAX_VALUE || end > Integer.MAX_VALUE) { - throw new IllegalArgumentException("Start and end must be less than Integer.MAX_VALUE for getRange in Jedis."); - } - - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.substr(key, (int) start, (int) end), JedisConverters.stringToBytes())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.substr(key, (int) start, (int) end), JedisConverters.stringToBytes())); - return null; - } - return jedis.substr(key, (int) start, (int) end); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long decr(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.decr(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.decr(key))); - return null; - } - return jedis.decr(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long decrBy(byte[] key, long value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.decrBy(key, value))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.decrBy(key, value))); - return null; - } - return jedis.decrBy(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long incr(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.incr(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.incr(key))); - return null; - } - return jedis.incr(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long incrBy(byte[] key, long value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.incrBy(key, value))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.incrBy(key, value))); - return null; - } - return jedis.incrBy(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Double incrBy(byte[] key, double value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.incrByFloat(key, value))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.incrByFloat(key, value))); - return null; - } - return jedis.incrByFloat(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Boolean getBit(byte[] key, long offset) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.getbit(key, offset))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.getbit(key, offset))); - return null; - } - // compatibility check for Jedis 2.0.0 - Object getBit = jedis.getbit(key, offset); - // Jedis 2.0 - if (getBit instanceof Long) { - return (((Long) getBit) == 0 ? Boolean.FALSE : Boolean.TRUE); - } - // Jedis 2.1 - return ((Boolean) getBit); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Boolean setBit(byte[] key, long offset, boolean value) { - try { - if (isPipelined()) { - - pipeline(new JedisResult(pipeline.setbit(key, offset, JedisConverters.toBit(value)))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.setbit(key, offset, JedisConverters.toBit(value)))); - return null; - } - return jedis.setbit(key, offset, JedisConverters.toBit(value)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public void setRange(byte[] key, byte[] value, long start) { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.setrange(key, start, value))); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.setrange(key, start, value))); - return; - } - jedis.setrange(key, start, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long strLen(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.strlen(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.strlen(key))); - return null; - } - return jedis.strlen(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long bitCount(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.bitcount(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.bitcount(key))); - return null; - } - return jedis.bitcount(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long bitCount(byte[] key, long begin, long end) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.bitcount(key, begin, end))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.bitcount(key, begin, end))); - return null; - } - return jedis.bitcount(key, begin, end); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long bitOp(BitOperation op, byte[] destination, byte[]... keys) { - if (op == BitOperation.NOT && keys.length > 1) { - throw new UnsupportedOperationException("Bitop NOT should only be performed against one key"); - } - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.bitop(JedisConverters.toBitOp(op), destination, keys))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.bitop(JedisConverters.toBitOp(op), destination, keys))); - return null; - } - return jedis.bitop(JedisConverters.toBitOp(op), destination, keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - // - // List commands - // - - public Long lPush(byte[] key, byte[]... values) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.lpush(key, values))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.lpush(key, values))); - return null; - } - return jedis.lpush(key, values); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long rPush(byte[] key, byte[]... values) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.rpush(key, values))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.rpush(key, values))); - return null; - } - return jedis.rpush(key, values); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public List bLPop(int timeout, byte[]... keys) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.blpop(bXPopArgs(timeout, keys)))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.blpop(bXPopArgs(timeout, keys)))); - return null; - } - return jedis.blpop(timeout, keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public List bRPop(int timeout, byte[]... keys) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.brpop(bXPopArgs(timeout, keys)))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.brpop(bXPopArgs(timeout, keys)))); - return null; - } - return jedis.brpop(timeout, keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public byte[] lIndex(byte[] key, long index) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.lindex(key, index))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.lindex(key, index))); - return null; - } - return jedis.lindex(key, index); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long lInsert(byte[] key, Position where, byte[] pivot, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.linsert(key, JedisConverters.toListPosition(where), pivot, value))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.linsert(key, JedisConverters.toListPosition(where), pivot, value))); - return null; - } - return jedis.linsert(key, JedisConverters.toListPosition(where), pivot, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long lLen(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.llen(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.llen(key))); - return null; - } - return jedis.llen(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public byte[] lPop(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.lpop(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.lpop(key))); - return null; - } - return jedis.lpop(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public List lRange(byte[] key, long start, long end) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.lrange(key, start, end))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.lrange(key, start, end))); - return null; - } - return jedis.lrange(key, start, end); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long lRem(byte[] key, long count, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.lrem(key, count, value))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.lrem(key, count, value))); - return null; - } - return jedis.lrem(key, count, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public void lSet(byte[] key, long index, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.lset(key, index, value))); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.lset(key, index, value))); - return; - } - jedis.lset(key, index, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public void lTrim(byte[] key, long start, long end) { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.ltrim(key, start, end))); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.ltrim(key, start, end))); - return; - } - jedis.ltrim(key, start, end); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public byte[] rPop(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.rpop(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.rpop(key))); - return null; - } - return jedis.rpop(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public byte[] rPopLPush(byte[] srcKey, byte[] dstKey) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.rpoplpush(srcKey, dstKey))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.rpoplpush(srcKey, dstKey))); - return null; - } - return jedis.rpoplpush(srcKey, dstKey); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public byte[] bRPopLPush(int timeout, byte[] srcKey, byte[] dstKey) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.brpoplpush(srcKey, dstKey, timeout))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.brpoplpush(srcKey, dstKey, timeout))); - return null; - } - return jedis.brpoplpush(srcKey, dstKey, timeout); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long lPushX(byte[] key, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.lpushx(key, value))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.lpushx(key, value))); - return null; - } - return jedis.lpushx(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long rPushX(byte[] key, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.rpushx(key, value))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.rpushx(key, value))); - return null; - } - return jedis.rpushx(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - // - // Set commands - // - - public Long sAdd(byte[] key, byte[]... values) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.sadd(key, values))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.sadd(key, values))); - return null; - } - return jedis.sadd(key, values); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long sCard(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.scard(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.scard(key))); - return null; - } - return jedis.scard(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Set sDiff(byte[]... keys) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.sdiff(keys))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.sdiff(keys))); - return null; - } - return jedis.sdiff(keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long sDiffStore(byte[] destKey, byte[]... keys) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.sdiffstore(destKey, keys))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.sdiffstore(destKey, keys))); - return null; - } - return jedis.sdiffstore(destKey, keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Set sInter(byte[]... keys) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.sinter(keys))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.sinter(keys))); - return null; - } - return jedis.sinter(keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long sInterStore(byte[] destKey, byte[]... keys) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.sinterstore(destKey, keys))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.sinterstore(destKey, keys))); - return null; - } - return jedis.sinterstore(destKey, keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Boolean sIsMember(byte[] key, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.sismember(key, value))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.sismember(key, value))); - return null; - } - return jedis.sismember(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Set sMembers(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.smembers(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.smembers(key))); - return null; - } - return jedis.smembers(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Boolean sMove(byte[] srcKey, byte[] destKey, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.smove(srcKey, destKey, value), JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.smove(srcKey, destKey, value), JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(jedis.smove(srcKey, destKey, value)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public byte[] sPop(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.spop(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.spop(key))); - return null; - } - return jedis.spop(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public byte[] sRandMember(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.srandmember(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.srandmember(key))); - return null; - } - return jedis.srandmember(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public List sRandMember(byte[] key, long count) { - - if (count > Integer.MAX_VALUE) { - throw new IllegalArgumentException("Count must be less than Integer.MAX_VALUE for sRandMember in Jedis."); - } - - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.srandmember(key, (int) count))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.srandmember(key, (int) count))); - return null; - } - return jedis.srandmember(key, (int) count); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long sRem(byte[] key, byte[]... values) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.srem(key, values))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.srem(key, values))); - return null; - } - return jedis.srem(key, values); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Set sUnion(byte[]... keys) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.sunion(keys))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.sunion(keys))); - return null; - } - return jedis.sunion(keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long sUnionStore(byte[] destKey, byte[]... keys) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.sunionstore(destKey, keys))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.sunionstore(destKey, keys))); - return null; - } - return jedis.sunionstore(destKey, keys); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - // - // ZSet commands - // - - public Boolean zAdd(byte[] key, double score, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zadd(key, score, value), JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zadd(key, score, value), JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(jedis.zadd(key, score, value)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long zAdd(byte[] key, Set tuples) { - if (isPipelined() || isQueueing()) { - throw new UnsupportedOperationException("zAdd of multiple fields not supported " + "in pipeline or transaction"); - } - Map args = zAddArgs(tuples); - try { - return jedis.zadd(key, args); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long zCard(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zcard(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zcard(key))); - return null; - } - return jedis.zcard(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long zCount(byte[] key, double min, double max) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zcount(key, min, max))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zcount(key, min, max))); - return null; - } - return jedis.zcount(key, min, max); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - /* + /* * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zCount(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], java.util.Map) */ - @Override - public Long zCount(byte[] key, Range range) { + @Override + public Long geoAdd(byte[] key, Map memberCoordinateMap) { - if (isPipelined() || isQueueing()) { - throw new UnsupportedOperationException( - "ZCOUNT not implemented in jedis for binary protocol on transaction and pipeline"); - } + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(memberCoordinateMap, "MemberCoordinateMap must not be null!"); - byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); - byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); + Map redisGeoCoordinateMap = new HashMap(); - return jedis.zcount(key, min, max); - } + for (byte[] mapKey : memberCoordinateMap.keySet()) { + redisGeoCoordinateMap.put(mapKey, JedisConverters.toGeoCoordinate(memberCoordinateMap.get(mapKey))); + } - public Double zIncrBy(byte[] key, double increment, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zincrby(key, increment, value))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zincrby(key, increment, value))); - return null; - } - return jedis.zincrby(key, increment, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.geoadd(key, redisGeoCoordinateMap))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.geoadd(key, redisGeoCoordinateMap))); + return null; + } - public Long zInterStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets) { - try { - ZParams zparams = new ZParams().weights(weights).aggregate(ZParams.Aggregate.valueOf(aggregate.name())); + return jedis.geoadd(key, redisGeoCoordinateMap); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zinterstore(destKey, zparams, sets))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zinterstore(destKey, zparams, sets))); - return null; - } - return jedis.zinterstore(destKey, zparams, sets); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long zInterStore(byte[] destKey, byte[]... sets) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zinterstore(destKey, sets))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zinterstore(destKey, sets))); - return null; - } - return jedis.zinterstore(destKey, sets); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Set zRange(byte[] key, long start, long end) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zrange(key, start, end))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zrange(key, start, end))); - return null; - } - return jedis.zrange(key, start, end); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Set zRangeWithScores(byte[] key, long start, long end) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zrangeWithScores(key, start, end), JedisConverters.tupleSetToTupleSet())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zrangeWithScores(key, start, end), JedisConverters.tupleSetToTupleSet())); - return null; - } - return JedisConverters.toTupleSet(jedis.zrangeWithScores(key, start, end)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - /* + /* * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByLex(byte[]) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], java.lang.Iterable) */ - public Set zRangeByLex(byte[] key) { - return zRangeByLex(key, Range.unbounded()); - } + @Override + public Long geoAdd(byte[] key, Iterable> locations) { - /* + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(locations, "Locations must not be null!"); + + Map redisGeoCoordinateMap = new HashMap(); + + for (GeoLocation location : locations) { + redisGeoCoordinateMap.put(location.getName(), JedisConverters.toGeoCoordinate(location.getPoint())); + } + + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.geoadd(key, redisGeoCoordinateMap))); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.geoadd(key, redisGeoCoordinateMap))); + return null; + } + + return jedis.geoadd(key, redisGeoCoordinateMap); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByLex(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoDist(byte[], byte[], byte[]) */ - public Set zRangeByLex(byte[] key, Range range) { - return zRangeByLex(key, range, null); - } + @Override + public Distance geoDist(byte[] key, byte[] member1, byte[] member2) { - /* + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(member1, "Member1 must not be null!"); + Assert.notNull(member2, "Member2 must not be null!"); + + Converter distanceConverter = JedisConverters.distanceConverterForMetric(DistanceUnit.METERS); + + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.geodist(key, member1, member2), distanceConverter)); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.geodist(key, member1, member2), distanceConverter)); + return null; + } + + return distanceConverter.convert(jedis.geodist(key, member1, member2)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByLex(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoDist(byte[], byte[], byte[], org.springframework.data.geo.Metric) */ - public Set zRangeByLex(byte[] key, Range range, Limit limit) { + @Override + public Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric metric) { - Assert.notNull(range, "Range cannot be null for ZRANGEBYLEX."); + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(member1, "Member1 must not be null!"); + Assert.notNull(member2, "Member2 must not be null!"); + Assert.notNull(metric, "Metric must not be null!"); - byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.MINUS_BYTES); - byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES); + GeoUnit geoUnit = JedisConverters.toGeoUnit(metric); + Converter distanceConverter = JedisConverters.distanceConverterForMetric(metric); - try { - if (isPipelined()) { - if (limit != null) { - pipeline(new JedisResult(pipeline.zrangeByLex(key, min, max, limit.getOffset(), limit.getCount()))); - } else { - pipeline(new JedisResult(pipeline.zrangeByLex(key, min, max))); - } - return null; - } + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.geodist(key, member1, member2, geoUnit), distanceConverter)); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.geodist(key, member1, member2, geoUnit), distanceConverter)); + return null; + } - if (isQueueing()) { - if (limit != null) { - transaction(new JedisResult(transaction.zrangeByLex(key, min, max, limit.getOffset(), limit.getCount()))); - } else { - transaction(new JedisResult(transaction.zrangeByLex(key, min, max))); - } - return null; - } + return distanceConverter.convert(jedis.geodist(key, member1, member2, geoUnit)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - if (limit != null) { - return jedis.zrangeByLex(key, min, max, limit.getOffset(), limit.getCount()); - } - return jedis.zrangeByLex(key, min, max); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - /* + /* * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScore(byte[], double, double) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoHash(byte[], byte[][]) */ - public Set zRangeByScore(byte[] key, double min, double max) { - return zRangeByScore(key, new Range().gte(min).lte(max)); - } + @Override + public List geoHash(byte[] key, byte[]... members) { - /* + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(members, "Members must not be null!"); + Assert.noNullElements(members, "Members must not contain null!"); + + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.geohash(key, members), JedisConverters.bytesListToStringListConverter())); + return null; + } + if (isQueueing()) { + transaction( + new JedisResult(transaction.geohash(key, members), JedisConverters.bytesListToStringListConverter())); + return null; + } + + return JedisConverters.bytesListToStringListConverter().convert(jedis.geohash(key, members)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoPos(byte[], byte[][]) */ - @Override - public Set zRangeByScore(byte[] key, Range range) { - return zRangeByScore(key, range, null); - } + @Override + public List geoPos(byte[] key, byte[]... members) { - /* + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(members, "Members must not be null!"); + Assert.noNullElements(members, "Members must not contain null!"); + + ListConverter converter = JedisConverters.geoCoordinateToPointConverter(); + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.geopos(key, members), converter)); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.geopos(key, members), converter)); + return null; + } + return converter.convert(jedis.geopos(key, members)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadius(byte[], org.springframework.data.geo.Circle) */ - @Override - public Set zRangeByScore(byte[] key, Range range, Limit limit) { + @Override + public GeoResults> geoRadius(byte[] key, Circle within) { - Assert.notNull(range, "Range cannot be null for ZRANGEBYSCORE."); + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(within, "Within must not be null!"); - byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); - byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); + Converter, GeoResults>> converter = JedisConverters + .geoRadiusResponseToGeoResultsConverter(within.getRadius().getMetric()); + try { + if (isPipelined()) { + pipeline( + new JedisResult( + pipeline.georadius(key, within.getCenter().getX(), within.getCenter().getY(), + within.getRadius().getValue(), JedisConverters.toGeoUnit(within.getRadius().getMetric())), + converter)); + return null; + } + if (isQueueing()) { + transaction( + new JedisResult( + transaction.georadius(key, within.getCenter().getX(), within.getCenter().getY(), + within.getRadius().getValue(), JedisConverters.toGeoUnit(within.getRadius().getMetric())), + converter)); + return null; + } - try { - if (isPipelined()) { - if (limit != null) { - pipeline(new JedisResult(pipeline.zrangeByScore(key, min, max, limit.getOffset(), limit.getCount()))); - } else { - pipeline(new JedisResult(pipeline.zrangeByScore(key, min, max))); - } - return null; - } + return converter.convert(jedis.georadius(key, within.getCenter().getX(), within.getCenter().getY(), + within.getRadius().getValue(), JedisConverters.toGeoUnit(within.getRadius().getMetric()))); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - if (isQueueing()) { - if (limit != null) { - transaction(new JedisResult(transaction.zrangeByScore(key, min, max, limit.getOffset(), limit.getCount()))); - } else { - transaction(new JedisResult(transaction.zrangeByScore(key, min, max))); - } - return null; - } - - if (limit != null) { - return jedis.zrangeByScore(key, min, max, limit.getOffset(), limit.getCount()); - } - return jedis.zrangeByScore(key, min, max); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - /* + /* * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScoreWithScores(byte[], double, double) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadius(byte[], org.springframework.data.geo.Circle, org.springframework.data.redis.core.GeoRadiusCommandArgs) */ - public Set zRangeByScoreWithScores(byte[] key, double min, double max) { - return zRangeByScoreWithScores(key, new Range().gte(min).lte(max)); - } + @Override + public GeoResults> geoRadius(byte[] key, Circle within, GeoRadiusCommandArgs args) { - /* + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(within, "Within must not be null!"); + Assert.notNull(args, "Args must not be null!"); + + redis.clients.jedis.params.geo.GeoRadiusParam geoRadiusParam = JedisConverters.toGeoRadiusParam(args); + Converter, GeoResults>> converter = JedisConverters + .geoRadiusResponseToGeoResultsConverter(within.getRadius().getMetric()); + + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.georadius(key, within.getCenter().getX(), within.getCenter().getY(), + within.getRadius().getValue(), JedisConverters.toGeoUnit(within.getRadius().getMetric()), geoRadiusParam), + converter)); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.georadius(key, within.getCenter().getX(), within.getCenter().getY(), + within.getRadius().getValue(), JedisConverters.toGeoUnit(within.getRadius().getMetric()), geoRadiusParam), + converter)); + return null; + } + + return converter.convert(jedis.georadius(key, within.getCenter().getX(), within.getCenter().getY(), + within.getRadius().getValue(), JedisConverters.toGeoUnit(within.getRadius().getMetric()), geoRadiusParam)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], double) */ - @Override - public Set zRangeByScoreWithScores(byte[] key, Range range) { - return zRangeByScoreWithScores(key, range, null); - } + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, double radius) { + return geoRadiusByMember(key, member, new Distance(radius, DistanceUnit.METERS)); + } - /* + /* * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], org.springframework.data.geo.Distance) */ - @Override - public Set zRangeByScoreWithScores(byte[] key, Range range, Limit limit) { + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius) { - Assert.notNull(range, "Range cannot be null for ZRANGEBYSCOREWITHSCORES."); + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(member, "Member must not be null!"); + Assert.notNull(radius, "Radius must not be null!"); - byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); - byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); + GeoUnit geoUnit = JedisConverters.toGeoUnit(radius.getMetric()); + Converter, GeoResults>> converter = JedisConverters + .geoRadiusResponseToGeoResultsConverter(radius.getMetric()); - try { - if (isPipelined()) { - if (limit != null) { - pipeline(new JedisResult( - pipeline.zrangeByScoreWithScores(key, min, max, limit.getOffset(), limit.getCount()), - JedisConverters.tupleSetToTupleSet())); - } else { - pipeline(new JedisResult(pipeline.zrangeByScoreWithScores(key, min, max), - JedisConverters.tupleSetToTupleSet())); - } - return null; - } + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.georadiusByMember(key, member, radius.getValue(), geoUnit), converter)); + return null; + } + if (isQueueing()) { + transaction(new JedisResult(transaction.georadiusByMember(key, member, radius.getValue(), geoUnit), converter)); + return null; + } - if (isQueueing()) { - if (limit != null) { - transaction(new JedisResult(transaction.zrangeByScoreWithScores(key, min, max, limit.getOffset(), - limit.getCount()), JedisConverters.tupleSetToTupleSet())); - } else { - transaction(new JedisResult(transaction.zrangeByScoreWithScores(key, min, max), - JedisConverters.tupleSetToTupleSet())); - } - return null; - } + return converter.convert(jedis.georadiusByMember(key, member, radius.getValue(), geoUnit)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } - if (limit != null) { - return JedisConverters.toTupleSet(jedis.zrangeByScoreWithScores(key, min, max, limit.getOffset(), - limit.getCount())); - } - return JedisConverters.toTupleSet(jedis.zrangeByScoreWithScores(key, min, max)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius, + GeoRadiusCommandArgs args) { - public Set zRevRangeWithScores(byte[] key, long start, long end) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zrevrangeWithScores(key, start, end), JedisConverters.tupleSetToTupleSet())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zrevrangeWithScores(key, start, end), - JedisConverters.tupleSetToTupleSet())); - return null; - } - return JedisConverters.toTupleSet(jedis.zrevrangeWithScores(key, start, end)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(member, "Member must not be null!"); + Assert.notNull(radius, "Radius must not be null!"); + Assert.notNull(args, "Args must not be null!"); - } + GeoUnit geoUnit = JedisConverters.toGeoUnit(radius.getMetric()); + Converter, GeoResults>> converter = JedisConverters + .geoRadiusResponseToGeoResultsConverter(radius.getMetric()); + redis.clients.jedis.params.geo.GeoRadiusParam geoRadiusParam = JedisConverters.toGeoRadiusParam(args); - /* + try { + if (isPipelined()) { + pipeline(new JedisResult(pipeline.georadiusByMember(key, member, radius.getValue(), geoUnit, geoRadiusParam), + converter)); + return null; + } + if (isQueueing()) { + transaction(new JedisResult( + transaction.georadiusByMember(key, member, radius.getValue(), geoUnit, geoRadiusParam), converter)); + return null; + } + return converter.convert(jedis.georadiusByMember(key, member, radius.getValue(), geoUnit, geoRadiusParam)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + /* * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScore(byte[], double, double, long, long) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoRemove(byte[], byte[][]) */ - @Override - public Set zRangeByScore(byte[] key, double min, double max, long offset, long count) { + @Override + public Long geoRemove(byte[] key, byte[]... members) { + return zRem(key, members); + } - return zRangeByScore(key, new Range().gte(min).lte(max), - new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue())); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScoreWithScores(byte[], double, double, long, long) - */ - @Override - public Set zRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { - - return zRangeByScoreWithScores(key, new Range().gte(min).lte(max), - new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue())); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScore(byte[], double, double, long, long) - */ - @Override - public Set zRevRangeByScore(byte[] key, double min, double max, long offset, long count) { - - return zRevRangeByScore(key, new Range().gte(min).lte(max), new Limit().offset(Long.valueOf(offset).intValue()) - .count(Long.valueOf(count).intValue())); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScore(byte[], double, double) - */ - @Override - public Set zRevRangeByScore(byte[] key, double min, double max) { - return zRevRangeByScore(key, new Range().gte(min).lte(max)); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range) - */ - @Override - public Set zRevRangeByScore(byte[] key, Range range) { - return zRevRangeByScore(key, range, null); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit) - */ - @Override - public Set zRevRangeByScore(byte[] key, Range range, Limit limit) { - - Assert.notNull(range, "Range cannot be null for ZREVRANGEBYSCORE."); - - byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); - byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); - - try { - if (isPipelined()) { - if (limit != null) { - pipeline(new JedisResult(pipeline.zrevrangeByScore(key, max, min, limit.getOffset(), limit.getCount()))); - } else { - pipeline(new JedisResult(pipeline.zrevrangeByScore(key, max, min))); - } - return null; - } - - if (isQueueing()) { - if (limit != null) { - transaction(new JedisResult(transaction.zrevrangeByScore(key, max, min, limit.getOffset(), limit.getCount()))); - } else { - transaction(new JedisResult(transaction.zrevrangeByScore(key, max, min))); - } - return null; - } - - if (limit != null) { - return jedis.zrevrangeByScore(key, max, min, limit.getOffset(), limit.getCount()); - } - return jedis.zrevrangeByScore(key, max, min); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - /* - * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScoreWithScores(byte[], double, double, long, long) - */ - @Override - public Set zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { - - return zRevRangeByScoreWithScores(key, new Range().gte(min).lte(max), - new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue())); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range) - */ - @Override - public Set zRevRangeByScoreWithScores(byte[] key, Range range) { - return zRevRangeByScoreWithScores(key, range, null); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit) - */ - @Override - public Set zRevRangeByScoreWithScores(byte[] key, Range range, Limit limit) { - - Assert.notNull(range, "Range cannot be null for ZREVRANGEBYSCOREWITHSCORES."); - - byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); - byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); - - try { - if (isPipelined()) { - if (limit != null) { - pipeline(new JedisResult(pipeline.zrevrangeByScoreWithScores(key, max, min, limit.getOffset(), - limit.getCount()), JedisConverters.tupleSetToTupleSet())); - } else { - pipeline(new JedisResult(pipeline.zrevrangeByScoreWithScores(key, max, min), - JedisConverters.tupleSetToTupleSet())); - } - return null; - } - - if (isQueueing()) { - if (limit != null) { - transaction(new JedisResult(transaction.zrevrangeByScoreWithScores(key, max, min, limit.getOffset(), - limit.getCount()), JedisConverters.tupleSetToTupleSet())); - } else { - transaction(new JedisResult(transaction.zrevrangeByScoreWithScores(key, max, min), - JedisConverters.tupleSetToTupleSet())); - } - return null; - } - - if (limit != null) { - return JedisConverters.toTupleSet(jedis.zrevrangeByScoreWithScores(key, max, min, limit.getOffset(), - limit.getCount())); - } - return JedisConverters.toTupleSet(jedis.zrevrangeByScoreWithScores(key, max, min)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - /* - * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScoreWithScores(byte[], double, double) - */ - public Set zRevRangeByScoreWithScores(byte[] key, double min, double max) { - return zRevRangeByScoreWithScores(key, new Range().gte(min).lte(max), null); - } - - public Long zRank(byte[] key, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zrank(key, value))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zrank(key, value))); - return null; - } - return jedis.zrank(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long zRem(byte[] key, byte[]... values) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zrem(key, values))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zrem(key, values))); - return null; - } - return jedis.zrem(key, values); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long zRemRange(byte[] key, long start, long end) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zremrangeByRank(key, start, end))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zremrangeByRank(key, start, end))); - return null; - } - return jedis.zremrangeByRank(key, start, end); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - /* - * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRangeByScore(byte[], double, double) - */ - @Override - public Long zRemRangeByScore(byte[] key, double min, double max) { - return zRemRangeByScore(key, new Range().gte(min).lte(max)); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range) - */ - @Override - public Long zRemRangeByScore(byte[] key, Range range) { - - Assert.notNull(range, "Range cannot be null for ZREMRANGEBYSCORE."); - - byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES); - byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES); - - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zremrangeByScore(key, min, max))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zremrangeByScore(key, min, max))); - return null; - } - return jedis.zremrangeByScore(key, min, max); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Set zRevRange(byte[] key, long start, long end) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zrevrange(key, start, end))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zrevrange(key, start, end))); - return null; - } - return jedis.zrevrange(key, start, end); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long zRevRank(byte[] key, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zrevrank(key, value))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zrevrank(key, value))); - return null; - } - return jedis.zrevrank(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Double zScore(byte[] key, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zscore(key, value))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zscore(key, value))); - return null; - } - return jedis.zscore(key, value); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long zUnionStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets) { - try { - ZParams zparams = new ZParams().weights(weights).aggregate(ZParams.Aggregate.valueOf(aggregate.name())); - - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zunionstore(destKey, zparams, sets))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zunionstore(destKey, zparams, sets))); - return null; - } - return jedis.zunionstore(destKey, zparams, sets); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long zUnionStore(byte[] destKey, byte[]... sets) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.zunionstore(destKey, sets))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.zunionstore(destKey, sets))); - return null; - } - return jedis.zunionstore(destKey, sets); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - // - // Hash commands - // - - public Boolean hSet(byte[] key, byte[] field, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.hset(key, field, value), JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.hset(key, field, value), JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(jedis.hset(key, field, value)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Boolean hSetNX(byte[] key, byte[] field, byte[] value) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.hsetnx(key, field, value), JedisConverters.longToBoolean())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.hsetnx(key, field, value), JedisConverters.longToBoolean())); - return null; - } - return JedisConverters.toBoolean(jedis.hsetnx(key, field, value)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long hDel(byte[] key, byte[]... fields) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.hdel(key, fields))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.hdel(key, fields))); - return null; - } - return jedis.hdel(key, fields); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Boolean hExists(byte[] key, byte[] field) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.hexists(key, field))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.hexists(key, field))); - return null; - } - return jedis.hexists(key, field); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public byte[] hGet(byte[] key, byte[] field) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.hget(key, field))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.hget(key, field))); - return null; - } - return jedis.hget(key, field); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Map hGetAll(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.hgetAll(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.hgetAll(key))); - return null; - } - return jedis.hgetAll(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long hIncrBy(byte[] key, byte[] field, long delta) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.hincrBy(key, field, delta))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.hincrBy(key, field, delta))); - return null; - } - return jedis.hincrBy(key, field, delta); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Double hIncrBy(byte[] key, byte[] field, double delta) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.hincrByFloat(key, field, delta))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.hincrByFloat(key, field, delta))); - return null; - } - return jedis.hincrByFloat(key, field, delta); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Set hKeys(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.hkeys(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.hkeys(key))); - return null; - } - return jedis.hkeys(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Long hLen(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.hlen(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.hlen(key))); - return null; - } - return jedis.hlen(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public List hMGet(byte[] key, byte[]... fields) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.hmget(key, fields))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.hmget(key, fields))); - return null; - } - return jedis.hmget(key, fields); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public void hMSet(byte[] key, Map tuple) { - try { - if (isPipelined()) { - pipeline(new JedisStatusResult(pipeline.hmset(key, tuple))); - return; - } - if (isQueueing()) { - transaction(new JedisStatusResult(transaction.hmset(key, tuple))); - return; - } - jedis.hmset(key, tuple); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public List hVals(byte[] key) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.hvals(key))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.hvals(key))); - return null; - } - return jedis.hvals(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - // - // Pub/Sub functionality - // - - public Long publish(byte[] channel, byte[] message) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.publish(channel, message))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.publish(channel, message))); - return null; - } - return jedis.publish(channel, message); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public Subscription getSubscription() { - return subscription; - } - - public boolean isSubscribed() { - return (subscription != null && subscription.isAlive()); - } - - public void pSubscribe(MessageListener listener, byte[]... patterns) { - if (isSubscribed()) { - throw new RedisSubscribedConnectionException( - "Connection already subscribed; use the connection Subscription to cancel or add new channels"); - } - if (isQueueing()) { - throw new UnsupportedOperationException(); - } - if (isPipelined()) { - throw new UnsupportedOperationException(); - } - - try { - BinaryJedisPubSub jedisPubSub = new JedisMessageListener(listener); - - subscription = new JedisSubscription(listener, jedisPubSub, null, patterns); - jedis.psubscribe(jedisPubSub, patterns); - - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - public void subscribe(MessageListener listener, byte[]... channels) { - if (isSubscribed()) { - throw new RedisSubscribedConnectionException( - "Connection already subscribed; use the connection Subscription to cancel or add new channels"); - } - - if (isQueueing()) { - throw new UnsupportedOperationException(); - } - if (isPipelined()) { - throw new UnsupportedOperationException(); - } - - try { - BinaryJedisPubSub jedisPubSub = new JedisMessageListener(listener); - - subscription = new JedisSubscription(listener, jedisPubSub, channels, null); - jedis.subscribe(jedisPubSub, channels); - - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - // - // Geo commands - // - @Override - public Long geoAdd(byte[] key, double longitude, double latitude, byte[] member) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.geoadd(key, longitude, latitude, member))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.geoadd(key, longitude, latitude, member))); - return null; - } - - return jedis.geoadd(key, longitude, latitude, member); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public Long geoAdd(byte[] key, Map memberCoordinateMap){ - try { - Map redisGeoCoordinateMap = new HashMap(); - for(byte[] mapKey : memberCoordinateMap.keySet()){ - redisGeoCoordinateMap.put(mapKey, JedisConverters.toGeoCoordinate(memberCoordinateMap.get(mapKey))); - } - - if (isPipelined()) { - pipeline(new JedisResult(pipeline.geoadd(key, redisGeoCoordinateMap))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.geoadd(key, redisGeoCoordinateMap))); - return null; - } - - return jedis.geoadd(key, redisGeoCoordinateMap); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - - @Override - public Double geoDist(byte[] key, byte[] member1, byte[] member2) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.geodist(key, member1, member2))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.geodist(key, member1, member2))); - return null; - } - - return jedis.geodist(key, member1, member2); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public Double geoDist(byte[] key, byte[] member1, byte[] member2, org.springframework.data.redis.core.GeoUnit unit) { - GeoUnit geoUnit = JedisConverters.toGeoUnit(unit); - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.geodist(key, member1, member2, geoUnit))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.geodist(key, member1, member2, geoUnit))); - return null; - } - - return jedis.geodist(key, member1, member2, geoUnit); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public List geoHash(byte[] key, byte[]... members) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.geohash(key, members))); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.geohash(key, members))); - return null; - } - - return jedis.geohash(key, members); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public List geoPos(byte[] key, byte[]... members) { - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.geopos(key, members), JedisConverters.geoCoordinateListToGeoCoordinateList())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.geopos(key, members), JedisConverters.geoCoordinateListToGeoCoordinateList())); - return null; - } - - return JedisConverters.geoCoordinateListToGeoCoordinateList().convert(jedis.geopos(key, members)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public List georadius(byte[] key, double longitude, double latitude, - double radius, org.springframework.data.redis.core.GeoUnit unit) { - GeoUnit geoUnit = JedisConverters.toGeoUnit(unit); - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.georadius(key, longitude, latitude, radius, geoUnit), JedisConverters.geoRadiusResponseGeoRadiusResponseList())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.georadius(key, longitude, latitude, radius, geoUnit), JedisConverters.geoRadiusResponseGeoRadiusResponseList())); - return null; - } - - return JedisConverters.geoRadiusResponseGeoRadiusResponseList().convert(jedis.georadius(key, longitude, latitude, radius, geoUnit)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public List georadius(byte[] key, double longitude, double latitude, - double radius, org.springframework.data.redis.core.GeoUnit unit, GeoRadiusParam param) { - GeoUnit geoUnit = JedisConverters.toGeoUnit(unit); - redis.clients.jedis.params.geo.GeoRadiusParam geoRadiusParam = JedisConverters.toGeoRadiusParam(param); - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.georadius(key, longitude, latitude, radius, geoUnit, geoRadiusParam), - JedisConverters.geoRadiusResponseGeoRadiusResponseList())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.georadius(key, longitude, latitude, radius, geoUnit, geoRadiusParam), - JedisConverters.geoRadiusResponseGeoRadiusResponseList())); - return null; - } - - return JedisConverters.geoRadiusResponseGeoRadiusResponseList(). - convert(jedis.georadius(key, longitude, latitude, radius, geoUnit, geoRadiusParam)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public List georadiusByMember(byte[] key, byte[] member, double radius, - org.springframework.data.redis.core.GeoUnit unit) { - GeoUnit geoUnit = JedisConverters.toGeoUnit(unit); - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.georadiusByMember(key, member, radius, geoUnit), - JedisConverters.geoRadiusResponseGeoRadiusResponseList())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.georadiusByMember(key, member, radius, geoUnit), - JedisConverters.geoRadiusResponseGeoRadiusResponseList())); - return null; - } - - return JedisConverters.geoRadiusResponseGeoRadiusResponseList().convert(jedis.georadiusByMember(key, member, radius, geoUnit)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public List georadiusByMember(byte[] key, byte[] member, double radius, - org.springframework.data.redis.core.GeoUnit unit, GeoRadiusParam param) { - GeoUnit geoUnit = JedisConverters.toGeoUnit(unit); - redis.clients.jedis.params.geo.GeoRadiusParam geoRadiusParam = JedisConverters.toGeoRadiusParam(param); - try { - if (isPipelined()) { - pipeline(new JedisResult(pipeline.georadiusByMember(key, member, radius, geoUnit, geoRadiusParam), - JedisConverters.geoRadiusResponseGeoRadiusResponseList())); - return null; - } - if (isQueueing()) { - transaction(new JedisResult(transaction.georadiusByMember(key, member, radius, geoUnit, geoRadiusParam), - JedisConverters.geoRadiusResponseGeoRadiusResponseList())); - return null; - } - return JedisConverters.geoRadiusResponseGeoRadiusResponseList(). - convert(jedis.georadiusByMember(key, member, radius, geoUnit, geoRadiusParam)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); - } - } - - @Override - public Long geoRemove(byte[] key, byte[]... values) { - return zRem(key, values); - } - - // + // // Scripting commands // @@ -3337,8 +3541,8 @@ public class JedisConnection extends AbstractRedisConnection { throw new UnsupportedOperationException(); } try { - return (T) new JedisScriptReturnConverter(returnType).convert(jedis.eval(script, - JedisConverters.toBytes(numKeys), keysAndArgs)); + return (T) new JedisScriptReturnConverter(returnType) + .convert(jedis.eval(script, JedisConverters.toBytes(numKeys), keysAndArgs)); } catch (Exception ex) { throw convertJedisAccessException(ex); } @@ -3507,8 +3711,8 @@ public class JedisConnection extends AbstractRedisConnection { 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())); + return new ScanIteration(Long.valueOf(result.getStringCursor()), + JedisConverters.stringListToByteList().convert(result.getResult())); } }.open(); @@ -3545,8 +3749,8 @@ public class JedisConnection extends AbstractRedisConnection { ScanParams params = JedisConverters.toScanParams(options); ScanResult result = jedis.zscan(key, JedisConverters.toBytes(cursorId), params); - return new ScanIteration(Long.valueOf(result.getStringCursor()), JedisConverters - .tuplesToTuples().convert(result.getResult())); + return new ScanIteration(Long.valueOf(result.getStringCursor()), + JedisConverters.tuplesToTuples().convert(result.getResult())); } }.open(); @@ -3733,8 +3937,8 @@ public class JedisConnection extends AbstractRedisConnection { transaction(new JedisResult(transaction.zrangeByScore(keyStr, min, max, (int) offset, (int) count))); return null; } - return JedisConverters.stringSetToByteSet().convert( - jedis.zrangeByScore(keyStr, min, max, (int) offset, (int) count)); + return JedisConverters.stringSetToByteSet() + .convert(jedis.zrangeByScore(keyStr, min, max, (int) offset, (int) count)); } catch (Exception ex) { throw convertJedisAccessException(ex); } @@ -3833,8 +4037,8 @@ public class JedisConnection extends AbstractRedisConnection { try { if (isPipelined()) { - pipeline(new JedisResult(pipeline.migrate(JedisConverters.toBytes(target.getHost()), target.getPort(), key, - dbIndex, timeoutToUse))); + pipeline(new JedisResult( + pipeline.migrate(JedisConverters.toBytes(target.getHost()), target.getPort(), key, dbIndex, timeoutToUse))); return; } if (isQueueing()) { 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 8cd082b78..2fad1e34f 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 @@ -25,8 +25,18 @@ import java.util.concurrent.TimeUnit; import org.springframework.core.convert.converter.Converter; import org.springframework.dao.DataAccessException; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResult; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Metrics; +import org.springframework.data.geo.Point; import org.springframework.data.redis.connection.DefaultTuple; import org.springframework.data.redis.connection.RedisClusterNode; +import org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.Flag; import org.springframework.data.redis.connection.RedisListCommands.Position; import org.springframework.data.redis.connection.RedisServer; import org.springframework.data.redis.connection.RedisStringCommands; @@ -42,10 +52,6 @@ import org.springframework.data.redis.connection.convert.ListConverter; 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.GeoCoordinate; -import org.springframework.data.redis.core.GeoRadiusParam; -import org.springframework.data.redis.core.GeoRadiusResponse; -import org.springframework.data.redis.core.GeoUnit; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.types.Expiration; import org.springframework.data.redis.core.types.RedisClientInfo; @@ -56,8 +62,12 @@ import org.springframework.util.StringUtils; import redis.clients.jedis.BinaryClient.LIST_POSITION; import redis.clients.jedis.BitOP; +import redis.clients.jedis.GeoCoordinate; +import redis.clients.jedis.GeoRadiusResponse; +import redis.clients.jedis.GeoUnit; import redis.clients.jedis.ScanParams; import redis.clients.jedis.SortingParams; +import redis.clients.jedis.params.geo.GeoRadiusParam; import redis.clients.util.SafeEncoder; /** @@ -68,6 +78,7 @@ import redis.clients.util.SafeEncoder; * @author Thomas Darimont * @author Jungtaek Lim * @author Mark Paluch + * @author Ninad Divadkar */ abstract public class JedisConverters extends Converters { @@ -83,10 +94,10 @@ abstract public class JedisConverters extends Converters { private static final Converter OBJECT_TO_CLUSTER_NODE_CONVERTER; private static final Converter EXPIRATION_TO_COMMAND_OPTION_CONVERTER; private static final Converter SET_OPTION_TO_COMMAND_OPTION_CONVERTER; - private static final Converter GEO_COORDINATE_CONVERTER; - private static final ListConverter GEO_COORDINATE_LIST_TO_GEO_COORDINATE_LIST; - private static final Converter GEO_RADIUS_RESPONSE_CONVERTER; - private static final ListConverter GEO_RADIUS_RESPONSE_LIST_TO_GEO_RADIUS_RESPONSE_LIST; + private static final Converter GEO_COORDINATE_TO_POINT_CONVERTER; + private static final ListConverter LIST_GEO_COORDINATE_TO_POINT_CONVERTER; + private static final Converter BYTES_TO_STRING_CONVERTER; + private static final ListConverter BYTES_LIST_TO_STRING_LIST_CONVERTER; public static final byte[] PLUS_BYTES; public static final byte[] MINUS_BYTES; @@ -99,6 +110,15 @@ abstract public class JedisConverters extends Converters { static { + BYTES_TO_STRING_CONVERTER = new Converter() { + + @Override + public String convert(byte[] source) { + return source == null ? null : SafeEncoder.encode(source); + } + }; + BYTES_LIST_TO_STRING_LIST_CONVERTER = new ListConverter(BYTES_TO_STRING_CONVERTER); + STRING_TO_BYTES = new Converter() { public byte[] convert(String source) { return source == null ? null : SafeEncoder.encode(source); @@ -174,26 +194,14 @@ abstract public class JedisConverters extends Converters { }; - GEO_COORDINATE_CONVERTER = new Converter() { - @Override - public GeoCoordinate convert(redis.clients.jedis.GeoCoordinate geoCoordinate) { - return geoCoordinate != null ? new GeoCoordinate(geoCoordinate.getLongitude(), geoCoordinate.getLatitude()) : null; - } - }; - GEO_COORDINATE_LIST_TO_GEO_COORDINATE_LIST = new ListConverter(GEO_COORDINATE_CONVERTER); - - GEO_RADIUS_RESPONSE_CONVERTER = new Converter() { + GEO_COORDINATE_TO_POINT_CONVERTER = new Converter() { @Override - public GeoRadiusResponse convert(redis.clients.jedis.GeoRadiusResponse geoRadiusResponse) { - if (geoRadiusResponse == null) - return null; - GeoRadiusResponse response = new GeoRadiusResponse(geoRadiusResponse.getMember()); - response.setDistance(geoRadiusResponse.getDistance()); - response.setCoordinate(GEO_COORDINATE_CONVERTER.convert(geoRadiusResponse.getCoordinate())); - return response; + public Point convert(redis.clients.jedis.GeoCoordinate geoCoordinate) { + return geoCoordinate != null ? new Point(geoCoordinate.getLongitude(), geoCoordinate.getLatitude()) : null; } }; - GEO_RADIUS_RESPONSE_LIST_TO_GEO_RADIUS_RESPONSE_LIST = new ListConverter(GEO_RADIUS_RESPONSE_CONVERTER); + LIST_GEO_COORDINATE_TO_POINT_CONVERTER = new ListConverter( + GEO_COORDINATE_TO_POINT_CONVERTER); } public static Converter stringToBytes() { @@ -230,10 +238,6 @@ abstract public class JedisConverters extends Converters { return EXCEPTION_CONVERTER; } - public static ListConverter geoCoordinateListToGeoCoordinateList() { return GEO_COORDINATE_LIST_TO_GEO_COORDINATE_LIST; } - - public static ListConverter geoRadiusResponseGeoRadiusResponseList() { return GEO_RADIUS_RESPONSE_LIST_TO_GEO_RADIUS_RESPONSE_LIST; } - public static String[] toStrings(byte[][] source) { String[] result = new String[source.length]; for (int i = 0; i < source.length; i++) { @@ -475,9 +479,9 @@ abstract public class JedisConverters extends Converters { * @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()); @@ -489,41 +493,179 @@ abstract public class JedisConverters extends Converters { return sp; } - public static redis.clients.jedis.GeoUnit toGeoUnit(GeoUnit geoUnit){ - switch (geoUnit){ - case Meters: return redis.clients.jedis.GeoUnit.M; - case KiloMeters: return redis.clients.jedis.GeoUnit.KM; - case Miles: return redis.clients.jedis.GeoUnit.MI; - case Feet: return redis.clients.jedis.GeoUnit.FT; - default: throw new IllegalArgumentException("geoUnit not supported"); - } - } + /** + * @param source + * @return + * @since 1.8 + */ + public static List toStrings(List source) { + return BYTES_LIST_TO_STRING_LIST_CONVERTER.convert(source); + } - public static redis.clients.jedis.GeoCoordinate toGeoCoordinate(GeoCoordinate geoCoordinate){ - return new redis.clients.jedis.GeoCoordinate(geoCoordinate.getLongitude(), geoCoordinate.getLatitude()); - } + /** + * @return + */ + public static ListConverter bytesListToStringListConverter() { + return BYTES_LIST_TO_STRING_LIST_CONVERTER; + } - public static redis.clients.jedis.params.geo.GeoRadiusParam toGeoRadiusParam(GeoRadiusParam geoRadiusParam){ - redis.clients.jedis.params.geo.GeoRadiusParam param = redis.clients.jedis.params.geo.GeoRadiusParam.geoRadiusParam(); - for (String k : geoRadiusParam.getParams().keySet()){ - if (k.equals(GeoRadiusParam.getASC())) - param.sortAscending(); - if (k.equals(GeoRadiusParam.getDESC())) - param.sortDescending(); - if (k.equals(GeoRadiusParam.getCOUNT())) - param.count((Integer)geoRadiusParam.getParams().get(k)); - if (k.equals(GeoRadiusParam.getWITHCOORD())) - param.withCoord(); - if (k.equals(GeoRadiusParam.getWITHDIST())) - param.withDist(); - } + /** + * @return + * @since 1.8 + */ + public static ListConverter geoCoordinateToPointConverter() { + return LIST_GEO_COORDINATE_TO_POINT_CONVERTER; + } + + /** + * Get a {@link Converter} capable of converting {@link GeoRadiusResponse} into {@link GeoResults}. + * + * @param metric + * @return + * @since 1.8 + */ + public static Converter, GeoResults>> geoRadiusResponseToGeoResultsConverter( + Metric metric) { + return GeoResultsConverterFactory.INSTANCE.forMetric(metric); + } + + /** + * Convert {@link Metric} into {@link GeoUnit}. + * + * @param metric + * @return + * @since 1.8 + */ + public static GeoUnit toGeoUnit(Metric metric) { + + Metric metricToUse = metric == null || ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, metric) ? DistanceUnit.METERS + : metric; + return ObjectUtils.caseInsensitiveValueOf(GeoUnit.values(), metricToUse.getAbbreviation()); + } + + /** + * Convert {@link Point} into {@link GeoCoordinate}. + * + * @param source + * @return + * @since 1.8 + */ + public static GeoCoordinate toGeoCoordinate(Point source) { + return source == null ? null : new redis.clients.jedis.GeoCoordinate(source.getX(), source.getY()); + } + + /** + * Convert {@link GeoRadiusCommandArgs} into {@link GeoRadiusParam}. + * + * @param source + * @return + * @since 1.8 + */ + public static GeoRadiusParam toGeoRadiusParam(GeoRadiusCommandArgs source) { + + GeoRadiusParam param = GeoRadiusParam.geoRadiusParam(); + if (source == null) { return param; - } - - public static redis.clients.jedis.GeoRadiusResponse toGeoRadiusResponse(GeoRadiusResponse geoRadiusResponse){ - redis.clients.jedis.GeoRadiusResponse response = new redis.clients.jedis.GeoRadiusResponse(geoRadiusResponse.getMember()); - response.setCoordinate(toGeoCoordinate(geoRadiusResponse.getCoordinate())); - response.setDistance(geoRadiusResponse.getDistance()); - return response; } + + if (source.hasFlags()) { + for (Flag flag : source.getFlags()) { + switch (flag) { + case WITHCOORD: + param.withCoord(); + break; + case WITHDIST: + param.withDist(); + break; + } + } + } + + if (source.hasSortDirection()) { + switch (source.getSortDirection()) { + case ASC: + param.sortAscending(); + break; + case DESC: + param.sortDescending(); + break; + } + } + + if (source.hasLimit()) { + param.count(source.getLimit().intValue()); + } + + return param; + } + + /** + * @author Christoph Strobl + * @since 1.8 + */ + static enum GeoResultsConverterFactory { + + INSTANCE; + + Converter, GeoResults>> forMetric(Metric metric) { + return new GeoResultsConverter( + metric == null || ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, metric) ? DistanceUnit.METERS : metric); + } + + private static class GeoResultsConverter + implements Converter, GeoResults>> { + + private Metric metric; + + public GeoResultsConverter(Metric metric) { + this.metric = metric; + } + + @Override + public GeoResults> convert(List source) { + + List>> results = new ArrayList>>(source.size()); + + Converter>> converter = GeoResultConverterFactory.INSTANCE + .forMetric(metric); + for (GeoRadiusResponse result : source) { + results.add(converter.convert(result)); + } + + return new GeoResults>(results, metric); + } + } + } + + /** + * @author Christoph Strobl + * @since 1.8 + */ + static enum GeoResultConverterFactory { + + INSTANCE; + + Converter>> forMetric(Metric metric) { + return new GeoResultConverter(metric); + } + + private static class GeoResultConverter + implements Converter>> { + + private Metric metric; + + public GeoResultConverter(Metric metric) { + this.metric = metric; + } + + @Override + public GeoResult> convert(redis.clients.jedis.GeoRadiusResponse source) { + + Point point = GEO_COORDINATE_TO_POINT_CONVERTER.convert(source.getCoordinate()); + + return new GeoResult>(new GeoLocation(source.getMember(), point), + new Distance(source.getDistance(), metric)); + } + } + } } diff --git a/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java b/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java index b147b2566..309d3b5ec 100644 --- a/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java @@ -36,6 +36,11 @@ import org.jredis.connector.NotConnectedException; import org.jredis.protocol.Command; import org.jredis.ri.alphazero.JRedisSupport; import org.springframework.dao.DataAccessException; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Point; import org.springframework.data.redis.RedisSystemException; import org.springframework.data.redis.connection.AbstractRedisConnection; import org.springframework.data.redis.connection.DataType; @@ -45,7 +50,8 @@ import org.springframework.data.redis.connection.RedisNode; 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.core.*; +import org.springframework.data.redis.core.Cursor; +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; @@ -60,6 +66,7 @@ import org.springframework.util.ReflectionUtils; * @author Christoph Strobl * @author Thomas Darimont * @author David Liu + * @author Ninad Divadkar * @deprecated since 1.7. Will be removed in subsequent version. */ @Deprecated @@ -1186,67 +1193,138 @@ public class JredisConnection extends AbstractRedisConnection { throw new UnsupportedOperationException(); } - public void subscribe(MessageListener listener, byte[]... channels) { - throw new UnsupportedOperationException(); - } - - // - // Geo commands - // - - @Override - public Long geoAdd(byte[] key, double longitude, double latitude, byte[] member) { - throw new UnsupportedOperationException(); - } - - @Override - public Long geoAdd(byte[] key, Map memberCoordinateMap){ - throw new UnsupportedOperationException(); - } - - - @Override - public Double geoDist(byte[] key, byte[] member1, byte[] member2) { - throw new UnsupportedOperationException(); - } - - @Override - public Double geoDist(byte[] key, byte[] member1, byte[] member2, org.springframework.data.redis.core.GeoUnit unit) { - throw new UnsupportedOperationException(); - } - - @Override - public List geoHash(byte[] key, byte[]... members) { - throw new UnsupportedOperationException(); - } - - @Override - public List geoPos(byte[] key, byte[]... members) { - throw new UnsupportedOperationException(); - } - - @Override - public List georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit) { + public void subscribe(MessageListener listener, byte[]... channels) { throw new UnsupportedOperationException(); } + // + // Geo commands + // + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], org.springframework.data.geo.Point, byte[]) + */ @Override - public List georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { + public Long geoAdd(byte[] key, Point point, byte[] member) { throw new UnsupportedOperationException(); } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation) + */ @Override - public List georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit) { + public Long geoAdd(byte[] key, GeoLocation location) { throw new UnsupportedOperationException(); } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], java.util.Map) + */ @Override - public List georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param) { + public Long geoAdd(byte[] key, Map memberCoordinateMap) { throw new UnsupportedOperationException(); } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], java.lang.Iterable) + */ @Override - public Long geoRemove(byte[] key, byte[]... values) { + public Long geoAdd(byte[] key, Iterable> locations) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoDist(byte[], byte[], byte[]) + */ + @Override + public Distance geoDist(byte[] key, byte[] member1, byte[] member2) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoDist(byte[], byte[], byte[], org.springframework.data.geo.Metric) + */ + @Override + public Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric metric) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoHash(byte[], byte[][]) + */ + @Override + public List geoHash(byte[] key, byte[]... members) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoPos(byte[], byte[][]) + */ + @Override + public List geoPos(byte[] key, byte[]... members) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadius(byte[], org.springframework.data.geo.Circle) + */ + @Override + public GeoResults> geoRadius(byte[] key, Circle within) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadius(byte[], org.springframework.data.geo.Circle, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> geoRadius(byte[] key, Circle within, GeoRadiusCommandArgs args) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], double) + */ + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, double radius) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], org.springframework.data.geo.Distance) + */ + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], org.springframework.data.geo.Distance, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius, + GeoRadiusCommandArgs args) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoRemove(byte[], byte[][]) + */ + @Override + public Long geoRemove(byte[] key, byte[]... members) { throw new UnsupportedOperationException(); } diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java index ea54364d9..efa8fa785 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2015 the original author or authors. + * Copyright 2011-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. @@ -21,6 +21,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; @@ -35,12 +36,16 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import com.lambdaworks.redis.*; import org.springframework.beans.BeanUtils; import org.springframework.core.convert.converter.Converter; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.QueryTimeoutException; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Point; import org.springframework.data.redis.ExceptionTranslationStrategy; import org.springframework.data.redis.FallbackExceptionTranslationStrategy; import org.springframework.data.redis.RedisConnectionFailureException; @@ -56,9 +61,14 @@ 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.Converters; +import org.springframework.data.redis.connection.convert.ListConverter; import org.springframework.data.redis.connection.convert.TransactionResultConverter; -import org.springframework.data.redis.core.*; +import org.springframework.data.redis.core.Cursor; +import org.springframework.data.redis.core.KeyBoundCursor; +import org.springframework.data.redis.core.RedisCommand; import org.springframework.data.redis.core.ScanCursor; +import org.springframework.data.redis.core.ScanIteration; +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; @@ -66,6 +76,28 @@ import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; +import com.lambdaworks.redis.AbstractRedisClient; +import com.lambdaworks.redis.GeoArgs; +import com.lambdaworks.redis.GeoCoordinates; +import com.lambdaworks.redis.GeoWithin; +import com.lambdaworks.redis.KeyScanCursor; +import com.lambdaworks.redis.LettuceFutures; +import com.lambdaworks.redis.MapScanCursor; +import com.lambdaworks.redis.RedisAsyncConnection; +import com.lambdaworks.redis.RedisAsyncConnectionImpl; +import com.lambdaworks.redis.RedisChannelHandler; +import com.lambdaworks.redis.RedisClient; +import com.lambdaworks.redis.RedisClusterConnection; +import com.lambdaworks.redis.RedisConnection; +import com.lambdaworks.redis.RedisException; +import com.lambdaworks.redis.RedisSentinelAsyncConnection; +import com.lambdaworks.redis.RedisURI; +import com.lambdaworks.redis.ScanArgs; +import com.lambdaworks.redis.ScoredValue; +import com.lambdaworks.redis.ScoredValueScanCursor; +import com.lambdaworks.redis.SortArgs; +import com.lambdaworks.redis.ValueScanCursor; +import com.lambdaworks.redis.ZStoreArgs; import com.lambdaworks.redis.codec.RedisCodec; import com.lambdaworks.redis.output.BooleanOutput; import com.lambdaworks.redis.output.ByteArrayOutput; @@ -96,6 +128,7 @@ import com.lambdaworks.redis.pubsub.RedisPubSubConnection; * @author Thomas Darimont * @author David Liu * @author Mark Paluch + * @author Ninad Divadkar */ public class LettuceConnection extends AbstractRedisConnection { @@ -349,8 +382,8 @@ public class LettuceConnection extends AbstractRedisConnection { RedisAsyncConnectionImpl connectionImpl = (RedisAsyncConnectionImpl) getAsyncConnection(); - CommandOutput expectedOutput = commandOutputTypeHint != null ? commandOutputTypeHint : typeHints - .getTypeHint(commandType); + CommandOutput expectedOutput = commandOutputTypeHint != null ? commandOutputTypeHint + : typeHints.getTypeHint(commandType); Command cmd = new Command(commandType, expectedOutput, cmdArg); if (isPipelined()) { @@ -827,8 +860,9 @@ public class LettuceConnection extends AbstractRedisConnection { return null; } List results = getDedicatedConnection().exec(); - return convertPipelineAndTxResults ? new LettuceTransactionResultConverter(txResults, - LettuceConverters.exceptionConverter()).convert(results) : results; + return convertPipelineAndTxResults + ? new LettuceTransactionResultConverter(txResults, LettuceConverters.exceptionConverter()).convert(results) + : results; } catch (Exception ex) { throw convertLettuceAccessException(ex); } finally { @@ -1206,13 +1240,13 @@ public class LettuceConnection extends AbstractRedisConnection { try { if (isPipelined()) { - pipeline(new LettuceStatusResult(getAsyncConnection().set(key, value, - LettuceConverters.toSetArgs(expiration, option)))); + pipeline(new LettuceStatusResult( + getAsyncConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option)))); return; } if (isQueueing()) { - transaction(new LettuceTxStatusResult(getConnection().set(key, value, - LettuceConverters.toSetArgs(expiration, option)))); + transaction(new LettuceTxStatusResult( + getConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option)))); return; } getConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option)); @@ -1479,8 +1513,8 @@ public class LettuceConnection extends AbstractRedisConnection { LettuceConverters.longToBooleanConverter())); return null; } - return LettuceConverters.longToBooleanConverter().convert( - getConnection().setbit(key, offset, LettuceConverters.toInt(value))); + return LettuceConverters.longToBooleanConverter() + .convert(getConnection().setbit(key, offset, LettuceConverters.toInt(value))); } catch (Exception ex) { throw convertLettuceAccessException(ex); } @@ -1659,11 +1693,13 @@ public class LettuceConnection extends AbstractRedisConnection { public Long lInsert(byte[] key, Position where, byte[] pivot, byte[] value) { try { if (isPipelined()) { - pipeline(new LettuceResult(getAsyncConnection().linsert(key, LettuceConverters.toBoolean(where), pivot, value))); + pipeline( + new LettuceResult(getAsyncConnection().linsert(key, LettuceConverters.toBoolean(where), pivot, value))); return null; } if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().linsert(key, LettuceConverters.toBoolean(where), pivot, value))); + transaction( + new LettuceTxResult(getConnection().linsert(key, LettuceConverters.toBoolean(where), pivot, value))); return null; } return getConnection().linsert(key, LettuceConverters.toBoolean(where), pivot, value); @@ -2031,13 +2067,13 @@ public class LettuceConnection extends AbstractRedisConnection { public List sRandMember(byte[] key, long count) { try { if (isPipelined()) { - pipeline(new LettuceResult(getAsyncConnection().srandmember(key, count), - LettuceConverters.bytesSetToBytesList())); + pipeline( + new LettuceResult(getAsyncConnection().srandmember(key, count), LettuceConverters.bytesSetToBytesList())); return null; } if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().srandmember(key, count), - LettuceConverters.bytesSetToBytesList())); + transaction( + new LettuceTxResult(getConnection().srandmember(key, count), LettuceConverters.bytesSetToBytesList())); return null; } return LettuceConverters.toBytesList(getConnection().srandmember(key, count)); @@ -2227,13 +2263,13 @@ public class LettuceConnection extends AbstractRedisConnection { public Set zRange(byte[] key, long start, long end) { try { if (isPipelined()) { - pipeline(new LettuceResult(getAsyncConnection().zrange(key, start, end), - LettuceConverters.bytesListToBytesSet())); + pipeline( + new LettuceResult(getAsyncConnection().zrange(key, start, end), LettuceConverters.bytesListToBytesSet())); return null; } if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().zrange(key, start, end), - LettuceConverters.bytesListToBytesSet())); + transaction( + new LettuceTxResult(getConnection().zrange(key, start, end), LettuceConverters.bytesListToBytesSet())); return null; } return LettuceConverters.toBytesSet(getConnection().zrange(key, start, end)); @@ -2281,8 +2317,9 @@ public class LettuceConnection extends AbstractRedisConnection { try { if (isPipelined()) { if (limit != null) { - pipeline(new LettuceResult(getAsyncConnection().zrangebyscore(key, min, max, limit.getOffset(), - limit.getCount()), LettuceConverters.bytesListToBytesSet())); + pipeline( + new LettuceResult(getAsyncConnection().zrangebyscore(key, min, max, limit.getOffset(), limit.getCount()), + LettuceConverters.bytesListToBytesSet())); } else { pipeline(new LettuceResult(getAsyncConnection().zrangebyscore(key, min, max), LettuceConverters.bytesListToBytesSet())); @@ -2291,8 +2328,9 @@ public class LettuceConnection extends AbstractRedisConnection { } if (isQueueing()) { if (limit != null) { - transaction(new LettuceTxResult(getConnection().zrangebyscore(key, min, max, limit.getOffset(), - limit.getCount()), LettuceConverters.bytesListToBytesSet())); + transaction( + new LettuceTxResult(getConnection().zrangebyscore(key, min, max, limit.getOffset(), limit.getCount()), + LettuceConverters.bytesListToBytesSet())); } else { transaction(new LettuceTxResult(getConnection().zrangebyscore(key, min, max), LettuceConverters.bytesListToBytesSet())); @@ -2300,8 +2338,8 @@ public class LettuceConnection extends AbstractRedisConnection { return null; } if (limit != null) { - return LettuceConverters.toBytesSet(getConnection().zrangebyscore(key, min, max, limit.getOffset(), - limit.getCount())); + return LettuceConverters + .toBytesSet(getConnection().zrangebyscore(key, min, max, limit.getOffset(), limit.getCount())); } return LettuceConverters.toBytesSet(getConnection().zrangebyscore(key, min, max)); } catch (Exception ex) { @@ -2330,8 +2368,9 @@ public class LettuceConnection extends AbstractRedisConnection { try { if (isPipelined()) { if (limit != null) { - pipeline(new LettuceResult(getAsyncConnection().zrangebyscoreWithScores(key, min, max, limit.getOffset(), - limit.getCount()), LettuceConverters.scoredValuesToTupleSet())); + pipeline(new LettuceResult( + getAsyncConnection().zrangebyscoreWithScores(key, min, max, limit.getOffset(), limit.getCount()), + LettuceConverters.scoredValuesToTupleSet())); } else { pipeline(new LettuceResult(getAsyncConnection().zrangebyscoreWithScores(key, min, max), LettuceConverters.scoredValuesToTupleSet())); @@ -2340,8 +2379,9 @@ public class LettuceConnection extends AbstractRedisConnection { } if (isQueueing()) { if (limit != null) { - transaction(new LettuceTxResult(getConnection().zrangebyscoreWithScores(key, min, max, limit.getOffset(), - limit.getCount()), LettuceConverters.scoredValuesToTupleSet())); + transaction(new LettuceTxResult( + getConnection().zrangebyscoreWithScores(key, min, max, limit.getOffset(), limit.getCount()), + LettuceConverters.scoredValuesToTupleSet())); } else { transaction(new LettuceTxResult(getConnection().zrangebyscoreWithScores(key, min, max), LettuceConverters.scoredValuesToTupleSet())); @@ -2349,8 +2389,8 @@ public class LettuceConnection extends AbstractRedisConnection { return null; } if (limit != null) { - return LettuceConverters.toTupleSet(getConnection().zrangebyscoreWithScores(key, min, max, limit.getOffset(), - limit.getCount())); + return LettuceConverters + .toTupleSet(getConnection().zrangebyscoreWithScores(key, min, max, limit.getOffset(), limit.getCount())); } return LettuceConverters.toTupleSet(getConnection().zrangebyscoreWithScores(key, min, max)); } catch (Exception ex) { @@ -2393,8 +2433,8 @@ public class LettuceConnection extends AbstractRedisConnection { @Override public Set zRevRangeByScore(byte[] key, double min, double max, long offset, long count) { - return zRevRangeByScore(key, new Range().gte(min).lte(max), new Limit().offset(Long.valueOf(offset).intValue()) - .count(Long.valueOf(count).intValue())); + return zRevRangeByScore(key, new Range().gte(min).lte(max), + new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue())); } @Override @@ -2413,8 +2453,9 @@ public class LettuceConnection extends AbstractRedisConnection { try { if (isPipelined()) { if (limit != null) { - pipeline(new LettuceResult(getAsyncConnection().zrevrangebyscore(key, max, min, limit.getOffset(), - limit.getCount()), LettuceConverters.bytesListToBytesSet())); + pipeline(new LettuceResult( + getAsyncConnection().zrevrangebyscore(key, max, min, limit.getOffset(), limit.getCount()), + LettuceConverters.bytesListToBytesSet())); } else { pipeline(new LettuceResult(getAsyncConnection().zrevrangebyscore(key, max, min), LettuceConverters.bytesListToBytesSet())); @@ -2423,8 +2464,9 @@ public class LettuceConnection extends AbstractRedisConnection { } if (isQueueing()) { if (limit != null) { - transaction(new LettuceTxResult(getConnection().zrevrangebyscore(key, max, min, limit.getOffset(), - limit.getCount()), LettuceConverters.bytesListToBytesSet())); + transaction( + new LettuceTxResult(getConnection().zrevrangebyscore(key, max, min, limit.getOffset(), limit.getCount()), + LettuceConverters.bytesListToBytesSet())); } else { transaction(new LettuceTxResult(getConnection().zrevrangebyscore(key, max, min), LettuceConverters.bytesListToBytesSet())); @@ -2432,8 +2474,8 @@ public class LettuceConnection extends AbstractRedisConnection { return null; } if (limit != null) { - return LettuceConverters.toBytesSet(getConnection().zrevrangebyscore(key, max, min, limit.getOffset(), - limit.getCount())); + return LettuceConverters + .toBytesSet(getConnection().zrevrangebyscore(key, max, min, limit.getOffset(), limit.getCount())); } return LettuceConverters.toBytesSet(getConnection().zrevrangebyscore(key, max, min)); } catch (Exception ex) { @@ -2469,8 +2511,9 @@ public class LettuceConnection extends AbstractRedisConnection { try { if (isPipelined()) { if (limit != null) { - pipeline(new LettuceResult(getAsyncConnection().zrevrangebyscoreWithScores(key, max, min, limit.getOffset(), - limit.getCount()), LettuceConverters.scoredValuesToTupleSet())); + pipeline(new LettuceResult( + getAsyncConnection().zrevrangebyscoreWithScores(key, max, min, limit.getOffset(), limit.getCount()), + LettuceConverters.scoredValuesToTupleSet())); } else { pipeline(new LettuceResult(getAsyncConnection().zrevrangebyscoreWithScores(key, max, min), LettuceConverters.scoredValuesToTupleSet())); @@ -2479,8 +2522,9 @@ public class LettuceConnection extends AbstractRedisConnection { } if (isQueueing()) { if (limit != null) { - transaction(new LettuceTxResult(getConnection().zrevrangebyscoreWithScores(key, max, min, limit.getOffset(), - limit.getCount()), LettuceConverters.scoredValuesToTupleSet())); + transaction(new LettuceTxResult( + getConnection().zrevrangebyscoreWithScores(key, max, min, limit.getOffset(), limit.getCount()), + LettuceConverters.scoredValuesToTupleSet())); } else { transaction(new LettuceTxResult(getConnection().zrevrangebyscoreWithScores(key, max, min), LettuceConverters.scoredValuesToTupleSet())); @@ -2488,8 +2532,8 @@ public class LettuceConnection extends AbstractRedisConnection { return null; } if (limit != null) { - return LettuceConverters.toTupleSet(getConnection().zrevrangebyscoreWithScores(key, max, min, - limit.getOffset(), limit.getCount())); + return LettuceConverters + .toTupleSet(getConnection().zrevrangebyscoreWithScores(key, max, min, limit.getOffset(), limit.getCount())); } return LettuceConverters.toTupleSet(getConnection().zrevrangebyscoreWithScores(key, max, min)); } catch (Exception ex) { @@ -2586,8 +2630,8 @@ public class LettuceConnection extends AbstractRedisConnection { return null; } if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().zrevrange(key, start, end), - LettuceConverters.bytesListToBytesSet())); + transaction( + new LettuceTxResult(getConnection().zrevrange(key, start, end), LettuceConverters.bytesListToBytesSet())); return null; } return LettuceConverters.toBytesSet(getConnection().zrevrange(key, start, end)); @@ -2951,19 +2995,19 @@ public class LettuceConnection extends AbstractRedisConnection { byte[][] args = extractScriptArgs(numKeys, keysAndArgs); String convertedScript = LettuceConverters.toString(script); if (isPipelined()) { - pipeline(new LettuceResult(getAsyncConnection().eval(convertedScript, - LettuceConverters.toScriptOutputType(returnType), keys, args), new LettuceEvalResultsConverter( - returnType))); + pipeline(new LettuceResult( + getAsyncConnection().eval(convertedScript, LettuceConverters.toScriptOutputType(returnType), keys, args), + new LettuceEvalResultsConverter(returnType))); return null; } if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().eval(convertedScript, - LettuceConverters.toScriptOutputType(returnType), keys, args), new LettuceEvalResultsConverter( - returnType))); + transaction(new LettuceTxResult( + getConnection().eval(convertedScript, LettuceConverters.toScriptOutputType(returnType), keys, args), + new LettuceEvalResultsConverter(returnType))); return null; } - return new LettuceEvalResultsConverter(returnType).convert(getConnection().eval(convertedScript, - LettuceConverters.toScriptOutputType(returnType), keys, args)); + return new LettuceEvalResultsConverter(returnType) + .convert(getConnection().eval(convertedScript, LettuceConverters.toScriptOutputType(returnType), keys, args)); } catch (Exception ex) { throw convertLettuceAccessException(ex); } @@ -2975,19 +3019,19 @@ public class LettuceConnection extends AbstractRedisConnection { byte[][] args = extractScriptArgs(numKeys, keysAndArgs); if (isPipelined()) { - pipeline(new LettuceResult(getAsyncConnection().evalsha(scriptSha1, - LettuceConverters.toScriptOutputType(returnType), keys, args), new LettuceEvalResultsConverter( - returnType))); + pipeline(new LettuceResult( + getAsyncConnection().evalsha(scriptSha1, LettuceConverters.toScriptOutputType(returnType), keys, args), + new LettuceEvalResultsConverter(returnType))); return null; } if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().evalsha(scriptSha1, - LettuceConverters.toScriptOutputType(returnType), keys, args), new LettuceEvalResultsConverter( - returnType))); + transaction(new LettuceTxResult( + getConnection().evalsha(scriptSha1, LettuceConverters.toScriptOutputType(returnType), keys, args), + new LettuceEvalResultsConverter(returnType))); return null; } - return new LettuceEvalResultsConverter(returnType).convert(getConnection().evalsha(scriptSha1, - LettuceConverters.toScriptOutputType(returnType), keys, args)); + return new LettuceEvalResultsConverter(returnType) + .convert(getConnection().evalsha(scriptSha1, LettuceConverters.toScriptOutputType(returnType), keys, args)); } catch (Exception ex) { throw convertLettuceAccessException(ex); } @@ -3057,184 +3101,367 @@ public class LettuceConnection extends AbstractRedisConnection { } } - // - // Geo functionality - // - @Override - public Long geoAdd(byte[] key, double longitude, double latitude, byte[] member) { - try { - if (isPipelined()) { - pipeline(new LettuceResult(getAsyncConnection().geoadd(key, longitude, latitude, member))); - return null; - } - if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().geoadd(key, longitude, latitude, member))); - return null; - } - return getConnection().geoadd(key, longitude, latitude, member); - } catch (Exception ex) { - throw convertLettuceAccessException(ex); - } - } - - @Override - public Long geoAdd(byte[] key, Map memberCoordinateMap){ - try { - if (isPipelined()) { - pipeline(new LettuceResult(getAsyncConnection().geoadd(key, memberCoordinateMap))); - return null; - } - if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().geoadd(key, memberCoordinateMap))); - return null; - } - return getConnection().geoadd(key, memberCoordinateMap); - } catch (Exception ex) { - throw convertLettuceAccessException(ex); - } - } - - - @Override - public Double geoDist(byte[] key, byte[] member1, byte[] member2) { - throw new UnsupportedOperationException("Lettuce does not support this method without unit parameter passed"); - } - - @Override - public Double geoDist(byte[] key, byte[] member1, byte[] member2, GeoUnit unit) { - GeoArgs.Unit geoUnit = LettuceConverters.toGeoArgsUnit(unit); - try { - if (isPipelined()) { - pipeline(new LettuceResult(getAsyncConnection().geodist(key, member1, member2, geoUnit))); - return null; - } - if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().geodist(key, member1, member2, geoUnit))); - return null; - } - return getConnection().geodist(key, member1, member2, geoUnit); - } catch (Exception ex) { - throw convertLettuceAccessException(ex); - } - } - - @Override - public List geoHash(byte[] key, byte[]... members) { - throw new UnsupportedOperationException(); - } - - @Override - public List geoPos(byte[] key, byte[]... members) { - try { - if (isPipelined()) { - pipeline(new LettuceResult(getAsyncConnection().geopos(key, members), LettuceConverters.geoCoordinateListToGeoCoordinateList())); - return null; - } - if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().geopos(key, members), LettuceConverters.geoCoordinateListToGeoCoordinateList())); - return null; - } - return LettuceConverters.geoCoordinateListToGeoCoordinateList().convert(getConnection().geopos(key, members)); - } catch (Exception ex) { - throw convertLettuceAccessException(ex); - } - } + // + // Geo functionality + // + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], org.springframework.data.geo.Point, byte[]) + */ @Override - public List georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit) { - GeoArgs.Unit geoUnit = LettuceConverters.toGeoArgsUnit(unit); + public Long geoAdd(byte[] key, Point point, byte[] member) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(point, "Point must not be null!"); + Assert.notNull(member, "Member must not be null!"); + try { if (isPipelined()) { - pipeline(new LettuceResult(getAsyncConnection().georadius(key, longitude, latitude, radius, geoUnit), - LettuceConverters.bytesSetToGeoRadiusResponseListConverter())); + pipeline(new LettuceResult(getAsyncConnection().geoadd(key, point.getX(), point.getY(), member))); return null; } if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().georadius(key, longitude, latitude, radius, geoUnit), - LettuceConverters.bytesSetToGeoRadiusResponseListConverter())); + transaction(new LettuceTxResult(getConnection().geoadd(key, point.getX(), point.getY(), member))); return null; } - return LettuceConverters.bytesSetToGeoRadiusResponseListConverter(). - convert(getConnection().georadius(key, longitude, latitude, radius, geoUnit)); + return getConnection().geoadd(key, point.getX(), point.getY(), member); } catch (Exception ex) { throw convertLettuceAccessException(ex); } } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation) + */ @Override - public List georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { - GeoArgs.Unit geoUnit = LettuceConverters.toGeoArgsUnit(unit); - GeoArgs geoArgs = LettuceConverters.toGeoArgs(param); + public Long geoAdd(byte[] key, GeoLocation location) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(location, "Location must not be null!"); + try { if (isPipelined()) { - pipeline(new LettuceResult(getAsyncConnection().georadius(key, longitude, latitude, radius, geoUnit, geoArgs), - LettuceConverters.getGeowithinListToGeoRadiusResponseList())); + pipeline(new LettuceResult(getAsyncConnection().geoadd(key, location.getPoint().getX(), + location.getPoint().getY(), location.getName()))); return null; } if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().georadius(key, longitude, latitude, radius, geoUnit, geoArgs), - LettuceConverters.getGeowithinListToGeoRadiusResponseList())); + transaction(new LettuceTxResult( + getConnection().geoadd(key, location.getPoint().getX(), location.getPoint().getY(), location.getName()))); return null; } - return LettuceConverters.getGeowithinListToGeoRadiusResponseList(). - convert(getConnection().georadius(key, longitude, latitude, radius, geoUnit, geoArgs)); + return getConnection().geoadd(key, location.getPoint().getX(), location.getPoint().getY(), location.getName()); } catch (Exception ex) { throw convertLettuceAccessException(ex); } } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], java.util.Map) + */ @Override - public List georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit) { - GeoArgs.Unit geoUnit = LettuceConverters.toGeoArgsUnit(unit); + public Long geoAdd(byte[] key, Map memberCoordinateMap) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(memberCoordinateMap, "MemberCoordinateMap must not be null!"); + + List values = new ArrayList(); + for (Entry entry : memberCoordinateMap.entrySet()) { + + values.add(entry.getValue().getX()); + values.add(entry.getValue().getY()); + values.add(entry.getKey()); + } + + return geoAdd(key, values); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], java.lang.Iterable) + */ + @Override + public Long geoAdd(byte[] key, Iterable> locations) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(locations, "Locations must not be null!"); + + List values = new ArrayList(); + for (GeoLocation location : locations) { + + values.add(location.getPoint().getX()); + values.add(location.getPoint().getY()); + values.add(location.getName()); + } + + return geoAdd(key, values); + } + + private Long geoAdd(byte[] key, Collection values) { + try { + if (isPipelined()) { - pipeline(new LettuceResult(getAsyncConnection().georadiusbymember(key, member, radius, geoUnit), - LettuceConverters.bytesSetToGeoRadiusResponseListConverter())); + pipeline(new LettuceResult(getAsyncConnection().geoadd(key, values.toArray()))); return null; } if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().georadiusbymember(key, member, radius, geoUnit), - LettuceConverters.bytesSetToGeoRadiusResponseListConverter())); + transaction(new LettuceTxResult(getConnection().geoadd(key, values.toArray()))); return null; } - return LettuceConverters.bytesSetToGeoRadiusResponseListConverter(). - convert(getConnection().georadiusbymember(key, member, radius, geoUnit)); + return getConnection().geoadd(key, values.toArray()); } catch (Exception ex) { throw convertLettuceAccessException(ex); } } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoDist(byte[], byte[], byte[]) + */ @Override - public List georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param) { - GeoArgs.Unit geoUnit = LettuceConverters.toGeoArgsUnit(unit); - GeoArgs geoArgs = LettuceConverters.toGeoArgs(param); + public Distance geoDist(byte[] key, byte[] member1, byte[] member2) { + return geoDist(key, member1, member2, DistanceUnit.METERS); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoDist(byte[], byte[], byte[], org.springframework.data.geo.Metric) + */ + @Override + public Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric metric) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(member1, "Member1 must not be null!"); + Assert.notNull(member2, "Member2 must not be null!"); + Assert.notNull(metric, "Metric must not be null!"); + + GeoArgs.Unit geoUnit = LettuceConverters.toGeoArgsUnit(metric); + Converter distanceConverter = LettuceConverters.distanceConverterForMetric(metric); + try { if (isPipelined()) { - pipeline(new LettuceResult(getAsyncConnection().georadiusbymember(key, member, radius, geoUnit, geoArgs), - LettuceConverters.getGeowithinListToGeoRadiusResponseList())); + pipeline(new LettuceResult(getAsyncConnection().geodist(key, member1, member2, geoUnit), distanceConverter)); return null; } if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().georadiusbymember(key, member, radius, geoUnit, geoArgs), - LettuceConverters.getGeowithinListToGeoRadiusResponseList())); + transaction(new LettuceTxResult(getConnection().geodist(key, member1, member2, geoUnit), distanceConverter)); return null; } - return LettuceConverters.getGeowithinListToGeoRadiusResponseList(). - convert(getConnection().georadiusbymember(key, member, radius, geoUnit, geoArgs)); + return distanceConverter.convert(getConnection().geodist(key, member1, member2, geoUnit)); } catch (Exception ex) { throw convertLettuceAccessException(ex); } } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoHash(byte[], byte[][]) + */ + @Override + public List geoHash(byte[] key, byte[]... members) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(members, "Members must not be null!"); + Assert.noNullElements(members, "Members must not contain null!"); + + throw new UnsupportedOperationException("Lettuce does currently not supprt GEOHASH."); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoPos(byte[], byte[][]) + */ + @Override + public List geoPos(byte[] key, byte[]... members) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(members, "Members must not be null!"); + Assert.noNullElements(members, "Members must not contain null!"); + + ListConverter converter = LettuceConverters.geoCoordinatesToPointConverter(); + + try { + if (isPipelined()) { + pipeline(new LettuceResult(getAsyncConnection().geopos(key, members), converter)); + return null; + } + if (isQueueing()) { + transaction(new LettuceTxResult(getConnection().geopos(key, members), converter)); + return null; + } + return converter.convert(getConnection().geopos(key, members)); + } catch (Exception ex) { + throw convertLettuceAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadius(byte[], org.springframework.data.geo.Circle) + */ + @Override + public GeoResults> geoRadius(byte[] key, Circle within) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(within, "Within must not be null!"); + + Converter, GeoResults>> geoResultsConverter = LettuceConverters + .bytesSetToGeoResultsConverter(); + + try { + if (isPipelined()) { + pipeline(new LettuceResult( + getAsyncConnection().georadius(key, within.getCenter().getX(), within.getCenter().getY(), + within.getRadius().getValue(), LettuceConverters.toGeoArgsUnit(within.getRadius().getMetric())), + geoResultsConverter)); + return null; + } + if (isQueueing()) { + transaction(new LettuceTxResult( + getConnection().georadius(key, within.getCenter().getX(), within.getCenter().getY(), + within.getRadius().getValue(), LettuceConverters.toGeoArgsUnit(within.getRadius().getMetric())), + geoResultsConverter)); + return null; + } + return geoResultsConverter + .convert(getConnection().georadius(key, within.getCenter().getX(), within.getCenter().getY(), + within.getRadius().getValue(), LettuceConverters.toGeoArgsUnit(within.getRadius().getMetric()))); + } catch (Exception ex) { + throw convertLettuceAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadius(byte[], org.springframework.data.geo.Circle, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> geoRadius(byte[] key, Circle within, GeoRadiusCommandArgs args) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(within, "Within must not be null!"); + Assert.notNull(args, "Args must not be null!"); + + GeoArgs geoArgs = LettuceConverters.toGeoArgs(args); + Converter>, GeoResults>> geoResultsConverter = LettuceConverters + .geoRadiusResponseToGeoResultsConverter(within.getRadius().getMetric()); + + try { + if (isPipelined()) { + pipeline(new LettuceResult(getAsyncConnection().georadius(key, within.getCenter().getX(), + within.getCenter().getY(), within.getRadius().getValue(), + LettuceConverters.toGeoArgsUnit(within.getRadius().getMetric()), geoArgs), geoResultsConverter)); + return null; + } + if (isQueueing()) { + transaction(new LettuceTxResult(getConnection().georadius(key, within.getCenter().getX(), + within.getCenter().getY(), within.getRadius().getValue(), + LettuceConverters.toGeoArgsUnit(within.getRadius().getMetric()), geoArgs), geoResultsConverter)); + return null; + } + return geoResultsConverter + .convert(getConnection().georadius(key, within.getCenter().getX(), within.getCenter().getY(), + within.getRadius().getValue(), LettuceConverters.toGeoArgsUnit(within.getRadius().getMetric()), geoArgs)); + } catch (Exception ex) { + throw convertLettuceAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], double) + */ + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, double radius) { + return geoRadiusByMember(key, member, new Distance(radius, DistanceUnit.METERS)); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], double, org.springframework.data.geo.Metric) + */ + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(member, "Member must not be null!"); + Assert.notNull(radius, "Radius must not be null!"); + + GeoArgs.Unit geoUnit = LettuceConverters.toGeoArgsUnit(radius.getMetric()); + Converter, GeoResults>> converter = LettuceConverters + .bytesSetToGeoResultsConverter(); + + try { + if (isPipelined()) { + pipeline(new LettuceResult(getAsyncConnection().georadiusbymember(key, member, radius.getValue(), geoUnit), + converter)); + return null; + } + if (isQueueing()) { + transaction( + new LettuceTxResult(getConnection().georadiusbymember(key, member, radius.getValue(), geoUnit), converter)); + return null; + } + return converter.convert(getConnection().georadiusbymember(key, member, radius.getValue(), geoUnit)); + } catch (Exception ex) { + throw convertLettuceAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], org.springframework.data.geo.Distance, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius, + GeoRadiusCommandArgs args) { + + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(member, "Member must not be null!"); + Assert.notNull(radius, "Radius must not be null!"); + Assert.notNull(args, "Args must not be null!"); + + GeoArgs.Unit geoUnit = LettuceConverters.toGeoArgsUnit(radius.getMetric()); + GeoArgs geoArgs = LettuceConverters.toGeoArgs(args); + Converter>, GeoResults>> geoResultsConverter = LettuceConverters + .geoRadiusResponseToGeoResultsConverter(radius.getMetric()); + + try { + if (isPipelined()) { + pipeline( + new LettuceResult(getAsyncConnection().georadiusbymember(key, member, radius.getValue(), geoUnit, geoArgs), + geoResultsConverter)); + return null; + } + if (isQueueing()) { + transaction(new LettuceTxResult( + getConnection().georadiusbymember(key, member, radius.getValue(), geoUnit, geoArgs), geoResultsConverter)); + return null; + } + return geoResultsConverter + .convert(getConnection().georadiusbymember(key, member, radius.getValue(), geoUnit, geoArgs)); + } catch (Exception ex) { + throw convertLettuceAccessException(ex); + } + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoRemove(byte[], byte[][]) + */ @Override public Long geoRemove(byte[] key, byte[]... values) { return zRem(key, values); } /* - * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisServerCommands#time() - */ + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisServerCommands#time() + */ @Override public Long time() { try { @@ -3242,8 +3469,8 @@ public class LettuceConnection extends AbstractRedisConnection { List result = getConnection().time(); Assert.notEmpty(result, "Received invalid result from server. Expected 2 items in collection."); - Assert.isTrue(result.size() == 2, "Received invalid nr of arguments from redis server. Expected 2 received " - + result.size()); + Assert.isTrue(result.size() == 2, + "Received invalid nr of arguments from redis server. Expected 2 received " + result.size()); return Converters.toTimeMillis(new String(result.get(0)), new String(result.get(1))); @@ -3338,8 +3565,8 @@ public class LettuceConnection extends AbstractRedisConnection { throw new UnsupportedOperationException("Cannot be called in pipeline mode."); } if (isQueueing()) { - transaction(new LettuceTxResult(getAsyncConnection().clientList(), - LettuceConverters.stringToRedisClientListConverter())); + transaction( + new LettuceTxResult(getAsyncConnection().clientList(), LettuceConverters.stringToRedisClientListConverter())); return null; } @@ -3800,10 +4027,10 @@ public class LettuceConnection extends AbstractRedisConnection { */ static class TypeHints { - @SuppressWarnings("rawtypes")// + @SuppressWarnings("rawtypes") // private static final Map> COMMAND_OUTPUT_TYPE_MAPPING = new HashMap>(); - @SuppressWarnings("rawtypes")// + @SuppressWarnings("rawtypes") // private static final Map, Constructor> CONSTRUCTORS = new ConcurrentHashMap, Constructor>(); { @@ -4004,8 +4231,8 @@ public class LettuceConnection extends AbstractRedisConnection { return null; } if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().zrangebyscore(key, min, max), - LettuceConverters.bytesListToBytesSet())); + transaction( + new LettuceTxResult(getConnection().zrangebyscore(key, min, max), LettuceConverters.bytesListToBytesSet())); return null; } return LettuceConverters.toBytesSet(getConnection().zrangebyscore(key, min, max)); @@ -4049,7 +4276,8 @@ public class LettuceConnection extends AbstractRedisConnection { if (values.length == 1) { pipeline(new LettuceResult(getAsyncConnection().pfadd(key, values[0]))); } else { - pipeline(new LettuceResult(getAsyncConnection().pfadd(key, values[0], LettuceConverters.subarray(values, 1)))); + pipeline( + new LettuceResult(getAsyncConnection().pfadd(key, values[0], LettuceConverters.subarray(values, 1)))); } return null; } @@ -4057,7 +4285,8 @@ public class LettuceConnection extends AbstractRedisConnection { if (values.length == 1) { transaction(new LettuceTxResult(getConnection().pfadd(key, values[0]))); } else { - transaction(new LettuceTxResult(getConnection().pfadd(key, values[0], LettuceConverters.subarray(values, 1)))); + transaction( + new LettuceTxResult(getConnection().pfadd(key, values[0], LettuceConverters.subarray(values, 1)))); } return null; @@ -4126,16 +4355,16 @@ public class LettuceConnection extends AbstractRedisConnection { if (sourceKeys.length == 1) { pipeline(new LettuceResult(getAsyncConnection().pfmerge(destinationKey, sourceKeys[0]))); } else { - pipeline(new LettuceResult(getAsyncConnection().pfmerge(destinationKey, sourceKeys[0], - LettuceConverters.subarray(sourceKeys, 1)))); + pipeline(new LettuceResult( + getAsyncConnection().pfmerge(destinationKey, sourceKeys[0], LettuceConverters.subarray(sourceKeys, 1)))); } } if (isQueueing()) { if (sourceKeys.length == 1) { transaction(new LettuceTxResult(getConnection().pfmerge(destinationKey, sourceKeys[0]))); } else { - transaction(new LettuceTxResult(getConnection().pfmerge(destinationKey, sourceKeys[0], - LettuceConverters.subarray(sourceKeys, 1)))); + transaction(new LettuceTxResult( + getConnection().pfmerge(destinationKey, sourceKeys[0], LettuceConverters.subarray(sourceKeys, 1)))); } } @@ -4182,8 +4411,9 @@ public class LettuceConnection extends AbstractRedisConnection { try { if (isPipelined()) { if (limit != null) { - pipeline(new LettuceResult(getAsyncConnection().zrangebylex(key, min, max, limit.getOffset(), - limit.getCount()), LettuceConverters.bytesListToBytesSet())); + pipeline( + new LettuceResult(getAsyncConnection().zrangebylex(key, min, max, limit.getOffset(), limit.getCount()), + LettuceConverters.bytesListToBytesSet())); } else { pipeline(new LettuceResult(getAsyncConnection().zrangebylex(key, min, max), LettuceConverters.bytesListToBytesSet())); @@ -4192,18 +4422,19 @@ public class LettuceConnection extends AbstractRedisConnection { } if (isQueueing()) { if (limit != null) { - transaction(new LettuceTxResult(getConnection().zrangebylex(key, min, max, limit.getOffset(), - limit.getCount()), LettuceConverters.bytesListToBytesSet())); + transaction( + new LettuceTxResult(getConnection().zrangebylex(key, min, max, limit.getOffset(), limit.getCount()), + LettuceConverters.bytesListToBytesSet())); } else { - transaction(new LettuceTxResult(getConnection().zrangebylex(key, min, max), - LettuceConverters.bytesListToBytesSet())); + transaction( + new LettuceTxResult(getConnection().zrangebylex(key, min, max), LettuceConverters.bytesListToBytesSet())); } return null; } if (limit != null) { - return LettuceConverters.bytesListToBytesSet().convert( - getConnection().zrangebylex(key, min, max, limit.getOffset(), limit.getCount())); + return LettuceConverters.bytesListToBytesSet() + .convert(getConnection().zrangebylex(key, min, max, limit.getOffset(), limit.getCount())); } return LettuceConverters.bytesListToBytesSet().convert(getConnection().zrangebylex(key, min, max)); @@ -4230,13 +4461,13 @@ public class LettuceConnection extends AbstractRedisConnection { try { if (isPipelined()) { - pipeline(new LettuceResult(getAsyncConnection().migrate(target.getHost(), target.getPort(), key, dbIndex, - timeout))); + pipeline( + new LettuceResult(getAsyncConnection().migrate(target.getHost(), target.getPort(), key, dbIndex, timeout))); return; } if (isQueueing()) { - transaction(new LettuceTxResult(getConnection().migrate(target.getHost(), target.getPort(), key, dbIndex, - timeout))); + transaction( + new LettuceTxResult(getConnection().migrate(target.getHost(), target.getPort(), key, dbIndex, timeout))); return; } getConnection().migrate(target.getHost(), target.getPort(), key, dbIndex, timeout); 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 30a747111..9de44e8ee 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 @@ -28,14 +28,22 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; -import com.lambdaworks.redis.*; import org.springframework.core.convert.converter.Converter; import org.springframework.dao.DataAccessException; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResult; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Metrics; +import org.springframework.data.geo.Point; import org.springframework.data.redis.connection.DefaultTuple; import org.springframework.data.redis.connection.RedisClusterNode; import org.springframework.data.redis.connection.RedisClusterNode.Flag; import org.springframework.data.redis.connection.RedisClusterNode.LinkState; import org.springframework.data.redis.connection.RedisClusterNode.SlotRange; +import org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs; import org.springframework.data.redis.connection.RedisListCommands.Position; import org.springframework.data.redis.connection.RedisNode; import org.springframework.data.redis.connection.RedisNode.NodeType; @@ -51,16 +59,21 @@ import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.connection.convert.ListConverter; import org.springframework.data.redis.connection.convert.LongToBooleanConverter; import org.springframework.data.redis.connection.convert.StringToRedisClientInfoConverter; -import org.springframework.data.redis.core.GeoCoordinate; -import org.springframework.data.redis.core.GeoRadiusParam; -import org.springframework.data.redis.core.GeoRadiusResponse; -import org.springframework.data.redis.core.GeoUnit; import org.springframework.data.redis.core.types.Expiration; import org.springframework.data.redis.core.types.RedisClientInfo; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; +import com.lambdaworks.redis.GeoArgs; +import com.lambdaworks.redis.GeoCoordinates; +import com.lambdaworks.redis.GeoWithin; +import com.lambdaworks.redis.KeyValue; +import com.lambdaworks.redis.RedisURI; +import com.lambdaworks.redis.ScoredValue; +import com.lambdaworks.redis.ScriptOutputType; +import com.lambdaworks.redis.SortArgs; import com.lambdaworks.redis.cluster.models.partitions.Partitions; import com.lambdaworks.redis.cluster.models.partitions.RedisClusterNode.NodeFlag; import com.lambdaworks.redis.protocol.LettuceCharsets; @@ -73,6 +86,7 @@ import com.lambdaworks.redis.protocol.SetArgs; * @author Christoph Strobl * @author Thomas Darimont * @author Mark Paluch + * @author Ninad Divadkar */ abstract public class LettuceConverters extends Converters { @@ -92,10 +106,8 @@ abstract public class LettuceConverters extends Converters { private static final Converter> STRING_TO_LIST_OF_CLIENT_INFO = new StringToRedisClientInfoConverter(); private static final Converter> PARTITIONS_TO_CLUSTER_NODES; private static Converter CLUSTER_NODE_TO_CLUSTER_NODE_CONVERTER; - private static final Converter GEO_COORDINATE_CONVERTER; - private static final ListConverter GEO_COORDINATE_LIST_TO_GEO_COORDINATE_LIST; - private static final Converter, List> BYTES_SET_TO_GEO_RADIUS_RESPONSE_LIST; - private static final Converter>, List> GEOWITHIN_LIST_TO_GEO_RADIUS_RESPONSE_LIST; + private static final Converter GEO_COORDINATE_TO_POINT_CONVERTER; + private static final ListConverter GEO_COORDINATE_LIST_TO_POINT_LIST_CONVERTER; public static final byte[] PLUS_BYTES; public static final byte[] MINUS_BYTES; @@ -210,8 +222,8 @@ abstract public class LettuceConverters extends Converters { List tuples = new ArrayList(); Iterator it = source.iterator(); while (it.hasNext()) { - tuples.add(new DefaultTuple(it.next(), it.hasNext() ? Double.valueOf(LettuceConverters.toString(it.next())) - : null)); + tuples.add( + new DefaultTuple(it.next(), it.hasNext() ? Double.valueOf(LettuceConverters.toString(it.next())) : null)); } return tuples; } @@ -245,8 +257,8 @@ abstract public class LettuceConverters extends Converters { return RedisClusterNode.newRedisClusterNode().listeningAt(source.getUri().getHost(), source.getUri().getPort()) .withId(source.getNodeId()).promotedAs(flags.contains(Flag.MASTER) ? NodeType.MASTER : NodeType.SLAVE) .serving(new SlotRange(source.getSlots())).withFlags(flags) - .linkState(source.isConnected() ? LinkState.CONNECTED : LinkState.DISCONNECTED) - .slaveOf(source.getSlaveOf()).build(); + .linkState(source.isConnected() ? LinkState.CONNECTED : LinkState.DISCONNECTED).slaveOf(source.getSlaveOf()) + .build(); } private Set parseFlags(Set source) { @@ -290,53 +302,14 @@ abstract public class LettuceConverters extends Converters { POSITIVE_INFINITY_BYTES = toBytes("+inf"); NEGATIVE_INFINITY_BYTES = toBytes("-inf"); - GEO_COORDINATE_CONVERTER = new Converter() { - @Override - public GeoCoordinate convert(com.lambdaworks.redis.GeoCoordinates geoCoordinate) { - return geoCoordinate != null ? new GeoCoordinate(geoCoordinate.x.doubleValue(), geoCoordinate.y.doubleValue()) : null; - } - }; - GEO_COORDINATE_LIST_TO_GEO_COORDINATE_LIST = new ListConverter(GEO_COORDINATE_CONVERTER); - - BYTES_SET_TO_GEO_RADIUS_RESPONSE_LIST = new Converter, List>() { - + GEO_COORDINATE_TO_POINT_CONVERTER = new Converter() { @Override - public List convert(Set source) { - - if (CollectionUtils.isEmpty(source)) { - return Collections.emptyList(); - } - - List geoRadiusResponses = new ArrayList(); - Iterator it = source.iterator(); - while (it.hasNext()) { - geoRadiusResponses.add(new GeoRadiusResponse(it.next())); - } - return geoRadiusResponses; - } - }; - - GEOWITHIN_LIST_TO_GEO_RADIUS_RESPONSE_LIST = new Converter>, List>() { - - @Override - public List convert(List> source) { - - if (CollectionUtils.isEmpty(source)) { - return Collections.emptyList(); - } - - List geoRadiusResponses = new ArrayList(); - Iterator> it = source.iterator(); - while (it.hasNext()) { - GeoWithin geoWithin = it.next(); - GeoRadiusResponse geoRadiusResponse = new GeoRadiusResponse(geoWithin.member); - geoRadiusResponse.setCoordinate(new GeoCoordinate(geoWithin.coordinates.x.doubleValue(), - geoWithin.coordinates.y.doubleValue())); - geoRadiusResponse.setDistance(geoWithin.distance); - } - return geoRadiusResponses; + public Point convert(com.lambdaworks.redis.GeoCoordinates geoCoordinate) { + return geoCoordinate != null ? new Point(geoCoordinate.x.doubleValue(), geoCoordinate.y.doubleValue()) : null; } }; + GEO_COORDINATE_LIST_TO_POINT_LIST_CONVERTER = new ListConverter( + GEO_COORDINATE_TO_POINT_CONVERTER); } @@ -348,14 +321,6 @@ abstract public class LettuceConverters extends Converters { return BYTES_LIST_TO_TUPLE_LIST_CONVERTER; } - public static Converter, List> bytesSetToGeoRadiusResponseListConverter() { - return BYTES_SET_TO_GEO_RADIUS_RESPONSE_LIST; - } - - public static Converter>, List> getGeowithinListToGeoRadiusResponseList() { - return GEOWITHIN_LIST_TO_GEO_RADIUS_RESPONSE_LIST; - } - public static Converter> stringToRedisClientListConverter() { return new Converter>() { @@ -406,8 +371,6 @@ abstract public class LettuceConverters extends Converters { return EXCEPTION_CONVERTER; } - public static ListConverter geoCoordinateListToGeoCoordinateList() { return GEO_COORDINATE_LIST_TO_GEO_COORDINATE_LIST; } - /** * @return * @sice 1.3 @@ -579,8 +542,8 @@ abstract public class LettuceConverters extends Converters { for (RedisNode sentinel : sentinels) { if (builder == null) { - builder = RedisURI.Builder.sentinel(sentinel.getHost(), sentinel.getPort(), sentinelConfiguration.getMaster() - .getName()); + builder = RedisURI.Builder.sentinel(sentinel.getHost(), sentinel.getPort(), + sentinelConfiguration.getMaster().getName()); } else { builder.withSentinel(sentinel.getHost(), sentinel.getPort()); } @@ -717,36 +680,176 @@ abstract public class LettuceConverters extends Converters { break; } } - return args; } - public static com.lambdaworks.redis.GeoArgs.Unit toGeoArgsUnit(GeoUnit geoUnit){ - switch (geoUnit){ - case Meters: return GeoArgs.Unit.m; - case KiloMeters: return GeoArgs.Unit.km; - case Miles: return GeoArgs.Unit.mi; - case Feet: return GeoArgs.Unit.ft; - default: throw new IllegalArgumentException("geoUnit not supported"); - } - } + /** + * Convert {@link Metric} into {@link GeoArgs.Unit}. + * + * @param metric + * @return + * @since 1.8 + */ + public static GeoArgs.Unit toGeoArgsUnit(Metric metric) { - public static com.lambdaworks.redis.GeoArgs toGeoArgs(GeoRadiusParam geoRadiusParam){ - com.lambdaworks.redis.GeoArgs geoArgs = new GeoArgs(); - for (String k : geoRadiusParam.getParams().keySet()){ - if (k.equals(GeoRadiusParam.getASC())) - geoArgs.asc(); - else if (k.equals(GeoRadiusParam.getDESC())) - geoArgs.desc(); - else if (k.equals(GeoRadiusParam.getCOUNT())) - geoArgs.withCount((Integer)geoRadiusParam.getParams().get(k)); - else if (k.equals(GeoRadiusParam.getWITHCOORD())) - geoArgs.withCoordinates(); - else if (k.equals(GeoRadiusParam.getWITHDIST())) - geoArgs.withDistance(); - else - throw new IllegalArgumentException("unknown key value"); + Metric metricToUse = metric == null || ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, metric) ? DistanceUnit.METERS + : metric; + return ObjectUtils.caseInsensitiveValueOf(GeoArgs.Unit.values(), metricToUse.getAbbreviation()); + } + + /** + * Convert {@link GeoRadiusCommandArgs} into {@link GeoArgs}. + * + * @param args + * @return + * @since 1.8 + */ + public static GeoArgs toGeoArgs(GeoRadiusCommandArgs args) { + + GeoArgs geoArgs = new GeoArgs(); + + if (args.hasFlags()) { + for (GeoRadiusCommandArgs.Flag flag : args.getFlags()) { + switch (flag) { + case WITHCOORD: + geoArgs.withCoordinates(); + break; + case WITHDIST: + geoArgs.withDistance(); + break; + } + } + } + + if (args.hasSortDirection()) { + switch (args.getSortDirection()) { + case ASC: + geoArgs.asc(); + break; + case DESC: + geoArgs.desc(); + break; + } + } + + if (args.hasLimit()) { + geoArgs.withCount(args.getLimit()); } return geoArgs; - } + } + + /** + * Get {@link Converter} capable of {@link Set} of {@link Byte} into {@link GeoResults}. + * + * @return + * @since 1.8 + */ + public static Converter, GeoResults>> bytesSetToGeoResultsConverter() { + return new Converter, GeoResults>>() { + + @Override + public GeoResults> convert(Set source) { + + if (CollectionUtils.isEmpty(source)) { + return new GeoResults>(Collections.>> emptyList()); + } + + List>> results = new ArrayList>>(source.size()); + Iterator it = source.iterator(); + while (it.hasNext()) { + results.add(new GeoResult>(new GeoLocation(it.next(), null), new Distance(0D))); + } + return new GeoResults>(results); + } + }; + } + + /** + * Get {@link Converter} capable of convering {@link GeoWithin} into {@link GeoResults}. + * + * @param metric + * @return + * @since 1.8 + */ + public static Converter>, GeoResults>> geoRadiusResponseToGeoResultsConverter( + Metric metric) { + return GeoResultsConverterFactory.INSTANCE.forMetric(metric); + } + + /** + * @return + * @since 1.8 + */ + public static ListConverter geoCoordinatesToPointConverter() { + return GEO_COORDINATE_LIST_TO_POINT_LIST_CONVERTER; + } + + /** + * @author Christoph Strobl + * @since 1.8 + */ + static enum GeoResultsConverterFactory { + + INSTANCE; + + Converter>, GeoResults>> forMetric(Metric metric) { + return new GeoResultsConverter( + metric == null || ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, metric) ? DistanceUnit.METERS : metric); + } + + private static class GeoResultsConverter + implements Converter>, GeoResults>> { + + private Metric metric; + + public GeoResultsConverter(Metric metric) { + this.metric = metric; + } + + @Override + public GeoResults> convert(List> source) { + + List>> results = new ArrayList>>(source.size()); + + Converter, GeoResult>> converter = GeoResultConverterFactory.INSTANCE + .forMetric(metric); + for (GeoWithin result : source) { + results.add(converter.convert(result)); + } + + return new GeoResults>(results, metric); + } + } + } + + /** + * @author Christoph Strobl + * @since 1.8 + */ + static enum GeoResultConverterFactory { + + INSTANCE; + + Converter, GeoResult>> forMetric(Metric metric) { + return new GeoResultConverter(metric); + } + + private static class GeoResultConverter implements Converter, GeoResult>> { + + private Metric metric; + + public GeoResultConverter(Metric metric) { + this.metric = metric; + } + + @Override + public GeoResult> convert(GeoWithin source) { + + Point point = GEO_COORDINATE_TO_POINT_CONVERTER.convert(source.coordinates); + + return new GeoResult>(new GeoLocation(source.member, point), + new Distance(source.distance != null ? source.distance : 0D, metric)); + } + } + } } diff --git a/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java b/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java index 8512d02d5..eac4482c0 100644 --- a/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java @@ -31,6 +31,11 @@ import java.util.concurrent.Future; import org.springframework.core.convert.converter.Converter; import org.springframework.dao.DataAccessException; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Point; import org.springframework.data.redis.ExceptionTranslationStrategy; import org.springframework.data.redis.FallbackExceptionTranslationStrategy; import org.springframework.data.redis.RedisConnectionFailureException; @@ -44,11 +49,17 @@ import org.springframework.data.redis.connection.RedisSubscribedConnectionExcept 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.core.*; +import org.springframework.data.redis.core.Cursor; +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; +import com.google.common.base.Charsets; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; + import redis.Command; import redis.client.RedisClient; import redis.client.RedisClient.Pipeline; @@ -56,11 +67,6 @@ import redis.client.RedisException; import redis.reply.MultiBulkReply; import redis.reply.Reply; -import com.google.common.base.Charsets; -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - /** * {@code RedisConnection} implementation on top of spullara Redis * Protocol library. @@ -70,6 +76,7 @@ import com.google.common.util.concurrent.ListenableFuture; * @author Christoph Strobl * @author Thomas Darimont * @author David Liu + * @author Ninad Divadkar * @deprecated since 1.7. Will be removed in subsequent version. */ @Deprecated @@ -134,8 +141,8 @@ public class SrpConnection extends AbstractRedisConnection { // ignore } if (futureResults.size() != results.size() + txResults) { - throw new RedisPipelineException("Received a different number of results than expected. Expected: " - + futureResults.size(), results); + throw new RedisPipelineException( + "Received a different number of results than expected. Expected: " + futureResults.size(), results); } List convertedResults = new ArrayList(); @@ -1747,8 +1754,8 @@ public class SrpConnection extends AbstractRedisConnection { } public Set zRevRangeByScore(byte[] key, double min, double max, long offset, long count) { - return zRevRangeByScore(key, new Range().gte(min).lte(max), new Limit().offset(Long.valueOf(offset).intValue()) - .count(Long.valueOf(count).intValue())); + return zRevRangeByScore(key, new Range().gte(min).lte(max), + new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue())); } @@ -1785,8 +1792,8 @@ public class SrpConnection extends AbstractRedisConnection { try { if (isPipelined()) { - pipeline(new SrpResult(pipeline.zrevrangebyscore(key, max, min, null, params), - SrpConverters.repliesToBytesSet())); + pipeline( + new SrpResult(pipeline.zrevrangebyscore(key, max, min, null, params), SrpConverters.repliesToBytesSet())); return null; } return SrpConverters.toBytesSet(client.zrevrangebyscore(key, max, min, null, params).data()); @@ -2137,8 +2144,8 @@ public class SrpConnection extends AbstractRedisConnection { public List scriptExists(String... scriptSha1) { try { if (isPipelined()) { - pipeline(new SrpGenericResult(pipeline.script_exists((Object[]) scriptSha1), - SrpConverters.repliesToBooleanList())); + pipeline( + new SrpGenericResult(pipeline.script_exists((Object[]) scriptSha1), SrpConverters.repliesToBooleanList())); return null; } return SrpConverters.toBooleanList(((MultiBulkReply) client.script_exists_((Object[]) scriptSha1)).data()); @@ -2155,8 +2162,8 @@ public class SrpConnection extends AbstractRedisConnection { new SrpScriptReturnConverter(returnType))); return null; } - return (T) new SrpScriptReturnConverter(returnType).convert(client.eval(script, numKeys, (Object[]) keysAndArgs) - .data()); + return (T) new SrpScriptReturnConverter(returnType) + .convert(client.eval(script, numKeys, (Object[]) keysAndArgs).data()); } catch (Exception ex) { throw convertSrpAccessException(ex); } @@ -2170,8 +2177,8 @@ public class SrpConnection extends AbstractRedisConnection { new SrpScriptReturnConverter(returnType))); return null; } - return (T) new SrpScriptReturnConverter(returnType).convert(client.evalsha(scriptSha1, numKeys, - (Object[]) keysAndArgs).data()); + return (T) new SrpScriptReturnConverter(returnType) + .convert(client.evalsha(scriptSha1, numKeys, (Object[]) keysAndArgs).data()); } catch (Exception ex) { throw convertSrpAccessException(ex); } @@ -2240,58 +2247,130 @@ public class SrpConnection extends AbstractRedisConnection { } } - @Override - public Long geoAdd(byte[] key, double longitude, double latitude, byte[] member) { - throw new UnsupportedOperationException(); - } - - @Override - public Long geoAdd(byte[] key, Map memberCoordinateMap) { - throw new UnsupportedOperationException(); - } - - @Override - public Double geoDist(byte[] key, byte[] member1, byte[] member2) { - throw new UnsupportedOperationException(); - } - - @Override - public Double geoDist(byte[] key, byte[] member1, byte[] member2, GeoUnit unit) { - throw new UnsupportedOperationException(); - } - - @Override - public List geoHash(byte[] key, byte[]... members) { - throw new UnsupportedOperationException(); - } - - @Override - public List geoPos(byte[] key, byte[]... members) { - throw new UnsupportedOperationException(); - } - + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], org.springframework.data.geo.Point, byte[]) + */ @Override - public List georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit) { + public Long geoAdd(byte[] key, Point point, byte[] member) { throw new UnsupportedOperationException(); } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation) + */ @Override - public List georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { + public Long geoAdd(byte[] key, GeoLocation location) { throw new UnsupportedOperationException(); } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], java.util.Map) + */ @Override - public List georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit) { + public Long geoAdd(byte[] key, Map memberCoordinateMap) { throw new UnsupportedOperationException(); } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoAdd(byte[], java.lang.Iterable) + */ @Override - public List georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param) { + public Long geoAdd(byte[] key, Iterable> locations) { throw new UnsupportedOperationException(); } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoDist(byte[], byte[], byte[]) + */ @Override - public Long geoRemove(byte[] key, byte[]... values) { + public Distance geoDist(byte[] key, byte[] member1, byte[] member2) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoDist(byte[], byte[], byte[], org.springframework.data.geo.Metric) + */ + @Override + public Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric metric) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoHash(byte[], byte[][]) + */ + @Override + public List geoHash(byte[] key, byte[]... members) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoPos(byte[], byte[][]) + */ + @Override + public List geoPos(byte[] key, byte[]... members) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadius(byte[], org.springframework.data.geo.Circle) + */ + @Override + public GeoResults> geoRadius(byte[] key, Circle within) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadius(byte[], org.springframework.data.geo.Circle, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> geoRadius(byte[] key, Circle within, GeoRadiusCommandArgs args) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], double) + */ + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, double radius) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], org.springframework.data.geo.Distance) + */ + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#georadiusByMember(byte[], byte[], org.springframework.data.geo.Distance, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius, + GeoRadiusCommandArgs param) { + throw new UnsupportedOperationException(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisGeoCommands#geoRemove(byte[], byte[][]) + */ + @Override + public Long geoRemove(byte[] key, byte[]... members) { throw new UnsupportedOperationException(); } @@ -2626,7 +2705,8 @@ public class SrpConnection extends AbstractRedisConnection { String keyStr = new String(key, "UTF-8"); Object[] limit = limitParams(offset, count); if (isPipelined()) { - pipeline(new SrpResult(pipeline.zrangebyscore(keyStr, min, max, null, limit), SrpConverters.repliesToBytesSet())); + pipeline( + new SrpResult(pipeline.zrangebyscore(keyStr, min, max, null, limit), SrpConverters.repliesToBytesSet())); return null; } return SrpConverters.toBytesSet(client.zrangebyscore(keyStr, min, max, null, limit).data()); diff --git a/src/main/java/org/springframework/data/redis/core/AbstractOperations.java b/src/main/java/org/springframework/data/redis/core/AbstractOperations.java index 5611da96b..7c4a19a11 100644 --- a/src/main/java/org/springframework/data/redis/core/AbstractOperations.java +++ b/src/main/java/org/springframework/data/redis/core/AbstractOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2015 the original author or authors. + * Copyright 2011-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. @@ -23,9 +23,12 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.springframework.data.geo.GeoResults; import org.springframework.data.redis.connection.DefaultTuple; import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; import org.springframework.data.redis.connection.RedisZSetCommands.Tuple; +import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.core.ZSetOperations.TypedTuple; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.SerializationUtils; @@ -334,4 +337,20 @@ abstract class AbstractOperations { } return (HV) hashValueSerializer().deserialize(value); } + + /** + * Deserialize {@link GeoLocation} of {@link GeoResults}. + * + * @param source can be {@literal null}. + * @return converted or {@literal null}. + * @since 1.8 + */ + GeoResults> deserializeGeoResults(GeoResults> source) { + + if (valueSerializer() == null) { + return (GeoResults>) (Object) source; + } + + return Converters.deserializingGeoResultsConverter((RedisSerializer) valueSerializer()).convert(source); + } } diff --git a/src/main/java/org/springframework/data/redis/core/BoundGeoOperations.java b/src/main/java/org/springframework/data/redis/core/BoundGeoOperations.java index 6e0f4cc3e..0546c5db1 100644 --- a/src/main/java/org/springframework/data/redis/core/BoundGeoOperations.java +++ b/src/main/java/org/springframework/data/redis/core/BoundGeoOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2014 the original author or authors. + * Copyright 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. @@ -18,35 +18,157 @@ package org.springframework.data.redis.core; import java.util.List; import java.util.Map; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Point; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs; + /** - * Hash operations bound to a certain key. + * {@link GeoOperations} bound to a certain key. * * @author Ninad Divadkar + * @author Christoph Strobl + * @since 1.8 */ -public interface BoundGeoOperations extends BoundKeyOperations { - Long geoAdd(K key, double longitude, double latitude, M member); +public interface BoundGeoOperations extends BoundKeyOperations { - Long geoAdd(K key, Map memberCoordinateMap); + /** + * Add {@link Point} with given member {@literal name} to {@literal key}. + * + * @param point must not be {@literal null}. + * @param member must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + */ + Long geoAdd(Point point, M member); - Double geoDist(K key, M member1, M member2); + /** + * Add {@link GeoLocation} to {@literal key}. + * + * @param location must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + */ + Long geoAdd(GeoLocation location); - Double geoDist(K key, M member1, M member2, GeoUnit unit); + /** + * Add {@link Map} of member / {@link Point} pairs to {@literal key}. + * + * @param memberCoordinateMap must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + */ + Long geoAdd(Map memberCoordinateMap); - List geoHash(K key, M... members); + /** + * Add {@link GeoLocation}s to {@literal key} + * + * @param locations must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + */ + Long geoAdd(Iterable> locations); - List geoPos(K key, M... members); + /** + * Get the {@link Distance} between {@literal member1} and {@literal member2}. + * + * @param member1 must not be {@literal null}. + * @param member2 must not be {@literal null}. + * @return can be {@literal null}. + * @see http://redis.io/commands/geodist + */ + Distance geoDist(M member1, M member2); - List georadius(K key, double longitude, double latitude, - double radius, GeoUnit unit); + /** + * Get the {@link Distance} between {@literal member1} and {@literal member2} in the given {@link Metric}. + * + * @param member1 must not be {@literal null}. + * @param member2 must not be {@literal null}. + * @param metric must not be {@literal null}. + * @return can be {@literal null}. + * @see http://redis.io/commands/geodist + */ + Distance geoDist(M member1, M member2, Metric metric); - List georadius(K key, double longitude, double latitude, - double radius, GeoUnit unit, GeoRadiusParam param); + /** + * Get Geohash representation of the position for one or more {@literal member}s. + * + * @param members must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/geohash + */ + List geoHash(M... members); - List georadiusByMember(K key, M member, double radius, - GeoUnit unit); + /** + * Get the {@link Point} representation of positions for one or more {@literal member}s. + * + * @param members must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/geopos + */ + List geoPos(M... members); - List georadiusByMember(K key, M member, double radius, - GeoUnit unit, GeoRadiusParam param); + /** + * Get the {@literal member}s within the boundaries of a given {@link Circle}. + * + * @param within must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadius + */ + GeoResults> georadius(Circle within); - Long geoRemove(K key, M... members); + /** + * Get the {@literal member}s within the boundaries of a given {@link Circle} applying {@link GeoRadiusCommandArgs}. + * + * @param within must not be {@literal null}. + * @param args must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadius + */ + GeoResults> georadius(Circle within, GeoRadiusCommandArgs args); + + /** + * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given + * {@literal radius}. + * + * @param member must not be {@literal null}. + * @param radius + * @return never {@literal null}. + * @see http://redis.io/commands/georadiusbymember + */ + GeoResults> georadiusByMember(K key, M member, double radius); + + /** + * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given + * {@literal radius} applying {@link Metric}. + * + * @param member must not be {@literal null}. + * @param distance must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadiusbymember + */ + GeoResults> georadiusByMember(M member, Distance distance); + + /** + * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given + * {@literal radius} applying {@link Metric} and {@link GeoRadiusCommandArgs}. + * + * @param member must not be {@literal null}. + * @param distance must not be {@literal null}. + * @param args must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadiusbymember + */ + GeoResults> georadiusByMember(M member, Distance distance, GeoRadiusCommandArgs args); + + /** + * Remove the {@literal member}s. + * + * @param members must not be {@literal null}. + * @return Number of elements removed. + */ + Long geoRemove(M... members); } diff --git a/src/main/java/org/springframework/data/redis/core/DefaultBoundGeoOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultBoundGeoOperations.java index 22ff893b8..d19991874 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultBoundGeoOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultBoundGeoOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013 the original author or authors. + * Copyright 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. @@ -15,87 +15,174 @@ */ package org.springframework.data.redis.core; -import org.springframework.data.redis.connection.DataType; - import java.util.List; import java.util.Map; -import java.util.concurrent.TimeUnit; + +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Point; +import org.springframework.data.redis.connection.DataType; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs; /** + * Default implementation of {@link BoundGeoOperations}. + * * @author Ninad Divadkar + * @author Christoph Strobl + * @since 1.8 */ class DefaultBoundGeoOperations extends DefaultBoundKeyOperations implements BoundGeoOperations { private final GeoOperations ops; /** - * Constructs a new DefaultBoundGeoOperations instance. + * Constructs a new {@code DefaultBoundGeoOperations}. * - * @param key - * @param operations + * @param key must not be {@literal null}. + * @param operations must not be {@literal null}. */ public DefaultBoundGeoOperations(K key, RedisOperations operations) { + super(key, operations); this.ops = operations.opsForGeo(); } - @Override - public Long geoAdd(K key, double longitude, double latitude, M member) { - return ops.geoAdd(key, longitude, latitude, member); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.BoundGeoOperations#geoAdd(org.springframework.data.geo.Point, java.lang.Object) + */ + @Override + public Long geoAdd(Point point, M member) { + return ops.geoAdd(getKey(), point, member); + } - @Override - public Long geoAdd(K key, Map memberCoordinateMap) { - return ops.geoAdd(key, memberCoordinateMap); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.BoundGeoOperations#geoAdd(org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation) + */ + @Override + public Long geoAdd(GeoLocation location) { + return ops.geoAdd(getKey(), location); + } - @Override - public Double geoDist(K key, M member1, M member2) { - return ops.geoDist(key, member1, member2); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.BoundGeoOperations#geoAdd(java.util.Map) + */ + @Override + public Long geoAdd(Map memberCoordinateMap) { + return ops.geoAdd(getKey(), memberCoordinateMap); + } - @Override - public Double geoDist(K key, M member1, M member2, GeoUnit unit) { - return ops.geoDist(key, member1, member2, unit); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.BoundGeoOperations#geoAdd(java.lang.Iterable) + */ + @Override + public Long geoAdd(Iterable> locations) { + return ops.geoAdd(getKey(), locations); + } - @Override - public List geoHash(K key, M... members) { - return ops.geoHash(key, members); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.BoundGeoOperations#geoDist(java.lang.Object, java.lang.Object) + */ + @Override + public Distance geoDist(M member1, M member2) { + return ops.geoDist(getKey(), member1, member2); + } - @Override - public List geoPos(K key, M... members) { - return ops.geoPos(key, members); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.BoundGeoOperations#geoDist(java.lang.Object, java.lang.Object, org.springframework.data.geo.Metric) + */ + @Override + public Distance geoDist(M member1, M member2, Metric unit) { + return ops.geoDist(getKey(), member1, member2, unit); + } - @Override - public List georadius(K key, double longitude, double latitude, double radius, GeoUnit unit) { - return ops.georadius(key, longitude, latitude, radius, unit); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.BoundGeoOperations#geoHash(java.lang.Object[]) + */ + @Override + public List geoHash(M... members) { + return ops.geoHash(getKey(), members); + } - @Override - public List georadius(K key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { - return ops.georadius(key, longitude, latitude, radius, unit, param); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.BoundGeoOperations#geoPos(java.lang.Object[]) + */ + @Override + public List geoPos(M... members) { + return ops.geoPos(getKey(), members); + } - @Override - public List georadiusByMember(K key, M member, double radius, GeoUnit unit) { - return ops.georadiusByMember(key, member, radius, unit); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.BoundGeoOperations#georadius(org.springframework.data.geo.Circle) + */ + @Override + public GeoResults> georadius(Circle within) { + return ops.georadius(getKey(), within); + } - @Override - public List georadiusByMember(K key, M member, double radius, GeoUnit unit, GeoRadiusParam param) { - return ops.georadiusByMember(key, member, radius, unit, param); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.BoundGeoOperations#georadius(org.springframework.data.geo.Circle, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> georadius(Circle within, GeoRadiusCommandArgs param) { + return ops.georadius(getKey(), within, param); + } - @Override - public Long geoRemove(K key, M... members) { - return ops.geoRemove(key, members); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.BoundGeoOperations#georadiusByMember(java.lang.Object, java.lang.Object, double) + */ + @Override + public GeoResults> georadiusByMember(K key, M member, double radius) { + return ops.georadiusByMember(getKey(), member, radius); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.BoundGeoOperations#georadiusByMember(java.lang.Object, org.springframework.data.geo.Distance) + */ + @Override + public GeoResults> georadiusByMember(M member, Distance distance) { + return ops.georadiusByMember(getKey(), member, distance); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.BoundGeoOperations#georadiusByMember(java.lang.Object, org.springframework.data.geo.Distance, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> georadiusByMember(M member, Distance distance, GeoRadiusCommandArgs param) { + return ops.georadiusByMember(getKey(), member, distance, param); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.BoundGeoOperations#geoRemove(java.lang.Object[]) + */ + @Override + public Long geoRemove(M... members) { + return ops.geoRemove(getKey(), members); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.BoundKeyOperations#getType() + */ + @Override + public DataType getType() { + return DataType.ZSET; + } - @Override - public DataType getType() { - return DataType.STRING; - } } diff --git a/src/main/java/org/springframework/data/redis/core/DefaultGeoOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultGeoOperations.java index 53f907188..710e76402 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultGeoOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultGeoOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2014 the original author or authors. + * Copyright 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. @@ -15,166 +15,289 @@ */ package org.springframework.data.redis.core; -import org.springframework.data.redis.connection.RedisConnection; - import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Point; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs; + /** * Default implementation of {@link GeoOperations}. * * @author Ninad Divadkar + * @author Christoph Strobl + * @since 1.8 */ public class DefaultGeoOperations extends AbstractOperations implements GeoOperations { - DefaultGeoOperations(RedisTemplate template) { - super(template); - } - @Override - public Long geoAdd(K key, final double longitude, final double latitude, M member) { - final byte[] rawKey = rawKey(key); - final byte[] rawMember = rawValue(member); + /** + * Creates new {@link DefaultGeoOperations}. + * + * @param template must not be {@literal null}. + */ + DefaultGeoOperations(RedisTemplate template) { + super(template); + } - return execute(new RedisCallback() { + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.GeoOperations#geoAdd(java.lang.Object, org.springframework.data.geo.Point, java.lang.Object) + */ + @Override + public Long geoAdd(K key, final Point point, M member) { - public Long doInRedis(RedisConnection connection) { - return connection.geoAdd(rawKey, longitude, latitude, rawMember); - } - }, true); - } + final byte[] rawKey = rawKey(key); + final byte[] rawMember = rawValue(member); - @Override - public Long geoAdd(K key, Map memberCoordinateMap) { - final byte[] rawKey = rawKey(key); - final Map rawMemberCoordinateMap = new HashMap(); - for(M member : memberCoordinateMap.keySet()){ - final byte[] rawMember = rawValue(member); - rawMemberCoordinateMap.put(rawMember, memberCoordinateMap.get(member)); - } + return execute(new RedisCallback() { - return execute(new RedisCallback() { + public Long doInRedis(RedisConnection connection) { + return connection.geoAdd(rawKey, point, rawMember); + } + }, true); + } - public Long doInRedis(RedisConnection connection) { - return connection.geoAdd(rawKey, rawMemberCoordinateMap); - } - }, true); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.GeoOperations#geoAdd(java.lang.Object, org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation) + */ + @Override + public Long geoAdd(K key, GeoLocation location) { + return geoAdd(key, location.getPoint(), location.getName()); + } - @Override - public Double geoDist(K key, final M member1, final M member2) { - final byte[] rawKey = rawKey(key); - final byte[] rawMember1 = rawValue(member1); - final byte[] rawMember2 = rawValue(member2); + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.GeoOperations#geoAdd(java.lang.Object, java.util.Map) + */ + @Override + public Long geoAdd(K key, Map memberCoordinateMap) { - return execute(new RedisCallback() { + final byte[] rawKey = rawKey(key); + final Map rawMemberCoordinateMap = new HashMap(); - public Double doInRedis(RedisConnection connection) { - return connection.geoDist(rawKey, rawMember1, rawMember2); - } - }, true); - } + for (M member : memberCoordinateMap.keySet()) { + final byte[] rawMember = rawValue(member); + rawMemberCoordinateMap.put(rawMember, memberCoordinateMap.get(member)); + } - @Override - public Double geoDist(K key, M member1, M member2, final GeoUnit unit) { - final byte[] rawKey = rawKey(key); - final byte[] rawMember1 = rawValue(member1); - final byte[] rawMember2 = rawValue(member2); + return execute(new RedisCallback() { - return execute(new RedisCallback() { + public Long doInRedis(RedisConnection connection) { + return connection.geoAdd(rawKey, rawMemberCoordinateMap); + } + }, true); + } - public Double doInRedis(RedisConnection connection) { - return connection.geoDist(rawKey, rawMember1, rawMember2, unit); - } - }, true); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.GeoOperations#geoAdd(java.lang.Object, java.lang.Iterable) + */ + @Override + public Long geoAdd(K key, Iterable> locations) { - @Override - public List geoHash(K key, final M... members) { - final byte[] rawKey = rawKey(key); - final byte[][] rawMembers = rawValues(members); + Map memberCoordinateMap = new LinkedHashMap(); + for (GeoLocation location : locations) { + memberCoordinateMap.put(location.getName(), location.getPoint()); + } - return execute(new RedisCallback>() { + return geoAdd(key, memberCoordinateMap); + } - public List doInRedis(RedisConnection connection) { - return connection.geoHash(rawKey, rawMembers); - } - }, true); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.GeoOperations#geoDist(java.lang.Object, java.lang.Object, java.lang.Object) + */ + @Override + public Distance geoDist(K key, final M member1, final M member2) { - @Override - public List geoPos(K key, M... members) { - final byte[] rawKey = rawKey(key); - final byte[][] rawMembers = rawValues(members); + final byte[] rawKey = rawKey(key); + final byte[] rawMember1 = rawValue(member1); + final byte[] rawMember2 = rawValue(member2); - return execute(new RedisCallback>() { + return execute(new RedisCallback() { - public List doInRedis(RedisConnection connection) { - return connection.geoPos(rawKey, rawMembers); - } - }, true); - } + public Distance doInRedis(RedisConnection connection) { + return connection.geoDist(rawKey, rawMember1, rawMember2); + } + }, true); + } - @Override - public List georadius(K key, final double longitude, final double latitude, final double radius, final GeoUnit unit) { - final byte[] rawKey = rawKey(key); + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.GeoOperations#geoDist(java.lang.Object, java.lang.Object, java.lang.Object, org.springframework.data.geo.Metric) + */ + @Override + public Distance geoDist(K key, M member1, M member2, final Metric metric) { - return execute(new RedisCallback>() { + final byte[] rawKey = rawKey(key); + final byte[] rawMember1 = rawValue(member1); + final byte[] rawMember2 = rawValue(member2); - public List doInRedis(RedisConnection connection) { - return connection.georadius(rawKey, longitude, latitude, radius, unit); - } - }, true); - } + return execute(new RedisCallback() { - @Override - public List georadius(K key, final double longitude, final double latitude, final double radius, final GeoUnit unit, final GeoRadiusParam param) { - final byte[] rawKey = rawKey(key); + public Distance doInRedis(RedisConnection connection) { + return connection.geoDist(rawKey, rawMember1, rawMember2, metric); + } + }, true); + } - return execute(new RedisCallback>() { + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.GeoOperations#geoHash(java.lang.Object, java.lang.Object[]) + */ + @Override + public List geoHash(K key, final M... members) { - public List doInRedis(RedisConnection connection) { - return connection.georadius(rawKey, longitude, latitude, radius, unit, param); - } - }, true); - } + final byte[] rawKey = rawKey(key); + final byte[][] rawMembers = rawValues(members); - @Override - public List georadiusByMember(K key, M member, final double radius, final GeoUnit unit) { - final byte[] rawKey = rawKey(key); - final byte[] rawMember = rawValue(member); + return execute(new RedisCallback>() { - return execute(new RedisCallback>() { + public List doInRedis(RedisConnection connection) { + return connection.geoHash(rawKey, rawMembers); + } + }, true); + } - public List doInRedis(RedisConnection connection) { - return connection.georadiusByMember(rawKey, rawMember, radius, unit); - } - }, true); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.GeoOperations#geoPos(java.lang.Object, java.lang.Object[]) + */ + @Override + public List geoPos(K key, M... members) { + final byte[] rawKey = rawKey(key); + final byte[][] rawMembers = rawValues(members); - @Override - public List georadiusByMember(K key, M member, final double radius, final GeoUnit unit, final GeoRadiusParam param) { - final byte[] rawKey = rawKey(key); - final byte[] rawMember = rawValue(member); + return execute(new RedisCallback>() { - return execute(new RedisCallback>() { + public List doInRedis(RedisConnection connection) { + return connection.geoPos(rawKey, rawMembers); + } + }, true); + } - public List doInRedis(RedisConnection connection) { - return connection.georadiusByMember(rawKey, rawMember, radius, unit, param); - } - }, true); - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.GeoOperations#georadius(java.lang.Object, org.springframework.data.geo.Circle) + */ + @Override + public GeoResults> georadius(K key, final Circle within) { - @Override - public Long geoRemove(K key, M... members) { - final byte[] rawKey = rawKey(key); - final byte[][] rawMembers = rawValues(members); + final byte[] rawKey = rawKey(key); - return execute(new RedisCallback() { + GeoResults> raw = execute(new RedisCallback>>() { - public Long doInRedis(RedisConnection connection) { - return connection.zRem(rawKey, rawMembers); - } - }, true); - } + public GeoResults> doInRedis(RedisConnection connection) { + return connection.geoRadius(rawKey, within); + } + }, true); + + return deserializeGeoResults(raw); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.GeoOperations#georadius(java.lang.Object, org.springframework.data.geo.Circle, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> georadius(K key, final Circle within, final GeoRadiusCommandArgs args) { + + final byte[] rawKey = rawKey(key); + + GeoResults> raw = execute(new RedisCallback>>() { + + public GeoResults> doInRedis(RedisConnection connection) { + return connection.geoRadius(rawKey, within, args); + } + }, true); + + return deserializeGeoResults(raw); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.GeoOperations#georadiusByMember(java.lang.Object, java.lang.Object, double) + */ + @Override + public GeoResults> georadiusByMember(K key, M member, final double radius) { + + final byte[] rawKey = rawKey(key); + final byte[] rawMember = rawValue(member); + GeoResults> raw = execute(new RedisCallback>>() { + + public GeoResults> doInRedis(RedisConnection connection) { + return connection.geoRadiusByMember(rawKey, rawMember, radius); + } + }, true); + + return deserializeGeoResults(raw); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.GeoOperations#georadiusByMember(java.lang.Object, java.lang.Object, org.springframework.data.geo.Distance) + */ + @Override + public GeoResults> georadiusByMember(K key, M member, final Distance distance) { + + final byte[] rawKey = rawKey(key); + final byte[] rawMember = rawValue(member); + + GeoResults> raw = execute(new RedisCallback>>() { + + public GeoResults> doInRedis(RedisConnection connection) { + return connection.geoRadiusByMember(rawKey, rawMember, distance); + } + }, true); + + return deserializeGeoResults(raw); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.GeoOperations#georadiusByMember(java.lang.Object, java.lang.Object, double, org.springframework.data.geo.Metric, org.springframework.data.redis.core.GeoRadiusCommandArgs) + */ + @Override + public GeoResults> georadiusByMember(K key, M member, final Distance distance, + final GeoRadiusCommandArgs param) { + + final byte[] rawKey = rawKey(key); + final byte[] rawMember = rawValue(member); + + GeoResults> raw = execute(new RedisCallback>>() { + + public GeoResults> doInRedis(RedisConnection connection) { + return connection.geoRadiusByMember(rawKey, rawMember, distance, param); + } + }, true); + + return deserializeGeoResults(raw); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.GeoOperations#geoRemove(java.lang.Object, java.lang.Object[]) + */ + @Override + public Long geoRemove(K key, M... members) { + + final byte[] rawKey = rawKey(key); + final byte[][] rawMembers = rawValues(members); + + return execute(new RedisCallback() { + + public Long doInRedis(RedisConnection connection) { + return connection.zRem(rawKey, rawMembers); + } + }, true); + } } diff --git a/src/main/java/org/springframework/data/redis/core/GeoCoordinate.java b/src/main/java/org/springframework/data/redis/core/GeoCoordinate.java deleted file mode 100644 index 504905951..000000000 --- a/src/main/java/org/springframework/data/redis/core/GeoCoordinate.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.springframework.data.redis.core; - -/** - * Created by ndivadkar on 3/29/16. - */ -public class GeoCoordinate { - private double longitude; - private double latitude; - - public GeoCoordinate(double longitude, double latitude) { - this.longitude = longitude; - this.latitude = latitude; - } - - public double getLongitude() { - return longitude; - } - - public double getLatitude() { - return latitude; - } -} diff --git a/src/main/java/org/springframework/data/redis/core/GeoOperations.java b/src/main/java/org/springframework/data/redis/core/GeoOperations.java index 8a2a32206..fabb08e17 100644 --- a/src/main/java/org/springframework/data/redis/core/GeoOperations.java +++ b/src/main/java/org/springframework/data/redis/core/GeoOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2014 the original author or authors. + * Copyright 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. @@ -18,35 +18,172 @@ package org.springframework.data.redis.core; import java.util.List; import java.util.Map; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Point; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs; + /** * Redis operations for geo commands. * * @author Ninad Divadkar + * @author Christoph Strobl + * @see http://redis.io/commands#geo + * @since 1.8 */ public interface GeoOperations { - Long geoAdd(K key, double longitude, double latitude, M member); - Long geoAdd(K key, Map memberCoordinateMap); + /** + * Add {@link Point} with given member {@literal name} to {@literal key}. + * + * @param key must not be {@literal null}. + * @param point must not be {@literal null}. + * @param member must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + */ + Long geoAdd(K key, Point point, M member); - Double geoDist(K key, M member1, M member2); + /** + * Add {@link GeoLocation} to {@literal key}. + * + * @param key must not be {@literal null}. + * @param location must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + */ + Long geoAdd(K key, GeoLocation location); - Double geoDist(K key, M member1, M member2, GeoUnit unit); + /** + * Add {@link Map} of member / {@link Point} pairs to {@literal key}. + * + * @param key must not be {@literal null}. + * @param memberCoordinateMap must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + */ + Long geoAdd(K key, Map memberCoordinateMap); - List geoHash(K key, M... members); + /** + * Add {@link GeoLocation}s to {@literal key} + * + * @param key must not be {@literal null}. + * @param locations must not be {@literal null}. + * @return Number of elements added. + * @see http://redis.io/commands/geoadd + */ + Long geoAdd(K key, Iterable> locations); - List geoPos(K key, M... members); + /** + * Get the {@link Distance} between {@literal member1} and {@literal member2}. + * + * @param key must not be {@literal null}. + * @param member1 must not be {@literal null}. + * @param member2 must not be {@literal null}. + * @return can be {@literal null}. + * @see http://redis.io/commands/geodist + */ + Distance geoDist(K key, M member1, M member2); - List georadius(K key, double longitude, double latitude, - double radius, GeoUnit unit); + /** + * Get the {@link Distance} between {@literal member1} and {@literal member2} in the given {@link Metric}. + * + * @param key must not be {@literal null}. + * @param member1 must not be {@literal null}. + * @param member2 must not be {@literal null}. + * @param metric must not be {@literal null}. + * @return can be {@literal null}. + * @see http://redis.io/commands/geodist + */ + Distance geoDist(K key, M member1, M member2, Metric metric); - List georadius(K key, double longitude, double latitude, - double radius, GeoUnit unit, GeoRadiusParam param); + /** + * Get Geohash representation of the position for one or more {@literal member}s. + * + * @param key must not be {@literal null}. + * @param members must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/geohash + */ + List geoHash(K key, M... members); - List georadiusByMember(K key, M member, double radius, - GeoUnit unit); + /** + * Get the {@link Point} representation of positions for one or more {@literal member}s. + * + * @param key must not be {@literal null}. + * @param members must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/geopos + */ + List geoPos(K key, M... members); - List georadiusByMember(K key, M member, double radius, - GeoUnit unit, GeoRadiusParam param); + /** + * Get the {@literal member}s within the boundaries of a given {@link Circle}. + * + * @param key must not be {@literal null}. + * @param within must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadius + */ + GeoResults> georadius(K key, Circle within); - Long geoRemove(K key, M... members); + /** + * Get the {@literal member}s within the boundaries of a given {@link Circle} applying {@link GeoRadiusCommandArgs}. + * + * @param key must not be {@literal null}. + * @param within must not be {@literal null}. + * @param args must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadius + */ + GeoResults> georadius(K key, Circle within, GeoRadiusCommandArgs args); + + /** + * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given + * {@literal radius}. + * + * @param key must not be {@literal null}. + * @param member must not be {@literal null}. + * @param radius + * @return never {@literal null}. + * @see http://redis.io/commands/georadiusbymember + */ + GeoResults> georadiusByMember(K key, M member, double radius); + + /** + * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given + * {@literal radius} applying {@link Metric}. + * + * @param key must not be {@literal null}. + * @param member must not be {@literal null}. + * @param distance must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadiusbymember + */ + GeoResults> georadiusByMember(K key, M member, Distance distance); + + /** + * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given + * {@literal radius} applying {@link Metric} and {@link GeoRadiusCommandArgs}. + * + * @param key must not be {@literal null}. + * @param member must not be {@literal null}. + * @param distance must not be {@literal null}. + * @param args must not be {@literal null}. + * @return never {@literal null}. + * @see http://redis.io/commands/georadiusbymember + */ + GeoResults> georadiusByMember(K key, M member, Distance distance, GeoRadiusCommandArgs args); + + /** + * Remove the {@literal member}s. + * + * @param key must not be {@literal null}. + * @param members must not be {@literal null}. + * @return Number of elements removed. + */ + Long geoRemove(K key, M... members); } diff --git a/src/main/java/org/springframework/data/redis/core/GeoOperationsEditor.java b/src/main/java/org/springframework/data/redis/core/GeoOperationsEditor.java index e36a02364..8e0bc3353 100644 --- a/src/main/java/org/springframework/data/redis/core/GeoOperationsEditor.java +++ b/src/main/java/org/springframework/data/redis/core/GeoOperationsEditor.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013 the original author or authors. + * Copyright 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. @@ -18,13 +18,16 @@ package org.springframework.data.redis.core; import java.beans.PropertyEditorSupport; /** - * PropertyEditor allowing for easy injection of {@link org.springframework.data.redis.core.GeoOperations} from {@link org.springframework.data.redis.core.RedisOperations}. + * PropertyEditor allowing for easy injection of {@link org.springframework.data.redis.core.GeoOperations} from + * {@link org.springframework.data.redis.core.RedisOperations}. * * @author Ninad Divadkar + * @author Christoph Strobl */ class GeoOperationsEditor extends PropertyEditorSupport { public void setValue(Object value) { + if (value instanceof RedisOperations) { super.setValue(((RedisOperations) value).opsForGeo()); } else { diff --git a/src/main/java/org/springframework/data/redis/core/GeoRadiusParam.java b/src/main/java/org/springframework/data/redis/core/GeoRadiusParam.java deleted file mode 100644 index 4ecd887c0..000000000 --- a/src/main/java/org/springframework/data/redis/core/GeoRadiusParam.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.springframework.data.redis.core; - -import java.util.HashMap; -import java.util.Map; - -/** - * Created by ndivadkar on 3/29/16. - */ -public class GeoRadiusParam { - private static final String WITHCOORD = "withcoord"; - private static final String WITHDIST = "withdist"; - private static final String ASC = "asc"; - private static final String DESC = "desc"; - private static final String COUNT = "count"; - - private Map params; - private GeoRadiusParam() { - } - - public static GeoRadiusParam geoRadiusParam() { - return new GeoRadiusParam(); - } - - public GeoRadiusParam withCoord() { - addParam(WITHCOORD); - return this; - } - - public GeoRadiusParam withDist() { - addParam(WITHDIST); - return this; - } - - public GeoRadiusParam sortAscending() { - addParam(ASC); - return this; - } - - public GeoRadiusParam sortDescending() { - addParam(DESC); - return this; - } - - public GeoRadiusParam count(int count) { - if (count > 0) { - addParam(COUNT, count); - } - return this; - } - - protected void addParam(String name, Object value) { - if (params == null) { - params = new HashMap(); - } - params.put(name, value); - } - - protected void addParam(String name) { - if (params == null) { - params = new HashMap(); - } - params.put(name, null); - } - - public Map getParams() { - return params; - } - - public static String getWITHCOORD() { - return WITHCOORD; - } - - public static String getWITHDIST() { - return WITHDIST; - } - - public static String getASC() { - return ASC; - } - - public static String getDESC() { - return DESC; - } - - public static String getCOUNT() { - return COUNT; - } -} diff --git a/src/main/java/org/springframework/data/redis/core/GeoRadiusResponse.java b/src/main/java/org/springframework/data/redis/core/GeoRadiusResponse.java deleted file mode 100644 index 8da66467d..000000000 --- a/src/main/java/org/springframework/data/redis/core/GeoRadiusResponse.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.springframework.data.redis.core; - -/** - * Created by ndivadkar on 4/1/16. - */ -public class GeoRadiusResponse { - private byte[] member; - private double distance; - private GeoCoordinate coordinate; - - public GeoRadiusResponse(byte[] member) { - this.member = member; - } - - public void setDistance(double distance) { - this.distance = distance; - } - - public void setCoordinate(GeoCoordinate coordinate) { - this.coordinate = coordinate; - } - - public byte[] getMember() { - return member; - } - - public double getDistance() { - return distance; - } - - public GeoCoordinate getCoordinate() { - return coordinate; - } -} diff --git a/src/main/java/org/springframework/data/redis/core/GeoUnit.java b/src/main/java/org/springframework/data/redis/core/GeoUnit.java deleted file mode 100644 index d31918d4a..000000000 --- a/src/main/java/org/springframework/data/redis/core/GeoUnit.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.springframework.data.redis.core; - -/** - * Created by ndivadkar on 3/29/16. - */ -public enum GeoUnit { - Meters, - KiloMeters, - Miles, - Feet; -} diff --git a/src/main/java/org/springframework/data/redis/core/RedisCommand.java b/src/main/java/org/springframework/data/redis/core/RedisCommand.java index 8f006c817..0d7363ff8 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisCommand.java +++ b/src/main/java/org/springframework/data/redis/core/RedisCommand.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -28,6 +28,7 @@ import org.springframework.util.StringUtils; /** * @author Christoph Strobl * @author Thomas Darimont + * @author Ninad Divadkar * @since 1.3 * @see Redis command list: * https://github.com/antirez/redis/blob/93e7a130fc9594e41ccfc996b5eca7626ae5356a/src/redis.c#L119 @@ -78,7 +79,12 @@ public enum RedisCommand { GETBIT("r", 2, 2), // GETRANGE("r", 3, 3), // GETSET("rw", 2, 2), // - GEOADD("w", 3, 2), + GEOADD("w", 3), // + GEODIST("r", 2), // + GEOHASH("r", 2), // + GEOPOS("r", 2), // + GEORADIUS("r", 4), // + GEORADIUSBYMEMBER("r", 3), // -- H HDEL("rw", 2), // HEXISTS("r", 2, 2), // @@ -332,13 +338,13 @@ public enum RedisCommand { if (requiresArguments()) { if (requiresExactNumberOfArguments()) { if (nrArguments != maxArgs) { - throw new IllegalArgumentException(String.format("%s command requires %s arguments.", this.name(), - this.maxArgs)); + throw new IllegalArgumentException( + String.format("%s command requires %s arguments.", this.name(), this.maxArgs)); } } if (nrArguments < minArgs) { - throw new IllegalArgumentException(String.format("%s command requires at least %s arguments.", this.name(), - this.minArgs)); + throw new IllegalArgumentException( + String.format("%s command requires at least %s arguments.", this.name(), this.minArgs)); } } } diff --git a/src/main/java/org/springframework/data/redis/core/RedisOperations.java b/src/main/java/org/springframework/data/redis/core/RedisOperations.java index 0a827c347..74d9d15ee 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisOperations.java +++ b/src/main/java/org/springframework/data/redis/core/RedisOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2015 the original author or authors. + * Copyright 2011-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. @@ -33,6 +33,7 @@ import org.springframework.data.redis.serializer.RedisSerializer; * * @author Costin Leau * @author Christoph Strobl + * @author Ninad Divadkar */ public interface RedisOperations { @@ -283,20 +284,22 @@ public interface RedisOperations { */ BoundHashOperations boundHashOps(K key); - /** - * Returns the operations performed on geo values. - * - * @return geo operations - */ - GeoOperations opsForGeo(); + /** + * Returns geospatial specific operations interface. + * + * @return never {@literal null}. + * @since 1.8 + */ + GeoOperations opsForGeo(); - /** - * Returns the operations performed on values bound to the given key. - * - * @param key Redis key - * @return geo operations bound to the given key. - */ - BoundGeoOperations boundGeoOps(K key); + /** + * Returns geospatial specific operations interface bound to the given key. + * + * @param key must not be {@literal null}. + * @return never {@literal null}. + * @since 1.8 + */ + BoundGeoOperations boundGeoOps(K key); /** * Returns the cluster specific operations interface. diff --git a/src/main/java/org/springframework/data/redis/core/RedisTemplate.java b/src/main/java/org/springframework/data/redis/core/RedisTemplate.java index af16e0e18..83e02d326 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisTemplate.java +++ b/src/main/java/org/springframework/data/redis/core/RedisTemplate.java @@ -72,6 +72,7 @@ import org.springframework.util.CollectionUtils; * * @author Costin Leau * @author Christoph Strobl + * @author Ninad Divadkar * @param the Redis key type against which the template works (usually a String) * @param the Redis value type against which the template works * @see StringRedisTemplate @@ -98,7 +99,7 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation private ListOperations listOps; private SetOperations setOps; private ZSetOperations zSetOps; - private GeoOperations geoOps; + private GeoOperations geoOps; private HyperLogLogOperations hllOps; /** @@ -1007,23 +1008,32 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation return zSetOps; } - @Override - public GeoOperations opsForGeo() { - if (geoOps == null) { - geoOps = new DefaultGeoOperations(this); - } - return geoOps; - } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.RedisOperations#opsForGeo() + */ + @Override + public GeoOperations opsForGeo() { - @Override - public BoundGeoOperations boundGeoOps(K key) { - return new DefaultBoundGeoOperations(key, this); - } + if (geoOps == null) { + geoOps = new DefaultGeoOperations(this); + } + return geoOps; + } - /* - * (non-Javadoc) - * @see org.springframework.data.redis.core.RedisOperations#opsForHyperLogLog() - */ + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.RedisOperations#boundGeoOps(java.lang.Object) + */ + @Override + public BoundGeoOperations boundGeoOps(K key) { + return new DefaultBoundGeoOperations(key, this); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.core.RedisOperations#opsForHyperLogLog() + */ @Override public HyperLogLogOperations opsForHyperLogLog() { diff --git a/src/test/java/org/springframework/data/redis/RedisTestProfileValueSource.java b/src/test/java/org/springframework/data/redis/RedisTestProfileValueSource.java index 598707150..02a207f60 100644 --- a/src/test/java/org/springframework/data/redis/RedisTestProfileValueSource.java +++ b/src/test/java/org/springframework/data/redis/RedisTestProfileValueSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2015 the original author or authors. + * Copyright 2011-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. @@ -39,6 +39,7 @@ public class RedisTestProfileValueSource implements ProfileValueSource { private static final String REDIS_26 = "2.6"; private static final String REDIS_28 = "2.8"; private static final String REDIS_30 = "3.0"; + private static final String REDIS_32 = "3.2"; private static final String REDIS_VERSION_KEY = "redisVersion"; private static RedisTestProfileValueSource INSTANCE; @@ -95,6 +96,10 @@ public class RedisTestProfileValueSource implements ProfileValueSource { return System.getProperty(key); } + if (redisVersion.compareTo(RedisVersionUtils.parseVersion(REDIS_32)) >= 0) { + return REDIS_32; + } + if (redisVersion.compareTo(RedisVersionUtils.parseVersion(REDIS_30)) >= 0) { return REDIS_30; } diff --git a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java index 513281a53..976416d79 100644 --- a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java @@ -16,10 +16,14 @@ package org.springframework.data.redis.connection; import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.collection.IsCollectionWithSize.*; +import static org.hamcrest.core.Is.is; import static org.hamcrest.number.IsCloseTo.*; import static org.junit.Assert.*; import static org.junit.Assume.*; import static org.springframework.data.redis.SpinBarrier.*; +import static org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit.*; +import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.*; import static org.springframework.data.redis.core.ScanOptions.*; import java.util.ArrayList; @@ -48,10 +52,16 @@ import org.junit.Test; import org.junit.internal.AssumptionViolatedException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metrics; +import org.springframework.data.geo.Point; import org.springframework.data.redis.RedisSystemException; import org.springframework.data.redis.RedisTestProfileValueSource; import org.springframework.data.redis.RedisVersionUtils; import org.springframework.data.redis.TestCondition; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; import org.springframework.data.redis.connection.RedisListCommands.Position; import org.springframework.data.redis.connection.RedisStringCommands.BitOperation; import org.springframework.data.redis.connection.RedisStringCommands.SetOption; @@ -86,6 +96,14 @@ import org.springframework.test.annotation.ProfileValueSourceConfiguration; @ProfileValueSourceConfiguration(RedisTestProfileValueSource.class) public abstract class AbstractConnectionIntegrationTests { + private static final Point POINT_ARIGENTO = new Point(13.583333, 37.316667); + private static final Point POINT_CATANIA = new Point(15.087269, 37.502669); + private static final Point POINT_PALERMO = new Point(13.361389, 38.115556); + + private static final GeoLocation ARIGENTO = new GeoLocation("arigento", POINT_ARIGENTO); + private static final GeoLocation CATANIA = new GeoLocation("catania", POINT_CATANIA); + private static final GeoLocation PALERMO = new GeoLocation("palermo", POINT_PALERMO); + protected StringRedisConnection connection; protected RedisSerializer serializer = new JdkSerializationRedisSerializer(); protected RedisSerializer stringSerializer = new StringRedisSerializer(); @@ -1219,7 +1237,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.rPush("PopList", "world")); connection.lSet("PopList", 1, "cruel"); actual.add(connection.lRange("PopList", 0, -1)); - verifyResults(Arrays.asList(new Object[] { 1l, 2l, 3l, Arrays.asList(new String[] { "hello", "cruel", "world" }) })); + verifyResults( + Arrays.asList(new Object[] { 1l, 2l, 3l, Arrays.asList(new String[] { "hello", "cruel", "world" }) })); } @Test @@ -1318,8 +1337,8 @@ 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[] { 1l, 1l, - new HashSet(Arrays.asList(new String[] { "foo", "bar" })) })); + verifyResults( + Arrays.asList(new Object[] { 1l, 1l, new HashSet(Arrays.asList(new String[] { "foo", "bar" })) })); } @Test @@ -1327,8 +1346,8 @@ public abstract class AbstractConnectionIntegrationTests { 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(Arrays.asList(new String[] { "foo", "bar", "baz" })) })); + verifyResults(Arrays + .asList(new Object[] { 2l, 1l, new HashSet(Arrays.asList(new String[] { "foo", "bar", "baz" })) })); } @Test @@ -1355,7 +1374,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.sAdd("otherset", "bar")); actual.add(connection.sDiffStore("thirdset", "myset", "otherset")); actual.add(connection.sMembers("thirdset")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, 1l, new HashSet(Collections.singletonList("foo")) })); + verifyResults( + Arrays.asList(new Object[] { 1l, 1l, 1l, 1l, new HashSet(Collections.singletonList("foo")) })); } @Test @@ -1374,7 +1394,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.sAdd("otherset", "bar")); actual.add(connection.sInterStore("thirdset", "myset", "otherset")); actual.add(connection.sMembers("thirdset")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, 1l, new HashSet(Collections.singletonList("bar")) })); + verifyResults( + Arrays.asList(new Object[] { 1l, 1l, 1l, 1l, new HashSet(Collections.singletonList("bar")) })); } @Test @@ -1400,7 +1421,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.sAdd("myset", "foo")); actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sPop("myset")); - assertTrue(new HashSet(Arrays.asList(new String[] { "foo", "bar" })).contains((String) getResults().get(2))); + assertTrue( + new HashSet(Arrays.asList(new String[] { "foo", "bar" })).contains((String) getResults().get(2))); } @Test @@ -1408,7 +1430,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.sAdd("myset", "foo")); actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sRandMember("myset")); - assertTrue(new HashSet(Arrays.asList(new String[] { "foo", "bar" })).contains((String) getResults().get(2))); + assertTrue( + new HashSet(Arrays.asList(new String[] { "foo", "bar" })).contains((String) getResults().get(2))); } @Test @@ -1452,7 +1475,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.sRem("myset", "foo")); actual.add(connection.sRem("myset", "baz")); actual.add(connection.sMembers("myset")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, 0l, new HashSet(Collections.singletonList("bar")) })); + verifyResults( + Arrays.asList(new Object[] { 1l, 1l, 1l, 0l, new HashSet(Collections.singletonList("bar")) })); } @Test @@ -1462,7 +1486,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.sAdd("myset", "baz")); actual.add(connection.sRem("myset", "foo", "nope", "baz")); actual.add(connection.sMembers("myset")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, 2l, new HashSet(Collections.singletonList("bar")) })); + verifyResults( + Arrays.asList(new Object[] { 1l, 1l, 1l, 2l, new HashSet(Collections.singletonList("bar")) })); } @Test @@ -1472,8 +1497,8 @@ 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[] { 1l, 1l, 1l, 1l, - new HashSet(Arrays.asList(new String[] { "foo", "bar", "baz" })) })); + verifyResults(Arrays.asList( + new Object[] { 1l, 1l, 1l, 1l, new HashSet(Arrays.asList(new String[] { "foo", "bar", "baz" })) })); } @Test @@ -1484,8 +1509,8 @@ 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[] { 1l, 1l, 1l, 1l, 3l, - new HashSet(Arrays.asList(new String[] { "foo", "bar", "baz" })) })); + verifyResults(Arrays.asList( + new Object[] { 1l, 1l, 1l, 1l, 3l, new HashSet(Arrays.asList(new String[] { "foo", "bar", "baz" })) })); } // ZSet @@ -1495,8 +1520,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRange("myset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { true, true, - new LinkedHashSet(Arrays.asList(new String[] { "James", "Bob" })) })); + verifyResults(Arrays.asList( + new Object[] { true, true, new LinkedHashSet(Arrays.asList(new String[] { "James", "Bob" })) })); } @Test @@ -1509,8 +1534,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset", strTuples)); actual.add(connection.zAdd("myset".getBytes(), tuples)); actual.add(connection.zRange("myset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { 2l, 1l, - new LinkedHashSet(Arrays.asList(new String[] { "James", "Bob", "Joe" })) })); + verifyResults(Arrays.asList( + new Object[] { 2l, 1l, new LinkedHashSet(Arrays.asList(new String[] { "James", "Bob", "Joe" })) })); } @Test @@ -1537,8 +1562,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset", 4, "Joe")); actual.add(connection.zIncrBy("myset", 2, "Joe")); actual.add(connection.zRangeByScore("myset", 6, 6)); - verifyResults(Arrays.asList(new Object[] { true, true, true, 6d, - new LinkedHashSet(Collections.singletonList("Joe")) })); + verifyResults(Arrays + .asList(new Object[] { true, true, true, 6d, new LinkedHashSet(Collections.singletonList("Joe")) })); } @Test @@ -1564,16 +1589,10 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zInterStore("thirdset", Aggregate.MAX, new int[] { 2, 3 }, "myset", "otherset")); actual.add(connection.zRangeWithScores("thirdset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { - true, - true, - true, - true, - true, - 2l, - new LinkedHashSet(Arrays.asList(new StringTuple[] { - new DefaultStringTuple("Bob".getBytes(), "Bob", 4d), - new DefaultStringTuple("James".getBytes(), "James", 12d) })) })); + verifyResults(Arrays.asList(new Object[] { true, true, true, true, true, 2l, + new LinkedHashSet( + Arrays.asList(new StringTuple[] { new DefaultStringTuple("Bob".getBytes(), "Bob", 4d), + new DefaultStringTuple("James".getBytes(), "James", 12d) })) })); } @Test @@ -1581,12 +1600,10 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRangeWithScores("myset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { - true, - true, - new LinkedHashSet(Arrays.asList(new StringTuple[] { - new DefaultStringTuple("James".getBytes(), "James", 1d), - new DefaultStringTuple("Bob".getBytes(), "Bob", 2d) })) })); + verifyResults(Arrays.asList(new Object[] { true, true, + new LinkedHashSet( + Arrays.asList(new StringTuple[] { new DefaultStringTuple("James".getBytes(), "James", 1d), + new DefaultStringTuple("Bob".getBytes(), "Bob", 2d) })) })); } @Test @@ -1594,8 +1611,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRangeByScore("myset", 1, 1)); - verifyResults(Arrays.asList(new Object[] { true, true, - new LinkedHashSet(Arrays.asList(new String[] { "James" })) })); + verifyResults( + Arrays.asList(new Object[] { true, true, new LinkedHashSet(Arrays.asList(new String[] { "James" })) })); } @Test @@ -1603,8 +1620,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRangeByScore("myset", 1d, 3d, 1, -1)); - verifyResults(Arrays.asList(new Object[] { true, true, - new LinkedHashSet(Arrays.asList(new String[] { "Bob" })) })); + verifyResults( + Arrays.asList(new Object[] { true, true, new LinkedHashSet(Arrays.asList(new String[] { "Bob" })) })); } @Test @@ -1612,11 +1629,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRangeByScoreWithScores("myset", 2d, 5d)); - verifyResults(Arrays.asList(new Object[] { - true, - true, - new LinkedHashSet(Arrays.asList(new StringTuple[] { new DefaultStringTuple("Bob".getBytes(), - "Bob", 2d) })) })); + verifyResults(Arrays.asList(new Object[] { true, true, new LinkedHashSet( + Arrays.asList(new StringTuple[] { new DefaultStringTuple("Bob".getBytes(), "Bob", 2d) })) })); } @Test @@ -1624,11 +1638,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRangeByScoreWithScores("myset", 1d, 5d, 0, 1)); - verifyResults(Arrays.asList(new Object[] { - true, - true, - new LinkedHashSet(Arrays.asList(new StringTuple[] { new DefaultStringTuple("James".getBytes(), - "James", 1d) })) })); + verifyResults(Arrays.asList(new Object[] { true, true, new LinkedHashSet( + Arrays.asList(new StringTuple[] { new DefaultStringTuple("James".getBytes(), "James", 1d) })) })); } @Test @@ -1636,8 +1647,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRevRange("myset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { true, true, - new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James" })) })); + verifyResults(Arrays.asList( + new Object[] { true, true, new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James" })) })); } @Test @@ -1645,12 +1656,10 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRevRangeWithScores("myset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { - true, - true, - new LinkedHashSet(Arrays.asList(new StringTuple[] { - new DefaultStringTuple("Bob".getBytes(), "Bob", 2d), - new DefaultStringTuple("James".getBytes(), "James", 1d) })) })); + verifyResults(Arrays.asList(new Object[] { true, true, + new LinkedHashSet( + Arrays.asList(new StringTuple[] { new DefaultStringTuple("Bob".getBytes(), "Bob", 2d), + new DefaultStringTuple("James".getBytes(), "James", 1d) })) })); } @Test @@ -1658,8 +1667,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); actual.add(connection.zAdd("myset".getBytes(), 1, "James".getBytes())); actual.add(connection.zRevRangeByScore("myset", 0d, 3d, 0, 5)); - verifyResults(Arrays.asList(new Object[] { true, true, - new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James" })) })); + verifyResults(Arrays.asList( + new Object[] { true, true, new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James" })) })); } @Test @@ -1667,8 +1676,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); actual.add(connection.zAdd("myset".getBytes(), 1, "James".getBytes())); actual.add(connection.zRevRangeByScore("myset", 0d, 3d)); - verifyResults(Arrays.asList(new Object[] { true, true, - new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James" })) })); + verifyResults(Arrays.asList( + new Object[] { true, true, new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James" })) })); } @Test @@ -1676,11 +1685,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); actual.add(connection.zAdd("myset".getBytes(), 1, "James".getBytes())); actual.add(connection.zRevRangeByScoreWithScores("myset", 0d, 3d, 0, 1)); - verifyResults(Arrays.asList(new Object[] { - true, - true, - new LinkedHashSet(Arrays.asList(new StringTuple[] { new DefaultStringTuple("Bob".getBytes(), - "Bob", 2d) })) })); + verifyResults(Arrays.asList(new Object[] { true, true, new LinkedHashSet( + Arrays.asList(new StringTuple[] { new DefaultStringTuple("Bob".getBytes(), "Bob", 2d) })) })); } @Test @@ -1689,13 +1695,10 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zAdd("myset", 3, "Joe")); actual.add(connection.zRevRangeByScoreWithScores("myset", 0d, 2d)); - verifyResults(Arrays.asList(new Object[] { - true, - true, - true, - new LinkedHashSet(Arrays.asList(new StringTuple[] { - new DefaultStringTuple("Bob".getBytes(), "Bob", 2d), - new DefaultStringTuple("James".getBytes(), "James", 1d) })) })); + verifyResults(Arrays.asList(new Object[] { true, true, true, + new LinkedHashSet( + Arrays.asList(new StringTuple[] { new DefaultStringTuple("Bob".getBytes(), "Bob", 2d), + new DefaultStringTuple("James".getBytes(), "James", 1d) })) })); } @Test @@ -1713,8 +1716,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRem("myset", "James")); actual.add(connection.zRange("myset", 0l, -1l)); - verifyResults(Arrays.asList(new Object[] { true, true, 1l, - new LinkedHashSet(Arrays.asList(new String[] { "Bob" })) })); + verifyResults(Arrays + .asList(new Object[] { true, true, 1l, new LinkedHashSet(Arrays.asList(new String[] { "Bob" })) })); } @Test @@ -1744,8 +1747,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRemRangeByScore("myset", 0d, 1d)); actual.add(connection.zRange("myset", 0l, -1l)); - verifyResults(Arrays.asList(new Object[] { true, true, 1l, - new LinkedHashSet(Arrays.asList(new String[] { "Bob" })) })); + verifyResults(Arrays + .asList(new Object[] { true, true, 1l, new LinkedHashSet(Arrays.asList(new String[] { "Bob" })) })); } @Test @@ -1788,13 +1791,7 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.zAdd("otherset", 4, "James")); actual.add(connection.zUnionStore("thirdset", Aggregate.MAX, new int[] { 2, 3 }, "myset", "otherset")); actual.add(connection.zRangeWithScores("thirdset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { - true, - true, - true, - true, - true, - 3l, + verifyResults(Arrays.asList(new Object[] { true, true, true, true, true, 3l, new LinkedHashSet(Arrays.asList(new StringTuple[] { new DefaultStringTuple("Bob".getBytes(), "Bob", 4d), new DefaultStringTuple("Joe".getBytes(), "Joe", 8d), new DefaultStringTuple("James".getBytes(), "James", 12d) })) })); @@ -1868,8 +1865,8 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.hSet("test", "key", "2")); actual.add(connection.hSet("test", "key2", "2")); actual.add(connection.hKeys("test")); - verifyResults(Arrays.asList(new Object[] { true, true, - new LinkedHashSet(Arrays.asList(new String[] { "key", "key2" })) })); + verifyResults(Arrays + .asList(new Object[] { true, true, new LinkedHashSet(Arrays.asList(new String[] { "key", "key2" })) })); } @Test @@ -2098,8 +2095,8 @@ public abstract class AbstractConnectionIntegrationTests { connection.hSet("hscankey", "foo-2", "v-2"); connection.hSet("hscankey", "foo-3", "v-3"); - Cursor> cursor = connection - .hScan("hscankey", scanOptions().count(2).match("fo*").build()); + Cursor> cursor = connection.hScan("hscankey", + scanOptions().count(2).match("fo*").build()); int i = 0; while (cursor.hasNext()) { @@ -2509,6 +2506,269 @@ public abstract class AbstractConnectionIntegrationTests { assertThat(((Long) result.get(1)).doubleValue(), is(closeTo(-2, 0))); } + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE }) + public void geoAddSingleGeoLocation() { + + String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, PALERMO)); + + List result = getResults(); + assertThat((Long) result.get(0), is(1L)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE }) + public void geoAddMultipleGeoLocations() { + + String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, ARIGENTO, CATANIA, PALERMO))); + + List result = getResults(); + assertThat((Long) result.get(0), is(3L)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE }) + public void geoDist() { + + String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, CATANIA))); + actual.add(connection.geoDist(key, PALERMO.getName(), CATANIA.getName())); + + List result = getResults(); + assertThat(((Distance) result.get(1)).getValue(), is(closeTo(166274.15156960033D, 0.005))); + assertThat(((Distance) result.get(1)).getUnit(), is("m")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE }) + public void geoDistWithMetric() { + + String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, CATANIA))); + actual.add(connection.geoDist(key, PALERMO.getName(), CATANIA.getName(), Metrics.KILOMETERS)); + + List result = getResults(); + assertThat(((Distance) result.get(1)).getValue(), is(closeTo(166.27415156960033D, 0.005))); + assertThat(((Distance) result.get(1)).getUnit(), is("km")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @WithRedisDriver({ RedisDriver.JEDIS }) + public void geoHash() { + + String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, CATANIA))); + actual.add(connection.geoHash(key, PALERMO.getName(), CATANIA.getName())); + + List result = getResults(); + assertThat(((List) result.get(1)).get(0), is("sqc8b49rny0")); + assertThat(((List) result.get(1)).get(1), is("sqdtr74hyu0")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @WithRedisDriver({ RedisDriver.JEDIS }) + public void geoHashNonExisting() { + + String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, CATANIA))); + actual.add(connection.geoHash(key, PALERMO.getName(), ARIGENTO.getName(), CATANIA.getName())); + + List result = getResults(); + assertThat(((List) result.get(1)).get(0), is("sqc8b49rny0")); + assertThat(((List) result.get(1)).get(1), is(nullValue())); + assertThat(((List) result.get(1)).get(2), is("sqdtr74hyu0")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE }) + public void geoPosition() { + + String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, CATANIA))); + + actual.add(connection.geoPos(key, PALERMO.getName(), CATANIA.getName())); + + List result = getResults(); + assertThat(((List) result.get(1)).get(0).getX(), is(closeTo(POINT_PALERMO.getX(), 0.005))); + assertThat(((List) result.get(1)).get(0).getY(), is(closeTo(POINT_PALERMO.getY(), 0.005))); + + assertThat(((List) result.get(1)).get(1).getX(), is(closeTo(POINT_CATANIA.getX(), 0.005))); + assertThat(((List) result.get(1)).get(1).getY(), is(closeTo(POINT_CATANIA.getY(), 0.005))); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE }) + public void geoPositionNonExisting() { + + String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, CATANIA))); + + actual.add(connection.geoPos(key, PALERMO.getName(), ARIGENTO.getName(), CATANIA.getName())); + + List result = getResults(); + assertThat(((List) result.get(1)).get(0).getX(), is(closeTo(POINT_PALERMO.getX(), 0.005))); + assertThat(((List) result.get(1)).get(0).getY(), is(closeTo(POINT_PALERMO.getY(), 0.005))); + + assertThat(((List) result.get(1)).get(1), is(nullValue())); + + assertThat(((List) result.get(1)).get(2).getX(), is(closeTo(POINT_CATANIA.getX(), 0.005))); + assertThat(((List) result.get(1)).get(2).getY(), is(closeTo(POINT_CATANIA.getY(), 0.005))); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE }) + public void geoRadiusShouldReturnMembersCorrectly() { + + String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + + actual.add(connection.georadius(key, new Circle(new Point(15D, 37D), new Distance(200D, KILOMETERS)))); + actual.add(connection.georadius(key, new Circle(new Point(15D, 37D), new Distance(150D, KILOMETERS)))); + + List results = getResults(); + assertThat(((GeoResults>) results.get(1)).getContent(), hasSize(3)); + assertThat(((GeoResults>) results.get(2)).getContent(), hasSize(2)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE }) + public void geoRadiusShouldReturnDistanceCorrectly() { + + String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + + actual.add(connection.georadius(key, new Circle(new Point(15D, 37D), new Distance(200D, KILOMETERS)), + newGeoRadiusArgs().includeDistance())); + + List results = getResults(); + assertThat(((GeoResults>) results.get(1)).getContent(), hasSize(3)); + assertThat(((GeoResults>) results.get(1)).getContent().get(0).getDistance().getValue(), + is(closeTo(130.423D, 0.005))); + assertThat(((GeoResults>) results.get(1)).getContent().get(0).getDistance().getUnit(), + is("km")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE }) + public void geoRadiusShouldApplyLimit() { + + String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + + actual.add(connection.georadius(key, new Circle(new Point(15D, 37D), new Distance(200D, KILOMETERS)), + newGeoRadiusArgs().limit(2))); + + List results = getResults(); + assertThat(((GeoResults>) results.get(1)).getContent(), hasSize(2)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE }) + public void geoRadiusByMemberShouldReturnMembersCorrectly() { + + String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + + actual.add(connection.georadiusByMember(key, PALERMO.getName(), new Distance(100, KILOMETERS), + newGeoRadiusArgs().sortAscending())); + + List results = getResults(); + assertThat(((GeoResults>) results.get(1)).getContent().get(0).getContent().getName(), + is(PALERMO.getName())); + assertThat(((GeoResults>) results.get(1)).getContent().get(1).getContent().getName(), + is(ARIGENTO.getName())); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE }) + public void geoRadiusByMemberShouldReturnDistanceCorrectly() { + + String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + + actual.add(connection.georadiusByMember(key, PALERMO.getName(), new Distance(100, KILOMETERS), + newGeoRadiusArgs().includeDistance())); + + List results = getResults(); + assertThat(((GeoResults>) results.get(1)).getContent(), hasSize(2)); + assertThat(((GeoResults>) results.get(1)).getContent().get(0).getDistance().getValue(), + is(closeTo(90.978D, 0.005))); + assertThat(((GeoResults>) results.get(1)).getContent().get(0).getDistance().getUnit(), + is("km")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE }) + public void geoRadiusByMemberShouldApplyLimit() { + + String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + + actual.add(connection.georadiusByMember(key, PALERMO.getName(), new Distance(200, KILOMETERS), + newGeoRadiusArgs().limit(2))); + + List results = getResults(); + assertThat(((GeoResults>) results.get(1)).getContent(), hasSize(2)); + } + protected void verifyResults(List expected) { assertEquals(expected, getResults()); } diff --git a/src/test/java/org/springframework/data/redis/connection/ClusterConnectionTests.java b/src/test/java/org/springframework/data/redis/connection/ClusterConnectionTests.java index bfb292734..feb5ae59c 100644 --- a/src/test/java/org/springframework/data/redis/connection/ClusterConnectionTests.java +++ b/src/test/java/org/springframework/data/redis/connection/ClusterConnectionTests.java @@ -15,11 +15,17 @@ */ package org.springframework.data.redis.connection; +import org.springframework.data.geo.Point; + /** * @author Christoph Strobl */ public interface ClusterConnectionTests { + static final Point POINT_ARIGENTO = new Point(13.583333, 37.316667); + static final Point POINT_CATANIA = new Point(15.087269, 37.502669); + static final Point POINT_PALERMO = new Point(13.361389, 38.115556); + /** * @see DATAREDIS-315 */ @@ -946,4 +952,78 @@ public interface ClusterConnectionTests { */ void setWithExpirationAndIfPresentShouldNotBeAppliedWhenKeyDoesNotExists(); + /** + * @see DATAREDIS-438 + */ + void geoAddSingleGeoLocation(); + + /** + * @see DATAREDIS-438 + */ + void geoAddMultipleGeoLocations(); + + /** + * @see DATAREDIS-438 + */ + void geoDist(); + + /** + * @see DATAREDIS-438 + */ + void geoDistWithMetric(); + + /** + * @see DATAREDIS-438 + */ + void geoHash(); + + /** + * @see DATAREDIS-438 + */ + void geoHashNonExisting(); + + /** + * @see DATAREDIS-438 + */ + void geoPosition(); + + /** + * @see DATAREDIS-438 + */ + void geoPositionNonExisting(); + + /** + * @see DATAREDIS-438 + */ + void geoRadiusShouldReturnMembersCorrectly(); + + /** + * @see DATAREDIS-438 + */ + void geoRadiusShouldReturnDistanceCorrectly(); + + /** + * @see DATAREDIS-438 + */ + void geoRadiusShouldApplyLimit(); + + /** + * @see DATAREDIS-438 + */ + void geoRadiusByMemberShouldReturnMembersCorrectly(); + + /** + * @see DATAREDIS-438 + */ + void geoRadiusByMemberShouldReturnDistanceCorrectly(); + + /** + * @see DATAREDIS-438 + */ + void geoRadiusByMemberShouldApplyLimit(); + + /** + * @see DATAREDIS-438 + */ + void geoRemoveDeletesMembers(); } diff --git a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTests.java b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTests.java index bfce657df..fa46b76c0 100644 --- a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTests.java +++ b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-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. @@ -17,16 +17,22 @@ package org.springframework.data.redis.connection; import static org.mockito.Mockito.*; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Properties; import org.junit.Before; import org.junit.Test; +import org.springframework.data.geo.Distance; +import org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit; /** * Unit test of {@link DefaultStringRedisConnection} that executes commands in a pipeline * * @author Jennifer Hickey * @author Christoph Strobl + * @author Ninad Divadkar */ public class DefaultStringRedisConnectionPipelineTests extends DefaultStringRedisConnectionTests { @@ -1287,155 +1293,282 @@ public class DefaultStringRedisConnectionPipelineTests extends DefaultStringRedi @Test public void testZUnionStoreAggWeights() { - doReturn(Arrays.asList(new Object[] { 5l })).when(nativeConnection).closePipeline(); + + doReturn(Collections.singletonList(5l)).when(nativeConnection).closePipeline(); super.testZUnionStoreAggWeights(); } @Test public void testZUnionStoreBytes() { - doReturn(Arrays.asList(new Object[] { 5l })).when(nativeConnection).closePipeline(); + + doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline(); super.testZUnionStoreBytes(); } @Test public void testZUnionStore() { - doReturn(Arrays.asList(new Object[] { 5l })).when(nativeConnection).closePipeline(); + + doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline(); super.testZUnionStore(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoAddBytes(){ - doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).closePipeline(); + public void testGeoAddBytes() { + + doReturn(Collections.singletonList(1L)).when(nativeConnection).closePipeline(); super.testGeoAddBytes(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoAdd(){ - doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).closePipeline(); + public void testGeoAdd() { + + doReturn(Collections.singletonList(1L)).when(nativeConnection).closePipeline(); super.testGeoAddBytes(); } + /** + * @see DATAREDIS-438 + */ + @Override + public void testGeoAddWithGeoLocationBytes() { + + doReturn(Collections.singletonList(1L)).when(nativeConnection).closePipeline(); + super.testGeoAddWithGeoLocationBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Override + public void testGeoAddWithGeoLocation() { + + doReturn(Collections.singletonList(1L)).when(nativeConnection).closePipeline(); + super.testGeoAddWithGeoLocation(); + } + + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoAddCoordinateMapBytes(){ - doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).closePipeline(); + public void testGeoAddCoordinateMapBytes() { + + doReturn(Collections.singletonList(1L)).when(nativeConnection).closePipeline(); super.testGeoAddCoordinateMapBytes(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoAddCoordinateMap(){ - doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).closePipeline(); + public void testGeoAddCoordinateMap() { + + doReturn(Collections.singletonList(1L)).when(nativeConnection).closePipeline(); super.testGeoAddCoordinateMap(); } + /** + * @see DATAREDIS-438 + */ + @Override + public void testGeoAddWithIterableOfGeoLocationBytes() { + + doReturn(Collections.singletonList(1L)).when(nativeConnection).closePipeline(); + super.testGeoAddWithIterableOfGeoLocationBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Override + public void testGeoAddWithIterableOfGeoLocation() { + + doReturn(Collections.singletonList(1L)).when(nativeConnection).closePipeline(); + super.testGeoAddWithIterableOfGeoLocation(); + } + + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoDistBytes(){ - doReturn(Arrays.asList(new Object[] { 102121.12d })).when(nativeConnection).closePipeline(); + public void testGeoDistBytes() { + + doReturn(Arrays.asList(new Distance(102121.12d, DistanceUnit.METERS))).when(nativeConnection).closePipeline(); super.testGeoDistBytes(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoDist(){ - doReturn(Arrays.asList(new Object[] { 102121.12d })).when(nativeConnection).closePipeline(); + public void testGeoDist() { + doReturn(Arrays.asList(new Distance(102121.12d, DistanceUnit.METERS))).when(nativeConnection).closePipeline(); super.testGeoDist(); + } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoHashBytes(){ - List expected = new ArrayList(); - expected.add(barBytes); - doReturn(Arrays.asList(new Object[] { expected })).when(nativeConnection).closePipeline(); + public void testGeoHashBytes() { + + doReturn(Arrays.asList(Collections.singletonList(bar))).when(nativeConnection).closePipeline(); super.testGeoHashBytes(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoHash(){ - List expected = new ArrayList(); - expected.add(barBytes); - doReturn(Arrays.asList(new Object[] { expected })).when(nativeConnection).closePipeline(); + public void testGeoHash() { + + doReturn(Arrays.asList(Collections.singletonList(bar))).when(nativeConnection).closePipeline(); super.testGeoHash(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoPosBytes(){ - doReturn(Arrays.asList(new Object[] { geoCoordinates })).when(nativeConnection).closePipeline(); + public void testGeoPosBytes() { + + doReturn(Arrays.asList(points)).when(nativeConnection).closePipeline(); super.testGeoPosBytes(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoPos(){ - doReturn(Arrays.asList(new Object[] { geoCoordinates })).when(nativeConnection).closePipeline(); + public void testGeoPos() { + + doReturn(Arrays.asList(points)).when(nativeConnection).closePipeline(); super.testGeoPos(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoRadiusWithoutParamBytes(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).closePipeline(); + public void testGeoRadiusWithoutParamBytes() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).closePipeline(); super.testGeoRadiusWithoutParamBytes(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoRadiusWithoutParam(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).closePipeline(); + public void testGeoRadiusWithoutParam() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).closePipeline(); super.testGeoRadiusWithoutParam(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoRadiusWithDistBytes(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).closePipeline(); + public void testGeoRadiusWithDistBytes() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).closePipeline(); super.testGeoRadiusWithDistBytes(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoRadiusWithDist(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).closePipeline(); + public void testGeoRadiusWithDist() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).closePipeline(); super.testGeoRadiusWithDist(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoRadiusWithCoordAndDescBytes(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).closePipeline(); + public void testGeoRadiusWithCoordAndDescBytes() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).closePipeline(); super.testGeoRadiusWithCoordAndDescBytes(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoRadiusWithCoordAndDesc(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).closePipeline(); + public void testGeoRadiusWithCoordAndDesc() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).closePipeline(); super.testGeoRadiusWithCoordAndDesc(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoRadiusByMemberWithoutParamBytes(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).closePipeline(); + public void testGeoRadiusByMemberWithoutParamBytes() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).closePipeline(); super.testGeoRadiusByMemberWithoutParamBytes(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoRadiusByMemberWithoutParam(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).closePipeline(); + public void testGeoRadiusByMemberWithoutParam() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).closePipeline(); super.testGeoRadiusByMemberWithoutParam(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoRadiusByMemberWithDistAndAscBytes(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).closePipeline(); + public void testGeoRadiusByMemberWithDistAndAscBytes() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).closePipeline(); super.testGeoRadiusByMemberWithDistAndAscBytes(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoRadiusByMemberWithDistAndAsc(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).closePipeline(); + public void testGeoRadiusByMemberWithDistAndAsc() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).closePipeline(); super.testGeoRadiusByMemberWithDistAndAsc(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoRadiusByMemberWithCoordAndCountBytes(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).closePipeline(); + public void testGeoRadiusByMemberWithCoordAndCountBytes() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).closePipeline(); super.testGeoRadiusByMemberWithCoordAndCountBytes(); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoRadiusByMemberWithCoordAndCount(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).closePipeline(); + public void testGeoRadiusByMemberWithCoordAndCount() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).closePipeline(); super.testGeoRadiusByMemberWithCoordAndCount(); } diff --git a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTxTests.java b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTxTests.java index 264bbd6e3..0707c42bd 100644 --- a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTxTests.java +++ b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTxTests.java @@ -1,14 +1,38 @@ +/* + * Copyright 2013-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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.data.redis.connection; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.when; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Properties; import org.junit.Before; import org.junit.Test; +import org.springframework.data.geo.Distance; +import org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit; +/** + * @author Jennifer Hickey + * @author Christoph Strobl + * @author Ninad Divadkar + */ public class DefaultStringRedisConnectionPipelineTxTests extends DefaultStringRedisConnectionTxTests { @Before @@ -1387,142 +1411,6 @@ public class DefaultStringRedisConnectionPipelineTxTests extends DefaultStringRe super.testZUnionStore(); } - @Test - public void testGeoAddBytes(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { 1l })})).when(nativeConnection).closePipeline(); - super.testGeoAddBytes(); - } - - @Test - public void testGeoAdd(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { 1l })})).when(nativeConnection).closePipeline(); - super.testGeoAddBytes(); - } - - @Test - public void testGeoAddCoordinateMapBytes(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { 1l })})).when(nativeConnection).closePipeline(); - super.testGeoAddCoordinateMapBytes(); - } - - @Test - public void testGeoAddCoordinateMap(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { 1l })})).when(nativeConnection).closePipeline(); - super.testGeoAddCoordinateMap(); - } - - @Test - public void testGeoDistBytes(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { 102121.12d }) })).when(nativeConnection).closePipeline(); - super.testGeoDistBytes(); - } - - @Test - public void testGeoDist(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { 102121.12d }) })).when(nativeConnection).closePipeline(); - super.testGeoDist(); - } - - @Test - public void testGeoHashBytes(){ - List expected = new ArrayList(); - expected.add(barBytes); - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { expected }) })).when(nativeConnection).closePipeline(); - super.testGeoHashBytes(); - } - - @Test - public void testGeoHash(){ - List expected = new ArrayList(); - expected.add(barBytes); - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { expected }) })).when(nativeConnection).closePipeline(); - super.testGeoHash(); - } - - @Test - public void testGeoPosBytes(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { geoCoordinates }) })).when(nativeConnection).closePipeline(); - super.testGeoPosBytes(); - } - - @Test - public void testGeoPos(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { geoCoordinates }) })).when(nativeConnection).closePipeline(); - super.testGeoPos(); - } - - @Test - public void testGeoRadiusWithoutParamBytes(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { geoRadiusResponses }) })).when(nativeConnection).closePipeline(); - super.testGeoRadiusWithoutParamBytes(); - } - - @Test - public void testGeoRadiusWithoutParam(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { geoRadiusResponses }) })).when(nativeConnection).closePipeline(); - super.testGeoRadiusWithoutParam(); - } - - @Test - public void testGeoRadiusWithDistBytes(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { geoRadiusResponses }) })).when(nativeConnection).closePipeline(); - super.testGeoRadiusWithDistBytes(); - } - - @Test - public void testGeoRadiusWithDist(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { geoRadiusResponses }) })).when(nativeConnection).closePipeline(); - super.testGeoRadiusWithDist(); - } - - @Test - public void testGeoRadiusWithCoordAndDescBytes(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { geoRadiusResponses }) })).when(nativeConnection).closePipeline(); - super.testGeoRadiusWithCoordAndDescBytes(); - } - - @Test - public void testGeoRadiusWithCoordAndDesc(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { geoRadiusResponses }) })).when(nativeConnection).closePipeline(); - super.testGeoRadiusWithCoordAndDesc(); - } - - @Test - public void testGeoRadiusByMemberWithoutParamBytes(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { geoRadiusResponses }) })).when(nativeConnection).closePipeline(); - super.testGeoRadiusByMemberWithoutParamBytes(); - } - - @Test - public void testGeoRadiusByMemberWithoutParam(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { geoRadiusResponses }) })).when(nativeConnection).closePipeline(); - super.testGeoRadiusByMemberWithoutParam(); - } - - @Test - public void testGeoRadiusByMemberWithDistAndAscBytes(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { geoRadiusResponses }) })).when(nativeConnection).closePipeline(); - super.testGeoRadiusByMemberWithDistAndAscBytes(); - } - - @Test - public void testGeoRadiusByMemberWithDistAndAsc(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { geoRadiusResponses }) })).when(nativeConnection).closePipeline(); - super.testGeoRadiusByMemberWithDistAndAsc(); - } - - @Test - public void testGeoRadiusByMemberWithCoordAndCountBytes(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { geoRadiusResponses }) })).when(nativeConnection).closePipeline(); - super.testGeoRadiusByMemberWithCoordAndCountBytes(); - } - - @Test - public void testGeoRadiusByMemberWithCoordAndCount(){ - doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { geoRadiusResponses }) })).when(nativeConnection).closePipeline(); - super.testGeoRadiusByMemberWithCoordAndCount(); - } - @Test public void testPExpireBytes() { doReturn(Arrays.asList(new Object[] { Arrays.asList(new Object[] { true }) })).when(nativeConnection) @@ -1655,9 +1543,9 @@ public class DefaultStringRedisConnectionPipelineTxTests extends DefaultStringRe @Test public void testTwoTxs() { - doReturn( - Arrays.asList(new Object[] { Arrays.asList(new Object[] { barBytes }), Arrays.asList(new Object[] { fooBytes }) })) - .when(nativeConnection).closePipeline(); + doReturn(Arrays + .asList(new Object[] { Arrays.asList(new Object[] { barBytes }), Arrays.asList(new Object[] { fooBytes }) })) + .when(nativeConnection).closePipeline(); connection.get(foo); connection.exec(); connection.get(bar); @@ -1668,6 +1556,268 @@ public class DefaultStringRedisConnectionPipelineTxTests extends DefaultStringRe results); } + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddBytes() { + + doReturn(Arrays.asList(Collections.singletonList(1L))).when(nativeConnection).closePipeline(); + super.testGeoAddBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAdd() { + + doReturn(Arrays.asList(Collections.singletonList(1L))).when(nativeConnection).closePipeline(); + super.testGeoAddBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddWithGeoLocationBytes() { + + doReturn(Arrays.asList(Collections.singletonList(1L))).when(nativeConnection).closePipeline(); + super.testGeoAddWithGeoLocationBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddWithGeoLocation() { + + doReturn(Arrays.asList(Collections.singletonList(1L))).when(nativeConnection).closePipeline(); + super.testGeoAddWithGeoLocation(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddCoordinateMapBytes() { + + doReturn(Arrays.asList(Collections.singletonList(1L))).when(nativeConnection).closePipeline(); + super.testGeoAddCoordinateMapBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddCoordinateMap() { + + doReturn(Arrays.asList(Collections.singletonList(1L))).when(nativeConnection).closePipeline(); + super.testGeoAddCoordinateMap(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddWithIterableOfGeoLocationBytes() { + + doReturn(Arrays.asList(Collections.singletonList(1L))).when(nativeConnection).closePipeline(); + super.testGeoAddWithIterableOfGeoLocationBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddWithIterableOfGeoLocation() { + + doReturn(Arrays.asList(Collections.singletonList(1L))).when(nativeConnection).closePipeline(); + super.testGeoAddWithIterableOfGeoLocation(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoDistBytes() { + + doReturn(Arrays.asList(Arrays.asList(new Distance(102121.12d, DistanceUnit.METERS)))).when(nativeConnection) + .closePipeline(); + super.testGeoDistBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoDist() { + + doReturn(Arrays.asList(Arrays.asList(new Distance(102121.12d, DistanceUnit.METERS)))).when(nativeConnection) + .closePipeline(); + super.testGeoDist(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoHashBytes() { + + doReturn(Arrays.asList(Arrays.asList(Collections.singletonList(bar)))).when(nativeConnection).closePipeline(); + super.testGeoHashBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoHash() { + + doReturn(Arrays.asList(Arrays.asList(Collections.singletonList(bar)))).when(nativeConnection).closePipeline(); + super.testGeoHash(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoPosBytes() { + + doReturn(Arrays.asList(Arrays.asList(points))).when(nativeConnection).closePipeline(); + super.testGeoPosBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoPos() { + + doReturn(Arrays.asList(Arrays.asList(points))).when(nativeConnection).closePipeline(); + super.testGeoPos(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithoutParamBytes() { + + doReturn(Arrays.asList(Arrays.asList(geoResults))).when(nativeConnection).closePipeline(); + super.testGeoRadiusWithoutParamBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithoutParam() { + + doReturn(Arrays.asList(Arrays.asList(geoResults))).when(nativeConnection).closePipeline(); + super.testGeoRadiusWithoutParam(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithDistBytes() { + + doReturn(Arrays.asList(Arrays.asList(geoResults))).when(nativeConnection).closePipeline(); + super.testGeoRadiusWithDistBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithDist() { + + doReturn(Arrays.asList(Arrays.asList(geoResults))).when(nativeConnection).closePipeline(); + super.testGeoRadiusWithDist(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithCoordAndDescBytes() { + + doReturn(Arrays.asList(Arrays.asList(geoResults))).when(nativeConnection).closePipeline(); + super.testGeoRadiusWithCoordAndDescBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithCoordAndDesc() { + + doReturn(Arrays.asList(Arrays.asList(geoResults))).when(nativeConnection).closePipeline(); + super.testGeoRadiusWithCoordAndDesc(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithoutParamBytes() { + + doReturn(Arrays.asList(Arrays.asList(geoResults))).when(nativeConnection).closePipeline(); + super.testGeoRadiusByMemberWithoutParamBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithoutParam() { + + doReturn(Arrays.asList(Arrays.asList(geoResults))).when(nativeConnection).closePipeline(); + super.testGeoRadiusByMemberWithoutParam(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithDistAndAscBytes() { + + doReturn(Arrays.asList(Arrays.asList(geoResults))).when(nativeConnection).closePipeline(); + super.testGeoRadiusByMemberWithDistAndAscBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithDistAndAsc() { + + doReturn(Arrays.asList(Arrays.asList(geoResults))).when(nativeConnection).closePipeline(); + super.testGeoRadiusByMemberWithDistAndAsc(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithCoordAndCountBytes() { + + doReturn(Arrays.asList(Arrays.asList(geoResults))).when(nativeConnection).closePipeline(); + super.testGeoRadiusByMemberWithCoordAndCountBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithCoordAndCount() { + + doReturn(Arrays.asList(Arrays.asList(geoResults))).when(nativeConnection).closePipeline(); + super.testGeoRadiusByMemberWithCoordAndCount(); + } + @SuppressWarnings("unchecked") protected List getResults() { connection.exec(); diff --git a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTests.java b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTests.java index 7a3e0ba28..c0b3ef508 100644 --- a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTests.java +++ b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-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. @@ -34,16 +34,21 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResult; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Point; +import org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs; import org.springframework.data.redis.connection.RedisListCommands.Position; import org.springframework.data.redis.connection.RedisServerCommands.ShutdownOption; import org.springframework.data.redis.connection.RedisStringCommands.BitOperation; import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate; import org.springframework.data.redis.connection.RedisZSetCommands.Tuple; import org.springframework.data.redis.connection.StringRedisConnection.StringTuple; -import org.springframework.data.redis.core.GeoCoordinate; -import org.springframework.data.redis.core.GeoRadiusParam; -import org.springframework.data.redis.core.GeoRadiusResponse; -import org.springframework.data.redis.core.GeoUnit; +import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.serializer.StringRedisSerializer; /** @@ -51,6 +56,7 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; * * @author Jennifer Hickey * @auhtor Christoph Strobl + * @author Ninad Divadkar */ public class DefaultStringRedisConnectionTests { @@ -66,13 +72,13 @@ public class DefaultStringRedisConnectionTests { protected String bar = "bar"; - protected String bar2 = "bar2"; + protected String bar2 = "bar2"; protected byte[] fooBytes = serializer.serialize(foo); protected byte[] barBytes = serializer.serialize(bar); - protected byte[] bar2Bytes = serializer.serialize(bar2); + protected byte[] bar2Bytes = serializer.serialize(bar2); protected List bytesList = Collections.singletonList(barBytes); @@ -91,11 +97,12 @@ public class DefaultStringRedisConnectionTests { protected Set stringTupleSet = new HashSet( Collections.singletonList(new DefaultStringTuple(new DefaultTuple(barBytes, 3d), bar))); - protected GeoCoordinate geoCoordinate = new GeoCoordinate(213.00, 324.343); - protected List geoCoordinates = new ArrayList(); + protected Point point = new Point(213.00, 324.343); + protected List points = new ArrayList(); - protected GeoRadiusResponse geoRadiusResponse = new GeoRadiusResponse(barBytes); - protected List geoRadiusResponses = new ArrayList(); + protected List>> geoResultList = Collections + .singletonList(new GeoResult>(new GeoLocation(barBytes, null), new Distance(0D))); + protected GeoResults> geoResults = new GeoResults>(geoResultList); @Before public void setUp() { @@ -103,8 +110,7 @@ public class DefaultStringRedisConnectionTests { this.connection = new DefaultStringRedisConnection(nativeConnection); bytesMap.put(fooBytes, barBytes); stringMap.put(foo, bar); - geoCoordinates.add(geoCoordinate); - geoRadiusResponses.add(geoRadiusResponse); + points.add(point); } @Test @@ -1586,188 +1592,6 @@ public class DefaultStringRedisConnectionTests { } @Test - public void testGeoAddBytes(){ - doReturn(1l).when(nativeConnection).geoAdd(fooBytes, 1.23232, 34.2342434, barBytes); - actual.add(connection.geoAdd(fooBytes, 1.23232, 34.2342434, barBytes)); - verifyResults(Arrays.asList(new Object[] { 1l })); - } - - @Test - public void testGeoAdd(){ - doReturn(1l).when(nativeConnection).geoAdd(fooBytes, 1.23232, 34.2342434, barBytes); - actual.add(connection.geoAdd(foo, 1.23232, 34.2342434, bar)); - verifyResults(Arrays.asList(new Object[] { 1l })); - } - - @Test - public void testGeoAddCoordinateMapBytes(){ - Map memberGeoCoordinateMap = new HashMap(); - memberGeoCoordinateMap.put(barBytes, new GeoCoordinate(1.23232, 34.2342434)); - doReturn(1l).when(nativeConnection).geoAdd(fooBytes, memberGeoCoordinateMap); - - actual.add(connection.geoAdd(fooBytes, memberGeoCoordinateMap)); - verifyResults(Arrays.asList(new Object[] { 1l })); - } - - @Test - public void testGeoAddCoordinateMap(){ - GeoCoordinate geoCoordinate = new GeoCoordinate(1.23232, 34.2342434); - doReturn(1l).when(nativeConnection).geoAdd(any(byte[].class), anyMapOf(byte[].class, GeoCoordinate.class)); - - Map stringGeoCoordinateMap = new HashMap(); - stringGeoCoordinateMap.put(bar, geoCoordinate); - actual.add(connection.geoAdd(foo, stringGeoCoordinateMap)); - verifyResults(Arrays.asList(new Object[] { 1l })); - } - - @Test - public void testGeoDistBytes(){ - doReturn(102121.12d).when(nativeConnection).geoDist(fooBytes, barBytes, bar2Bytes, GeoUnit.Meters); - actual.add(connection.geoDist(fooBytes, barBytes, bar2Bytes, GeoUnit.Meters)); - verifyResults(Arrays.asList(new Object[] { 102121.12d })); - } - - @Test - public void testGeoDist(){ - doReturn(102121.12d).when(nativeConnection).geoDist(fooBytes, barBytes, bar2Bytes, GeoUnit.Meters); - actual.add(connection.geoDist(foo, bar, bar2, GeoUnit.Meters)); - verifyResults(Arrays.asList(new Object[] { 102121.12d })); - } - - @Test - public void testGeoHashBytes(){ - doReturn(bytesList).when(nativeConnection).geoHash(fooBytes, barBytes); - actual.add(connection.geoHash(fooBytes, barBytes)); - List expected = new ArrayList(); - expected.add(barBytes); - verifyResults(Arrays.asList(new Object[]{expected})); - } - - @Test - public void testGeoHash(){ - doReturn(bytesList).when(nativeConnection).geoHash(fooBytes, barBytes); - actual.add(connection.geoHash(foo, bar)); - List expected = new ArrayList(); - expected.add(bar); - verifyResults(Arrays.asList(new Object[]{expected})); - } - - @Test - public void testGeoPosBytes(){ - doReturn(geoCoordinates).when(nativeConnection).geoPos(fooBytes, barBytes); - actual.add(connection.geoPos(fooBytes, barBytes)); - verifyResults(Arrays.asList(new Object[] { geoCoordinates })); - } - - @Test - public void testGeoPos(){ - doReturn(geoCoordinates).when(nativeConnection).geoPos(fooBytes, barBytes); - actual.add(connection.geoPos(foo, bar)); - verifyResults(Arrays.asList(new Object[] { geoCoordinates })); - } - - @Test - public void testGeoRadiusWithoutParamBytes(){ - - doReturn(geoRadiusResponses).when(nativeConnection).georadius(fooBytes, 13.361389, 38.115556, 10, GeoUnit.Feet); - actual.add(connection.georadius(fooBytes, 13.361389, 38.115556, 10, GeoUnit.Feet)); - verifyResults(Arrays.asList(new Object[] { geoRadiusResponses })); - } - - @Test - public void testGeoRadiusWithoutParam(){ - doReturn(geoRadiusResponses).when(nativeConnection).georadius(fooBytes, 13.361389, 38.115556, 10, GeoUnit.Feet); - actual.add(connection.georadius(foo, 13.361389, 38.115556, 10, GeoUnit.Feet)); - verifyResults(Arrays.asList(new Object[] { geoRadiusResponses })); - } - - @Test - public void testGeoRadiusWithDistBytes(){ - GeoRadiusParam geoRadiusParam = GeoRadiusParam.geoRadiusParam(); - geoRadiusParam.withDist(); - doReturn(geoRadiusResponses).when(nativeConnection).georadius(fooBytes, 13.361389, 38.115556, 10, GeoUnit.Feet, geoRadiusParam); - actual.add(connection.georadius(fooBytes, 13.361389, 38.115556, 10, GeoUnit.Feet, geoRadiusParam)); - verifyResults(Arrays.asList(new Object[] { geoRadiusResponses })); - } - - @Test - public void testGeoRadiusWithDist(){ - GeoRadiusParam geoRadiusParam = GeoRadiusParam.geoRadiusParam(); - geoRadiusParam.withDist(); - doReturn(geoRadiusResponses).when(nativeConnection).georadius(fooBytes, 13.361389, 38.115556, 10, GeoUnit.Feet, geoRadiusParam); - actual.add(connection.georadius(foo, 13.361389, 38.115556, 10, GeoUnit.Feet, geoRadiusParam)); - verifyResults(Arrays.asList(new Object[] { geoRadiusResponses })); - } - - @Test - public void testGeoRadiusWithCoordAndDescBytes(){ - GeoRadiusParam geoRadiusParam = GeoRadiusParam.geoRadiusParam(); - geoRadiusParam.withCoord().sortDescending(); - doReturn(geoRadiusResponses).when(nativeConnection).georadius(fooBytes, 13.361389, 38.115556, 10, GeoUnit.Feet, geoRadiusParam); - actual.add(connection.georadius(fooBytes, 13.361389, 38.115556, 10, GeoUnit.Feet, geoRadiusParam)); - verifyResults(Arrays.asList(new Object[] { geoRadiusResponses })); - } - - @Test - public void testGeoRadiusWithCoordAndDesc(){ - GeoRadiusParam geoRadiusParam = GeoRadiusParam.geoRadiusParam(); - geoRadiusParam.withCoord().sortDescending(); - doReturn(geoRadiusResponses).when(nativeConnection).georadius(fooBytes, 13.361389, 38.115556, 10, GeoUnit.Feet, geoRadiusParam); - actual.add(connection.georadius(foo, 13.361389, 38.115556, 10, GeoUnit.Feet, geoRadiusParam)); - verifyResults(Arrays.asList(new Object[] { geoRadiusResponses })); - } - - @Test - public void testGeoRadiusByMemberWithoutParamBytes(){ - doReturn(geoRadiusResponses).when(nativeConnection).georadiusByMember(fooBytes, barBytes, 38.115556, GeoUnit.Feet); - actual.add(connection.georadiusByMember(fooBytes, barBytes, 38.115556, GeoUnit.Feet)); - verifyResults(Arrays.asList(new Object[] { geoRadiusResponses })); - } - - @Test - public void testGeoRadiusByMemberWithoutParam(){ - doReturn(geoRadiusResponses).when(nativeConnection).georadiusByMember(fooBytes, barBytes, 38.115556, GeoUnit.Feet); - actual.add(connection.georadiusByMember(foo, bar, 38.115556, GeoUnit.Feet)); - verifyResults(Arrays.asList(new Object[] { geoRadiusResponses })); - } - - @Test - public void testGeoRadiusByMemberWithDistAndAscBytes(){ - GeoRadiusParam geoRadiusParam = GeoRadiusParam.geoRadiusParam(); - geoRadiusParam.withDist().sortAscending(); - doReturn(geoRadiusResponses).when(nativeConnection).georadiusByMember(fooBytes, barBytes, 38.115556, GeoUnit.Feet, geoRadiusParam); - actual.add(connection.georadiusByMember(fooBytes, barBytes, 38.115556, GeoUnit.Feet, geoRadiusParam)); - verifyResults(Arrays.asList(new Object[] { geoRadiusResponses })); - } - - @Test - public void testGeoRadiusByMemberWithDistAndAsc(){ - GeoRadiusParam geoRadiusParam = GeoRadiusParam.geoRadiusParam(); - geoRadiusParam.withDist().sortAscending(); - doReturn(geoRadiusResponses).when(nativeConnection).georadiusByMember(fooBytes, barBytes, 38.115556, GeoUnit.Feet, geoRadiusParam); - actual.add(connection.georadiusByMember(foo, bar, 38.115556, GeoUnit.Feet, geoRadiusParam)); - verifyResults(Arrays.asList(new Object[] { geoRadiusResponses })); - } - - @Test - public void testGeoRadiusByMemberWithCoordAndCountBytes(){ - GeoRadiusParam geoRadiusParam = GeoRadiusParam.geoRadiusParam(); - geoRadiusParam.withDist().count(23); - doReturn(geoRadiusResponses).when(nativeConnection).georadiusByMember(fooBytes, barBytes, 38.115556, GeoUnit.Feet, geoRadiusParam); - actual.add(connection.georadiusByMember(fooBytes, barBytes, 38.115556, GeoUnit.Feet, geoRadiusParam)); - verifyResults(Arrays.asList(new Object[] { geoRadiusResponses })); - } - - @Test - public void testGeoRadiusByMemberWithCoordAndCount(){ - GeoRadiusParam geoRadiusParam = GeoRadiusParam.geoRadiusParam(); - geoRadiusParam.withDist().count(23); - doReturn(geoRadiusResponses).when(nativeConnection).georadiusByMember(fooBytes, barBytes, 38.115556, GeoUnit.Feet, geoRadiusParam); - actual.add(connection.georadiusByMember(foo, bar, 38.115556, GeoUnit.Feet, geoRadiusParam)); - verifyResults(Arrays.asList(new Object[] { geoRadiusResponses })); - } - - @Test public void testPExpireBytes() { doReturn(true).when(nativeConnection).pExpire(fooBytes, 34l); actual.add(connection.pExpire(fooBytes, 34l)); @@ -1960,6 +1784,342 @@ public class DefaultStringRedisConnectionTests { verify(nativeConnection, times(1)).getClientName(); } + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddBytes() { + + doReturn(1l).when(nativeConnection).geoAdd(fooBytes, new Point(1.23232, 34.2342434), barBytes); + + actual.add(connection.geoAdd(fooBytes, new Point(1.23232, 34.2342434), barBytes)); + verifyResults(Collections.singletonList(1L)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAdd() { + + doReturn(1l).when(nativeConnection).geoAdd(fooBytes, new Point(1.23232, 34.2342434), barBytes); + + actual.add(connection.geoAdd(foo, new Point(1.23232, 34.2342434), bar)); + verifyResults(Collections.singletonList(1L)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddWithGeoLocationBytes() { + + doReturn(1l).when(nativeConnection).geoAdd(fooBytes, + new GeoLocation(barBytes, new Point(1.23232, 34.2342434))); + + actual.add(connection.geoAdd(fooBytes, new GeoLocation(barBytes, new Point(1.23232, 34.2342434)))); + verifyResults(Collections.singletonList(1L)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddWithGeoLocation() { + + doReturn(1l).when(nativeConnection).geoAdd(fooBytes, new Point(1.23232, 34.2342434), barBytes); + + actual.add(connection.geoAdd(foo, new GeoLocation(bar, new Point(1.23232, 34.2342434)))); + verifyResults(Collections.singletonList(1L)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddCoordinateMapBytes() { + + Map memberGeoCoordinateMap = Collections.singletonMap(barBytes, new Point(1.23232, 34.2342434)); + doReturn(1l).when(nativeConnection).geoAdd(fooBytes, memberGeoCoordinateMap); + + actual.add(connection.geoAdd(fooBytes, memberGeoCoordinateMap)); + verifyResults(Collections.singletonList(1L)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddCoordinateMap() { + + doReturn(1l).when(nativeConnection).geoAdd(any(byte[].class), anyMapOf(byte[].class, Point.class)); + + actual.add(connection.geoAdd(foo, Collections.singletonMap(bar, new Point(1.23232, 34.2342434)))); + verifyResults(Collections.singletonList(1L)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddWithIterableOfGeoLocationBytes() { + + List> values = Collections.singletonList(new GeoLocation(barBytes, new Point(1, 2))); + doReturn(1l).when(nativeConnection).geoAdd(fooBytes, values); + + actual.add(connection.geoAdd(fooBytes, values)); + verifyResults(Collections.singletonList(1L)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddWithIterableOfGeoLocation() { + + doReturn(1l).when(nativeConnection).geoAdd(eq(fooBytes), anyMapOf(byte[].class, Point.class)); + + actual.add(connection.geoAdd(foo, Collections.singletonList(new GeoLocation(bar, new Point(1, 2))))); + verifyResults(Collections.singletonList(1L)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoDistBytes() { + + doReturn(new Distance(102121.12d, DistanceUnit.METERS)).when(nativeConnection).geoDist(fooBytes, barBytes, + bar2Bytes, DistanceUnit.METERS); + + actual.add(connection.geoDist(fooBytes, barBytes, bar2Bytes, DistanceUnit.METERS)); + verifyResults(Collections.singletonList(new Distance(102121.12d, DistanceUnit.METERS))); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoDist() { + + doReturn(new Distance(102121.12d, DistanceUnit.METERS)).when(nativeConnection).geoDist(fooBytes, barBytes, + bar2Bytes, DistanceUnit.METERS); + + actual.add(connection.geoDist(foo, bar, bar2, DistanceUnit.METERS)); + verifyResults(Collections.singletonList(new Distance(102121.12d, DistanceUnit.METERS))); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoHashBytes() { + + doReturn(stringList).when(nativeConnection).geoHash(fooBytes, barBytes); + + actual.add(connection.geoHash(fooBytes, barBytes)); + verifyResults(Arrays.asList(Collections.singletonList(bar))); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoHash() { + + doReturn(stringList).when(nativeConnection).geoHash(fooBytes, barBytes); + + actual.add(connection.geoHash(foo, bar)); + verifyResults(Arrays.asList(Collections.singletonList(bar))); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoPosBytes() { + + doReturn(points).when(nativeConnection).geoPos(fooBytes, barBytes); + + actual.add(connection.geoPos(fooBytes, barBytes)); + verifyResults(Arrays.asList(points)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoPos() { + + doReturn(points).when(nativeConnection).geoPos(fooBytes, barBytes); + actual.add(connection.geoPos(foo, bar)); + verifyResults(Arrays.asList(points)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithoutParamBytes() { + + doReturn(geoResults).when(nativeConnection).geoRadius(eq(fooBytes), any(Circle.class)); + + actual.add(connection.geoRadius(fooBytes, null)); + verifyResults(Arrays.asList(geoResults)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithoutParam() { + + doReturn(geoResults).when(nativeConnection).geoRadius(eq(fooBytes), any(Circle.class)); + + actual.add( + connection.georadius(foo, new Circle(new Point(13.361389, 38.115556), new Distance(10, DistanceUnit.FEET)))); + verifyResults(Arrays.asList(Converters.deserializingGeoResultsConverter(serializer).convert(geoResults))); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithDistBytes() { + + GeoRadiusCommandArgs geoRadiusParam = GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance(); + doReturn(geoResults).when(nativeConnection).geoRadius(eq(fooBytes), any(Circle.class), eq(geoRadiusParam)); + + actual.add(connection.geoRadius(fooBytes, + new Circle(new Point(13.361389, 38.115556), new Distance(10, DistanceUnit.FEET)), geoRadiusParam)); + verifyResults(Arrays.asList(geoResults)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithDist() { + + GeoRadiusCommandArgs geoRadiusParam = GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance(); + doReturn(geoResults).when(nativeConnection).geoRadius(eq(fooBytes), any(Circle.class), eq(geoRadiusParam)); + + actual.add(connection.georadius(foo, + new Circle(new Point(13.361389, 38.115556), new Distance(10, DistanceUnit.FEET)), geoRadiusParam)); + verifyResults(Arrays.asList(Converters.deserializingGeoResultsConverter(serializer).convert(geoResults))); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithCoordAndDescBytes() { + + GeoRadiusCommandArgs geoRadiusParam = GeoRadiusCommandArgs.newGeoRadiusArgs().includeCoordinates().sortDescending(); + doReturn(geoResults).when(nativeConnection).geoRadius(eq(fooBytes), any(Circle.class), eq(geoRadiusParam)); + + actual.add(connection.geoRadius(fooBytes, + new Circle(new Point(13.361389, 38.115556), new Distance(10, DistanceUnit.FEET)), geoRadiusParam)); + verifyResults(Arrays.asList(geoResults)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithCoordAndDesc() { + GeoRadiusCommandArgs geoRadiusParam = GeoRadiusCommandArgs.newGeoRadiusArgs().includeCoordinates().sortDescending(); + doReturn(geoResults).when(nativeConnection).geoRadius(eq(fooBytes), any(Circle.class), eq(geoRadiusParam)); + + actual.add(connection.georadius(foo, + new Circle(new Point(13.361389, 38.115556), new Distance(10, DistanceUnit.FEET)), geoRadiusParam)); + verifyResults(Arrays.asList(Converters.deserializingGeoResultsConverter(serializer).convert(geoResults))); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithoutParamBytes() { + + doReturn(geoResults).when(nativeConnection).geoRadiusByMember(fooBytes, barBytes, + new Distance(38.115556, DistanceUnit.FEET)); + + actual.add(connection.geoRadiusByMember(fooBytes, barBytes, new Distance(38.115556, DistanceUnit.FEET))); + verifyResults(Arrays.asList(geoResults)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithoutParam() { + + doReturn(geoResults).when(nativeConnection).geoRadiusByMember(fooBytes, barBytes, + new Distance(38.115556, DistanceUnit.FEET)); + + actual.add(connection.georadiusByMember(foo, bar, new Distance(38.115556, DistanceUnit.FEET))); + verifyResults(Arrays.asList(Converters.deserializingGeoResultsConverter(serializer).convert(geoResults))); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithDistAndAscBytes() { + + GeoRadiusCommandArgs geoRadiusParam = GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().sortAscending(); + doReturn(geoResults).when(nativeConnection).geoRadiusByMember(fooBytes, barBytes, + new Distance(38.115556, DistanceUnit.FEET), geoRadiusParam); + + actual.add( + connection.geoRadiusByMember(fooBytes, barBytes, new Distance(38.115556, DistanceUnit.FEET), geoRadiusParam)); + verifyResults(Arrays.asList(geoResults)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithDistAndAsc() { + + GeoRadiusCommandArgs geoRadiusParam = GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().sortAscending(); + doReturn(geoResults).when(nativeConnection).geoRadiusByMember(fooBytes, barBytes, + new Distance(38.115556, DistanceUnit.FEET), geoRadiusParam); + + actual.add(connection.georadiusByMember(foo, bar, new Distance(38.115556, DistanceUnit.FEET), geoRadiusParam)); + verifyResults(Arrays.asList(Converters.deserializingGeoResultsConverter(serializer).convert(geoResults))); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithCoordAndCountBytes() { + + GeoRadiusCommandArgs geoRadiusParam = GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().limit(23); + doReturn(geoResults).when(nativeConnection).geoRadiusByMember(fooBytes, barBytes, + new Distance(38.115556, DistanceUnit.FEET), geoRadiusParam); + + actual.add( + connection.geoRadiusByMember(fooBytes, barBytes, new Distance(38.115556, DistanceUnit.FEET), geoRadiusParam)); + verifyResults(Arrays.asList(geoResults)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithCoordAndCount() { + + GeoRadiusCommandArgs geoRadiusParam = GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().limit(23); + doReturn(geoResults).when(nativeConnection).geoRadiusByMember(fooBytes, barBytes, + new Distance(38.115556, DistanceUnit.FEET), geoRadiusParam); + + actual.add(connection.georadiusByMember(foo, bar, new Distance(38.115556, DistanceUnit.FEET), geoRadiusParam)); + verifyResults(Arrays.asList(Converters.deserializingGeoResultsConverter(serializer).convert(geoResults))); + } + protected List getResults() { return actual; } diff --git a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTxTests.java b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTxTests.java index 0b1341109..6a991b44d 100644 --- a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTxTests.java +++ b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTxTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-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. @@ -17,18 +17,20 @@ package org.springframework.data.redis.connection; import static org.mockito.Mockito.*; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Properties; import org.junit.Before; import org.junit.Test; -import org.springframework.data.redis.core.GeoCoordinate; -import org.springframework.data.redis.core.GeoRadiusParam; -import org.springframework.data.redis.core.GeoRadiusResponse; -import org.springframework.data.redis.core.GeoUnit; +import org.springframework.data.geo.Distance; +import org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit; /** * @author Jennifer Hickey * @author Christoph Strobl + * @author Ninad Divadkar */ public class DefaultStringRedisConnectionTxTests extends DefaultStringRedisConnectionTests { @@ -1293,142 +1295,6 @@ public class DefaultStringRedisConnectionTxTests extends DefaultStringRedisConne super.testZUnionStore(); } - @Test - public void testGeoAddBytes(){ - doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).exec(); - super.testGeoAddBytes(); - } - - @Test - public void testGeoAdd(){ - doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).exec(); - super.testGeoAddBytes(); - } - - @Test - public void testGeoAddCoordinateMapBytes(){ - doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).exec(); - super.testGeoAddCoordinateMapBytes(); - } - - @Test - public void testGeoAddCoordinateMap(){ - doReturn(Arrays.asList(new Object[] { 1l })).when(nativeConnection).exec(); - super.testGeoAddCoordinateMap(); - } - - @Test - public void testGeoDistBytes(){ - doReturn(Arrays.asList(new Object[] { 102121.12d })).when(nativeConnection).exec(); - super.testGeoDistBytes(); - } - - @Test - public void testGeoDist(){ - doReturn(Arrays.asList(new Object[] { 102121.12d })).when(nativeConnection).exec(); - super.testGeoDist(); - } - - @Test - public void testGeoHashBytes(){ - List expected = new ArrayList(); - expected.add(barBytes); - doReturn(Arrays.asList(new Object[] { expected })).when(nativeConnection).exec(); - super.testGeoHashBytes(); - } - - @Test - public void testGeoHash(){ - List expected = new ArrayList(); - expected.add(barBytes); - doReturn(Arrays.asList(new Object[] { expected })).when(nativeConnection).exec(); - super.testGeoHash(); - } - - @Test - public void testGeoPosBytes(){ - doReturn(Arrays.asList(new Object[] { geoCoordinates })).when(nativeConnection).exec(); - super.testGeoPosBytes(); - } - - @Test - public void testGeoPos(){ - doReturn(Arrays.asList(new Object[] { geoCoordinates })).when(nativeConnection).exec(); - super.testGeoPos(); - } - - @Test - public void testGeoRadiusWithoutParamBytes(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).exec(); - super.testGeoRadiusWithoutParamBytes(); - } - - @Test - public void testGeoRadiusWithoutParam(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).exec(); - super.testGeoRadiusWithoutParam(); - } - - @Test - public void testGeoRadiusWithDistBytes(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).exec(); - super.testGeoRadiusWithDistBytes(); - } - - @Test - public void testGeoRadiusWithDist(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).exec(); - super.testGeoRadiusWithDist(); - } - - @Test - public void testGeoRadiusWithCoordAndDescBytes(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).exec(); - super.testGeoRadiusWithCoordAndDescBytes(); - } - - @Test - public void testGeoRadiusWithCoordAndDesc(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).exec(); - super.testGeoRadiusWithCoordAndDesc(); - } - - @Test - public void testGeoRadiusByMemberWithoutParamBytes(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).exec(); - super.testGeoRadiusByMemberWithoutParamBytes(); - } - - @Test - public void testGeoRadiusByMemberWithoutParam(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).exec(); - super.testGeoRadiusByMemberWithoutParam(); - } - - @Test - public void testGeoRadiusByMemberWithDistAndAscBytes(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).exec(); - super.testGeoRadiusByMemberWithDistAndAscBytes(); - } - - @Test - public void testGeoRadiusByMemberWithDistAndAsc(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).exec(); - super.testGeoRadiusByMemberWithDistAndAsc(); - } - - @Test - public void testGeoRadiusByMemberWithCoordAndCountBytes(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).exec(); - super.testGeoRadiusByMemberWithCoordAndCountBytes(); - } - - @Test - public void testGeoRadiusByMemberWithCoordAndCount(){ - doReturn(Arrays.asList(new Object[] { geoRadiusResponses })).when(nativeConnection).exec(); - super.testGeoRadiusByMemberWithCoordAndCount(); - } - @Test public void testPExpireBytes() { doReturn(Arrays.asList(new Object[] { true })).when(nativeConnection).exec(); @@ -1580,6 +1446,260 @@ public class DefaultStringRedisConnectionTxTests extends DefaultStringRedisConne super.testTimeIsDelegatedCorrectlyToNativeConnection(); } + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddBytes() { + + doReturn(Collections.singletonList(1L)).when(nativeConnection).exec(); + super.testGeoAddBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAdd() { + doReturn(Collections.singletonList(1L)).when(nativeConnection).exec(); + super.testGeoAddBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Override + public void testGeoAddWithGeoLocationBytes() { + + doReturn(Collections.singletonList(1L)).when(nativeConnection).exec(); + super.testGeoAddWithGeoLocationBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Override + public void testGeoAddWithGeoLocation() { + + doReturn(Collections.singletonList(1L)).when(nativeConnection).exec(); + super.testGeoAddWithGeoLocation(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddCoordinateMapBytes() { + doReturn(Collections.singletonList(1L)).when(nativeConnection).exec(); + super.testGeoAddCoordinateMapBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddCoordinateMap() { + doReturn(Collections.singletonList(1L)).when(nativeConnection).exec(); + super.testGeoAddCoordinateMap(); + } + + /** + * @see DATAREDIS-438 + */ + @Override + public void testGeoAddWithIterableOfGeoLocationBytes() { + + doReturn(Collections.singletonList(1L)).when(nativeConnection).exec(); + super.testGeoAddWithIterableOfGeoLocationBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Override + public void testGeoAddWithIterableOfGeoLocation() { + + doReturn(Collections.singletonList(1L)).when(nativeConnection).exec(); + super.testGeoAddWithIterableOfGeoLocation(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoDistBytes() { + + doReturn(Arrays.asList(new Distance(102121.12d, DistanceUnit.METERS))).when(nativeConnection).exec(); + super.testGeoDistBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoDist() { + + doReturn(Arrays.asList(new Distance(102121.12d, DistanceUnit.METERS))).when(nativeConnection).exec(); + super.testGeoDist(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoHashBytes() { + + doReturn(Arrays.asList(Collections.singletonList(bar))).when(nativeConnection).exec(); + super.testGeoHashBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoHash() { + + doReturn(Arrays.asList(Collections.singletonList(bar))).when(nativeConnection).exec(); + super.testGeoHash(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoPosBytes() { + + doReturn(Arrays.asList(points)).when(nativeConnection).exec(); + super.testGeoPosBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoPos() { + + doReturn(Arrays.asList(points)).when(nativeConnection).exec(); + super.testGeoPos(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithoutParamBytes() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).exec(); + super.testGeoRadiusWithoutParamBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithoutParam() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).exec(); + super.testGeoRadiusWithoutParam(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithDistBytes() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).exec(); + super.testGeoRadiusWithDistBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithDist() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).exec(); + super.testGeoRadiusWithDist(); + } + + @Test + public void testGeoRadiusWithCoordAndDescBytes() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).exec(); + super.testGeoRadiusWithCoordAndDescBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusWithCoordAndDesc() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).exec(); + super.testGeoRadiusWithCoordAndDesc(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithoutParamBytes() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).exec(); + super.testGeoRadiusByMemberWithoutParamBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithoutParam() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).exec(); + super.testGeoRadiusByMemberWithoutParam(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithDistAndAscBytes() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).exec(); + super.testGeoRadiusByMemberWithDistAndAscBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithDistAndAsc() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).exec(); + super.testGeoRadiusByMemberWithDistAndAsc(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithCoordAndCountBytes() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).exec(); + super.testGeoRadiusByMemberWithCoordAndCountBytes(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRadiusByMemberWithCoordAndCount() { + + doReturn(Arrays.asList(geoResults)).when(nativeConnection).exec(); + super.testGeoRadiusByMemberWithCoordAndCount(); + } + protected List getResults() { return connection.exec(); } diff --git a/src/test/java/org/springframework/data/redis/connection/RedisConnectionUnitTests.java b/src/test/java/org/springframework/data/redis/connection/RedisConnectionUnitTests.java index 1d1b48406..a4805a15e 100644 --- a/src/test/java/org/springframework/data/redis/connection/RedisConnectionUnitTests.java +++ b/src/test/java/org/springframework/data/redis/connection/RedisConnectionUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -27,8 +27,14 @@ import java.util.Set; import org.junit.Before; import org.junit.Test; import org.springframework.dao.DataAccessException; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Point; import org.springframework.data.redis.connection.RedisNode.RedisNodeBuilder; -import org.springframework.data.redis.core.*; +import org.springframework.data.redis.core.Cursor; +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.ObjectUtils; @@ -37,6 +43,7 @@ import org.springframework.util.ObjectUtils; * @author Christoph Strobl * @author Thomas Darimont * @author David Liu + * @author Ninad Divadkar */ public class RedisConnectionUnitTests { @@ -259,53 +266,69 @@ public class RedisConnectionUnitTests { delegate.subscribe(listener, channels); } - public Long geoAdd(byte[] key, double longitude, double latitude, byte[] member) { - return delegate.geoAdd(key, longitude, latitude, member); - } - - @Override - public Long geoAdd(byte[] key, Map memberCoordinateMap) { - return delegate.geoAdd(key, memberCoordinateMap); - } - - @Override - public Double geoDist(byte[] key, byte[] member1, byte[] member2) { - return delegate.geoDist(key, member1, member2); - } - - @Override - public Double geoDist(byte[] key, byte[] member1, byte[] member2, GeoUnit unit) { - return delegate.geoDist(key, member1, member2, unit); - } - - @Override - public List geoHash(byte[] key, byte[]... members) { - return delegate.geoHash(key, members); - } - - @Override - public List geoPos(byte[] key, byte[]... members) { - return delegate.geoPos(key, members); - } - - @Override - public List georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit) { - return delegate.georadius(key, longitude, latitude, radius, unit); + public Long geoAdd(byte[] key, Point point, byte[] member) { + return delegate.geoAdd(key, point, member); } @Override - public List georadius(byte[] key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam param) { - return delegate.georadius(key, longitude, latitude, radius, unit, param); + public Long geoAdd(byte[] key, GeoLocation location) { + return delegate.geoAdd(key, location); } @Override - public List georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit) { - return delegate.georadiusByMember(key, member, radius, unit); + public Long geoAdd(byte[] key, Map memberCoordinateMap) { + return delegate.geoAdd(key, memberCoordinateMap); } @Override - public List georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit, GeoRadiusParam param) { - return delegate.georadiusByMember(key, member, radius, unit, param); + public Long geoAdd(byte[] key, Iterable> locations) { + return delegate.geoAdd(key, locations); + } + + @Override + public Distance geoDist(byte[] key, byte[] member1, byte[] member2) { + return delegate.geoDist(key, member1, member2); + } + + @Override + public Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric unit) { + return delegate.geoDist(key, member1, member2, unit); + } + + @Override + public List geoHash(byte[] key, byte[]... members) { + return delegate.geoHash(key, members); + } + + @Override + public List geoPos(byte[] key, byte[]... members) { + return delegate.geoPos(key, members); + } + + @Override + public GeoResults> geoRadius(byte[] key, Circle within) { + return delegate.geoRadius(key, null); + } + + @Override + public GeoResults> geoRadius(byte[] key, Circle within, GeoRadiusCommandArgs param) { + return delegate.geoRadius(key, null, param); + } + + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, double radius) { + return delegate.geoRadiusByMember(key, member, radius); + } + + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius) { + return delegate.geoRadiusByMember(key, member, radius); + } + + @Override + public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius, + GeoRadiusCommandArgs param) { + return delegate.geoRadiusByMember(key, member, radius, param); } @Override 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 2b8803b03..5d0a4455a 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 @@ -16,13 +16,18 @@ package org.springframework.data.redis.connection.jedis; import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.collection.IsCollectionWithSize.*; import static org.hamcrest.collection.IsIterableContainingInOrder.*; +import static org.hamcrest.core.Is.is; 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.connection.RedisGeoCommands.DistanceUnit.*; +import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.*; import static org.springframework.data.redis.core.ScanOptions.*; import java.io.IOException; +import java.nio.charset.Charset; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -38,14 +43,20 @@ import java.util.Set; import org.junit.After; import org.junit.Before; import org.junit.ClassRule; +import org.junit.Rule; import org.junit.Test; import org.springframework.dao.DataAccessException; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Point; import org.springframework.data.redis.connection.ClusterConnectionTests; import org.springframework.data.redis.connection.ClusterSlotHashUtil; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.connection.DefaultSortParameters; import org.springframework.data.redis.connection.DefaultTuple; import org.springframework.data.redis.connection.RedisClusterNode; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; import org.springframework.data.redis.connection.RedisListCommands.Position; import org.springframework.data.redis.connection.RedisNode; import org.springframework.data.redis.connection.RedisStringCommands.BitOperation; @@ -55,7 +66,9 @@ import org.springframework.data.redis.connection.RedisZSetCommands.Tuple; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.types.Expiration; +import org.springframework.data.redis.test.util.MinimumRedisVersionRule; import org.springframework.data.redis.test.util.RedisClusterRule; +import org.springframework.test.annotation.IfProfileValue; import redis.clients.jedis.HostAndPort; import redis.clients.jedis.JedisCluster; @@ -82,6 +95,13 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests { static final byte[] VALUE_2_BYTES = JedisConverters.toBytes(VALUE_2); static final byte[] VALUE_3_BYTES = JedisConverters.toBytes(VALUE_3); + static final GeoLocation ARIGENTO = new GeoLocation("arigento".getBytes(Charset.forName("UTF-8")), + POINT_ARIGENTO); + static final GeoLocation CATANIA = new GeoLocation("catania".getBytes(Charset.forName("UTF-8")), + POINT_CATANIA); + static final GeoLocation PALERMO = new GeoLocation("palermo".getBytes(Charset.forName("UTF-8")), + POINT_PALERMO); + JedisCluster nativeConnection; JedisClusterConnection clusterConnection; @@ -90,6 +110,11 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests { */ public static @ClassRule RedisClusterRule clusterRule = new RedisClusterRule(); + /** + * Check for specific Redis Versions + */ + public @Rule MinimumRedisVersionRule version = new MinimumRedisVersionRule(); + @Before public void setUp() throws IOException { @@ -2454,4 +2479,245 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests { assertThat(nativeConnection.exists(KEY_1_BYTES), is(false)); } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoAddSingleGeoLocation() { + assertThat(clusterConnection.geoAdd(KEY_1_BYTES, PALERMO), is(1L)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoAddMultipleGeoLocations() { + assertThat(clusterConnection.geoAdd(KEY_1_BYTES, Arrays.asList(PALERMO, ARIGENTO, CATANIA, PALERMO)), is(3L)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoDist() { + + nativeConnection.geoadd(KEY_1_BYTES, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + Distance distance = clusterConnection.geoDist(KEY_1_BYTES, PALERMO.getName(), CATANIA.getName()); + assertThat(distance.getValue(), is(closeTo(166274.15156960033D, 0.005))); + assertThat(distance.getUnit(), is("m")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoDistWithMetric() { + + nativeConnection.geoadd(KEY_1_BYTES, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + Distance distance = clusterConnection.geoDist(KEY_1_BYTES, PALERMO.getName(), CATANIA.getName(), KILOMETERS); + assertThat(distance.getValue(), is(closeTo(166.27415156960033D, 0.005))); + assertThat(distance.getUnit(), is("km")); + + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoHash() { + + nativeConnection.geoadd(KEY_1_BYTES, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + List result = clusterConnection.geoHash(KEY_1_BYTES, PALERMO.getName(), CATANIA.getName()); + assertThat(result, contains("sqc8b49rny0", "sqdtr74hyu0")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoHashNonExisting() { + + nativeConnection.geoadd(KEY_1_BYTES, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + List result = clusterConnection.geoHash(KEY_1_BYTES, PALERMO.getName(), ARIGENTO.getName(), + CATANIA.getName()); + assertThat(result, contains("sqc8b49rny0", (String) null, "sqdtr74hyu0")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoPosition() { + + nativeConnection.geoadd(KEY_1_BYTES, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + List positions = clusterConnection.geoPos(KEY_1_BYTES, PALERMO.getName(), CATANIA.getName()); + + assertThat(positions.get(0).getX(), is(closeTo(POINT_PALERMO.getX(), 0.005))); + assertThat(positions.get(0).getY(), is(closeTo(POINT_PALERMO.getY(), 0.005))); + + assertThat(positions.get(1).getX(), is(closeTo(POINT_CATANIA.getX(), 0.005))); + assertThat(positions.get(1).getY(), is(closeTo(POINT_CATANIA.getY(), 0.005))); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoPositionNonExisting() { + + nativeConnection.geoadd(KEY_1_BYTES, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + List positions = clusterConnection.geoPos(KEY_1_BYTES, PALERMO.getName(), ARIGENTO.getName(), + CATANIA.getName()); + + assertThat(positions.get(0).getX(), is(closeTo(POINT_PALERMO.getX(), 0.005))); + assertThat(positions.get(0).getY(), is(closeTo(POINT_PALERMO.getY(), 0.005))); + + assertThat(positions.get(1), is(nullValue())); + + assertThat(positions.get(2).getX(), is(closeTo(POINT_CATANIA.getX(), 0.005))); + assertThat(positions.get(2).getY(), is(closeTo(POINT_CATANIA.getY(), 0.005))); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoRadiusShouldReturnMembersCorrectly() { + + nativeConnection.geoadd(KEY_1_BYTES, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + GeoResults> result = clusterConnection.geoRadius(KEY_1_BYTES, + new Circle(new Point(15D, 37D), new Distance(150D, KILOMETERS))); + assertThat(result.getContent(), hasSize(2)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoRadiusShouldReturnDistanceCorrectly() { + + nativeConnection.geoadd(KEY_1_BYTES, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + GeoResults> result = clusterConnection.geoRadius(KEY_1_BYTES, + new Circle(new Point(15D, 37D), new Distance(200D, KILOMETERS)), newGeoRadiusArgs().includeDistance()); + + assertThat(result.getContent(), hasSize(3)); + assertThat(result.getContent().get(0).getDistance().getValue(), is(closeTo(130.423D, 0.005))); + assertThat(result.getContent().get(0).getDistance().getUnit(), is("km")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoRadiusShouldApplyLimit() { + + nativeConnection.geoadd(KEY_1_BYTES, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + GeoResults> result = clusterConnection.geoRadius(KEY_1_BYTES, + new Circle(new Point(15D, 37D), new Distance(200D, KILOMETERS)), newGeoRadiusArgs().limit(2)); + + assertThat(result.getContent(), hasSize(2)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoRadiusByMemberShouldReturnMembersCorrectly() { + + nativeConnection.geoadd(KEY_1_BYTES, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + GeoResults> result = clusterConnection.geoRadiusByMember(KEY_1_BYTES, PALERMO.getName(), + new Distance(100, KILOMETERS), newGeoRadiusArgs().sortAscending()); + + assertThat(result.getContent().get(0).getContent().getName(), is(PALERMO.getName())); + assertThat(result.getContent().get(1).getContent().getName(), is(ARIGENTO.getName())); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoRadiusByMemberShouldReturnDistanceCorrectly() { + + nativeConnection.geoadd(KEY_1_BYTES, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + GeoResults> result = clusterConnection.geoRadiusByMember(KEY_1_BYTES, PALERMO.getName(), + new Distance(100, KILOMETERS), newGeoRadiusArgs().includeDistance()); + + assertThat(result.getContent(), hasSize(2)); + assertThat(result.getContent().get(0).getDistance().getValue(), is(closeTo(90.978D, 0.005))); + assertThat(result.getContent().get(0).getDistance().getUnit(), is("km")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoRadiusByMemberShouldApplyLimit() { + + nativeConnection.geoadd(KEY_1_BYTES, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + GeoResults> result = clusterConnection.geoRadiusByMember(KEY_1_BYTES, PALERMO.getName(), + new Distance(200, KILOMETERS), newGeoRadiusArgs().limit(2)); + + assertThat(result.getContent(), hasSize(2)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoRemoveDeletesMembers() { + + nativeConnection.geoadd(KEY_1_BYTES, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1_BYTES, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + assertThat(clusterConnection.geoRemove(KEY_1_BYTES, ARIGENTO.getName()), is(1L)); + } } diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisSentinelIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisSentinelIntegrationTests.java index f30a66c9f..60a8bc40a 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisSentinelIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisSentinelIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -16,13 +16,14 @@ package org.springframework.data.redis.connection.jedis; import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.*; import java.util.Collection; import java.util.List; import org.junit.After; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; @@ -32,6 +33,7 @@ import org.springframework.data.redis.connection.RedisSentinelConfiguration; import org.springframework.data.redis.connection.RedisSentinelConnection; import org.springframework.data.redis.connection.RedisServer; import org.springframework.data.redis.connection.ReturnType; +import org.springframework.data.redis.test.util.MinimumRedisVersionRule; import org.springframework.data.redis.test.util.RedisSentinelRule; import org.springframework.test.annotation.IfProfileValue; @@ -40,20 +42,19 @@ import org.springframework.test.annotation.IfProfileValue; * @author Thomas Darimont */ public class JedisSentinelIntegrationTests extends AbstractConnectionIntegrationTests { - + private static final String MASTER_NAME = "mymaster"; private static final RedisServer SENTINEL_0 = new RedisServer("127.0.0.1", 26379); private static final RedisServer SENTINEL_1 = new RedisServer("127.0.0.1", 26380); - + private static final RedisServer SLAVE_0 = new RedisServer("127.0.0.1", 6380); private static final RedisServer SLAVE_1 = new RedisServer("127.0.0.1", 6381); - - private static final RedisSentinelConfiguration SENTINEL_CONFIG = new RedisSentinelConfiguration() // - .master(MASTER_NAME) - .sentinel(SENTINEL_0) - .sentinel(SENTINEL_1); - public @Rule RedisSentinelRule sentinelRule = RedisSentinelRule.forConfig(SENTINEL_CONFIG).oneActive(); + private static final RedisSentinelConfiguration SENTINEL_CONFIG = new RedisSentinelConfiguration() // + .master(MASTER_NAME).sentinel(SENTINEL_0).sentinel(SENTINEL_1); + + public static @ClassRule RedisSentinelRule sentinelRule = RedisSentinelRule.forConfig(SENTINEL_CONFIG).oneActive(); + public @Rule MinimumRedisVersionRule minimumVersionRule = new MinimumRedisVersionRule(); @Before public void setUp() { @@ -129,9 +130,9 @@ public class JedisSentinelIntegrationTests extends AbstractConnectionIntegration List servers = (List) connectionFactory.getSentinelConnection().masters(); assertThat(servers.size(), is(1)); - assertThat(servers.get(0).getName(),is(MASTER_NAME)); + assertThat(servers.get(0).getName(), is(MASTER_NAME)); } - + /** * @see DATAREDIS-330 */ @@ -139,10 +140,10 @@ public class JedisSentinelIntegrationTests extends AbstractConnectionIntegration public void shouldReadSlavesOfMastersCorrectly() { RedisSentinelConnection sentinelConnection = connectionFactory.getSentinelConnection(); - + List servers = (List) sentinelConnection.masters(); assertThat(servers.size(), is(1)); - + Collection slaves = sentinelConnection.slaves(servers.get(0)); assertThat(slaves.size(), is(2)); assertThat(slaves, hasItems(SLAVE_0, SLAVE_1)); diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java index 0416846e9..decfce555 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java @@ -16,12 +16,18 @@ package org.springframework.data.redis.connection.lettuce; import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.collection.IsCollectionWithSize.*; import static org.hamcrest.collection.IsIterableContainingInOrder.*; +import static org.hamcrest.core.Is.is; 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.connection.RedisGeoCommands.DistanceUnit.*; +import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.*; import static org.springframework.data.redis.core.ScanOptions.*; +import java.nio.charset.Charset; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -36,14 +42,21 @@ import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Before; import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Rule; import org.junit.Test; import org.springframework.dao.DataAccessException; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Point; import org.springframework.data.redis.connection.ClusterConnectionTests; import org.springframework.data.redis.connection.ClusterSlotHashUtil; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.connection.DefaultSortParameters; import org.springframework.data.redis.connection.DefaultTuple; import org.springframework.data.redis.connection.RedisClusterNode; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; import org.springframework.data.redis.connection.RedisListCommands.Position; import org.springframework.data.redis.connection.RedisNode; import org.springframework.data.redis.connection.RedisStringCommands.BitOperation; @@ -54,7 +67,9 @@ import org.springframework.data.redis.connection.jedis.JedisConverters; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.types.Expiration; +import org.springframework.data.redis.test.util.MinimumRedisVersionRule; import org.springframework.data.redis.test.util.RedisClusterRule; +import org.springframework.test.annotation.IfProfileValue; import com.lambdaworks.redis.RedisURI.Builder; import com.lambdaworks.redis.cluster.RedisAdvancedClusterConnection; @@ -78,12 +93,28 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests { static final byte[] VALUE_2_BYTES = LettuceConverters.toBytes(VALUE_2); static final byte[] VALUE_3_BYTES = LettuceConverters.toBytes(VALUE_3); + static final GeoLocation ARIGENTO = new GeoLocation("arigento", POINT_ARIGENTO); + static final GeoLocation CATANIA = new GeoLocation("catania", POINT_CATANIA); + static final GeoLocation PALERMO = new GeoLocation("palermo", POINT_PALERMO); + + static final GeoLocation ARIGENTO_BYTES = new GeoLocation( + "arigento".getBytes(Charset.forName("UTF-8")), POINT_ARIGENTO); + static final GeoLocation CATANIA_BYTES = new GeoLocation("catania".getBytes(Charset.forName("UTF-8")), + POINT_CATANIA); + static final GeoLocation PALERMO_BYTES = new GeoLocation("palermo".getBytes(Charset.forName("UTF-8")), + POINT_PALERMO); + RedisClusterClient client; RedisAdvancedClusterConnection nativeConnection; LettuceClusterConnection clusterConnection; public static @ClassRule RedisClusterRule clusterAvailable = new RedisClusterRule(); + /** + * Check for specific Redis Versions + */ + public @Rule MinimumRedisVersionRule version = new MinimumRedisVersionRule(); + @Before public void setUp() { @@ -2441,4 +2472,249 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests { assertThat(nativeConnection.exists(KEY_1), is(false)); } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoAddSingleGeoLocation() { + assertThat(clusterConnection.geoAdd(KEY_1_BYTES, PALERMO_BYTES), is(1L)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoAddMultipleGeoLocations() { + assertThat(clusterConnection.geoAdd(KEY_1_BYTES, + Arrays.asList(PALERMO_BYTES, ARIGENTO_BYTES, CATANIA_BYTES, PALERMO_BYTES)), is(3L)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoDist() { + + nativeConnection.geoadd(KEY_1, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + Distance distance = clusterConnection.geoDist(KEY_1_BYTES, PALERMO_BYTES.getName(), CATANIA_BYTES.getName()); + assertThat(distance.getValue(), is(closeTo(166274.15156960033D, 0.005))); + assertThat(distance.getUnit(), is("m")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoDistWithMetric() { + + nativeConnection.geoadd(KEY_1, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + Distance distance = clusterConnection.geoDist(KEY_1_BYTES, PALERMO_BYTES.getName(), CATANIA_BYTES.getName(), + KILOMETERS); + assertThat(distance.getValue(), is(closeTo(166.27415156960033D, 0.005))); + assertThat(distance.getUnit(), is("km")); + + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @Ignore("see mp911de/lettuce#241") + public void geoHash() { + + nativeConnection.geoadd(KEY_1, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + List result = clusterConnection.geoHash(KEY_1_BYTES, PALERMO_BYTES.getName(), CATANIA_BYTES.getName()); + assertThat(result, contains("sqc8b49rny0", "sqdtr74hyu0")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + @Ignore("see mp911de/lettuce#241") + public void geoHashNonExisting() { + + nativeConnection.geoadd(KEY_1, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + List result = clusterConnection.geoHash(KEY_1_BYTES, PALERMO_BYTES.getName(), ARIGENTO_BYTES.getName(), + CATANIA_BYTES.getName()); + assertThat(result, contains("sqc8b49rny0", (String) null, "sqdtr74hyu0")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoPosition() { + + nativeConnection.geoadd(KEY_1, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + List positions = clusterConnection.geoPos(KEY_1_BYTES, PALERMO_BYTES.getName(), CATANIA_BYTES.getName()); + + assertThat(positions.get(0).getX(), is(closeTo(POINT_PALERMO.getX(), 0.005))); + assertThat(positions.get(0).getY(), is(closeTo(POINT_PALERMO.getY(), 0.005))); + + assertThat(positions.get(1).getX(), is(closeTo(POINT_CATANIA.getX(), 0.005))); + assertThat(positions.get(1).getY(), is(closeTo(POINT_CATANIA.getY(), 0.005))); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoPositionNonExisting() { + + nativeConnection.geoadd(KEY_1, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + List positions = clusterConnection.geoPos(KEY_1_BYTES, PALERMO_BYTES.getName(), ARIGENTO_BYTES.getName(), + CATANIA_BYTES.getName()); + + assertThat(positions.get(0).getX(), is(closeTo(POINT_PALERMO.getX(), 0.005))); + assertThat(positions.get(0).getY(), is(closeTo(POINT_PALERMO.getY(), 0.005))); + + assertThat(positions.get(1), is(nullValue())); + + assertThat(positions.get(2).getX(), is(closeTo(POINT_CATANIA.getX(), 0.005))); + assertThat(positions.get(2).getY(), is(closeTo(POINT_CATANIA.getY(), 0.005))); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoRadiusShouldReturnMembersCorrectly() { + + nativeConnection.geoadd(KEY_1, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + GeoResults> result = clusterConnection.geoRadius(KEY_1_BYTES, + new Circle(new Point(15D, 37D), new Distance(150D, KILOMETERS))); + assertThat(result.getContent(), hasSize(2)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoRadiusShouldReturnDistanceCorrectly() { + + nativeConnection.geoadd(KEY_1, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + GeoResults> result = clusterConnection.geoRadius(KEY_1_BYTES, + new Circle(new Point(15D, 37D), new Distance(200D, KILOMETERS)), newGeoRadiusArgs().includeDistance()); + + assertThat(result.getContent(), hasSize(3)); + assertThat(result.getContent().get(0).getDistance().getValue(), is(closeTo(130.423D, 0.005))); + assertThat(result.getContent().get(0).getDistance().getUnit(), is("km")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoRadiusShouldApplyLimit() { + + nativeConnection.geoadd(KEY_1, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + GeoResults> result = clusterConnection.geoRadius(KEY_1_BYTES, + new Circle(new Point(15D, 37D), new Distance(200D, KILOMETERS)), newGeoRadiusArgs().limit(2)); + + assertThat(result.getContent(), hasSize(2)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoRadiusByMemberShouldReturnMembersCorrectly() { + + nativeConnection.geoadd(KEY_1, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + GeoResults> result = clusterConnection.geoRadiusByMember(KEY_1_BYTES, PALERMO_BYTES.getName(), + new Distance(100, KILOMETERS), newGeoRadiusArgs().sortAscending()); + + assertThat(result.getContent().get(0).getContent().getName(), is(PALERMO_BYTES.getName())); + assertThat(result.getContent().get(1).getContent().getName(), is(ARIGENTO_BYTES.getName())); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoRadiusByMemberShouldReturnDistanceCorrectly() { + + nativeConnection.geoadd(KEY_1, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + GeoResults> result = clusterConnection.geoRadiusByMember(KEY_1_BYTES, PALERMO_BYTES.getName(), + new Distance(100, KILOMETERS), newGeoRadiusArgs().includeDistance()); + + assertThat(result.getContent(), hasSize(2)); + assertThat(result.getContent().get(0).getDistance().getValue(), is(closeTo(90.978D, 0.005))); + assertThat(result.getContent().get(0).getDistance().getUnit(), is("km")); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoRadiusByMemberShouldApplyLimit() { + + nativeConnection.geoadd(KEY_1, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + GeoResults> result = clusterConnection.geoRadiusByMember(KEY_1_BYTES, PALERMO_BYTES.getName(), + new Distance(200, KILOMETERS), newGeoRadiusArgs().limit(2)); + + assertThat(result.getContent(), hasSize(2)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @IfProfileValue(name = "redisVersion", value = "3.2+") + public void geoRemoveDeletesMembers() { + + nativeConnection.geoadd(KEY_1, PALERMO.getPoint().getX(), PALERMO.getPoint().getY(), PALERMO.getName()); + nativeConnection.geoadd(KEY_1, ARIGENTO.getPoint().getX(), ARIGENTO.getPoint().getY(), ARIGENTO.getName()); + nativeConnection.geoadd(KEY_1, CATANIA.getPoint().getX(), CATANIA.getPoint().getY(), CATANIA.getName()); + + assertThat(clusterConnection.geoRemove(KEY_1_BYTES, ARIGENTO_BYTES.getName()), is(1L)); + } } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxIntegrationTests.java index b1ef498fa..4b089cb48 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-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. diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionTransactionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionTransactionIntegrationTests.java index 446fb1a87..7066f6ea0 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionTransactionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionTransactionIntegrationTests.java @@ -19,6 +19,7 @@ import static org.junit.Assert.*; import java.util.Arrays; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.data.redis.connection.AbstractConnectionTransactionIntegrationTests; @@ -67,4 +68,83 @@ public class LettuceConnectionTransactionIntegrationTests extends AbstractConnec super.testSelect(); } + /** + * @see DATAREDIS-438 + */ + @Test + @Override + @Ignore("see mp911de/lettuce#241") + public void geoPosition() { + super.geoPosition(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @Override + @Ignore("see mp911de/lettuce#241") + public void geoPositionNonExisting() { + super.geoPositionNonExisting(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @Override + @Ignore("see mp911de/lettuce#241") + public void geoRadiusByMemberShouldApplyLimit() { + super.geoRadiusByMemberShouldApplyLimit(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @Override + @Ignore("see mp911de/lettuce#241") + public void geoRadiusByMemberShouldReturnDistanceCorrectly() { + super.geoRadiusByMemberShouldReturnDistanceCorrectly(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @Override + @Ignore("see mp911de/lettuce#241") + public void geoRadiusByMemberShouldReturnMembersCorrectly() { + super.geoRadiusByMemberShouldReturnMembersCorrectly(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @Override + @Ignore("see mp911de/lettuce#241") + public void geoRadiusShouldApplyLimit() { + super.geoRadiusShouldApplyLimit(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @Override + @Ignore("see mp911de/lettuce#") + public void geoRadiusShouldReturnDistanceCorrectly() { + super.geoRadiusShouldReturnDistanceCorrectly(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @Override + @Ignore("see mp911de/lettuce#241") + public void geoRadiusShouldReturnMembersCorrectly() { + super.geoRadiusShouldReturnMembersCorrectly(); + } } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceSentinelIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceSentinelIntegrationTests.java index 029be25a1..deb70242b 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceSentinelIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceSentinelIntegrationTests.java @@ -25,6 +25,8 @@ import java.util.List; import org.junit.After; import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.springframework.data.redis.ConnectionFactoryTracker; @@ -34,6 +36,7 @@ import org.springframework.data.redis.connection.RedisSentinelConfiguration; import org.springframework.data.redis.connection.RedisSentinelConnection; import org.springframework.data.redis.connection.RedisServer; import org.springframework.data.redis.connection.StringRedisConnection; +import org.springframework.data.redis.test.util.MinimumRedisVersionRule; import org.springframework.data.redis.test.util.RedisSentinelRule; /** @@ -52,7 +55,8 @@ public class LettuceSentinelIntegrationTests extends AbstractConnectionIntegrati private static final RedisSentinelConfiguration SENTINEL_CONFIG = new RedisSentinelConfiguration() // .master(MASTER_NAME).sentinel(SENTINEL_0).sentinel(SENTINEL_1); - public @Rule RedisSentinelRule sentinelRule = RedisSentinelRule.forConfig(SENTINEL_CONFIG).oneActive(); + public static @ClassRule RedisSentinelRule sentinelRule = RedisSentinelRule.forConfig(SENTINEL_CONFIG).oneActive(); + public @Rule MinimumRedisVersionRule minimumVersionRule = new MinimumRedisVersionRule(); @Before public void setUp() { @@ -121,4 +125,23 @@ public class LettuceSentinelIntegrationTests extends AbstractConnectionIntegrati } } + /** + * @see DATAREDIS-438 + */ + @Test + @Override + @Ignore("see mp911de/lettuce#241") + public void geoHash() { + super.geoHash(); + } + + /** + * @see DATAREDIS-438 + */ + @Test + @Override + @Ignore("see mp911de/lettuce#241") + public void geoHashNonExisting() { + super.geoHashNonExisting(); + } } diff --git a/src/test/java/org/springframework/data/redis/core/DefaultGeoOperationsTests.java b/src/test/java/org/springframework/data/redis/core/DefaultGeoOperationsTests.java index 5007bd177..9740c99bb 100644 --- a/src/test/java/org/springframework/data/redis/core/DefaultGeoOperationsTests.java +++ b/src/test/java/org/springframework/data/redis/core/DefaultGeoOperationsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 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. @@ -15,51 +15,76 @@ */ package org.springframework.data.redis.core; +import static org.hamcrest.collection.IsCollectionWithSize.*; +import static org.hamcrest.core.Is.*; +import static org.hamcrest.core.IsEqual.*; +import static org.hamcrest.core.IsNull.*; +import static org.hamcrest.number.IsCloseTo.*; +import static org.junit.Assert.*; +import static org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit.*; +import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.*; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.junit.After; -import org.junit.Assert; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; +import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Point; +import org.springframework.data.redis.ConnectionFactoryTracker; import org.springframework.data.redis.ObjectFactory; -import org.springframework.data.redis.RedisTestProfileValueSource; -import org.springframework.data.redis.TestCondition; import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit; +import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; - -import java.text.DecimalFormat; -import java.util.*; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - -import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; -import static org.springframework.data.redis.SpinBarrier.waitFor; -import static org.springframework.data.redis.matcher.RedisTestMatchers.isEqual; +import org.springframework.data.redis.test.util.MinimumRedisVersionRule; +import org.springframework.test.annotation.IfProfileValue; /** * Integration test of {@link org.springframework.data.redis.core.DefaultGeoOperations} * * @author Ninad Divadkar + * @author Christoph Strobl */ @RunWith(Parameterized.class) +@IfProfileValue(name = "redisVersion", value = "3.2.0+") public class DefaultGeoOperationsTests { + public static @ClassRule MinimumRedisVersionRule versionRule = new MinimumRedisVersionRule(); + + private static final Point POINT_ARIGENTO = new Point(13.583333, 37.316667); + private static final Point POINT_CATANIA = new Point(15.087269, 37.502669); + private static final Point POINT_PALERMO = new Point(13.361389, 38.115556); + + private static final double DISTANCE_PALERMO_CATANIA_METERS = 166274.15156960033; + private static final double DISTANCE_PALERMO_CATANIA_KILOMETERS = 166.27415156960033; + private static final double DISTANCE_PALERMO_CATANIA_MILES = 103.31822459492733; + private static final double DISTANCE_PALERMO_CATANIA_FEET = 545518.8699790037; + private RedisTemplate redisTemplate; - private ObjectFactory keyFactory; - private ObjectFactory valueFactory; - private GeoOperations geoOperations; public DefaultGeoOperationsTests(RedisTemplate redisTemplate, ObjectFactory keyFactory, - ObjectFactory valueFactory) { + ObjectFactory valueFactory) { + this.redisTemplate = redisTemplate; this.keyFactory = keyFactory; this.valueFactory = valueFactory; + + ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory()); } @Parameters @@ -67,6 +92,11 @@ public class DefaultGeoOperationsTests { return AbstractOperationsTestParams.testParams(); } + @AfterClass + public static void cleanUp() { + ConnectionFactoryTracker.cleanUp(); + } + @Before public void setUp() { geoOperations = redisTemplate.opsForGeo(); @@ -74,6 +104,7 @@ public class DefaultGeoOperationsTests { @After public void tearDown() { + redisTemplate.execute(new RedisCallback() { public Object doInRedis(RedisConnection connection) { connection.flushDb(); @@ -82,174 +113,370 @@ public class DefaultGeoOperationsTests { }); } + /** + * @see DATAREDIS-438 + */ @Test - public void testGeoAdd() throws Exception { - K key = keyFactory.instance(); - M v1 = valueFactory.instance(); - Long numAdded = geoOperations.geoAdd(key, 13.361389, 38.115556, v1); - assertEquals(numAdded.longValue(), 1L); + public void testGeoAdd() { + + Long numAdded = geoOperations.geoAdd(keyFactory.instance(), POINT_PALERMO, valueFactory.instance()); + + assertThat(numAdded, is(1L)); } - @Test - public void testGeoAdd2() throws Exception { - K key = keyFactory.instance(); - Map memberCoordinateMap = new HashMap(); - memberCoordinateMap.put(valueFactory.instance(), new GeoCoordinate(2.2323, 43.324)); - memberCoordinateMap.put(valueFactory.instance(), new GeoCoordinate(12.993, 31.3994)); - Long numAdded = geoOperations.geoAdd(key, memberCoordinateMap); - assertEquals(numAdded.longValue(), 2L); - } + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoAddWithLocationMap() { - @Test - public void testGeoDist() throws Exception { - K key = keyFactory.instance(); - M v1 = valueFactory.instance(); - M v2 = valueFactory.instance(); + Map memberCoordinateMap = new HashMap(); + memberCoordinateMap.put(valueFactory.instance(), POINT_PALERMO); + memberCoordinateMap.put(valueFactory.instance(), POINT_CATANIA); - geoOperations.geoAdd(key, 13.361389, 38.115556, v1); - geoOperations.geoAdd(key, 15.087269, 37.502669, v2); + Long numAdded = geoOperations.geoAdd(keyFactory.instance(), memberCoordinateMap); - Double dist = geoOperations.geoDist(key, v1, v2); - assertEquals(dist.doubleValue(), 166274.15156960033, 0.00001); // gives in meters + assertThat(numAdded, is(2L)); + } - dist = geoOperations.geoDist(key, v1, v2, GeoUnit.KiloMeters); - assertEquals(dist.doubleValue(), 166.27415156960033, 0.00001); + /** + * @see DATAREDIS-438 + */ + @Test + public void geoDistShouldReturnDistanceInMetersByDefault() { - dist = geoOperations.geoDist(key, v1, v2, GeoUnit.Miles); - assertEquals(dist.doubleValue(), 103.31822459492733, 0.00001); + K key = keyFactory.instance(); + M member1 = valueFactory.instance(); + M member2 = valueFactory.instance(); - dist = geoOperations.geoDist(key, v1, v2, GeoUnit.Feet); - assertEquals(dist.doubleValue(), 545518.8699790037, 0.00001); - } + geoOperations.geoAdd(key, POINT_PALERMO, member1); + geoOperations.geoAdd(key, POINT_CATANIA, member2); - @Test - public void testGeoHash() throws Exception { - K key = keyFactory.instance(); - M v1 = valueFactory.instance(); - M v2 = valueFactory.instance(); + Distance dist = geoOperations.geoDist(key, member1, member2); + assertThat(dist.getValue(), closeTo(DISTANCE_PALERMO_CATANIA_METERS, 0.005)); + assertThat(dist.getUnit(), is(equalTo("m"))); + } - geoOperations.geoAdd(key, 13.361389, 38.115556, v1); - geoOperations.geoAdd(key, 15.087269, 37.502669, v2); + /** + * @see DATAREDIS-438 + */ + @Test + public void geoDistShouldReturnDistanceInKilometersCorrectly() { - List result = geoOperations.geoHash(key, v1, v2); - assertEquals(result.size(), 2); + K key = keyFactory.instance(); + M member1 = valueFactory.instance(); + M member2 = valueFactory.instance(); - final RedisSerializer serializer = new StringRedisSerializer(); + geoOperations.geoAdd(key, POINT_PALERMO, member1); + geoOperations.geoAdd(key, POINT_CATANIA, member2); - assertEquals(serializer.deserialize(result.get(0)), "sqc8b49rny0"); - assertEquals(serializer.deserialize(result.get(1)), "sqdtr74hyu0"); - } + Distance dist = geoOperations.geoDist(key, member1, member2, KILOMETERS); + assertThat(dist.getValue(), closeTo(DISTANCE_PALERMO_CATANIA_KILOMETERS, 0.005)); + assertThat(dist.getUnit(), is(equalTo("km"))); + } - @Test - public void testGeoPos() throws Exception { - K key = keyFactory.instance(); - M v1 = valueFactory.instance(); - M v2 = valueFactory.instance(); - M v3 = valueFactory.instance(); + /** + * @see DATAREDIS-438 + */ + @Test + public void geoDistShouldReturnDistanceInMilesCorrectly() { - geoOperations.geoAdd(key, 13.361389, 38.115556, v1); - geoOperations.geoAdd(key, 15.087269, 37.502669, v2); + K key = keyFactory.instance(); + M member1 = valueFactory.instance(); + M member2 = valueFactory.instance(); - List result = geoOperations.geoPos(key, v1, v2, v3);// v3 is nonexisting - assertEquals(result.size(), 3); + geoOperations.geoAdd(key, POINT_PALERMO, member1); + geoOperations.geoAdd(key, POINT_CATANIA, member2); - assertEquals(result.get(0).getLongitude(), 13.361389338970184, 0.000001); - assertEquals(result.get(0).getLatitude(), 38.115556395496299, 0.000001); + Distance dist = geoOperations.geoDist(key, member1, member2, DistanceUnit.MILES); + assertThat(dist.getValue(), closeTo(DISTANCE_PALERMO_CATANIA_MILES, 0.005)); + assertThat(dist.getUnit(), is(equalTo("mi"))); + } - assertEquals(result.get(1).getLongitude(), 15.087267458438873, 0.000001); - assertEquals(result.get(1).getLatitude(), 37.50266842333162, 0.000001); + /** + * @see DATAREDIS-438 + */ + @Test + public void geoDistShouldReturnDistanceInFeeCorrectly() { - assertNull(result.get(2)); - } + K key = keyFactory.instance(); + M member1 = valueFactory.instance(); + M member2 = valueFactory.instance(); - @Test - public void testGeoRadius() throws Exception{ - K key = keyFactory.instance(); - M v1 = valueFactory.instance(); - M v2 = valueFactory.instance(); + geoOperations.geoAdd(key, POINT_PALERMO, member1); + geoOperations.geoAdd(key, POINT_CATANIA, member2); - geoOperations.geoAdd(key, 13.361389, 38.115556, v1); - geoOperations.geoAdd(key, 15.087269, 37.502669, v2); + Distance dist = geoOperations.geoDist(key, member1, member2, DistanceUnit.FEET); + assertThat(dist.getValue(), closeTo(DISTANCE_PALERMO_CATANIA_FEET, 0.005)); + assertThat(dist.getUnit(), is(equalTo("ft"))); + } - List result = geoOperations.georadius(key, 15, 37, 200, GeoUnit.KiloMeters); - Assert.assertEquals(2, result.size()); + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoHash() { - // with dist, descending - result = geoOperations.georadius(key, 15, 37, 200, GeoUnit.KiloMeters, GeoRadiusParam.geoRadiusParam().withDist().sortDescending()); - Assert.assertEquals(2, result.size()); - Assert.assertEquals(result.get(0).getDistance(), 190.4424d, 0.0001); - Assert.assertEquals(result.get(1).getDistance(), 56.4413d, 0.0001); + K key = keyFactory.instance(); + M v1 = valueFactory.instance(); + M v2 = valueFactory.instance(); - // with coord, ascending - result = geoOperations.georadius(key, 15, 37, 200, GeoUnit.KiloMeters, GeoRadiusParam.geoRadiusParam().withCoord().sortAscending()); - Assert.assertEquals(2, result.size()); - Assert.assertEquals(result.get(1).getCoordinate().getLongitude(), 13.361389338970184d, 0.0001); - Assert.assertEquals(result.get(1).getCoordinate().getLatitude(), 38.115556395496299d, 0.0001); - Assert.assertEquals(result.get(0).getCoordinate().getLongitude(), 15.087267458438873d, 0.0001); - Assert.assertEquals(result.get(0).getCoordinate().getLatitude(), 37.50266842333162d, 0.0001); + geoOperations.geoAdd(key, POINT_PALERMO, v1); + geoOperations.geoAdd(key, POINT_CATANIA, v2); - // with coord and dist, ascending - result = geoOperations.georadius(key, 15, 37, 200, GeoUnit.KiloMeters, GeoRadiusParam.geoRadiusParam().withCoord().withDist().sortAscending()); - Assert.assertEquals(2, result.size()); + List result = geoOperations.geoHash(key, v1, v2); + assertThat(result, hasSize(2)); - Assert.assertEquals(result.get(0).getDistance(), 56.4413d, 0.0001); - Assert.assertEquals(result.get(0).getCoordinate().getLongitude(), 15.087267458438873d, 0.0001); - Assert.assertEquals(result.get(0).getCoordinate().getLatitude(), 37.50266842333162d, 0.0001); - Assert.assertEquals(result.get(1).getDistance(), 190.4424d, 0.0001); - Assert.assertEquals(result.get(1).getCoordinate().getLongitude(), 13.361389338970184d, 0.0001); - Assert.assertEquals(result.get(1).getCoordinate().getLatitude(), 38.115556395496299d, 0.0001); - } + final RedisSerializer serializer = new StringRedisSerializer(); - @Test - public void testGeoRadiusByMember() throws Exception{ - K key = keyFactory.instance(); - M v1 = valueFactory.instance(); - M v2 = valueFactory.instance(); - M v3 = valueFactory.instance(); + assertThat(result.get(0), is(equalTo("sqc8b49rny0"))); + assertThat(result.get(1), is(equalTo("sqdtr74hyu0"))); + } - geoOperations.geoAdd(key, 13.361389, 38.115556, v1);//palermo - geoOperations.geoAdd(key, 15.087269, 37.502669, v2);//catania + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoPos() { - geoOperations.geoAdd(key, 13.583333, 37.316667, v3);//Agrigento + K key = keyFactory.instance(); + M v1 = valueFactory.instance(); + M v2 = valueFactory.instance(); + M v3 = valueFactory.instance(); - List result = geoOperations.georadiusByMember(key, v3, 200, GeoUnit.KiloMeters); - Assert.assertEquals(3, result.size()); + geoOperations.geoAdd(key, POINT_PALERMO, v1); + geoOperations.geoAdd(key, POINT_CATANIA, v2); - // with dist, descending - result = geoOperations.georadiusByMember(key, v3, 100, GeoUnit.KiloMeters, GeoRadiusParam.geoRadiusParam().withDist().sortDescending()); - Assert.assertEquals(2, result.size()); - Assert.assertEquals(result.get(0).getDistance(), 90.9778d, 0.0001); - Assert.assertEquals(result.get(1).getDistance(), 0.0d, 0.0001); //itself + List result = geoOperations.geoPos(key, v1, v2, v3);// v3 is nonexisting + assertThat(result, hasSize(3)); - // with coord, ascending - result = geoOperations.georadiusByMember(key, v3, 100, GeoUnit.KiloMeters, GeoRadiusParam.geoRadiusParam().withCoord().sortAscending()); - Assert.assertEquals(2, result.size()); - Assert.assertEquals(result.get(0).getCoordinate().getLongitude(), 13.583331406116486d, 0.0001); - Assert.assertEquals(result.get(0).getCoordinate().getLatitude(), 37.316668049938166d, 0.0001); - Assert.assertEquals(result.get(1).getCoordinate().getLongitude(), 13.361389338970184d, 0.0001); - Assert.assertEquals(result.get(1).getCoordinate().getLatitude(), 38.115556395496299d, 0.0001); + assertThat(result.get(0).getX(), is(closeTo(POINT_PALERMO.getX(), 0.005))); + assertThat(result.get(0).getY(), is(closeTo(POINT_PALERMO.getY(), 0.005))); + assertThat(result.get(1).getX(), is(closeTo(POINT_CATANIA.getX(), 0.005))); + assertThat(result.get(1).getY(), is(closeTo(POINT_CATANIA.getY(), 0.005))); - // with coord and dist, ascending - result = geoOperations.georadiusByMember(key, v1, 100, GeoUnit.KiloMeters, GeoRadiusParam.geoRadiusParam().withCoord().withDist().sortAscending()); - Assert.assertEquals(2, result.size()); + assertThat(result.get(2), is(nullValue())); + } - Assert.assertEquals(result.get(0).getDistance(), 0.0d, 0.0001); - Assert.assertEquals(result.get(0).getCoordinate().getLongitude(), 13.361389338970184d, 0.0001); - Assert.assertEquals(result.get(0).getCoordinate().getLatitude(), 38.1155563954963d, 0.0001); - Assert.assertEquals(result.get(1).getDistance(), 90.9778d, 0.0001); - Assert.assertEquals(result.get(1).getCoordinate().getLongitude(), 13.583331406116486d, 0.0001); - Assert.assertEquals(result.get(1).getCoordinate().getLatitude(), 37.316668049938166d, 0.0001); - } + /** + * @see DATAREDIS-438 + */ + @Test + public void geoRadiusShouldReturnMembersCorrectly() { - @Test - public void testGeoRemove(){ - K key = keyFactory.instance(); - M v1 = valueFactory.instance(); - Long numAdded = geoOperations.geoAdd(key, 13.361389, 38.115556, v1); - assertEquals(numAdded.longValue(), 1L); + K key = keyFactory.instance(); + M member1 = valueFactory.instance(); + M member2 = valueFactory.instance(); - Long numRemoved = geoOperations.geoRemove(key, v1); - assertEquals(1L, numRemoved.longValue()); - } + geoOperations.geoAdd(key, POINT_PALERMO, member1); + geoOperations.geoAdd(key, POINT_CATANIA, member2); + + GeoResults> result = geoOperations.georadius(key, + new Circle(new Point(15D, 37D), new Distance(200D, KILOMETERS))); + + assertThat(result.getContent(), hasSize(2)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void geoRadiusShouldReturnLocationsWithDistance() { + + K key = keyFactory.instance(); + M member1 = valueFactory.instance(); + M member2 = valueFactory.instance(); + + geoOperations.geoAdd(key, POINT_PALERMO, member1); + geoOperations.geoAdd(key, POINT_CATANIA, member2); + + GeoResults> result = geoOperations.georadius(key, + new Circle(new Point(15, 37), new Distance(200, KILOMETERS)), + newGeoRadiusArgs().includeDistance().sortDescending()); + + assertThat(result.getContent(), hasSize(2)); + assertThat(result.getContent().get(0).getDistance().getValue(), is(closeTo(190.4424d, 0.005))); + assertThat(result.getContent().get(0).getDistance().getUnit(), is(equalTo("km"))); + assertThat(result.getContent().get(0).getContent().getName(), is(member1)); + + assertThat(result.getContent().get(1).getDistance().getValue(), is(closeTo(56.4413d, 0.005))); + assertThat(result.getContent().get(1).getDistance().getUnit(), is(equalTo("km"))); + assertThat(result.getContent().get(1).getContent().getName(), is(member2)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void geoRadiusShouldReturnLocationsWithCoordinates() { + + K key = keyFactory.instance(); + M member1 = valueFactory.instance(); + M member2 = valueFactory.instance(); + + geoOperations.geoAdd(key, POINT_PALERMO, member1); + geoOperations.geoAdd(key, POINT_CATANIA, member2); + + GeoResults> result = geoOperations.georadius(key, + new Circle(new Point(15, 37), new Distance(200, KILOMETERS)), + newGeoRadiusArgs().includeCoordinates().sortAscending()); + + assertThat(result.getContent(), hasSize(2)); + assertThat(result.getContent().get(0).getContent().getPoint().getX(), is(closeTo(POINT_CATANIA.getX(), 0.005))); + assertThat(result.getContent().get(0).getContent().getPoint().getY(), is(closeTo(POINT_CATANIA.getY(), 0.005))); + assertThat(result.getContent().get(0).getContent().getName(), is(member2)); + + assertThat(result.getContent().get(1).getContent().getPoint().getX(), is(closeTo(POINT_PALERMO.getX(), 0.005))); + assertThat(result.getContent().get(1).getContent().getPoint().getY(), is(closeTo(POINT_PALERMO.getY(), 0.005))); + assertThat(result.getContent().get(1).getContent().getName(), is(member1)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void geoRadiusShouldReturnLocationsWithCoordinatesAndDistance() { + + K key = keyFactory.instance(); + M member1 = valueFactory.instance(); + M member2 = valueFactory.instance(); + + geoOperations.geoAdd(key, POINT_PALERMO, member1); + geoOperations.geoAdd(key, POINT_CATANIA, member2); + + GeoResults> result = geoOperations.georadius(key, + new Circle(new Point(15, 37), new Distance(200, KILOMETERS)), + newGeoRadiusArgs().includeCoordinates().includeDistance().sortAscending()); + assertThat(result.getContent(), hasSize(2)); + + assertThat(result.getContent().get(0).getDistance().getValue(), is(closeTo(56.4413d, 0.005))); + assertThat(result.getContent().get(0).getDistance().getUnit(), is(equalTo("km"))); + assertThat(result.getContent().get(0).getContent().getPoint().getX(), is(closeTo(POINT_CATANIA.getX(), 0.005))); + assertThat(result.getContent().get(0).getContent().getPoint().getY(), is(closeTo(POINT_CATANIA.getY(), 0.005))); + assertThat(result.getContent().get(0).getContent().getName(), is(member2)); + + assertThat(result.getContent().get(1).getDistance().getValue(), is(closeTo(190.4424d, 0.005))); + assertThat(result.getContent().get(1).getDistance().getUnit(), is(equalTo("km"))); + assertThat(result.getContent().get(1).getContent().getPoint().getX(), is(closeTo(POINT_PALERMO.getX(), 0.005))); + assertThat(result.getContent().get(1).getContent().getPoint().getY(), is(closeTo(POINT_PALERMO.getY(), 0.005))); + assertThat(result.getContent().get(1).getContent().getName(), is(member1)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void geoRadiusByMemberShouldReturnMembersCorrectly() { + + K key = keyFactory.instance(); + M member1 = valueFactory.instance(); + M member2 = valueFactory.instance(); + M member3 = valueFactory.instance(); + + geoOperations.geoAdd(key, POINT_PALERMO, member1); + geoOperations.geoAdd(key, POINT_CATANIA, member2); + geoOperations.geoAdd(key, POINT_ARIGENTO, member3); + + GeoResults> result = geoOperations.georadiusByMember(key, member3, new Distance(200, KILOMETERS)); + assertThat(result.getContent(), hasSize(3)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void geoRadiusByMemberShouldReturnDistanceCorrectly() { + + K key = keyFactory.instance(); + M member1 = valueFactory.instance(); + M member2 = valueFactory.instance(); + M member3 = valueFactory.instance(); + + geoOperations.geoAdd(key, POINT_PALERMO, member1); + geoOperations.geoAdd(key, POINT_CATANIA, member2); + geoOperations.geoAdd(key, POINT_ARIGENTO, member3); + + GeoResults> result = geoOperations.georadiusByMember(key, member3, new Distance(100, KILOMETERS), + newGeoRadiusArgs().includeDistance().sortDescending()); + + assertThat(result.getContent(), hasSize(2)); + assertThat(result.getContent().get(0).getDistance().getValue(), is(closeTo(90.9778d, 0.005))); + assertThat(result.getContent().get(0).getContent().getName(), is(member1)); + assertThat(result.getContent().get(1).getDistance().getValue(), is(closeTo(0.0d, 0.005))); // itself + assertThat(result.getContent().get(1).getContent().getName(), is(member3)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void geoRadiusByMemberShouldReturnCoordinates() { + + K key = keyFactory.instance(); + M member1 = valueFactory.instance(); + M member2 = valueFactory.instance(); + M member3 = valueFactory.instance(); + + geoOperations.geoAdd(key, POINT_PALERMO, member1); + geoOperations.geoAdd(key, POINT_CATANIA, member2); + geoOperations.geoAdd(key, POINT_ARIGENTO, member3); + + GeoResults> result = geoOperations.georadiusByMember(key, member3, + new Distance(100, DistanceUnit.KILOMETERS), newGeoRadiusArgs().includeCoordinates().sortAscending()); + + assertThat(result.getContent(), hasSize(2)); + assertThat(result.getContent().get(0).getContent().getPoint().getX(), is(closeTo(POINT_ARIGENTO.getX(), 0.005))); + assertThat(result.getContent().get(0).getContent().getPoint().getY(), is(closeTo(POINT_ARIGENTO.getY(), 0.005))); + assertThat(result.getContent().get(0).getContent().getName(), is(member3)); + + assertThat(result.getContent().get(1).getContent().getPoint().getX(), is(closeTo(POINT_PALERMO.getX(), 0.005))); + assertThat(result.getContent().get(1).getContent().getPoint().getY(), is(closeTo(POINT_PALERMO.getY(), 0.005))); + assertThat(result.getContent().get(1).getContent().getName(), is(member1)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void geoRadiusByMemberShouldReturnCoordinatesAndDistance() { + + K key = keyFactory.instance(); + M member1 = valueFactory.instance(); + M member2 = valueFactory.instance(); + M member3 = valueFactory.instance(); + + geoOperations.geoAdd(key, POINT_PALERMO, member1); + geoOperations.geoAdd(key, POINT_CATANIA, member2); + geoOperations.geoAdd(key, POINT_ARIGENTO, member3); + + // with coord and dist, ascending + GeoResults> result = geoOperations.georadiusByMember(key, member1, new Distance(100, KILOMETERS), + newGeoRadiusArgs().includeCoordinates().includeDistance().sortAscending()); + assertThat(result.getContent(), hasSize(2)); + + assertThat(result.getContent().get(0).getDistance().getValue(), is(closeTo(0.0d, 0.005))); + assertThat(result.getContent().get(0).getContent().getPoint().getX(), is(closeTo(POINT_PALERMO.getX(), 0.005))); + assertThat(result.getContent().get(0).getContent().getPoint().getY(), is(closeTo(POINT_PALERMO.getY(), 0.005))); + assertThat(result.getContent().get(0).getContent().getName(), is(member1)); + + assertThat(result.getContent().get(1).getDistance().getValue(), is(closeTo(90.9778d, 0.005))); + assertThat(result.getContent().get(1).getContent().getPoint().getX(), is(closeTo(POINT_ARIGENTO.getX(), 0.005))); + assertThat(result.getContent().get(1).getContent().getPoint().getY(), is(closeTo(POINT_ARIGENTO.getY(), 0.005))); + assertThat(result.getContent().get(1).getContent().getName(), is(member3)); + } + + /** + * @see DATAREDIS-438 + */ + @Test + public void testGeoRemove() { + + K key = keyFactory.instance(); + M member1 = valueFactory.instance(); + + geoOperations.geoAdd(key, POINT_PALERMO, member1); + + assertThat(geoOperations.geoRemove(key, member1), is(1L)); + } } diff --git a/src/test/java/org/springframework/data/redis/core/DefaultHashOperationsTests.java b/src/test/java/org/springframework/data/redis/core/DefaultHashOperationsTests.java index 96c449856..4f6871da1 100644 --- a/src/test/java/org/springframework/data/redis/core/DefaultHashOperationsTests.java +++ b/src/test/java/org/springframework/data/redis/core/DefaultHashOperationsTests.java @@ -24,12 +24,14 @@ import java.util.Iterator; import java.util.Map; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; +import org.springframework.data.redis.ConnectionFactoryTracker; import org.springframework.data.redis.ObjectFactory; import org.springframework.data.redis.RawObjectFactory; import org.springframework.data.redis.SettingsUtils; @@ -44,7 +46,6 @@ import org.springframework.test.annotation.IfProfileValue; * * @author Jennifer Hickey * @author Christoph Strobl - * @author Ninad Divadkar * @param Key type * @param Hash key type * @param Hash value type @@ -66,10 +67,13 @@ public class DefaultHashOperationsTests { public DefaultHashOperationsTests(RedisTemplate redisTemplate, ObjectFactory keyFactory, ObjectFactory hashKeyFactory, ObjectFactory hashValueFactory) { + this.redisTemplate = redisTemplate; this.keyFactory = keyFactory; this.hashKeyFactory = hashKeyFactory; this.hashValueFactory = hashValueFactory; + + ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory()); } @Parameters @@ -95,6 +99,11 @@ public class DefaultHashOperationsTests { { rawTemplate, rawFactory, rawFactory, rawFactory } }); } + @AfterClass + public static void cleanUp() { + ConnectionFactoryTracker.cleanUp(); + } + @Before public void setUp() { hashOps = redisTemplate.opsForHash(); diff --git a/src/test/java/org/springframework/data/redis/core/DefaultHyperLogLogOperationsTests.java b/src/test/java/org/springframework/data/redis/core/DefaultHyperLogLogOperationsTests.java index 27eef4c8d..88ce8af4f 100644 --- a/src/test/java/org/springframework/data/redis/core/DefaultHyperLogLogOperationsTests.java +++ b/src/test/java/org/springframework/data/redis/core/DefaultHyperLogLogOperationsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -21,12 +21,14 @@ import static org.junit.Assert.*; import java.util.Collection; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; +import org.springframework.data.redis.ConnectionFactoryTracker; import org.springframework.data.redis.ObjectFactory; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.test.util.MinimumRedisVersionRule; @@ -51,9 +53,12 @@ public class DefaultHyperLogLogOperationsTests { public DefaultHyperLogLogOperationsTests(RedisTemplate redisTemplate, ObjectFactory keyFactory, ObjectFactory valueFactory) { + this.redisTemplate = redisTemplate; this.keyFactory = keyFactory; this.valueFactory = valueFactory; + + ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory()); } @Parameters @@ -61,6 +66,11 @@ public class DefaultHyperLogLogOperationsTests { return AbstractOperationsTestParams.testParams(); } + @AfterClass + public static void cleanUp() { + ConnectionFactoryTracker.cleanUp(); + } + @Before public void setUp() { hyperLogLogOps = redisTemplate.opsForHyperLogLog(); diff --git a/src/test/java/org/springframework/data/redis/core/DefaultListOperationsTests.java b/src/test/java/org/springframework/data/redis/core/DefaultListOperationsTests.java index 275fae5d4..def76f617 100644 --- a/src/test/java/org/springframework/data/redis/core/DefaultListOperationsTests.java +++ b/src/test/java/org/springframework/data/redis/core/DefaultListOperationsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-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. @@ -25,11 +25,13 @@ import java.util.Collections; import java.util.concurrent.TimeUnit; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; +import org.springframework.data.redis.ConnectionFactoryTracker; import org.springframework.data.redis.ObjectFactory; import org.springframework.data.redis.RedisTestProfileValueSource; import org.springframework.data.redis.connection.RedisConnection; @@ -56,9 +58,12 @@ public class DefaultListOperationsTests { public DefaultListOperationsTests(RedisTemplate redisTemplate, ObjectFactory keyFactory, ObjectFactory valueFactory) { + this.redisTemplate = redisTemplate; this.keyFactory = keyFactory; this.valueFactory = valueFactory; + + ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory()); } @Parameters @@ -66,6 +71,11 @@ public class DefaultListOperationsTests { return AbstractOperationsTestParams.testParams(); } + @AfterClass + public static void cleanUp() { + ConnectionFactoryTracker.cleanUp(); + } + @Before public void setUp() { listOps = redisTemplate.opsForList(); diff --git a/src/test/java/org/springframework/data/redis/core/DefaultSetOperationsTests.java b/src/test/java/org/springframework/data/redis/core/DefaultSetOperationsTests.java index d5b2cb7a8..f5453758d 100644 --- a/src/test/java/org/springframework/data/redis/core/DefaultSetOperationsTests.java +++ b/src/test/java/org/springframework/data/redis/core/DefaultSetOperationsTests.java @@ -29,12 +29,14 @@ import java.util.Set; import org.hamcrest.CoreMatchers; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; +import org.springframework.data.redis.ConnectionFactoryTracker; import org.springframework.data.redis.ObjectFactory; import org.springframework.data.redis.RedisTestProfileValueSource; import org.springframework.data.redis.connection.RedisConnection; @@ -63,9 +65,12 @@ public class DefaultSetOperationsTests { public DefaultSetOperationsTests(RedisTemplate redisTemplate, ObjectFactory keyFactory, ObjectFactory valueFactory) { + this.redisTemplate = redisTemplate; this.keyFactory = keyFactory; this.valueFactory = valueFactory; + + ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory()); } @Parameters @@ -73,6 +78,11 @@ public class DefaultSetOperationsTests { return AbstractOperationsTestParams.testParams(); } + @AfterClass + public static void cleanUp() { + ConnectionFactoryTracker.cleanUp(); + } + @Before public void setUp() { setOps = redisTemplate.opsForSet(); diff --git a/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsTests.java b/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsTests.java index 468ea1284..6bfe1f892 100644 --- a/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsTests.java +++ b/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-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. @@ -15,14 +15,10 @@ */ package org.springframework.data.redis.core; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; -import static org.springframework.data.redis.SpinBarrier.waitFor; -import static org.springframework.data.redis.matcher.RedisTestMatchers.isEqual; +import static org.junit.Assert.*; +import static org.junit.Assume.*; +import static org.springframework.data.redis.SpinBarrier.*; +import static org.springframework.data.redis.matcher.RedisTestMatchers.*; import java.text.DecimalFormat; import java.util.ArrayList; @@ -34,11 +30,13 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; +import org.springframework.data.redis.ConnectionFactoryTracker; import org.springframework.data.redis.ObjectFactory; import org.springframework.data.redis.RedisTestProfileValueSource; import org.springframework.data.redis.TestCondition; @@ -65,9 +63,12 @@ public class DefaultValueOperationsTests { public DefaultValueOperationsTests(RedisTemplate redisTemplate, ObjectFactory keyFactory, ObjectFactory valueFactory) { + this.redisTemplate = redisTemplate; this.keyFactory = keyFactory; this.valueFactory = valueFactory; + + ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory()); } @Parameters @@ -75,6 +76,11 @@ public class DefaultValueOperationsTests { return AbstractOperationsTestParams.testParams(); } + @AfterClass + public static void cleanUp() { + ConnectionFactoryTracker.cleanUp(); + } + @Before public void setUp() { valueOps = redisTemplate.opsForValue(); @@ -280,19 +286,19 @@ public class DefaultValueOperationsTests { assumeTrue(key1 instanceof byte[]); assertNotNull(((DefaultValueOperations) valueOps).deserializeKey((byte[]) key1)); } - + /** * @see DATAREDIS-197 */ @Test public void testSetAndGetBit() { - + assumeTrue(redisTemplate instanceof StringRedisTemplate); - + K key1 = keyFactory.instance(); int bitOffset = 65; valueOps.setBit(key1, bitOffset, true); - + assertEquals(true, valueOps.getBit(key1, bitOffset)); } diff --git a/src/test/java/org/springframework/data/redis/core/DefaultZSetOperationsTests.java b/src/test/java/org/springframework/data/redis/core/DefaultZSetOperationsTests.java index a434a10bf..b03c38d68 100644 --- a/src/test/java/org/springframework/data/redis/core/DefaultZSetOperationsTests.java +++ b/src/test/java/org/springframework/data/redis/core/DefaultZSetOperationsTests.java @@ -30,12 +30,14 @@ import java.util.LinkedHashSet; import java.util.Set; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; +import org.springframework.data.redis.ConnectionFactoryTracker; import org.springframework.data.redis.DoubleAsStringObjectFactory; import org.springframework.data.redis.DoubleObjectFactory; import org.springframework.data.redis.LongAsStringObjectFactory; @@ -71,9 +73,12 @@ public class DefaultZSetOperationsTests { public DefaultZSetOperationsTests(RedisTemplate redisTemplate, ObjectFactory keyFactory, ObjectFactory valueFactory) { + this.redisTemplate = redisTemplate; this.keyFactory = keyFactory; this.valueFactory = valueFactory; + + ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory()); } @Parameters @@ -81,6 +86,11 @@ public class DefaultZSetOperationsTests { return AbstractOperationsTestParams.testParams(); } + @AfterClass + public static void cleanUp() { + ConnectionFactoryTracker.cleanUp(); + } + @Before public void setUp() { zSetOps = redisTemplate.opsForZSet(); @@ -179,10 +189,8 @@ public class DefaultZSetOperationsTests { @Test public void testRangeByLexUnbounded() { - assumeThat( - valueFactory, - anyOf(instanceOf(DoubleObjectFactory.class), instanceOf(DoubleAsStringObjectFactory.class), - instanceOf(LongAsStringObjectFactory.class), instanceOf(LongObjectFactory.class))); + assumeThat(valueFactory, anyOf(instanceOf(DoubleObjectFactory.class), instanceOf(DoubleAsStringObjectFactory.class), + instanceOf(LongAsStringObjectFactory.class), instanceOf(LongObjectFactory.class))); K key = keyFactory.instance(); V value1 = valueFactory.instance(); @@ -205,10 +213,8 @@ public class DefaultZSetOperationsTests { @Test public void testRangeByLexBounded() { - assumeThat( - valueFactory, - anyOf(instanceOf(DoubleObjectFactory.class), instanceOf(DoubleAsStringObjectFactory.class), - instanceOf(LongAsStringObjectFactory.class), instanceOf(LongObjectFactory.class))); + assumeThat(valueFactory, anyOf(instanceOf(DoubleObjectFactory.class), instanceOf(DoubleAsStringObjectFactory.class), + instanceOf(LongAsStringObjectFactory.class), instanceOf(LongObjectFactory.class))); K key = keyFactory.instance(); V value1 = valueFactory.instance(); @@ -231,10 +237,8 @@ public class DefaultZSetOperationsTests { @Test public void testRangeByLexUnboundedWithLimit() { - assumeThat( - valueFactory, - anyOf(instanceOf(DoubleObjectFactory.class), instanceOf(DoubleAsStringObjectFactory.class), - instanceOf(LongAsStringObjectFactory.class), instanceOf(LongObjectFactory.class))); + assumeThat(valueFactory, anyOf(instanceOf(DoubleObjectFactory.class), instanceOf(DoubleAsStringObjectFactory.class), + instanceOf(LongAsStringObjectFactory.class), instanceOf(LongObjectFactory.class))); K key = keyFactory.instance(); V value1 = valueFactory.instance(); @@ -258,10 +262,8 @@ public class DefaultZSetOperationsTests { @Test public void testRangeByLexBoundedWithLimit() { - assumeThat( - valueFactory, - anyOf(instanceOf(DoubleObjectFactory.class), instanceOf(DoubleAsStringObjectFactory.class), - instanceOf(LongAsStringObjectFactory.class), instanceOf(LongObjectFactory.class))); + assumeThat(valueFactory, anyOf(instanceOf(DoubleObjectFactory.class), instanceOf(DoubleAsStringObjectFactory.class), + instanceOf(LongAsStringObjectFactory.class), instanceOf(LongObjectFactory.class))); K key = keyFactory.instance(); V value1 = valueFactory.instance(); @@ -271,8 +273,8 @@ public class DefaultZSetOperationsTests { zSetOps.add(key, value1, 1.9); zSetOps.add(key, value2, 3.7); zSetOps.add(key, value3, 5.8); - Set tuples = zSetOps.rangeByLex(key, RedisZSetCommands.Range.range().gte(value1), RedisZSetCommands.Limit - .limit().count(1).offset(1)); + Set tuples = zSetOps.rangeByLex(key, RedisZSetCommands.Range.range().gte(value1), + RedisZSetCommands.Limit.limit().count(1).offset(1)); assertEquals(1, tuples.size()); V tuple = tuples.iterator().next();