From 577bd2607a6214048562ce58b875be685dca0dbd Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Sun, 13 Mar 2011 19:33:47 +0200 Subject: [PATCH] Merge branch 'master' into gradle-build --- .gitignore | 3 +- docs/src/info/changelog.txt | 35 +- docs/src/info/readme.txt | 6 +- .../connection/DefaultSortParameters.java | 28 +- .../redis/connection/RedisListCommands.java | 4 +- .../redis/connection/RedisPubSubCommands.java | 4 - .../redis/connection/RedisStringCommands.java | 4 +- .../redis/connection/RedisZSetCommands.java | 10 +- .../redis/connection/SortParameters.java | 2 +- .../connection/jedis/JedisConnection.java | 481 +++++++++++++++++- .../jedis/JedisConnectionFactory.java | 2 +- .../redis/connection/jedis/JedisUtils.java | 2 +- .../connection/jredis/JredisConnection.java | 338 ++++++------ .../jredis/JredisConnectionFactory.java | 7 +- .../redis/connection/jredis/JredisUtils.java | 21 +- .../redis/core/BoundSetOperations.java | 18 +- .../redis/core/BoundZSetOperations.java | 8 +- .../data/keyvalue/redis/core/BulkMapper.java | 31 ++ .../redis/core/DefaultBoundSetOperations.java | 46 +- .../core/DefaultBoundZSetOperations.java | 18 +- .../keyvalue/redis/core/RedisOperations.java | 24 +- .../keyvalue/redis/core/RedisTemplate.java | 268 +++++++--- .../keyvalue/redis/core/SetOperations.java | 26 +- .../keyvalue/redis/core/ZSetOperations.java | 8 +- .../core/query/DefaultSortCriterion.java | 82 +++ .../redis/core/query/DefaultSortQuery.java | 83 +++ .../redis/core/query/SortCriterion.java | 39 ++ .../keyvalue/redis/core/query/SortQuery.java | 78 +++ .../redis/core/query/SortQueryBuilder.java | 43 ++ .../redis/hash/BeanUtilsHashMapper.java | 54 ++ .../hash/DecoratingStringHashMapper.java | 51 ++ .../data/keyvalue/redis/hash/HashMapper.java | 31 ++ .../redis/hash/JacksonHashMapper.java | 55 ++ .../BasicNumberToStringSerializer.java | 68 +++ .../serializer/GenericToStringSerializer.java | 2 +- .../support/atomic/RedisAtomicInteger.java | 36 +- .../redis/support/atomic/RedisAtomicLong.java | 35 +- .../support/collections/DefaultRedisSet.java | 49 +- .../support/collections/DefaultRedisZSet.java | 20 +- .../redis/support/collections/RedisList.java | 4 +- .../redis/support/collections/RedisSet.java | 18 +- .../redis/support/collections/RedisZSet.java | 8 +- .../AbstractConnectionIntegrationTests.java | 47 +- .../data/keyvalue/redis/core/SortTest.java | 37 ++ .../redis/mapping/AbstractHashMapperTest.java | 49 ++ .../mapping/BeanUtilsHashMapperTest.java | 36 ++ .../redis/mapping/JacksonHashMapperTest.java | 27 + .../support/atomic/RedisAtomicTests.java | 26 + .../collections/AbstractRedisSetTests.java | 6 +- .../collections/AbstractRedisZSetTest.java | 4 +- spring-data-redis/template.mf | 4 +- spring-datastore-keyvalue-parent/.project | 17 - 52 files changed, 1987 insertions(+), 416 deletions(-) create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BulkMapper.java create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/DefaultSortCriterion.java create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/DefaultSortQuery.java create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/SortCriterion.java create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/SortQuery.java create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/SortQueryBuilder.java create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/BeanUtilsHashMapper.java create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/DecoratingStringHashMapper.java create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/HashMapper.java create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/JacksonHashMapper.java create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/serializer/BasicNumberToStringSerializer.java create mode 100644 spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/core/SortTest.java create mode 100644 spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/mapping/AbstractHashMapperTest.java create mode 100644 spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/mapping/BeanUtilsHashMapperTest.java create mode 100644 spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/mapping/JacksonHashMapperTest.java delete mode 100644 spring-datastore-keyvalue-parent/.project diff --git a/.gitignore b/.gitignore index 2683d4724..f0c169959 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ -build +.DS_Store target +build .gradle .springBeans .ant-targets-build.xml diff --git a/docs/src/info/changelog.txt b/docs/src/info/changelog.txt index 9f5766a14..94d51f782 100644 --- a/docs/src/info/changelog.txt +++ b/docs/src/info/changelog.txt @@ -1,23 +1,50 @@ -SPRING DATA REDIS INTEGRATION CHANGELOG -======================================= +SPRING DATA KEY/VALUE INTEGRATION CHANGELOG +=========================================== http://www.springsource.org/spring-data -Changes in version 1.0.0.M2 (2011-xx-yy) +Changes in version 1.0.0.M2 (2011-02-10) ---------------------------------------- + +Redis +----- + General +* Added PubSub support (message listener container and namespace) +* Added JSON and Object/XML Mapping serializers +* Completed support for Redis (2.2) commands * Improved documentation * Upgraded to Redis 2.2 -* Updraded to Jedis 1.5.1 +* Updraded to Jedis 1.5.2 Package o.s.d.k.redis.connection +* Added sort support +* Added pipelining support +* Added StringRedisConnection for String-focused operations * Renamed JedisConnectionFactory pooling to usePool * Renamed JredisConnectionFactory pooling to usePool +Package o.s.d.k.redis.connection.jedis +* Added support for Jedis rich exceptions +* Added support for broken pooled connection + +Package o.s.d.k.redis.core +* Fix serializationg bug for hash value inside RedisTemplate +* Added injection for Redis operations ("views") + Package o.s.d.k.redis.support * Refined AtomicInteger and AtomicLong constructors to use the backing store value as initial counter +Riak +---- + +General +* Important bug fixes +* Fully asynchronous AsyncRiakTemplate object +* Groovy DSL for Riak access using async template underneath + + Changes in version Riak 1.0.0.M1 (2010-12-15) --------------------------------------------- General diff --git a/docs/src/info/readme.txt b/docs/src/info/readme.txt index 71d8f0ab9..eb45a4e73 100644 --- a/docs/src/info/readme.txt +++ b/docs/src/info/readme.txt @@ -1,5 +1,5 @@ -SPRING DATASTORE KEY-VALUE 1.0.0 ${version} -------------------------------------------- +SPRING DATASTORE KEY-VALUE 1.0.0 M2 (2010 02 10) +------------------------------------------------ Spring Datastore Key-Value is released under the terms of the Apache Software License Version 2.0 (see license.txt). @@ -14,4 +14,4 @@ The reference manual and javadoc are located in the 'docs' directory. ADDITIONAL RESOURCES: Spring Data Homepage: http://www.springsource.org/spring-data -Spring Data Forum: http://forum.springsource.org/forumdisplay.php?f=80 +Spring Data Forum : http://forum.springsource.org/forumdisplay.php?f=80 diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/DefaultSortParameters.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/DefaultSortParameters.java index de25bce3f..194957054 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/DefaultSortParameters.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/DefaultSortParameters.java @@ -15,6 +15,10 @@ */ package org.springframework.data.keyvalue.redis.connection; +import java.util.ArrayList; +import java.util.List; + + /** * Default implementation for {@link SortParameters}. @@ -25,7 +29,7 @@ public class DefaultSortParameters implements SortParameters { private byte[] byPattern; private Range limit; - private byte[] getPattern; + private final List getPattern = new ArrayList(4); private Order order; private Boolean alphabetic; @@ -56,13 +60,13 @@ public class DefaultSortParameters implements SortParameters { * @param order * @param alphabetic */ - public DefaultSortParameters(byte[] byPattern, Range limit, byte[] getPattern, Order order, Boolean alphabetic) { + public DefaultSortParameters(byte[] byPattern, Range limit, byte[][] getPattern, Order order, Boolean alphabetic) { super(); this.byPattern = byPattern; this.limit = limit; - this.getPattern = getPattern; this.order = order; this.alphabetic = alphabetic; + setGetPattern(getPattern); } @Override @@ -84,12 +88,20 @@ public class DefaultSortParameters implements SortParameters { } @Override - public byte[] getGetPattern() { - return getPattern; + public byte[][] getGetPattern() { + return getPattern.toArray(new byte[getPattern.size()][]); } - public void setGetPattern(byte[] getPattern) { - this.getPattern = getPattern; + public void addGetPattern(byte[] gPattern) { + getPattern.add(gPattern); + } + + public void setGetPattern(byte[][] gPattern) { + getPattern.clear(); + + for (byte[] bs : gPattern) { + getPattern.add(bs); + } } @Override @@ -130,7 +142,7 @@ public class DefaultSortParameters implements SortParameters { } public SortParameters get(byte[] pattern) { - setGetPattern(pattern); + addGetPattern(pattern); return this; } diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisListCommands.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisListCommands.java index 75b0520b8..deee6298e 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisListCommands.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisListCommands.java @@ -42,9 +42,9 @@ public interface RedisListCommands { Long lLen(byte[] key); - List lRange(byte[] key, long start, long end); + List lRange(byte[] key, long begin, long end); - void lTrim(byte[] key, long start, long end); + void lTrim(byte[] key, long begin, long end); byte[] lIndex(byte[] key, long index); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisPubSubCommands.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisPubSubCommands.java index 3fa37ffe8..64772fe0d 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisPubSubCommands.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisPubSubCommands.java @@ -27,8 +27,6 @@ public interface RedisPubSubCommands { * or not. * * @return true if the connection is subscribed, false otherwise - * @see #subscribe(MessageListener, byte[]...) - * @see #pSubscribe(MessageListener, byte[]...) */ boolean isSubscribed(); @@ -37,8 +35,6 @@ public interface RedisPubSubCommands { * not subscribed. * * @return the current subscription, null if none is available - * @see #subscribe(listener, channels) - * @see #pSubscribe(listener, channels) */ Subscription getSubscription(); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisStringCommands.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisStringCommands.java index ab81f31d3..ea96dfde6 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisStringCommands.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisStringCommands.java @@ -52,9 +52,9 @@ public interface RedisStringCommands { Long append(byte[] key, byte[] value); - byte[] getRange(byte[] key, int start, int end); + byte[] getRange(byte[] key, int begin, int end); - void setRange(byte[] key, int start, int end); + void setRange(byte[] key, int begin, int end); Boolean getBit(byte[] key, long offset); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisZSetCommands.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisZSetCommands.java index 7ede85506..eacc7de72 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisZSetCommands.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisZSetCommands.java @@ -52,13 +52,13 @@ public interface RedisZSetCommands { Long zRevRank(byte[] key, byte[] value); - Set zRange(byte[] key, long start, long end); + Set zRange(byte[] key, long begin, long end); - Set zRangeWithScore(byte[] key, long start, long end); + Set zRangeWithScore(byte[] key, long begin, long end); - Set zRevRange(byte[] key, long start, long end); + Set zRevRange(byte[] key, long begin, long end); - Set zRevRangeWithScore(byte[] key, long start, long end); + Set zRevRangeWithScore(byte[] key, long begin, long end); Set zRangeByScore(byte[] key, double min, double max); @@ -74,7 +74,7 @@ public interface RedisZSetCommands { Double zScore(byte[] key, byte[] value); - Long zRemRange(byte[] key, long start, long end); + Long zRemRange(byte[] key, long begin, long end); Long zRemRangeByScore(byte[] key, double min, double max); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/SortParameters.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/SortParameters.java index 0fd65c0b3..ca69f3315 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/SortParameters.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/SortParameters.java @@ -80,7 +80,7 @@ public interface SortParameters { * * @return GET pattern. */ - byte[] getGetPattern(); + byte[][] getGetPattern(); /** * Returns the sorting limit (range or pagination). diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java index 08833b217..3187f0370 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java @@ -41,6 +41,7 @@ import redis.clients.jedis.BinaryTransaction; import redis.clients.jedis.Client; import redis.clients.jedis.Jedis; import redis.clients.jedis.Pipeline; +import redis.clients.jedis.Protocol; import redis.clients.jedis.SortingParams; import redis.clients.jedis.Transaction; import redis.clients.jedis.ZParams; @@ -109,7 +110,7 @@ public class JedisConnection implements RedisConnection { return JedisUtils.convertJedisAccessException((IOException) ex); } - throw new UncategorizedKeyvalueStoreException("Unknown jedis exception", ex); + return new UncategorizedKeyvalueStoreException("Unknown jedis exception", ex); } @Override @@ -201,6 +202,16 @@ public class JedisConnection implements RedisConnection { return null; } + if (isPipelined()) { + if (sortParams != null) { + pipeline.sort(key, sortParams); + } + else { + pipeline.sort(key); + } + + return null; + } return (sortParams != null ? jedis.sort(key, sortParams) : jedis.sort(key)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -223,6 +234,16 @@ public class JedisConnection implements RedisConnection { return null; } + if (isPipelined()) { + if (sortParams != null) { + pipeline.sort(key, sortParams, sortKey); + } + else { + pipeline.sort(key, sortKey); + } + + return null; + } return (sortParams != null ? jedis.sort(key, sortParams, sortKey) : jedis.sort(key, sortKey)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -236,6 +257,9 @@ public class JedisConnection implements RedisConnection { transaction.dbSize(); return null; } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } return jedis.dbSize(); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -250,6 +274,9 @@ public class JedisConnection implements RedisConnection { transaction.flushDB(); return; } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } jedis.flushDB(); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -263,6 +290,9 @@ public class JedisConnection implements RedisConnection { transaction.flushAll(); return; } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } jedis.flushAll(); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -275,6 +305,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.bgsave(); + return; + } jedis.bgsave(); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -287,6 +321,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.bgrewriteaof(); + return; + } jedis.bgrewriteaof(); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -299,6 +337,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.save(); + return; + } jedis.save(); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -311,6 +353,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.configGet(param); + return null; + } return jedis.configGet(param); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -323,6 +369,9 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } return JedisUtils.info(jedis.info()); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -335,6 +384,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.lastsave(); + return null; + } return jedis.lastsave(); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -347,6 +400,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.configSet(param, value); + return; + } jedis.configSet(param, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -360,6 +417,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.configResetStat(); + return; + } jedis.configResetStat(); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -372,6 +433,9 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } jedis.shutdown(); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -384,6 +448,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.echo(message); + return null; + } return jedis.echo(message); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -397,6 +465,9 @@ public class JedisConnection implements RedisConnection { transaction.ping(); return null; } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } return jedis.ping(); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -410,6 +481,10 @@ public class JedisConnection implements RedisConnection { transaction.del(keys); return null; } + if (isPipelined()) { + pipeline.del(keys); + return null; + } return jedis.del(keys); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -428,6 +503,10 @@ public class JedisConnection implements RedisConnection { @Override public List exec() { try { + if (isPipelined()) { + pipeline.exec(); + return null; + } return transaction.exec(); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -441,6 +520,10 @@ public class JedisConnection implements RedisConnection { transaction.exists(key); return null; } + if (isPipelined()) { + pipeline.exists(key); + return null; + } return jedis.exists(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -454,6 +537,10 @@ public class JedisConnection implements RedisConnection { transaction.expire(key, (int) seconds); return null; } + if (isPipelined()) { + pipeline.expire(key, (int) seconds); + return null; + } return (jedis.expire(key, (int) seconds) == 1); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -467,6 +554,10 @@ public class JedisConnection implements RedisConnection { transaction.expireAt(key, unixTime); return null; } + if (isPipelined()) { + pipeline.expireAt(key, unixTime); + return null; + } return (jedis.expireAt(key, unixTime) == 1); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -480,6 +571,10 @@ public class JedisConnection implements RedisConnection { transaction.keys(pattern); return null; } + if (isPipelined()) { + pipeline.keys(pattern); + return null; + } return (jedis.keys(pattern)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -491,8 +586,11 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { return; } - try { + if (isPipelined()) { + pipeline.multi(); + return; + } jedis.multi(); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -506,6 +604,10 @@ public class JedisConnection implements RedisConnection { client.persist(key); return null; } + if (isPipelined()) { + pipeline.persist(key); + return null; + } return (jedis.persist(key) == 1); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -519,6 +621,9 @@ public class JedisConnection implements RedisConnection { transaction.randomBinaryKey(); return null; } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } return jedis.randomBinaryKey(); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -532,6 +637,10 @@ public class JedisConnection implements RedisConnection { transaction.rename(oldName, newName); return; } + if (isPipelined()) { + pipeline.rename(oldName, newName); + return; + } jedis.rename(oldName, newName); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -545,6 +654,10 @@ public class JedisConnection implements RedisConnection { transaction.renamenx(oldName, newName); return null; } + if (isPipelined()) { + pipeline.renamenx(oldName, newName); + return null; + } return (jedis.renamenx(oldName, newName) == 1); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -558,6 +671,9 @@ public class JedisConnection implements RedisConnection { transaction.select(dbIndex); return; } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } jedis.select(dbIndex); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -571,6 +687,10 @@ public class JedisConnection implements RedisConnection { transaction.ttl(key); return null; } + if (isPipelined()) { + pipeline.ttl(key); + return null; + } return jedis.ttl(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -584,6 +704,10 @@ public class JedisConnection implements RedisConnection { transaction.type(key); return null; } + if (isPipelined()) { + pipeline.type(key); + return null; + } return DataType.fromCode(jedis.type(key)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -605,10 +729,13 @@ public class JedisConnection implements RedisConnection { // ignore (as watch not allowed in multi) return; } - try { for (byte[] key : keys) { - jedis.watch(key); + if (isPipelined()) { + pipeline.watch(key); + } else { + jedis.watch(key); + } } } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -626,6 +753,10 @@ public class JedisConnection implements RedisConnection { transaction.get(key); return null; } + if (isPipelined()) { + pipeline.get(key); + return null; + } return jedis.get(key); } catch (Exception ex) { @@ -640,6 +771,10 @@ public class JedisConnection implements RedisConnection { transaction.set(key, value); return; } + if (isPipelined()) { + pipeline.set(key, value); + return; + } jedis.set(key, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -654,6 +789,10 @@ public class JedisConnection implements RedisConnection { transaction.getSet(key, value); return null; } + if (isPipelined()) { + pipeline.getSet(key, value); + return null; + } return jedis.getSet(key, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -667,6 +806,10 @@ public class JedisConnection implements RedisConnection { transaction.append(key, value); return null; } + if (isPipelined()) { + pipeline.append(key, value); + return null; + } return jedis.append(key, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -680,6 +823,10 @@ public class JedisConnection implements RedisConnection { transaction.mget(keys); return null; } + if (isPipelined()) { + pipeline.mget(keys); + return null; + } return jedis.mget(keys); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -693,6 +840,10 @@ public class JedisConnection implements RedisConnection { transaction.mset(JedisUtils.convert(tuples)); return; } + if (isPipelined()) { + pipeline.mset(JedisUtils.convert(tuples)); + return; + } jedis.mset(JedisUtils.convert(tuples)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -706,6 +857,10 @@ public class JedisConnection implements RedisConnection { transaction.msetnx(JedisUtils.convert(tuples)); return; } + if (isPipelined()) { + pipeline.msetnx(JedisUtils.convert(tuples)); + return; + } jedis.msetnx(JedisUtils.convert(tuples)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -719,6 +874,10 @@ public class JedisConnection implements RedisConnection { transaction.setex(key, (int) time, value); return; } + if (isPipelined()) { + pipeline.setex(key, (int) time, value); + return; + } jedis.setex(key, (int) time, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -732,6 +891,10 @@ public class JedisConnection implements RedisConnection { transaction.setnx(key, value); return null; } + if (isPipelined()) { + pipeline.setnx(key, value); + return null; + } return JedisUtils.convertCodeReply(jedis.setnx(key, value)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -745,6 +908,10 @@ public class JedisConnection implements RedisConnection { transaction.substr(key, (int) start, (int) end); return null; } + if (isPipelined()) { + pipeline.substr(key, (int) start, (int) end); + return null; + } return jedis.substr(key, (int) start, (int) end); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -758,6 +925,10 @@ public class JedisConnection implements RedisConnection { transaction.decr(key); return null; } + if (isPipelined()) { + pipeline.decr(key); + return null; + } return jedis.decr(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -771,6 +942,10 @@ public class JedisConnection implements RedisConnection { transaction.decrBy(key, (int) value); return null; } + if (isPipelined()) { + pipeline.decrBy(key, (int) value); + return null; + } return jedis.decrBy(key, (int) value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -784,6 +959,10 @@ public class JedisConnection implements RedisConnection { transaction.incr(key); return null; } + if (isPipelined()) { + pipeline.incr(key); + return null; + } return jedis.incr(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -797,6 +976,10 @@ public class JedisConnection implements RedisConnection { transaction.incrBy(key, (int) value); return null; } + if (isPipelined()) { + pipeline.incrBy(key, (int) value); + return null; + } return jedis.incrBy(key, (int) value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -811,6 +994,9 @@ public class JedisConnection implements RedisConnection { // return null; throw new UnsupportedOperationException(); } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } return (jedis.getbit(key, offset) == 0 ? Boolean.FALSE : Boolean.TRUE); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -825,6 +1011,9 @@ public class JedisConnection implements RedisConnection { // return; throw new UnsupportedOperationException(); } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } jedis.setbit(key, offset, JedisUtils.asBit(value)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -842,6 +1031,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.strlen(key); + return null; + } return jedis.strlen(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -859,6 +1052,10 @@ public class JedisConnection implements RedisConnection { transaction.lpush(key, value); return null; } + if (isPipelined()) { + pipeline.lpush(key, value); + return null; + } return jedis.lpush(key, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -872,6 +1069,10 @@ public class JedisConnection implements RedisConnection { transaction.rpush(key, value); return null; } + if (isPipelined()) { + pipeline.rpush(key, value); + return null; + } return jedis.rpush(key, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -884,6 +1085,15 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + final List args = new ArrayList(); + for (final byte[] arg : keys) { + args.add(arg); + } + args.add(Protocol.toByteArray(timeout)); + pipeline.blpop(args.toArray(new byte[args.size()][])); + return null; + } return jedis.blpop(timeout, keys); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -896,6 +1106,15 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + final List args = new ArrayList(); + for (final byte[] arg : keys) { + args.add(arg); + } + args.add(Protocol.toByteArray(timeout)); + pipeline.brpop(args.toArray(new byte[args.size()][])); + return null; + } return jedis.brpop(timeout, keys); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -909,6 +1128,10 @@ public class JedisConnection implements RedisConnection { transaction.lindex(key, (int) index); return null; } + if (isPipelined()) { + pipeline.lindex(key, (int) index); + return null; + } return jedis.lindex(key, (int) index); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -923,6 +1146,10 @@ public class JedisConnection implements RedisConnection { // return null; throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.linsert(key, JedisUtils.convertPosition(where), pivot, value); + return null; + } return jedis.linsert(key, JedisUtils.convertPosition(where), pivot, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -936,6 +1163,10 @@ public class JedisConnection implements RedisConnection { transaction.llen(key); return null; } + if (isPipelined()) { + pipeline.llen(key); + return null; + } return jedis.llen(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -949,6 +1180,10 @@ public class JedisConnection implements RedisConnection { transaction.lpop(key); return null; } + if (isPipelined()) { + pipeline.lpop(key); + return null; + } return jedis.lpop(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -962,6 +1197,10 @@ public class JedisConnection implements RedisConnection { transaction.lrange(key, (int) start, (int) end); return null; } + if (isPipelined()) { + pipeline.lrange(key, (int) start, (int) end); + return null; + } return jedis.lrange(key, (int) start, (int) end); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -975,6 +1214,10 @@ public class JedisConnection implements RedisConnection { transaction.lrem(key, (int) count, value); return null; } + if (isPipelined()) { + pipeline.lrem(key, (int) count, value); + return null; + } return jedis.lrem(key, (int) count, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -988,6 +1231,10 @@ public class JedisConnection implements RedisConnection { transaction.lset(key, (int) index, value); return; } + if (isPipelined()) { + pipeline.lset(key, (int) index, value); + return; + } jedis.lset(key, (int) index, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1001,6 +1248,10 @@ public class JedisConnection implements RedisConnection { transaction.ltrim(key, (int) start, (int) end); return; } + if (isPipelined()) { + pipeline.ltrim(key, (int) start, (int) end); + return; + } jedis.ltrim(key, (int) start, (int) end); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1014,6 +1265,10 @@ public class JedisConnection implements RedisConnection { transaction.rpop(key); return null; } + if (isPipelined()) { + pipeline.rpop(key); + return null; + } return jedis.rpop(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1027,6 +1282,10 @@ public class JedisConnection implements RedisConnection { transaction.rpoplpush(srcKey, dstKey); return null; } + if (isPipelined()) { + pipeline.rpoplpush(srcKey, dstKey); + return null; + } return jedis.rpoplpush(srcKey, dstKey); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1039,6 +1298,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.brpoplpush(srcKey, dstKey, timeout); + return null; + } return jedis.brpoplpush(srcKey, dstKey, timeout); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1051,6 +1314,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.lpushx(key, value); + return null; + } return jedis.lpushx(key, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1063,6 +1330,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.rpushx(key, value); + return null; + } return jedis.rpushx(key, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1081,6 +1352,10 @@ public class JedisConnection implements RedisConnection { transaction.sadd(key, value); return null; } + if (isPipelined()) { + pipeline.sadd(key, value); + return null; + } return (jedis.sadd(key, value) == 1); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1094,6 +1369,10 @@ public class JedisConnection implements RedisConnection { transaction.scard(key); return null; } + if (isPipelined()) { + pipeline.scard(key); + return null; + } return jedis.scard(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1107,6 +1386,10 @@ public class JedisConnection implements RedisConnection { transaction.sdiff(keys); return null; } + if (isPipelined()) { + pipeline.sdiff(keys); + return null; + } return jedis.sdiff(keys); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1120,6 +1403,10 @@ public class JedisConnection implements RedisConnection { transaction.sdiffstore(destKey, keys); return; } + if (isPipelined()) { + pipeline.sdiffstore(destKey, keys); + return; + } jedis.sdiffstore(destKey, keys); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1133,6 +1420,10 @@ public class JedisConnection implements RedisConnection { transaction.sinter(keys); return null; } + if (isPipelined()) { + pipeline.sinter(keys); + return null; + } return jedis.sinter(keys); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1146,6 +1437,10 @@ public class JedisConnection implements RedisConnection { transaction.sinterstore(destKey, keys); return; } + if (isPipelined()) { + pipeline.sinterstore(destKey, keys); + return; + } jedis.sinterstore(destKey, keys); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1159,6 +1454,10 @@ public class JedisConnection implements RedisConnection { transaction.sismember(key, value); return null; } + if (isPipelined()) { + pipeline.sismember(key, value); + return null; + } return jedis.sismember(key, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1172,6 +1471,10 @@ public class JedisConnection implements RedisConnection { transaction.smembers(key); return null; } + if (isPipelined()) { + pipeline.smembers(key); + return null; + } return jedis.smembers(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1185,6 +1488,10 @@ public class JedisConnection implements RedisConnection { transaction.smove(srcKey, destKey, value); return null; } + if (isPipelined()) { + pipeline.smove(srcKey, destKey, value); + return null; + } return JedisUtils.convertCodeReply(jedis.smove(srcKey, destKey, value)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1198,6 +1505,10 @@ public class JedisConnection implements RedisConnection { transaction.spop(key); return null; } + if (isPipelined()) { + pipeline.spop(key); + return null; + } return jedis.spop(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1211,6 +1522,10 @@ public class JedisConnection implements RedisConnection { transaction.srandmember(key); return null; } + if (isPipelined()) { + pipeline.srandmember(key); + return null; + } return jedis.srandmember(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1224,6 +1539,10 @@ public class JedisConnection implements RedisConnection { transaction.srem(key, value); return null; } + if (isPipelined()) { + pipeline.srem(key, value); + return null; + } return JedisUtils.convertCodeReply(jedis.srem(key, value)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1237,6 +1556,10 @@ public class JedisConnection implements RedisConnection { transaction.sunion(keys); return null; } + if (isPipelined()) { + pipeline.sunion(keys); + return null; + } return jedis.sunion(keys); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1250,6 +1573,10 @@ public class JedisConnection implements RedisConnection { transaction.sunionstore(destKey, keys); return; } + if (isPipelined()) { + pipeline.sunionstore(destKey, keys); + return; + } jedis.sunionstore(destKey, keys); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1267,6 +1594,10 @@ public class JedisConnection implements RedisConnection { transaction.zadd(key, score, value); return null; } + if (isPipelined()) { + pipeline.zadd(key, score, value); + return null; + } return JedisUtils.convertCodeReply(jedis.zadd(key, score, value)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1280,6 +1611,10 @@ public class JedisConnection implements RedisConnection { transaction.zcard(key); return null; } + if (isPipelined()) { + pipeline.zcard(key); + return null; + } return jedis.zcard(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1292,6 +1627,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isQueueing()) { + pipeline.zcount(key, min, max); + return null; + } return jedis.zcount(key, min, max); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1305,6 +1644,10 @@ public class JedisConnection implements RedisConnection { transaction.zincrby(key, increment, value); return null; } + if (isPipelined()) { + pipeline.zincrby(key, increment, value); + return null; + } return jedis.zincrby(key, increment, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1319,6 +1662,10 @@ public class JedisConnection implements RedisConnection { } ZParams zparams = new ZParams().weights(weights).aggregate( redis.clients.jedis.ZParams.Aggregate.valueOf(aggregate.name())); + if (isPipelined()) { + pipeline.zinterstore(destKey, zparams, sets); + return null; + } return jedis.zinterstore(destKey, zparams, sets); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1331,6 +1678,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isQueueing()) { + pipeline.zinterstore(destKey, sets); + return null; + } return jedis.zinterstore(destKey, sets); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1344,6 +1695,10 @@ public class JedisConnection implements RedisConnection { transaction.zrange(key, (int) start, (int) end); return null; } + if (isPipelined()) { + pipeline.zrange(key, (int) start, (int) end); + return null; + } return jedis.zrange(key, (int) start, (int) end); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1357,6 +1712,10 @@ public class JedisConnection implements RedisConnection { transaction.zrangeWithScores(key, (int) start, (int) end); return null; } + if (isPipelined()) { + pipeline.zrangeWithScores(key, (int) start, (int) end); + return null; + } return JedisUtils.convertJedisTuple(jedis.zrangeWithScores(key, (int) start, (int) end)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1369,6 +1728,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.zrangeByScore(key, min, max); + return null; + } return jedis.zrangeByScore(key, min, max); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1381,6 +1744,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.zrangeByScoreWithScores(key, min, max); + return null; + } return JedisUtils.convertJedisTuple(jedis.zrangeByScoreWithScores(key, min, max)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1394,6 +1761,10 @@ public class JedisConnection implements RedisConnection { transaction.zrangeWithScores(key, (int) start, (int) end); return null; } + if (isPipelined()) { + pipeline.zrangeWithScores(key, (int) start, (int) end); + return null; + } return JedisUtils.convertJedisTuple(jedis.zrangeByScoreWithScores(key, (int) start, (int) end)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1406,6 +1777,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.zrangeByScore(key, min, max, (int) offset, (int) count); + return null; + } return jedis.zrangeByScore(key, min, max, (int) offset, (int) count); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1418,6 +1793,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.zrangeByScoreWithScores(key, min, max, (int) offset, (int) count); + return null; + } return JedisUtils.convertJedisTuple(jedis.zrangeByScoreWithScores(key, min, max, (int) offset, (int) count)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1431,6 +1810,10 @@ public class JedisConnection implements RedisConnection { transaction.zrank(key, value); return null; } + if (isPipelined()) { + pipeline.zrank(key, value); + return null; + } return jedis.zrank(key, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1444,6 +1827,10 @@ public class JedisConnection implements RedisConnection { transaction.zrem(key, value); return null; } + if (isPipelined()) { + pipeline.zrem(key, value); + return null; + } return JedisUtils.convertCodeReply(jedis.zrem(key, value)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1456,6 +1843,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.zremrangeByRank(key, (int) start, (int) end); + return null; + } return jedis.zremrangeByRank(key, (int) start, (int) end); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1468,6 +1859,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.zremrangeByScore(key, min, max); + return null; + } return jedis.zremrangeByScore(key, min, max); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1481,6 +1876,10 @@ public class JedisConnection implements RedisConnection { transaction.zrevrange(key, (int) start, (int) end); return null; } + if (isPipelined()) { + pipeline.zrevrange(key, (int) start, (int) end); + return null; + } return jedis.zrevrange(key, (int) start, (int) end); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1494,6 +1893,10 @@ public class JedisConnection implements RedisConnection { transaction.zrevrank(key, value); return null; } + if (isPipelined()) { + pipeline.zrevrank(key, value); + return null; + } return jedis.zrevrank(key, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1507,6 +1910,10 @@ public class JedisConnection implements RedisConnection { transaction.zscore(key, value); return null; } + if (isPipelined()) { + pipeline.zscore(key, value); + return null; + } return jedis.zscore(key, value); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1521,6 +1928,10 @@ public class JedisConnection implements RedisConnection { } ZParams zparams = new ZParams().weights(weights).aggregate( redis.clients.jedis.ZParams.Aggregate.valueOf(aggregate.name())); + if (isPipelined()) { + pipeline.zunionstore(destKey, zparams, sets); + return null; + } return jedis.zunionstore(destKey, zparams, sets); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1533,6 +1944,10 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + pipeline.zunionstore(destKey, sets); + return null; + } return jedis.zunionstore(destKey, sets); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1550,6 +1965,10 @@ public class JedisConnection implements RedisConnection { transaction.hset(key, field, value); return null; } + if (isPipelined()) { + pipeline.hset(key, field, value); + return null; + } return JedisUtils.convertCodeReply(jedis.hset(key, field, value)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1563,6 +1982,10 @@ public class JedisConnection implements RedisConnection { transaction.hsetnx(key, field, value); return null; } + if (isPipelined()) { + pipeline.hsetnx(key, field, value); + return null; + } return JedisUtils.convertCodeReply(jedis.hsetnx(key, field, value)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1576,6 +1999,10 @@ public class JedisConnection implements RedisConnection { transaction.hdel(key, field); return null; } + if (isPipelined()) { + pipeline.hdel(key, field); + return null; + } return JedisUtils.convertCodeReply(jedis.hdel(key, field)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1589,6 +2016,10 @@ public class JedisConnection implements RedisConnection { transaction.hexists(key, field); return null; } + if (isPipelined()) { + pipeline.hexists(key, field); + return null; + } return jedis.hexists(key, field); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1602,6 +2033,10 @@ public class JedisConnection implements RedisConnection { transaction.hget(key, field); return null; } + if (isPipelined()) { + pipeline.hget(key, field); + return null; + } return jedis.hget(key, field); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1615,6 +2050,10 @@ public class JedisConnection implements RedisConnection { transaction.hgetAll(key); return null; } + if (isPipelined()) { + pipeline.hgetAll(key); + return null; + } return jedis.hgetAll(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1628,6 +2067,10 @@ public class JedisConnection implements RedisConnection { transaction.hincrBy(key, field, (int) delta); return null; } + if (isPipelined()) { + pipeline.hincrBy(key, field, (int) delta); + return null; + } return jedis.hincrBy(key, field, (int) delta); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1641,6 +2084,10 @@ public class JedisConnection implements RedisConnection { transaction.hkeys(key); return null; } + if (isPipelined()) { + pipeline.hkeys(key); + return null; + } return jedis.hkeys(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1654,6 +2101,10 @@ public class JedisConnection implements RedisConnection { transaction.hlen(key); return null; } + if (isPipelined()) { + pipeline.hlen(key); + return null; + } return jedis.hlen(key); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1667,6 +2118,10 @@ public class JedisConnection implements RedisConnection { transaction.hmget(key, fields); return null; } + if (isPipelined()) { + pipeline.hmget(key, fields); + return null; + } return jedis.hmget(key, fields); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1680,6 +2135,10 @@ public class JedisConnection implements RedisConnection { transaction.hmset(key, tuple); return; } + if (isPipelined()) { + pipeline.hmset(key, tuple); + return; + } jedis.hmset(key, tuple); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1693,6 +2152,10 @@ public class JedisConnection implements RedisConnection { transaction.hvals(key); return null; } + if (isPipelined()) { + pipeline.hvals(key); + return null; + } return new ArrayList(jedis.hvals(key)); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1709,7 +2172,9 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } - + if (isPipelined()) { + throw new UnsupportedOperationException(); + } return jedis.publish(channel, message); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1737,6 +2202,9 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } BinaryJedisPubSub jedisPubSub = JedisUtils.adaptPubSub(listener); @@ -1758,6 +2226,9 @@ public class JedisConnection implements RedisConnection { if (isQueueing()) { throw new UnsupportedOperationException(); } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } BinaryJedisPubSub jedisPubSub = JedisUtils.adaptPubSub(listener); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnectionFactory.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnectionFactory.java index 09f51d755..20cdfba51 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnectionFactory.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnectionFactory.java @@ -87,7 +87,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean, */ protected Jedis fetchJedisConnector() { try { - if (usePool) { + if (usePool && pool != null) { return pool.getResource(); } Jedis jedis = new Jedis(getShardInfo()); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisUtils.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisUtils.java index ee83bd9bd..bdfe315cd 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisUtils.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisUtils.java @@ -161,7 +161,7 @@ public abstract class JedisUtils { jedisParams.by(params.getByPattern()); } - byte[] getPattern = params.getGetPattern(); + byte[][] getPattern = params.getGetPattern(); if (getPattern != null) { jedisParams.get(getPattern); } diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisConnection.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisConnection.java index acd879bd3..e8360b1b4 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisConnection.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisConnection.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.Properties; import java.util.Set; +import org.jredis.ClientRuntimeException; import org.jredis.JRedis; import org.jredis.RedisException; import org.jredis.Sort; @@ -62,11 +63,16 @@ public class JredisConnection implements RedisConnection { this.isPool = (jredis instanceof JRedisService); } - protected DataAccessException convertJedisAccessException(Exception ex) { + protected DataAccessException convertJredisAccessException(Exception ex) { if (ex instanceof RedisException) { return JredisUtils.convertJredisAccessException((RedisException) ex); } - throw new UncategorizedKeyvalueStoreException("Unknown JRedis exception", ex); + + if (ex instanceof ClientRuntimeException) { + return JredisUtils.convertJredisAccessException((ClientRuntimeException) ex); + } + + return new UncategorizedKeyvalueStoreException("Unknown JRedis exception", ex); } @Override @@ -116,8 +122,8 @@ public class JredisConnection implements RedisConnection { JredisUtils.applySortingParams(sort, params, null); try { return sort.exec(); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -127,8 +133,8 @@ public class JredisConnection implements RedisConnection { JredisUtils.applySortingParams(sort, params, null); try { return Support.unpackValue(sort.exec()); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -136,8 +142,8 @@ public class JredisConnection implements RedisConnection { public Long dbSize() { try { return jredis.dbsize(); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -145,8 +151,8 @@ public class JredisConnection implements RedisConnection { public void flushDb() { try { jredis.flushdb(); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -154,8 +160,8 @@ public class JredisConnection implements RedisConnection { public void flushAll() { try { jredis.flushall(); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -163,8 +169,8 @@ public class JredisConnection implements RedisConnection { public byte[] echo(byte[] message) { try { return jredis.echo(message); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -173,8 +179,8 @@ public class JredisConnection implements RedisConnection { try { jredis.ping(); return "PONG"; - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -182,8 +188,8 @@ public class JredisConnection implements RedisConnection { public void bgSave() { try { jredis.bgsave(); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -191,8 +197,8 @@ public class JredisConnection implements RedisConnection { public void bgWriteAof() { try { jredis.bgrewriteaof(); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -200,8 +206,8 @@ public class JredisConnection implements RedisConnection { public void save() { try { jredis.save(); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -214,8 +220,8 @@ public class JredisConnection implements RedisConnection { public Properties info() { try { return JredisUtils.info(jredis.info()); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -223,8 +229,8 @@ public class JredisConnection implements RedisConnection { public Long lastSave() { try { return jredis.lastsave(); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -247,8 +253,8 @@ public class JredisConnection implements RedisConnection { public Long del(byte[]... keys) { try { return jredis.del(JredisUtils.decodeMultiple(keys)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -256,8 +262,8 @@ public class JredisConnection implements RedisConnection { public void discard() { try { jredis.discard(); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -270,8 +276,8 @@ public class JredisConnection implements RedisConnection { public Boolean exists(byte[] key) { try { return jredis.exists(JredisUtils.decode(key)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -279,8 +285,8 @@ public class JredisConnection implements RedisConnection { public Boolean expire(byte[] key, long seconds) { try { return jredis.expire(JredisUtils.decode(key), (int) seconds); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -288,8 +294,8 @@ public class JredisConnection implements RedisConnection { public Boolean expireAt(byte[] key, long unixTime) { try { return jredis.expireat(JredisUtils.decode(key), unixTime); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -297,8 +303,8 @@ public class JredisConnection implements RedisConnection { public Collection keys(byte[] pattern) { try { return JredisUtils.convertCollection(jredis.keys(JredisUtils.decode(pattern))); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -316,8 +322,8 @@ public class JredisConnection implements RedisConnection { public byte[] randomKey() { try { return JredisUtils.encode(jredis.randomkey()); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -325,8 +331,8 @@ public class JredisConnection implements RedisConnection { public void rename(byte[] oldName, byte[] newName) { try { jredis.rename(JredisUtils.decode(oldName), JredisUtils.decode(newName)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -334,8 +340,8 @@ public class JredisConnection implements RedisConnection { public Boolean renameNX(byte[] oldName, byte[] newName) { try { return jredis.renamenx(JredisUtils.decode(oldName), JredisUtils.decode(newName)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -348,8 +354,8 @@ public class JredisConnection implements RedisConnection { public Long ttl(byte[] key) { try { return jredis.ttl(JredisUtils.decode(key)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -357,8 +363,8 @@ public class JredisConnection implements RedisConnection { public DataType type(byte[] key) { try { return JredisUtils.convertDataType(jredis.type(JredisUtils.decode(key))); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -380,8 +386,8 @@ public class JredisConnection implements RedisConnection { public byte[] get(byte[] key) { try { return jredis.get(JredisUtils.decode(key)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -389,8 +395,8 @@ public class JredisConnection implements RedisConnection { public void set(byte[] key, byte[] value) { try { jredis.set(JredisUtils.decode(key), value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -398,8 +404,8 @@ public class JredisConnection implements RedisConnection { public byte[] getSet(byte[] key, byte[] value) { try { return jredis.getset(JredisUtils.decode(key), value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -407,8 +413,8 @@ public class JredisConnection implements RedisConnection { public Long append(byte[] key, byte[] value) { try { return jredis.append(JredisUtils.decode(key), value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -416,8 +422,8 @@ public class JredisConnection implements RedisConnection { public List mGet(byte[]... keys) { try { return jredis.mget(JredisUtils.decodeMultiple(keys)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -425,8 +431,8 @@ public class JredisConnection implements RedisConnection { public void mSet(Map tuple) { try { jredis.mset(JredisUtils.decodeMap(tuple)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -434,8 +440,8 @@ public class JredisConnection implements RedisConnection { public void mSetNX(Map tuple) { try { jredis.msetnx(JredisUtils.decodeMap(tuple)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -448,8 +454,8 @@ public class JredisConnection implements RedisConnection { public Boolean setNX(byte[] key, byte[] value) { try { return jredis.setnx(JredisUtils.decode(key), value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -457,8 +463,8 @@ public class JredisConnection implements RedisConnection { public byte[] getRange(byte[] key, int start, int end) { try { return jredis.substr(JredisUtils.decode(key), start, end); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -466,8 +472,8 @@ public class JredisConnection implements RedisConnection { public Long decr(byte[] key) { try { return jredis.decr(JredisUtils.decode(key)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -475,8 +481,8 @@ public class JredisConnection implements RedisConnection { public Long decrBy(byte[] key, long value) { try { return jredis.decrby(JredisUtils.decode(key), (int) value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -484,8 +490,8 @@ public class JredisConnection implements RedisConnection { public Long incr(byte[] key) { try { return jredis.incr(JredisUtils.decode(key)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -493,8 +499,8 @@ public class JredisConnection implements RedisConnection { public Long incrBy(byte[] key, long value) { try { return jredis.incrby(JredisUtils.decode(key), (int) value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -536,8 +542,8 @@ public class JredisConnection implements RedisConnection { public byte[] lIndex(byte[] key, long index) { try { return jredis.lindex(JredisUtils.decode(key), index); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -545,8 +551,8 @@ public class JredisConnection implements RedisConnection { public Long lLen(byte[] key) { try { return jredis.llen(JredisUtils.decode(key)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -554,8 +560,8 @@ public class JredisConnection implements RedisConnection { public byte[] lPop(byte[] key) { try { return jredis.lpop(JredisUtils.decode(key)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -564,8 +570,8 @@ public class JredisConnection implements RedisConnection { try { jredis.lpush(JredisUtils.decode(key), value); return null; - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -575,8 +581,8 @@ public class JredisConnection implements RedisConnection { List lrange = jredis.lrange(JredisUtils.decode(key), start, end); return lrange; - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -584,8 +590,8 @@ public class JredisConnection implements RedisConnection { public Long lRem(byte[] key, long count, byte[] value) { try { return jredis.lrem(JredisUtils.decode(key), value, (int) count); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -593,8 +599,8 @@ public class JredisConnection implements RedisConnection { public void lSet(byte[] key, long index, byte[] value) { try { jredis.lset(JredisUtils.decode(key), index, value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -602,8 +608,8 @@ public class JredisConnection implements RedisConnection { public void lTrim(byte[] key, long start, long end) { try { jredis.ltrim(JredisUtils.decode(key), start, end); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -611,8 +617,8 @@ public class JredisConnection implements RedisConnection { public byte[] rPop(byte[] key) { try { return jredis.rpop(JredisUtils.decode(key)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -620,8 +626,8 @@ public class JredisConnection implements RedisConnection { public byte[] rPopLPush(byte[] srcKey, byte[] dstKey) { try { return jredis.rpoplpush(JredisUtils.decode(srcKey), JredisUtils.decode(dstKey)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -630,8 +636,8 @@ public class JredisConnection implements RedisConnection { try { jredis.rpush(JredisUtils.decode(key), value); return null; - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -664,8 +670,8 @@ public class JredisConnection implements RedisConnection { public Boolean sAdd(byte[] key, byte[] value) { try { return jredis.sadd(JredisUtils.decode(key), value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -673,8 +679,8 @@ public class JredisConnection implements RedisConnection { public Long sCard(byte[] key) { try { return jredis.scard(JredisUtils.decode(key)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -686,8 +692,8 @@ public class JredisConnection implements RedisConnection { try { List result = jredis.sdiff(destKey, sets); return new LinkedHashSet(result); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -698,8 +704,8 @@ public class JredisConnection implements RedisConnection { try { jredis.sdiffstore(destSet, sets); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -711,8 +717,8 @@ public class JredisConnection implements RedisConnection { try { List result = jredis.sinter(set1, sets); return new LinkedHashSet(result); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -723,8 +729,8 @@ public class JredisConnection implements RedisConnection { try { jredis.sinterstore(destSet, sets); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -732,8 +738,8 @@ public class JredisConnection implements RedisConnection { public Boolean sIsMember(byte[] key, byte[] value) { try { return jredis.sismember(JredisUtils.decode(key), value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -741,8 +747,8 @@ public class JredisConnection implements RedisConnection { public Set sMembers(byte[] key) { try { return new LinkedHashSet(jredis.smembers(JredisUtils.decode(key))); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -750,8 +756,8 @@ public class JredisConnection implements RedisConnection { public Boolean sMove(byte[] srcKey, byte[] destKey, byte[] value) { try { return jredis.smove(JredisUtils.decode(srcKey), JredisUtils.decode(destKey), value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -759,8 +765,8 @@ public class JredisConnection implements RedisConnection { public byte[] sPop(byte[] key) { try { return jredis.spop(JredisUtils.decode(key)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -768,8 +774,8 @@ public class JredisConnection implements RedisConnection { public byte[] sRandMember(byte[] key) { try { return jredis.srandmember(JredisUtils.decode(key)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -777,8 +783,8 @@ public class JredisConnection implements RedisConnection { public Boolean sRem(byte[] key, byte[] value) { try { return jredis.srem(JredisUtils.decode(key), value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -789,8 +795,8 @@ public class JredisConnection implements RedisConnection { try { return new LinkedHashSet(jredis.sunion(set1, sets)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -801,8 +807,8 @@ public class JredisConnection implements RedisConnection { try { jredis.sunionstore(destSet, sets); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -815,8 +821,8 @@ public class JredisConnection implements RedisConnection { public Boolean zAdd(byte[] key, double score, byte[] value) { try { return jredis.zadd(JredisUtils.decode(key), score, value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -824,8 +830,8 @@ public class JredisConnection implements RedisConnection { public Long zCard(byte[] key) { try { return jredis.zcard(JredisUtils.decode(key)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -833,8 +839,8 @@ public class JredisConnection implements RedisConnection { public Long zCount(byte[] key, double min, double max) { try { return jredis.zcount(JredisUtils.decode(key), min, max); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -842,8 +848,8 @@ public class JredisConnection implements RedisConnection { public Double zIncrBy(byte[] key, double increment, byte[] value) { try { return jredis.zincrby(JredisUtils.decode(key), increment, value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -861,8 +867,8 @@ public class JredisConnection implements RedisConnection { public Set zRange(byte[] key, long start, long end) { try { return new LinkedHashSet(jredis.zrange(JredisUtils.decode(key), start, end)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -876,8 +882,8 @@ public class JredisConnection implements RedisConnection { public Set zRangeByScore(byte[] key, double min, double max) { try { return new LinkedHashSet(jredis.zrangebyscore(JredisUtils.decode(key), min, max)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -900,8 +906,8 @@ public class JredisConnection implements RedisConnection { public Long zRank(byte[] key, byte[] value) { try { return jredis.zrank(JredisUtils.decode(key), value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -909,8 +915,8 @@ public class JredisConnection implements RedisConnection { public Boolean zRem(byte[] key, byte[] value) { try { return jredis.zrem(JredisUtils.decode(key), value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -918,8 +924,8 @@ public class JredisConnection implements RedisConnection { public Long zRemRange(byte[] key, long start, long end) { try { return jredis.zremrangebyrank(JredisUtils.decode(key), start, end); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -927,8 +933,8 @@ public class JredisConnection implements RedisConnection { public Long zRemRangeByScore(byte[] key, double min, double max) { try { return jredis.zremrangebyscore(JredisUtils.decode(key), min, max); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -936,8 +942,8 @@ public class JredisConnection implements RedisConnection { public Set zRevRange(byte[] key, long start, long end) { try { return new LinkedHashSet(jredis.zrevrange(JredisUtils.decode(key), start, end)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -950,8 +956,8 @@ public class JredisConnection implements RedisConnection { public Long zRevRank(byte[] key, byte[] value) { try { return jredis.zrevrank(JredisUtils.decode(key), value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -959,8 +965,8 @@ public class JredisConnection implements RedisConnection { public Double zScore(byte[] key, byte[] value) { try { return jredis.zscore(JredisUtils.decode(key), value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -983,8 +989,8 @@ public class JredisConnection implements RedisConnection { public Boolean hDel(byte[] key, byte[] field) { try { return jredis.hdel(JredisUtils.decode(key), JredisUtils.decode(field)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -992,8 +998,8 @@ public class JredisConnection implements RedisConnection { public Boolean hExists(byte[] key, byte[] field) { try { return jredis.hexists(JredisUtils.decode(key), JredisUtils.decode(field)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -1001,8 +1007,8 @@ public class JredisConnection implements RedisConnection { public byte[] hGet(byte[] key, byte[] field) { try { return jredis.hget(JredisUtils.decode(key), JredisUtils.decode(field)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -1010,8 +1016,8 @@ public class JredisConnection implements RedisConnection { public Map hGetAll(byte[] key) { try { return JredisUtils.encodeMap(jredis.hgetall(JredisUtils.decode(key))); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -1024,8 +1030,8 @@ public class JredisConnection implements RedisConnection { public Set hKeys(byte[] key) { try { return new LinkedHashSet(JredisUtils.convertCollection(jredis.hkeys(JredisUtils.decode(key)))); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -1033,8 +1039,8 @@ public class JredisConnection implements RedisConnection { public Long hLen(byte[] key) { try { return jredis.hlen(JredisUtils.decode(key)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -1052,8 +1058,8 @@ public class JredisConnection implements RedisConnection { public Boolean hSet(byte[] key, byte[] field, byte[] value) { try { return jredis.hset(JredisUtils.decode(key), JredisUtils.decode(field), value); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } @@ -1066,8 +1072,8 @@ public class JredisConnection implements RedisConnection { public List hVals(byte[] key) { try { return jredis.hvals(JredisUtils.decode(key)); - } catch (RedisException ex) { - throw JredisUtils.convertJredisAccessException(ex); + } catch (Exception ex) { + throw convertJredisAccessException(ex); } } diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisConnectionFactory.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisConnectionFactory.java index c6c5ca649..832ca8f87 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisConnectionFactory.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisConnectionFactory.java @@ -15,6 +15,7 @@ */ package org.springframework.data.keyvalue.redis.connection.jredis; +import org.jredis.ClientRuntimeException; import org.jredis.connector.Connection; import org.jredis.connector.ConnectionSpec; import org.jredis.connector.Connection.Socket.Property; @@ -74,8 +75,7 @@ public class JredisConnectionFactory implements InitializingBean, DisposableBean public void afterPropertiesSet() { if (connectionSpec == null) { Assert.hasText(hostName); - connectionSpec = DefaultConnectionSpec.newSpec(hostName, port, DEFAULT_REDIS_DB, - DEFAULT_REDIS_PASSWORD); + connectionSpec = DefaultConnectionSpec.newSpec(hostName, port, DEFAULT_REDIS_DB, DEFAULT_REDIS_PASSWORD); connectionSpec.setConnectionFlag(Connection.Flag.RELIABLE, false); if (StringUtils.hasLength(password)) { @@ -111,6 +111,9 @@ public class JredisConnectionFactory implements InitializingBean, DisposableBean @Override public DataAccessException translateExceptionIfPossible(RuntimeException ex) { + if (ex instanceof ClientRuntimeException) { + return JredisUtils.convertJredisAccessException((ClientRuntimeException) ex); + } return null; } diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisUtils.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisUtils.java index f08d397fa..a41bd982a 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisUtils.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisUtils.java @@ -22,11 +22,13 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; +import org.jredis.ClientRuntimeException; import org.jredis.RedisException; import org.jredis.RedisType; import org.jredis.Sort; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.dao.InvalidDataAccessResourceUsageException; import org.springframework.data.keyvalue.redis.connection.DataType; import org.springframework.data.keyvalue.redis.connection.SortParameters; import org.springframework.data.keyvalue.redis.connection.SortParameters.Order; @@ -49,6 +51,16 @@ public abstract class JredisUtils { return new InvalidDataAccessApiUsageException(ex.getMessage(), ex); } + /** + * Converts the given, native JRedis exception to Spring's DAO hierarchy. + * + * @param ex JRedis exception + * @return converted exception + */ + public static DataAccessException convertJredisAccessException(ClientRuntimeException ex) { + return new InvalidDataAccessResourceUsageException(ex.getMessage(), ex); + } + static DataType convertDataType(RedisType type) { switch (type) { case NONE: @@ -117,9 +129,12 @@ public abstract class JredisUtils { if (byPattern != null) { jredisSort.BY(decode(byPattern)); } - byte[] getPattern = params.getGetPattern(); - if (getPattern != null) { - jredisSort.GET(decode(getPattern)); + byte[][] getPattern = params.getGetPattern(); + + if (getPattern != null && getPattern.length > 0) { + for (byte[] bs : getPattern) { + jredisSort.GET(decode(bs)); + } } Range limit = params.getLimit(); if (limit != null) { diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundSetOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundSetOperations.java index 7011c7257..2da61f806 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundSetOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundSetOperations.java @@ -28,17 +28,29 @@ public interface BoundSetOperations extends KeyBound { RedisOperations getOperations(); + Set diff(K key); + Set diff(Collection keys); - void diffAndStore(K destKey, Collection keys); + void diffAndStore(K key, K destKey); + + void diffAndStore(Collection keys, K destKey); + + Set intersect(K key); Set intersect(Collection keys); - void intersectAndStore(K destKey, Collection keys); + void intersectAndStore(K key, K destKey); + + void intersectAndStore(Collection keys, K destKey); + + Set union(K key); Set union(Collection keys); - void unionAndStore(K destKey, Collection keys); + void unionAndStore(K key, K destKey); + + void unionAndStore(Collection keys, K destKey); Boolean add(V value); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundZSetOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundZSetOperations.java index 87f992bfa..37222cc93 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundZSetOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundZSetOperations.java @@ -29,7 +29,9 @@ public interface BoundZSetOperations extends KeyBound { RedisOperations getOperations(); - void intersectAndStore(K destKey, Collection keys); + void intersectAndStore(K otherKey, K destKey); + + void intersectAndStore(Collection otherKeys, K destKey); Set range(long start, long end); @@ -41,7 +43,9 @@ public interface BoundZSetOperations extends KeyBound { void removeRangeByScore(double min, double max); - void unionAndStore(K destKey, Collection keys); + void unionAndStore(K otherKey, K destKey); + + void unionAndStore(Collection otherKeys, K destKey); Boolean add(V value, double score); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BulkMapper.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BulkMapper.java new file mode 100644 index 000000000..97d37998a --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BulkMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2011 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.keyvalue.redis.core; + +import java.util.List; + +/** + * Mapper translating Redis bulk value responses (typically returned by a sort query) to actual objects. Implementations of this interface do not have to worry + * about exception or connection handling. + *

+ * Typically used by {@link RedisTemplate} sort methods. + * + * @author Costin Leau + */ +public interface BulkMapper { + + T mapBulk(List tuple); +} diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundSetOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundSetOperations.java index ffae21d6f..e92e21bd2 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundSetOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundSetOperations.java @@ -45,14 +45,25 @@ class DefaultBoundSetOperations extends DefaultKeyBound implements Boun return ops.add(getKey(), value); } + @Override + public Set diff(K key) { + return ops.difference(getKey(), key); + } + @Override public Set diff(Collection keys) { return ops.difference(getKey(), keys); } + @Override - public void diffAndStore(K destKey, Collection keys) { - ops.differenceAndStore(getKey(), destKey, keys); + public void diffAndStore(K key, K destKey) { + ops.differenceAndStore(getKey(), key, destKey); + } + + @Override + public void diffAndStore(Collection keys, K destKey) { + ops.differenceAndStore(getKey(), keys, destKey); } @Override @@ -60,14 +71,24 @@ class DefaultBoundSetOperations extends DefaultKeyBound implements Boun return ops.getOperations(); } + @Override + public Set intersect(K key) { + return ops.intersect(getKey(), key); + } + @Override public Set intersect(Collection keys) { return ops.intersect(getKey(), keys); } @Override - public void intersectAndStore(K destKey, Collection keys) { - ops.intersectAndStore(getKey(), destKey, keys); + public void intersectAndStore(K key, K destKey) { + ops.intersectAndStore(getKey(), key, destKey); + } + + @Override + public void intersectAndStore(Collection keys, K destKey) { + ops.intersectAndStore(getKey(), keys, destKey); } @Override @@ -82,7 +103,7 @@ class DefaultBoundSetOperations extends DefaultKeyBound implements Boun @Override public Boolean move(K destKey, V value) { - return ops.move(getKey(), destKey, value); + return ops.move(getKey(), value, destKey); } @Override @@ -105,13 +126,24 @@ class DefaultBoundSetOperations extends DefaultKeyBound implements Boun return ops.size(getKey()); } + + @Override + public Set union(K key) { + return ops.union(getKey(), key); + } + @Override public Set union(Collection keys) { return ops.union(getKey(), keys); } @Override - public void unionAndStore(K destKey, Collection keys) { - ops.unionAndStore(getKey(), destKey, keys); + public void unionAndStore(K key, K destKey) { + ops.unionAndStore(getKey(), key, destKey); + } + + @Override + public void unionAndStore(Collection keys, K destKey) { + ops.unionAndStore(getKey(), keys, destKey); } } \ No newline at end of file diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundZSetOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundZSetOperations.java index 00443f515..343c1d72b 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundZSetOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundZSetOperations.java @@ -55,8 +55,13 @@ class DefaultBoundZSetOperations extends DefaultKeyBound implements Bou } @Override - public void intersectAndStore(K destKey, Collection keys) { - ops.intersectAndStore(getKey(), destKey, keys); + public void intersectAndStore(K destKey, K otherKey) { + ops.intersectAndStore(getKey(), otherKey, destKey); + } + + @Override + public void intersectAndStore(Collection otherKeys, K destKey) { + ops.intersectAndStore(getKey(), otherKeys, destKey); } @Override @@ -115,7 +120,12 @@ class DefaultBoundZSetOperations extends DefaultKeyBound implements Bou } @Override - public void unionAndStore(K destKey, Collection keys) { - ops.unionAndStore(getKey(), destKey, keys); + public void unionAndStore(K otherKey, K destKey) { + ops.unionAndStore(getKey(), otherKey, destKey); + } + + @Override + public void unionAndStore(Collection otherKeys, K destKey) { + ops.unionAndStore(getKey(), otherKeys, destKey); } } \ No newline at end of file diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisOperations.java index 396ae3ee3..f9c4411c3 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisOperations.java @@ -22,7 +22,8 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import org.springframework.data.keyvalue.redis.connection.DataType; -import org.springframework.data.keyvalue.redis.connection.SortParameters; +import org.springframework.data.keyvalue.redis.core.query.SortQuery; +import org.springframework.data.keyvalue.redis.serializer.RedisSerializer; /** @@ -65,6 +66,8 @@ public interface RedisOperations { Boolean hasKey(K key); + void delete(K key); + void delete(Collection key); DataType type(K key); @@ -85,6 +88,8 @@ public interface RedisOperations { Long getExpire(K key); + void watch(K keys); + void watch(Collection keys); void unwatch(); @@ -98,10 +103,6 @@ public interface RedisOperations { Object exec(); - List sort(K key, SortParameters params); - - Long sort(K key, SortParameters params, K destination); - // pubsub functionality on the template void convertAndSend(String destination, Object message); @@ -187,4 +188,17 @@ public interface RedisOperations { * @return hash operations bound to the given key. */ BoundHashOperations boundHashOps(K key); + + + List sort(SortQuery query); + + + List sort(SortQuery query, RedisSerializer resultSerializer); + + + List sort(SortQuery query, BulkMapper bulkMapper); + + List sort(SortQuery query, BulkMapper bulkMapper, RedisSerializer resultSerializer); + + Long sort(SortQuery query, K storeKey); } \ No newline at end of file diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisTemplate.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisTemplate.java index 718f73ace..52bded364 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisTemplate.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisTemplate.java @@ -32,10 +32,12 @@ import java.util.concurrent.TimeUnit; import org.springframework.dao.DataAccessException; import org.springframework.data.keyvalue.redis.connection.DataType; +import org.springframework.data.keyvalue.redis.connection.DefaultSortParameters; import org.springframework.data.keyvalue.redis.connection.RedisConnection; import org.springframework.data.keyvalue.redis.connection.RedisConnectionFactory; import org.springframework.data.keyvalue.redis.connection.SortParameters; import org.springframework.data.keyvalue.redis.connection.RedisListCommands.Position; +import org.springframework.data.keyvalue.redis.core.query.SortQuery; import org.springframework.data.keyvalue.redis.serializer.JdkSerializationRedisSerializer; import org.springframework.data.keyvalue.redis.serializer.RedisSerializer; import org.springframework.data.keyvalue.redis.serializer.StringRedisSerializer; @@ -145,7 +147,7 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation * @return object returned by the action */ public T execute(RedisCallback action, boolean exposeConnection) { - return execute(action, exposeConnection, valueSerializer); + return execute(action, exposeConnection, false); } /** @@ -158,35 +160,6 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation * @return object returned by the action */ public T execute(RedisCallback action, boolean exposeConnection, boolean pipeline) { - return execute(action, exposeConnection, pipeline, valueSerializer); - } - - /** - * Executes the given action object within a connection, which can be exposed or not. Allows a custom serializer - * to be specified for the returned object. - * - * @param return type - * @param action action callback object that specifies the Redis action - * @param exposeConnection whether to enforce exposure of the native Redis Connection to callback code - * @param returnSerializer serializer used for converting the binary data to the custom return type - * @return returned by the action - */ - public T execute(RedisCallback action, boolean exposeConnection, RedisSerializer returnSerializer) { - return execute(action, exposeConnection, false, returnSerializer); - } - - /** - * Executes the given action object within a connection, which can be exposed or not. Allows a custom serializer - * to be specified for the returned object. - * - * @param return type - * @param action action callback object that specifies the Redis action - * @param exposeConnection whether to enforce exposure of the native Redis Connection to callback code - * @param pipeline whether to pipeline or not the connection for the execution duration - * @param returnSerializer serializer used for converting the binary data to the custom return type - * @return returned by the action - */ - public T execute(RedisCallback action, boolean exposeConnection, boolean pipeline, RedisSerializer returnSerializer) { Assert.notNull(action, "Callback object must not be null"); RedisConnectionFactory factory = getConnectionFactory(); @@ -203,7 +176,7 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation try { RedisConnection connToExpose = (exposeConnection ? conn : createRedisConnectionProxy(conn)); T result = action.doInRedis(connToExpose); - // TODO: should do flush? + // TODO: any other connection processing? return postProcessResult(result, conn, existingConnection); } finally { try { @@ -426,6 +399,15 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation return rawKeys; } + private byte[][] rawKeys(K key, K otherKey) { + final byte[][] rawKeys = new byte[2][]; + + + rawKeys[0] = rawKey(key); + rawKeys[1] = rawKey(key); + return rawKeys; + } + private byte[][] rawKeys(K key, Collection keys) { final byte[][] rawKeys = new byte[keys.size() + 1][]; @@ -441,11 +423,16 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation @SuppressWarnings("unchecked") private > T deserializeValues(Collection rawValues, Class type) { - Collection values = (List.class.isAssignableFrom(type) ? new ArrayList(rawValues.size()) - : new LinkedHashSet(rawValues.size())); + return (T) deserializeValues(rawValues, type, valueSerializer); + } + + @SuppressWarnings("unchecked") + private > T deserializeValues(Collection rawValues, Class type, RedisSerializer redisSerializer) { + Collection values = (List.class.isAssignableFrom(type) ? new ArrayList(rawValues.size()) + : new LinkedHashSet(rawValues.size())); for (byte[] bs : rawValues) { if (bs != null) { - values.add((V) valueSerializer.deserialize(bs)); + values.add(redisSerializer.deserialize(bs)); } } @@ -575,6 +562,19 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation }); } + @Override + public void delete(K key) { + final byte[] rawKey = rawKey(key); + + execute(new RedisCallback() { + @Override + public Object doInRedis(RedisConnection connection) { + connection.del(rawKey); + return null; + } + }, true); + } + @Override public void delete(Collection keys) { final byte[][] rawKeys = rawKeys(keys); @@ -626,33 +626,6 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation }, true); } - @Override - public List sort(K key, final SortParameters params) { - final byte[] rawKey = rawKey(key); - - List rawValues = execute(new RedisCallback>() { - @Override - public List doInRedis(RedisConnection connection) { - return connection.sort(rawKey, params); - } - }, true); - - return deserializeValues(rawValues, List.class); - } - - @Override - public Long sort(K key, final SortParameters params, K destination) { - final byte[] rawKey = rawKey(key); - final byte[] rawDestKey = rawKey(destination); - - return execute(new RedisCallback() { - @Override - public Long doInRedis(RedisConnection connection) { - return connection.sort(rawKey, params, rawDestKey); - } - }, true); - } - @Override public void convertAndSend(String channel, Object message) { Assert.hasText(channel, "a non-empty channel is required"); @@ -787,6 +760,19 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation }, true); } + @Override + public void watch(K key) { + final byte[] rawKey = rawKey(key); + + execute(new RedisCallback() { + @Override + public Object doInRedis(RedisConnection connection) { + connection.watch(rawKey); + return null; + } + }, true); + } + @Override public void watch(Collection keys) { final byte[][] rawKeys = rawKeys(keys); @@ -1301,8 +1287,13 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation } @Override - public Set difference(final K key, final Collection keys) { - final byte[][] rawKeys = rawKeys(key, keys); + public Set difference(K key, K otherKey) { + return difference(key, Collections.singleton(otherKey)); + } + + @Override + public Set difference(final K key, final Collection otherKeys) { + final byte[][] rawKeys = rawKeys(key, otherKeys); Set rawValues = execute(new RedisCallback>() { @Override public Set doInRedis(RedisConnection connection) { @@ -1314,8 +1305,13 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation } @Override - public void differenceAndStore(final K key, K destKey, final Collection keys) { - final byte[][] rawKeys = rawKeys(key, keys); + public void differenceAndStore(K key, K otherKey, K destKey) { + differenceAndStore(key, Collections.singleton(otherKey), destKey); + } + + @Override + public void differenceAndStore(final K key, final Collection otherKeys, K destKey) { + final byte[][] rawKeys = rawKeys(key, otherKeys); final byte[] rawDestKey = rawKey(destKey); execute(new RedisCallback() { @Override @@ -1332,8 +1328,13 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation } @Override - public Set intersect(K key, Collection keys) { - final byte[][] rawKeys = rawKeys(key, keys); + public Set intersect(K key, K otherKey) { + return intersect(key, Collections.singleton(otherKey)); + } + + @Override + public Set intersect(K key, Collection otherKeys) { + final byte[][] rawKeys = rawKeys(key, otherKeys); Set rawValues = execute(new RedisCallback>() { @Override public Set doInRedis(RedisConnection connection) { @@ -1345,8 +1346,13 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation } @Override - public void intersectAndStore(K key, K destKey, Collection keys) { - final byte[][] rawKeys = rawKeys(key, keys); + public void intersectAndStore(K key, K otherKey, K destKey) { + intersectAndStore(key, Collections.singleton(otherKey), destKey); + } + + @Override + public void intersectAndStore(K key, Collection otherKeys, K destKey) { + final byte[][] rawKeys = rawKeys(key, otherKeys); final byte[] rawDestKey = rawKey(destKey); execute(new RedisCallback() { @Override @@ -1383,7 +1389,7 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation } @Override - public Boolean move(K key, K destKey, V value) { + public Boolean move(K key, V value, K destKey) { final byte[] rawKey = rawKey(key); final byte[] rawDestKey = rawKey(destKey); final byte[] rawValue = rawValue(value); @@ -1441,8 +1447,13 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation } @Override - public Set union(K key, Collection keys) { - final byte[][] rawKeys = rawKeys(key, keys); + public Set union(K key, K otherKey) { + return union(key, Collections.singleton(otherKey)); + } + + @Override + public Set union(K key, Collection otherKeys) { + final byte[][] rawKeys = rawKeys(key, otherKeys); Set rawValues = execute(new RedisCallback>() { @Override public Set doInRedis(RedisConnection connection) { @@ -1454,8 +1465,13 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation } @Override - public void unionAndStore(K key, K destKey, Collection keys) { - final byte[][] rawKeys = rawKeys(key, keys); + public void unionAndStore(K key, K otherKey, K destKey) { + unionAndStore(key, Collections.singleton(otherKey), destKey); + } + + @Override + public void unionAndStore(K key, Collection otherKeys, K destKey) { + final byte[][] rawKeys = rawKeys(key, otherKeys); final byte[] rawDestKey = rawKey(destKey); execute(new RedisCallback() { @Override @@ -1514,9 +1530,15 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation return RedisTemplate.this; } + @Override - public void intersectAndStore(K key, K destKey, Collection keys) { - final byte[][] rawKeys = rawKeys(key, keys); + public void intersectAndStore(K key, K otherKey, K destKey) { + intersectAndStore(key, Collections.singleton(otherKey), destKey); + } + + @Override + public void intersectAndStore(K key, Collection otherKeys, K destKey) { + final byte[][] rawKeys = rawKeys(key, otherKeys); final byte[] rawDestKey = rawKey(destKey); execute(new RedisCallback() { @Override @@ -1672,8 +1694,13 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation } @Override - public void unionAndStore(K key, K destKey, Collection keys) { - final byte[][] rawKeys = rawKeys(key, keys); + public void unionAndStore(K key, K otherKey, K destKey) { + unionAndStore(key, Collections.singleton(otherKey), destKey); + } + + @Override + public void unionAndStore(K key, Collection otherKeys, K destKey) { + final byte[][] rawKeys = rawKeys(key, otherKeys); final byte[] rawDestKey = rawKey(destKey); execute(new RedisCallback() { @Override @@ -1899,4 +1926,89 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation return deserializeHashMap(entries); } } + + // Sort operations + @SuppressWarnings("unchecked") + @Override + public List sort(SortQuery query) { + return sort(query, valueSerializer); + } + + @SuppressWarnings("unchecked") + @Override + public List sort(SortQuery query, RedisSerializer resultSerializer) { + final byte[] rawKey = rawKey(query.getKey()); + final SortParameters params = convertQuery(query, stringSerializer); + + List vals = execute(new RedisCallback>() { + @Override + public List doInRedis(RedisConnection connection) throws DataAccessException { + return connection.sort(rawKey, params); + } + }, true); + + return (List) deserializeValues(vals, List.class, resultSerializer); + } + + @SuppressWarnings("unchecked") + @Override + public List sort(SortQuery query, BulkMapper bulkMapper) { + return sort(query, bulkMapper, valueSerializer); + } + + @Override + public List sort(SortQuery query, BulkMapper bulkMapper, RedisSerializer resultSerializer) { + List values = sort(query, resultSerializer); + + int bulkSize = query.getGetPattern().size(); + List result = new ArrayList(values.size() / bulkSize + 1); + + List bulk = new ArrayList(bulkSize); + for (S s : values) { + + bulk.add(s); + if (bulk.size() == bulkSize) { + result.add(bulkMapper.mapBulk(Collections.unmodifiableList(bulk))); + // create a new list (we could reuse the old one but the client might hang on to it for some reason) + bulk = new ArrayList(bulkSize); + } + } + + return result; + } + + @Override + public Long sort(SortQuery query, K storeKey) { + final byte[] rawStoreKey = rawKey(storeKey); + final byte[] rawKey = rawKey(query.getKey()); + final SortParameters params = convertQuery(query, stringSerializer); + + return execute(new RedisCallback() { + @Override + public Long doInRedis(RedisConnection connection) throws DataAccessException { + return connection.sort(rawKey, params, rawStoreKey); + } + }, true); + } + + private static SortParameters convertQuery(SortQuery query, RedisSerializer stringSerializer) { + + return new DefaultSortParameters(stringSerializer.serialize(query.getBy()), query.getLimit(), serialize( + query.getGetPattern(), stringSerializer), query.getOrder(), query.isAlphabetic()); + } + + private static byte[][] serialize(List strings, RedisSerializer stringSerializer) { + List raw = null; + + if (strings == null) { + raw = Collections.emptyList(); + } + else { + raw = new ArrayList(strings.size()); + for (String key : strings) { + raw.add(stringSerializer.serialize(key)); + } + } + return raw.toArray(new byte[raw.size()][]); + } } \ No newline at end of file diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/SetOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/SetOperations.java index 1c852cd39..a8145f30c 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/SetOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/SetOperations.java @@ -26,17 +26,29 @@ import java.util.Set; */ public interface SetOperations { - Set difference(K key, Collection keys); + Set difference(K key, K otherKey); - void differenceAndStore(K key, K destKey, Collection keys); + Set difference(K key, Collection otherKeys); - Set intersect(K key, Collection keys); + void differenceAndStore(K key, K otherKey, K destKey); - void intersectAndStore(K key, K destKey, Collection keys); + void differenceAndStore(K key, Collection otherKeys, K destKey); - Set union(K key, Collection keys); + Set intersect(K key, K otherKey); - void unionAndStore(K key, K destKey, Collection keys); + Set intersect(K key, Collection otherKeys); + + void intersectAndStore(K key, K otherKey, K destKey); + + void intersectAndStore(K key, Collection otherKeys, K destKey); + + Set union(K key, K otherKey); + + Set union(K key, Collection otherKeys); + + void unionAndStore(K key, K otherKey, K destKey); + + void unionAndStore(K key, Collection otherKeys, K destKey); Boolean add(K key, V value); @@ -44,7 +56,7 @@ public interface SetOperations { Set members(K key); - Boolean move(K key, K destKey, V value); + Boolean move(K key, V value, K destKey); V randomMember(K key); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/ZSetOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/ZSetOperations.java index 08f0744a3..221138af9 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/ZSetOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/ZSetOperations.java @@ -26,9 +26,13 @@ import java.util.Set; */ public interface ZSetOperations { - void intersectAndStore(K key, K destKey, Collection keys); + void intersectAndStore(K key, K otherKey, K destKey); - void unionAndStore(K key, K destKey, Collection keys); + void intersectAndStore(K key, Collection otherKeys, K destKey); + + void unionAndStore(K key, K otherKey, K destKey); + + void unionAndStore(K key, Collection otherKeys, K destKey); Set range(K key, long start, long end); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/DefaultSortCriterion.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/DefaultSortCriterion.java new file mode 100644 index 000000000..242a7af6e --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/DefaultSortCriterion.java @@ -0,0 +1,82 @@ +/* + * Copyright 2011 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.keyvalue.redis.core.query; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.data.keyvalue.redis.connection.SortParameters.Order; +import org.springframework.data.keyvalue.redis.connection.SortParameters.Range; + +/** + * Default implementation for {@link SortCriterion}. + * + * @author Costin Leau + */ +class DefaultSortCriterion implements SortCriterion { + + private final K key; + private String by; + private final List getKeys = new ArrayList(4); + + private Range limit; + private Order order; + private Boolean alpha; + + DefaultSortCriterion(K key) { + this.key = key; + } + + @Override + public SortCriterion alphabetical(boolean alpha) { + this.alpha = Boolean.valueOf(alpha); + return this; + } + + @Override + public SortQuery build() { + return new DefaultSortQuery(key, by, limit, order, alpha, getKeys); + } + + @Override + public SortCriterion limit(long offset, long count) { + this.limit = new Range(offset, count); + return this; + } + + @Override + public SortCriterion limit(Range range) { + this.limit = range; + return this; + } + + @Override + public SortCriterion order(Order order) { + this.order = order; + return this; + } + + @Override + public SortCriterion get(String getPattern) { + this.getKeys.add(getPattern); + return this; + } + + SortCriterion addBy(String keyPattern) { + this.by = keyPattern; + return this; + } +} \ No newline at end of file diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/DefaultSortQuery.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/DefaultSortQuery.java new file mode 100644 index 000000000..4348e2fa2 --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/DefaultSortQuery.java @@ -0,0 +1,83 @@ +/* + * Copyright 2011 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.keyvalue.redis.core.query; + +import java.util.List; + +import org.springframework.data.keyvalue.redis.connection.SortParameters.Order; +import org.springframework.data.keyvalue.redis.connection.SortParameters.Range; + +/** + * Default SortQuery implementation. + * + * @author Costin Leau + */ +class DefaultSortQuery implements SortQuery { + + private final K key; + private final Boolean alpha; + private final Order order; + private final Range limit; + private final String by; + private final List gets; + + DefaultSortQuery(K key, String by, Range limit, Order order, Boolean alpha, List gets) { + this.key = key; + this.by = by; + this.limit = limit; + this.order = order; + this.alpha = alpha; + this.gets = gets; + } + + @Override + public String getBy() { + return by; + } + + @Override + public Range getLimit() { + return limit; + } + + @Override + public Order getOrder() { + return order; + } + + @Override + public Boolean isAlphabetic() { + return alpha; + } + + @Override + public K getKey() { + return key; + } + + @Override + public List getGetPattern() { + return gets; + } + + @Override + public String toString() { + return "DefaultSortQuery [alpha=" + alpha + ", by=" + by + ", gets=" + gets + ", key=" + key + ", limit=" + + limit + ", order=" + order + "]"; + } + + +} \ No newline at end of file diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/SortCriterion.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/SortCriterion.java new file mode 100644 index 000000000..50929b04d --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/SortCriterion.java @@ -0,0 +1,39 @@ +/* + * Copyright 2011 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.keyvalue.redis.core.query; + +import org.springframework.data.keyvalue.redis.connection.SortParameters.Order; +import org.springframework.data.keyvalue.redis.connection.SortParameters.Range; + +/** + * Internal interface part of the Sort DSL. Exposes generic operations. + * + * @author Costin Leau + */ +public interface SortCriterion { + + SortCriterion limit(long offset, long count); + + SortCriterion limit(Range range); + + SortCriterion order(Order order); + + SortCriterion alphabetical(boolean alpha); + + SortCriterion get(String pattern); + + SortQuery build(); +} diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/SortQuery.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/SortQuery.java new file mode 100644 index 000000000..27643c962 --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/SortQuery.java @@ -0,0 +1,78 @@ +/* + * Copyright 2011 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.keyvalue.redis.core.query; + +import java.util.List; + +import org.springframework.data.keyvalue.redis.connection.RedisConnection; +import org.springframework.data.keyvalue.redis.connection.SortParameters; +import org.springframework.data.keyvalue.redis.connection.SortParameters.Order; +import org.springframework.data.keyvalue.redis.connection.SortParameters.Range; +import org.springframework.data.keyvalue.redis.core.RedisTemplate; + +/** + * High-level abstraction over a Redis SORT (generified equivalent of {@link SortParameters}). To be used with {@link RedisTemplate} + * (just as {@link SortParameters} is used by {@link RedisConnection}). + * + * @author Costin Leau + */ +public interface SortQuery { + + /** + * Returns the sorting order. Can be null if nothing is specified. + * + * @return sorting order + */ + Order getOrder(); + + /** + * Indicates if the sorting is numeric (default) or alphabetical (lexicographical). + * Can be null if nothing is specified. + * + * @return the type of sorting + */ + Boolean isAlphabetic(); + + + /** + * Returns the sorting limit (range or pagination). + * Can be null if nothing is specified. + * + * @return sorting limit/range + */ + Range getLimit(); + + /** + * Return the target key for sorting. + * + * @return + */ + K getKey(); + + /** + * Returns the pattern of the external key used for sorting. + * + * @return + */ + String getBy(); + + /** + * Returns the external key(s) whose values are returned by the sort. + * + * @return + */ + List getGetPattern(); +} \ No newline at end of file diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/SortQueryBuilder.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/SortQueryBuilder.java new file mode 100644 index 000000000..588d80694 --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/query/SortQueryBuilder.java @@ -0,0 +1,43 @@ +/* + * Copyright 2011 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.keyvalue.redis.core.query; + + +/** + * Simple builder class for constructing {@link SortQuery}. + * + * @author Costin Leau + */ +public class SortQueryBuilder extends DefaultSortCriterion { + + private static final String NO_SORT_KEY = "~"; + + private SortQueryBuilder(K key) { + super(key); + } + + public static SortQueryBuilder sort(K key) { + return new SortQueryBuilder(key); + } + + public SortCriterion by(String keyPattern) { + return addBy(keyPattern); + } + + public SortCriterion noSort() { + return by(NO_SORT_KEY); + } +} diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/BeanUtilsHashMapper.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/BeanUtilsHashMapper.java new file mode 100644 index 000000000..1283eb26e --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/BeanUtilsHashMapper.java @@ -0,0 +1,54 @@ +/* + * Copyright 2011 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.keyvalue.redis.hash; + +import java.util.Map; + +import org.apache.commons.beanutils.BeanUtils; + +/** + * HashMapper based on Apache Commons BeanUtils project. Does NOT supports nested properties. + * + * @author Costin Leau + */ +public class BeanUtilsHashMapper implements HashMapper { + + private Class type; + + public BeanUtilsHashMapper(Class type) { + this.type = type; + } + + @Override + public T fromHash(Map hash) { + T instance = org.springframework.beans.BeanUtils.instantiate(type); + try { + BeanUtils.populate(instance, hash); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + return instance; + } + + @Override + public Map toHash(T object) { + try { + return BeanUtils.describe(object); + } catch (Exception ex) { + throw new IllegalArgumentException("Cannot describe object " + object); + } + } +} diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/DecoratingStringHashMapper.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/DecoratingStringHashMapper.java new file mode 100644 index 000000000..378203134 --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/DecoratingStringHashMapper.java @@ -0,0 +1,51 @@ +/* + * Copyright 2011 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.keyvalue.redis.hash; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Delegating hash mapper used for flattening objects into Strings. + * Suitable when dealing with mappers that support Strings and type conversion. + * + * @author Costin Leau + */ +public class DecoratingStringHashMapper implements HashMapper { + + private final HashMapper delegate; + + public DecoratingStringHashMapper(HashMapper mapper) { + this.delegate = mapper; + } + + @SuppressWarnings("unchecked") + @Override + public T fromHash(Map hash) { + Map h = hash; + return delegate.fromHash(h); + } + + @Override + public Map toHash(T object) { + Map hash = delegate.toHash(object); + Map flatten = new LinkedHashMap(hash.size()); + for (Map.Entry entry : hash.entrySet()) { + flatten.put(String.valueOf(entry.getKey()), String.valueOf(entry.getValue())); + } + return flatten; + } +} diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/HashMapper.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/HashMapper.java new file mode 100644 index 000000000..e1bafcbc9 --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/HashMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2011 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.keyvalue.redis.hash; + +import java.util.Map; + +/** + * Core mapping contract between Java types and Redis hashes/maps. + * It's up to the implementation to support nested objects. + * + * @author Costin Leau + */ +public interface HashMapper { + + Map toHash(T object); + + T fromHash(Map hash); +} diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/JacksonHashMapper.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/JacksonHashMapper.java new file mode 100644 index 000000000..895e0edfb --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/hash/JacksonHashMapper.java @@ -0,0 +1,55 @@ +/* + * Copyright 2011 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.keyvalue.redis.hash; + +import java.util.Map; + +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.type.TypeFactory; +import org.codehaus.jackson.type.JavaType; + +/** + * Mapper based on Jackson library. Supports nested properties (rich objects). + * + * @author Costin Leau + */ +public class JacksonHashMapper implements HashMapper { + + private final ObjectMapper mapper; + private final JavaType userType; + private final JavaType mapType = TypeFactory.type(Map.class); + + public JacksonHashMapper(Class type) { + this(type, new ObjectMapper()); + } + + public JacksonHashMapper(Class type, ObjectMapper mapper) { + this.mapper = mapper; + this.userType = TypeFactory.type(type); + } + + @SuppressWarnings("unchecked") + @Override + public T fromHash(Map hash) { + return (T) mapper.convertValue(hash, userType); + } + + @SuppressWarnings("unchecked") + @Override + public Map toHash(T object) { + return mapper.convertValue(object, mapType); + } +} diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/serializer/BasicNumberToStringSerializer.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/serializer/BasicNumberToStringSerializer.java new file mode 100644 index 000000000..e7a493879 --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/serializer/BasicNumberToStringSerializer.java @@ -0,0 +1,68 @@ +/* + * Copyright 2011 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.keyvalue.redis.serializer; + +import java.lang.reflect.Constructor; +import java.nio.charset.Charset; + +import org.springframework.beans.BeanUtils; +import org.springframework.util.Assert; + +/** + * Simple toString() serializer for the core (lang) numberic JDK types. + * + * @see String#valueOf(Object) + * @see Long#valueOf(String) + * @author Costin Leau + */ +public class BasicNumberToStringSerializer implements RedisSerializer { + + private final Charset charset; + private final Constructor ctor; + + public BasicNumberToStringSerializer(Class type) { + this(type, Charset.forName("UTF8")); + } + + public BasicNumberToStringSerializer(Class type, Charset charset) { + Assert.notNull(type); + this.charset = charset; + + if (!(Byte.class.isAssignableFrom(type) || Short.class.isAssignableFrom(type) + || Long.class.isAssignableFrom(type) || Integer.class.isAssignableFrom(type) + || Float.class.isAssignableFrom(type) || Double.class.isAssignableFrom(type))) { + throw new IllegalArgumentException("Type " + type + " not supported"); + } + + try { + ctor = type.getConstructor(String.class); + } catch (Exception ex) { + throw new IllegalArgumentException("Cannot find suitable constructor for " + type); + } + } + + @Override + public T deserialize(byte[] bytes) { + String string = new String(bytes, charset); + return BeanUtils.instantiateClass(ctor, string); + } + + @Override + public byte[] serialize(T object) { + String string = String.valueOf(object); + return string.getBytes(charset); + } +} \ No newline at end of file diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/serializer/GenericToStringSerializer.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/serializer/GenericToStringSerializer.java index 1887e92b1..8daafa1b9 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/serializer/GenericToStringSerializer.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/serializer/GenericToStringSerializer.java @@ -77,7 +77,7 @@ public class GenericToStringSerializer implements RedisSerializer, BeanFac @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - if (converter != null && beanFactory instanceof ConfigurableBeanFactory) { + if (converter == null && beanFactory instanceof ConfigurableBeanFactory) { ConfigurableBeanFactory cFB = (ConfigurableBeanFactory) beanFactory; ConversionService conversionService = cFB.getConversionService(); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicInteger.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicInteger.java index 653201532..cae600c76 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicInteger.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicInteger.java @@ -17,7 +17,6 @@ package org.springframework.data.keyvalue.redis.support.atomic; import java.io.Serializable; import java.util.Collections; -import java.util.concurrent.Callable; import org.springframework.data.keyvalue.redis.connection.RedisConnectionFactory; import org.springframework.data.keyvalue.redis.core.KeyBound; @@ -25,6 +24,8 @@ import org.springframework.data.keyvalue.redis.core.RedisOperations; import org.springframework.data.keyvalue.redis.core.RedisTemplate; import org.springframework.data.keyvalue.redis.core.SessionCallback; import org.springframework.data.keyvalue.redis.core.ValueOperations; +import org.springframework.data.keyvalue.redis.serializer.BasicNumberToStringSerializer; +import org.springframework.data.keyvalue.redis.serializer.StringRedisSerializer; /** * Atomic integer backed by Redis. @@ -48,6 +49,8 @@ public class RedisAtomicInteger extends Number implements Serializable, KeyBound */ public RedisAtomicInteger(String redisCounter, RedisConnectionFactory factory) { RedisTemplate redisTemplate = new RedisTemplate(factory); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new BasicNumberToStringSerializer(Integer.class)); redisTemplate.setExposeConnection(true); this.key = redisCounter; this.generalOps = redisTemplate; @@ -172,18 +175,11 @@ public class RedisAtomicInteger extends Number implements Serializable, KeyBound /** * Atomically increment by one the current value. + * * @return the previous value */ public int getAndIncrement() { - return CASUtils.execute(generalOps, key, new Callable() { - @Override - public Integer call() throws Exception { - int value = get(); - generalOps.multi(); - operations.increment(key, 1); - return value; - } - }); + return incrementAndGet() - 1; } @@ -192,15 +188,7 @@ public class RedisAtomicInteger extends Number implements Serializable, KeyBound * @return the previous value */ public int getAndDecrement() { - return CASUtils.execute(generalOps, key, new Callable() { - @Override - public Integer call() throws Exception { - int value = get(); - generalOps.multi(); - operations.increment(key, -1); - return value; - } - }); + return decrementAndGet() + 1; } @@ -210,15 +198,7 @@ public class RedisAtomicInteger extends Number implements Serializable, KeyBound * @return the previous value */ public int getAndAdd(final int delta) { - return CASUtils.execute(generalOps, key, new Callable() { - @Override - public Integer call() throws Exception { - int value = get(); - generalOps.multi(); - set(value + delta); - return value; - } - }); + return addAndGet(delta) - delta; } /** diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicLong.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicLong.java index b1c6c8bbf..001ee19ba 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicLong.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicLong.java @@ -17,7 +17,6 @@ package org.springframework.data.keyvalue.redis.support.atomic; import java.io.Serializable; import java.util.Collections; -import java.util.concurrent.Callable; import org.springframework.data.keyvalue.redis.connection.RedisConnectionFactory; import org.springframework.data.keyvalue.redis.core.KeyBound; @@ -25,6 +24,8 @@ import org.springframework.data.keyvalue.redis.core.RedisOperations; import org.springframework.data.keyvalue.redis.core.RedisTemplate; import org.springframework.data.keyvalue.redis.core.SessionCallback; import org.springframework.data.keyvalue.redis.core.ValueOperations; +import org.springframework.data.keyvalue.redis.serializer.BasicNumberToStringSerializer; +import org.springframework.data.keyvalue.redis.serializer.StringRedisSerializer; /** * Atomic long backed by Redis. @@ -48,6 +49,8 @@ public class RedisAtomicLong extends Number implements Serializable, KeyBound redisTemplate = new RedisTemplate(factory); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new BasicNumberToStringSerializer(Long.class)); redisTemplate.setExposeConnection(true); this.key = redisCounter; this.generalOps = redisTemplate; @@ -177,15 +180,7 @@ public class RedisAtomicLong extends Number implements Serializable, KeyBound() { - @Override - public Long call() throws Exception { - long value = get(); - generalOps.multi(); - operations.increment(key, 1); - return value; - } - }); + return incrementAndGet() - 1; } /** @@ -194,15 +189,7 @@ public class RedisAtomicLong extends Number implements Serializable, KeyBound() { - @Override - public Long call() throws Exception { - long value = get(); - generalOps.multi(); - operations.increment(key, -11); - return value; - } - }); + return decrementAndGet() + 1; } /** @@ -212,15 +199,7 @@ public class RedisAtomicLong extends Number implements Serializable, KeyBound() { - @Override - public Long call() throws Exception { - long value = get(); - generalOps.multi(); - set(value + delta); - return value; - } - }); + return addAndGet(delta) - delta; } /** diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/DefaultRedisSet.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/DefaultRedisSet.java index 43b4a5e67..50a69ea11 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/DefaultRedisSet.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/DefaultRedisSet.java @@ -66,36 +66,71 @@ public class DefaultRedisSet extends AbstractRedisCollection implements Re this.boundSetOps = boundOps; } + + @Override + public Set diff(RedisSet set) { + return boundSetOps.diff(set.getKey()); + } + @Override public Set diff(Collection> sets) { return boundSetOps.diff(CollectionUtils.extractKeys(sets)); } + @Override - public RedisSet diffAndStore(String destKey, Collection> sets) { - boundSetOps.diffAndStore(destKey, CollectionUtils.extractKeys(sets)); + public RedisSet diffAndStore(RedisSet set, String destKey) { + boundSetOps.diffAndStore(set.getKey(), destKey); return new DefaultRedisSet(boundSetOps.getOperations().boundSetOps(destKey)); } + @Override + public RedisSet diffAndStore(Collection> sets, String destKey) { + boundSetOps.diffAndStore(CollectionUtils.extractKeys(sets), destKey); + return new DefaultRedisSet(boundSetOps.getOperations().boundSetOps(destKey)); + } + + @Override + public Set intersect(RedisSet set) { + return boundSetOps.intersect(set.getKey()); + } + @Override public Set intersect(Collection> sets) { return boundSetOps.intersect(CollectionUtils.extractKeys(sets)); } @Override - public RedisSet intersectAndStore(String destKey, Collection> sets) { - boundSetOps.intersectAndStore(destKey, CollectionUtils.extractKeys(sets)); + public RedisSet intersectAndStore(RedisSet set, String destKey) { + boundSetOps.intersectAndStore(set.getKey(), destKey); return new DefaultRedisSet(boundSetOps.getOperations().boundSetOps(destKey)); } + @Override + public RedisSet intersectAndStore(Collection> sets, String destKey) { + boundSetOps.intersectAndStore(CollectionUtils.extractKeys(sets), destKey); + return new DefaultRedisSet(boundSetOps.getOperations().boundSetOps(destKey)); + } + + @Override + public Set union(RedisSet set) { + return boundSetOps.union(set.getKey()); + } + @Override public Set union(Collection> sets) { return boundSetOps.union(CollectionUtils.extractKeys(sets)); } @Override - public RedisSet unionAndStore(String destKey, Collection> sets) { - boundSetOps.unionAndStore(destKey, CollectionUtils.extractKeys(sets)); + public RedisSet unionAndStore(RedisSet set, String destKey) { + boundSetOps.unionAndStore(set.getKey(), destKey); + return new DefaultRedisSet(boundSetOps.getOperations().boundSetOps(destKey)); + } + + @Override + public RedisSet unionAndStore(Collection> sets, String destKey) { + boundSetOps.unionAndStore(CollectionUtils.extractKeys(sets), destKey); return new DefaultRedisSet(boundSetOps.getOperations().boundSetOps(destKey)); } @@ -109,7 +144,7 @@ public class DefaultRedisSet extends AbstractRedisCollection implements Re // intersect the set with a non existing one // TODO: find a safer way to clean the set String randomKey = UUID.randomUUID().toString(); - boundSetOps.intersectAndStore(getKey(), Collections.singleton(randomKey)); + boundSetOps.intersectAndStore(Collections.singleton(randomKey), getKey()); } @Override diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/DefaultRedisZSet.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/DefaultRedisZSet.java index f425c3b03..d3ee04765 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/DefaultRedisZSet.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/DefaultRedisZSet.java @@ -91,8 +91,14 @@ public class DefaultRedisZSet extends AbstractRedisCollection implements R } @Override - public RedisZSet intersectAndStore(String destKey, Collection> sets) { - boundZSetOps.intersectAndStore(destKey, CollectionUtils.extractKeys(sets)); + public RedisZSet intersectAndStore(RedisZSet set, String destKey) { + boundZSetOps.intersectAndStore(set.getKey(), destKey); + return new DefaultRedisZSet(boundZSetOps.getOperations().boundZSetOps(destKey), getDefaultScore()); + } + + @Override + public RedisZSet intersectAndStore(Collection> sets, String destKey) { + boundZSetOps.intersectAndStore(CollectionUtils.extractKeys(sets), destKey); return new DefaultRedisZSet(boundZSetOps.getOperations().boundZSetOps(destKey), getDefaultScore()); } @@ -124,8 +130,14 @@ public class DefaultRedisZSet extends AbstractRedisCollection implements R } @Override - public RedisZSet unionAndStore(String destKey, Collection> sets) { - boundZSetOps.unionAndStore(destKey, CollectionUtils.extractKeys(sets)); + public RedisZSet unionAndStore(RedisZSet set, String destKey) { + boundZSetOps.unionAndStore(set.getKey(), destKey); + return new DefaultRedisZSet(boundZSetOps.getOperations().boundZSetOps(destKey), getDefaultScore()); + } + + @Override + public RedisZSet unionAndStore(Collection> sets, String destKey) { + boundZSetOps.unionAndStore(CollectionUtils.extractKeys(sets), destKey); return new DefaultRedisZSet(boundZSetOps.getOperations().boundZSetOps(destKey), getDefaultScore()); } diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisList.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisList.java index 45d697576..846454fb5 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisList.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisList.java @@ -28,7 +28,7 @@ import java.util.concurrent.BlockingDeque; */ public interface RedisList extends RedisCollection, List, BlockingDeque { - List range(long start, long end); + List range(long begin, long end); - RedisList trim(int start, int end); + RedisList trim(int begin, int end); } diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisSet.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisSet.java index 02b2001fc..78cde802b 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisSet.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisSet.java @@ -26,15 +26,27 @@ import java.util.Set; */ public interface RedisSet extends RedisCollection, Set { + Set intersect(RedisSet set); + Set intersect(Collection> sets); + Set union(RedisSet set); + Set union(Collection> sets); + Set diff(RedisSet set); + Set diff(Collection> sets); - RedisSet intersectAndStore(String destKey, Collection> sets); + RedisSet intersectAndStore(RedisSet set, String destKey); - RedisSet unionAndStore(String destKey, Collection> sets); + RedisSet intersectAndStore(Collection> sets, String destKey); - RedisSet diffAndStore(String destKey, Collection> sets); + RedisSet unionAndStore(RedisSet set, String destKey); + + RedisSet unionAndStore(Collection> sets, String destKey); + + RedisSet diffAndStore(RedisSet set, String destKey); + + RedisSet diffAndStore(Collection> sets, String destKey); } diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisZSet.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisZSet.java index fde9160a2..0d6c24221 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisZSet.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisZSet.java @@ -30,9 +30,13 @@ import java.util.SortedSet; */ public interface RedisZSet extends RedisCollection, Set { - RedisZSet intersectAndStore(String destKey, Collection> sets); + RedisZSet intersectAndStore(RedisZSet set, String destKey); - RedisZSet unionAndStore(String destKey, Collection> sets); + RedisZSet intersectAndStore(Collection> sets, String destKey); + + RedisZSet unionAndStore(RedisZSet set, String destKey); + + RedisZSet unionAndStore(Collection> sets, String destKey); Set range(long start, long end); diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/connection/AbstractConnectionIntegrationTests.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/connection/AbstractConnectionIntegrationTests.java index 115ae28bf..95ee8ec75 100644 --- a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/connection/AbstractConnectionIntegrationTests.java +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/connection/AbstractConnectionIntegrationTests.java @@ -24,6 +24,7 @@ import java.util.UUID; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.springframework.dao.DataAccessException; import org.springframework.data.keyvalue.redis.Address; import org.springframework.data.keyvalue.redis.Person; import org.springframework.data.keyvalue.redis.serializer.JdkSerializationRedisSerializer; @@ -32,15 +33,16 @@ import org.springframework.data.keyvalue.redis.serializer.StringRedisSerializer; public abstract class AbstractConnectionIntegrationTests { - protected RedisConnection connection; + protected StringRedisConnection connection; protected RedisSerializer serializer = new JdkSerializationRedisSerializer(); protected RedisSerializer stringSerializer = new StringRedisSerializer(); private static final String listName = "test-list"; + private static final byte[] EMPTY_ARRAY = new byte[0]; @Before public void setUp() { - connection = getConnectionFactory().getConnection(); + connection = new DefaultStringRedisConnection(getConnectionFactory().getConnection()); } protected abstract RedisConnectionFactory getConnectionFactory(); @@ -97,4 +99,45 @@ public abstract class AbstractConnectionIntegrationTests { assertNotNull(version); System.out.println(info); } + + @Test + public void testNullKey() throws Exception { + connection.decr((String) null); + connection.decr(EMPTY_ARRAY); + } + + @Test + public void testNullValue() throws Exception { + byte[] key = UUID.randomUUID().toString().getBytes(); + connection.append(key, EMPTY_ARRAY); + try { + connection.append(key, null); + } catch (DataAccessException ex) { + // expected + } + } + + @Test + public void testHashNullKey() throws Exception { + byte[] key = UUID.randomUUID().toString().getBytes(); + connection.hExists(key, EMPTY_ARRAY); + try { + connection.hExists(key, null); + } catch (DataAccessException ex) { + // expected + } + } + + @Test + public void testHashNullValue() throws Exception { + byte[] key = UUID.randomUUID().toString().getBytes(); + byte[] field = "random".getBytes(); + + connection.hSet(key, field, EMPTY_ARRAY); + try { + connection.hSet(key, field, null); + } catch (DataAccessException ex) { + // expected + } + } } \ No newline at end of file diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/core/SortTest.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/core/SortTest.java new file mode 100644 index 000000000..df6fd0b95 --- /dev/null +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/core/SortTest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2011 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.keyvalue.redis.core; + + +import org.junit.After; +import org.junit.Before; +import org.springframework.data.keyvalue.redis.core.query.SortQueryBuilder; + +public class SortTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + public void testBasicDSL() throws Exception { + SortQueryBuilder.sort("list").build(); + } + +} diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/mapping/AbstractHashMapperTest.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/mapping/AbstractHashMapperTest.java new file mode 100644 index 000000000..6a6823987 --- /dev/null +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/mapping/AbstractHashMapperTest.java @@ -0,0 +1,49 @@ +/* + * Copyright 2011 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.keyvalue.redis.mapping; + +import static org.junit.Assert.*; + +import java.util.Map; + +import org.junit.Test; +import org.springframework.data.keyvalue.redis.Address; +import org.springframework.data.keyvalue.redis.Person; +import org.springframework.data.keyvalue.redis.hash.HashMapper; + +/** + * @author Costin Leau + */ +public abstract class AbstractHashMapperTest { + protected abstract HashMapper mapperFor(Class t); + + private void test(Object o) { + HashMapper mapper = mapperFor(o.getClass()); + Map hash = mapper.toHash(o); + System.out.println("object hash " + hash.size() + " is " + hash); + assertEquals(o, mapper.fromHash(hash)); + } + + @Test + public void testSimpleBean() throws Exception { + test(new Address("Broadway", 1)); + } + + @Test + public void testNestedBean() throws Exception { + test(new Person("George", "Enescu", 74, new Address("liveni", 19))); + } +} \ No newline at end of file diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/mapping/BeanUtilsHashMapperTest.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/mapping/BeanUtilsHashMapperTest.java new file mode 100644 index 000000000..de3cc1dad --- /dev/null +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/mapping/BeanUtilsHashMapperTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2011 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.keyvalue.redis.mapping; + +import org.junit.Test; +import org.springframework.data.keyvalue.redis.hash.BeanUtilsHashMapper; +import org.springframework.data.keyvalue.redis.hash.HashMapper; + +/** + * @author Costin Leau + */ +public class BeanUtilsHashMapperTest extends AbstractHashMapperTest { + + @Override + protected HashMapper mapperFor(Class t) { + return new BeanUtilsHashMapper(t); + } + + @Test(expected = IllegalArgumentException.class) + public void testNestedBean() throws Exception { + super.testNestedBean(); + } +} diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/mapping/JacksonHashMapperTest.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/mapping/JacksonHashMapperTest.java new file mode 100644 index 000000000..18b8d5951 --- /dev/null +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/mapping/JacksonHashMapperTest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2011 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.keyvalue.redis.mapping; + +import org.springframework.data.keyvalue.redis.hash.HashMapper; +import org.springframework.data.keyvalue.redis.hash.JacksonHashMapper; + +public class JacksonHashMapperTest extends AbstractHashMapperTest { + + @Override + protected HashMapper mapperFor(Class t) { + return new JacksonHashMapper(t); + } +} diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicTests.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicTests.java index 9254eb2a6..306f7dff9 100644 --- a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicTests.java +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicTests.java @@ -78,4 +78,30 @@ public class RedisAtomicTests { assertTrue(longCounter.compareAndSet(0, 10)); assertTrue(longCounter.compareAndSet(10, 0)); } + + @Test + public void testLongIncrement() throws Exception { + longCounter.set(0); + assertEquals(1, longCounter.incrementAndGet()); + } + + @Test + public void testIntIncrement() throws Exception { + intCounter.set(0); + assertEquals(1, intCounter.incrementAndGet()); + } + + @Test + public void testLongCustomIncrement() throws Exception { + longCounter.set(0); + long delta = 5; + assertEquals(delta, longCounter.addAndGet(delta)); + } + + @Test + public void testIntCustomIncrement() throws Exception { + intCounter.set(0); + int delta = 5; + assertEquals(delta, intCounter.addAndGet(delta)); + } } \ No newline at end of file diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/AbstractRedisSetTests.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/AbstractRedisSetTests.java index f66f80683..b06c1b139 100644 --- a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/AbstractRedisSetTests.java +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/AbstractRedisSetTests.java @@ -102,7 +102,7 @@ public abstract class AbstractRedisSetTests extends AbstractRedisCollectionTe diffSet2.add(t4); String resultName = "test:set:diff:result:1"; - RedisSet diff = set.diffAndStore(resultName, Arrays.asList(diffSet1, diffSet2)); + RedisSet diff = set.diffAndStore(Arrays.asList(diffSet1, diffSet2), resultName); assertEquals(1, diff.size()); assertThat(diff, hasItem(t1)); @@ -153,7 +153,7 @@ public abstract class AbstractRedisSetTests extends AbstractRedisCollectionTe intSet2.add(t3); String resultName = "test:set:intersect:result:1"; - RedisSet inter = set.intersectAndStore(resultName, Arrays.asList(intSet1, intSet2)); + RedisSet inter = set.intersectAndStore(Arrays.asList(intSet1, intSet2), resultName); assertEquals(1, inter.size()); assertThat(inter, hasItem(t2)); assertEquals(resultName, inter.getKey()); @@ -199,7 +199,7 @@ public abstract class AbstractRedisSetTests extends AbstractRedisCollectionTe unionSet2.add(t3); String resultName = "test:set:union:result:1"; - RedisSet union = set.unionAndStore(resultName, Arrays.asList(unionSet1, unionSet2)); + RedisSet union = set.unionAndStore(Arrays.asList(unionSet1, unionSet2), resultName); assertEquals(4, union.size()); assertThat(union, hasItems(t1, t2, t3, t4)); assertEquals(resultName, union.getKey()); diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/AbstractRedisZSetTest.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/AbstractRedisZSetTest.java index 8e5465ee1..9aae0fde4 100644 --- a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/AbstractRedisZSetTest.java +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/AbstractRedisZSetTest.java @@ -207,7 +207,7 @@ public abstract class AbstractRedisZSetTest extends AbstractRedisCollectionTe interSet2.add(t3, 3); String resultName = "test:zset:inter:result:1"; - RedisZSet inter = zSet.intersectAndStore(resultName, Arrays.asList(interSet1, interSet2)); + RedisZSet inter = zSet.intersectAndStore(Arrays.asList(interSet1, interSet2), resultName); assertEquals(1, inter.size()); assertThat(inter, hasItem(t2)); @@ -327,7 +327,7 @@ public abstract class AbstractRedisZSetTest extends AbstractRedisCollectionTe unionSet2.add(t3, 6); String resultName = "test:zset:union:result:1"; - RedisZSet union = zSet.unionAndStore(resultName, Arrays.asList(unionSet1, unionSet2)); + RedisZSet union = zSet.unionAndStore(Arrays.asList(unionSet1, unionSet2), resultName); assertEquals(4, union.size()); assertThat(union, hasItems(t1, t2, t3, t4)); assertEquals(resultName, union.getKey()); diff --git a/spring-data-redis/template.mf b/spring-data-redis/template.mf index 88cfc4de8..8bfce223f 100644 --- a/spring-data-redis/template.mf +++ b/spring-data-redis/template.mf @@ -23,4 +23,6 @@ Import-Template: redis.clients.jedis.*;version="[1.5.2, 2.0.0)", redis.clients.util.*;version="[1.5.2, 2.0.0)", org.apache.commons.pool.impl.*;version="[1.0.0, 3.0.0)", - org.codehaus.jackson.*;version="[1.6, 2.0.0)" + org.codehaus.jackson.*;version="[1.6, 2.0.0)", + org.apache.commons.beanutils.*;version="[1.8.0, 2.0.0)" + diff --git a/spring-datastore-keyvalue-parent/.project b/spring-datastore-keyvalue-parent/.project deleted file mode 100644 index fc55d1f3a..000000000 --- a/spring-datastore-keyvalue-parent/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - spring-datastore-keyvalue-parent - - - - - - org.maven.ide.eclipse.maven2Builder - - - - - - org.maven.ide.eclipse.maven2Nature - -