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();