From c7ab10481bd5f5a0d0085e8a78d00391d232ff45 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Tue, 7 Dec 2010 12:24:53 +0200 Subject: [PATCH] DATAKV-8 + add sort support at Connection level --- .../connection/DefaultSortParameters.java | 57 +++++++++++-------- .../redis/connection/RedisCommands.java | 6 ++ .../redis/connection/SortParameters.java | 9 +-- .../connection/jedis/JedisConnection.java | 39 +++++++++++++ .../redis/connection/jedis/JedisUtils.java | 37 ++++++++++++ .../connection/jredis/JredisConnection.java | 25 ++++++++ .../redis/connection/jredis/JredisUtils.java | 37 ++++++++++++ 7 files changed, 181 insertions(+), 29 deletions(-) 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 727d11936..b03c91fef 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 @@ -18,6 +18,7 @@ package org.springframework.data.keyvalue.redis.connection; /** * Default implementation for {@link SortParameters}. + * * @author Costin Leau */ public class DefaultSortParameters implements SortParameters { @@ -25,16 +26,14 @@ public class DefaultSortParameters implements SortParameters { private byte[] byPattern; private Range limit; private byte[] getPattern; - private byte[] hashKey; private Order order; private Boolean alphabetic; - private byte[] storeKey; /** * Constructs a new DefaultSortParameters instance. */ public DefaultSortParameters() { - this(null, null, null, null, null, null, null); + this(null, null, null, null, null); } /** @@ -45,7 +44,7 @@ public class DefaultSortParameters implements SortParameters { * @param alphabetic */ public DefaultSortParameters(Range limit, Order order, Boolean alphabetic) { - this(null, limit, null, null, order, alphabetic, null); + this(null, limit, null, order, alphabetic); } /** @@ -56,18 +55,14 @@ public class DefaultSortParameters implements SortParameters { * @param getPattern * @param order * @param alphabetic - * @param storeKey */ - public DefaultSortParameters(byte[] by, Range limit, byte[] get, byte[] hashKey, Order order, Boolean alphabetic, - byte[] storeKey) { + public DefaultSortParameters(byte[] by, Range limit, byte[] get, Order order, Boolean alphabetic) { super(); this.byPattern = by; this.limit = limit; this.getPattern = get; - this.hashKey = hashKey; this.order = order; this.alphabetic = alphabetic; - this.storeKey = storeKey; } @Override @@ -97,15 +92,6 @@ public class DefaultSortParameters implements SortParameters { this.getPattern = getPattern; } - @Override - public byte[] getHashKey() { - return hashKey; - } - - public void setHashKey(byte[] hashKey) { - this.hashKey = hashKey; - } - @Override public Order getOrder() { return order; @@ -124,12 +110,37 @@ public class DefaultSortParameters implements SortParameters { this.alphabetic = alphabetic; } - @Override - public byte[] getStoreKey() { - return storeKey; + // + // builder like methods + // + + public SortParameters order(Order order) { + setOrder(order); + return this; } - public void setStoreKey(byte[] storeKey) { - this.storeKey = storeKey; + public SortParameters alpha() { + setAlphabetic(true); + return this; + } + + public SortParameters numeric() { + setAlphabetic(false); + return this; + } + + public SortParameters get(byte[] pattern) { + setGetPattern(pattern); + return this; + } + + public SortParameters by(byte[] pattern) { + setByPattern(pattern); + return this; + } + + public SortParameters limit(long start, long count) { + setLimit(new Range(start, count)); + return this; } } \ No newline at end of file diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisCommands.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisCommands.java index e52c2bd4a..085339916 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisCommands.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisCommands.java @@ -17,6 +17,7 @@ package org.springframework.data.keyvalue.redis.connection; import java.util.Collection; +import java.util.List; /** * Commands supported by Redis . @@ -53,4 +54,9 @@ public interface RedisCommands extends RedisTxCommands, RedisStringCommands, Red void select(int dbIndex); void flushDb(); + + // sort commands + List sort(byte[] key, SortParameters params); + + Long sort(byte[] key, SortParameters params, byte[] storeKey); } \ No newline at end of file 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 e9cf29f39..f33ab25a2 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 @@ -40,14 +40,15 @@ public interface SortParameters { this.count = count; } - long start() { + public long getStart() { return start; } - long count() { + public long getCount() { return count; } } + Order getOrder(); Boolean isAlphabetic(); @@ -56,9 +57,5 @@ public interface SortParameters { byte[] getGetPattern(); - byte[] getHashKey(); - - byte[] getStoreKey(); - Range getLimit(); } 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 d41bfda6d..92736fc2a 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 @@ -28,6 +28,7 @@ import org.springframework.data.keyvalue.UncategorizedKeyvalueStoreException; import org.springframework.data.keyvalue.redis.UncategorizedRedisException; import org.springframework.data.keyvalue.redis.connection.DataType; import org.springframework.data.keyvalue.redis.connection.RedisConnection; +import org.springframework.data.keyvalue.redis.connection.SortParameters; import org.springframework.util.ReflectionUtils; import redis.clients.jedis.BinaryJedis; @@ -35,6 +36,7 @@ import redis.clients.jedis.BinaryTransaction; import redis.clients.jedis.Client; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisException; +import redis.clients.jedis.SortingParams; import redis.clients.jedis.Transaction; import redis.clients.jedis.ZParams; @@ -107,6 +109,43 @@ public class JedisConnection implements RedisConnection { return client.isInMulti(); } + @Override + public List sort(byte[] key, SortParameters params) { + + SortingParams sortParams = JedisUtils.convertSortParams(params); + + try { + if (isQueueing()) { + if (sortParams != null) { + transaction.sort(key, sortParams); + } + else { + transaction.sort(key); + } + + return null; + } + return (sortParams != null ? jedis.sort(key, sortParams) : jedis.sort(key)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + @Override + public Long sort(byte[] key, SortParameters params, byte[] sortKey) { + + SortingParams sortParams = JedisUtils.convertSortParams(params); + + try { + if (isQueueing()) { + throw new UnsupportedOperationException("Jedis does not support sort&store in MULTI/EXEC mode."); + } + return (sortParams != null ? jedis.sort(key, sortParams, sortKey) : jedis.sort(key, sortKey)); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + @Override public Long dbSize() { try { 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 924e9e382..d1074328d 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 @@ -29,9 +29,13 @@ import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.keyvalue.redis.RedisConnectionFailureException; import org.springframework.data.keyvalue.redis.UncategorizedRedisException; import org.springframework.data.keyvalue.redis.connection.DefaultTuple; +import org.springframework.data.keyvalue.redis.connection.SortParameters; import org.springframework.data.keyvalue.redis.connection.RedisZSetCommands.Tuple; +import org.springframework.data.keyvalue.redis.connection.SortParameters.Order; +import org.springframework.data.keyvalue.redis.connection.SortParameters.Range; import redis.clients.jedis.JedisException; +import redis.clients.jedis.SortingParams; /** * Helper class featuring methods for Jedis connection handling, providing support for exception translation. @@ -114,4 +118,37 @@ public abstract class JedisUtils { } return result; } + + static SortingParams convertSortParams(SortParameters params) { + SortingParams jedisParams = null; + + if (params != null) { + jedisParams = new SortingParams(); + + byte[] byPattern = params.getByPattern(); + if (byPattern != null) { + jedisParams.by(params.getByPattern()); + } + + byte[] getPattern = params.getGetPattern(); + if (getPattern != null) { + jedisParams.get(getPattern); + } + + Range limit = params.getLimit(); + if (limit != null) { + jedisParams.limit((int) limit.getStart(), (int) limit.getCount()); + } + Order order = params.getOrder(); + if (order != null && order.equals(Order.DESC)) { + jedisParams.desc(); + } + Boolean isAlpha = params.isAlphabetic(); + if (isAlpha != null && isAlpha) { + jedisParams.alpha(); + } + } + + return jedisParams; + } } \ No newline at end of file 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 5d911ee41..4d50491b7 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 @@ -25,11 +25,14 @@ import java.util.Set; import org.jredis.JRedis; import org.jredis.RedisException; +import org.jredis.Sort; +import org.jredis.Query.Support; import org.springframework.dao.DataAccessException; import org.springframework.data.keyvalue.UncategorizedKeyvalueStoreException; import org.springframework.data.keyvalue.redis.UncategorizedRedisException; import org.springframework.data.keyvalue.redis.connection.DataType; import org.springframework.data.keyvalue.redis.connection.RedisConnection; +import org.springframework.data.keyvalue.redis.connection.SortParameters; /** * JRedis based implementation. @@ -75,6 +78,28 @@ public class JredisConnection implements RedisConnection { return false; } + @Override + public List sort(byte[] key, SortParameters params) { + Sort sort = jredis.sort(JredisUtils.decode(key)); + JredisUtils.applySortingParams(sort, params, null); + try { + return sort.exec(); + } catch (RedisException ex) { + throw JredisUtils.convertJredisAccessException(ex); + } + } + + @Override + public Long sort(byte[] key, SortParameters params, byte[] storeKey) { + Sort sort = jredis.sort(JredisUtils.decode(key)); + JredisUtils.applySortingParams(sort, params, null); + try { + return Support.unpackValue(sort.exec()); + } catch (RedisException ex) { + throw JredisUtils.convertJredisAccessException(ex); + } + } + @Override public Long dbSize() { try { 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 cf25fd13a..042ab7257 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 @@ -23,9 +23,13 @@ import java.util.Map; 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.data.keyvalue.redis.connection.DataType; +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; /** * Helper class featuring methods for JRedis connection handling, providing support for exception translation. @@ -98,4 +102,37 @@ public abstract class JredisUtils { } return result; } + + + static Sort applySortingParams(Sort jredisSort, SortParameters params, byte[] storeKey) { + if (params != null) { + byte[] byPattern = params.getByPattern(); + if (byPattern != null) { + jredisSort.BY(decode(byPattern)); + } + byte[] getPattern = params.getGetPattern(); + if (getPattern != null) { + jredisSort.GET(decode(getPattern)); + } + Range limit = params.getLimit(); + if (limit != null) { + jredisSort.LIMIT(limit.getStart(), limit.getCount()); + } + Order order = params.getOrder(); + if (order != null && order.equals(Order.DESC)) { + jredisSort.DESC(); + } + Boolean isAlpha = params.isAlphabetic(); + if (isAlpha != null && isAlpha) { + jredisSort.ALPHA(); + } + } + + if (storeKey != null) { + jredisSort.STORE(decode(storeKey)); + } + + + return jredisSort; + } } \ No newline at end of file