diff --git a/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java
index 4e4b4ecd3..48fc7cad7 100644
--- a/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java
@@ -26,6 +26,7 @@ import java.util.Map.Entry;
import java.util.Properties;
import java.util.Queue;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -938,7 +939,13 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
return result;
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#ttl(byte[])
+ */
+ @Override
public Long ttl(byte[] key) {
+
Long result = delegate.ttl(key);
if (isFutureConversion()) {
addResultConverter(identityConverter);
@@ -946,6 +953,21 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
return result;
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#ttl(byte[], java.util.concurrent.TimeUnit)
+ */
+ @Override
+ public Long ttl(byte[] key, TimeUnit timeUnit) {
+
+ Long result = delegate.ttl(key, timeUnit);
+ if (isFutureConversion()) {
+ addResultConverter(identityConverter);
+ }
+
+ return result;
+ }
+
public DataType type(byte[] key) {
DataType result = delegate.type(key);
if (isFutureConversion()) {
@@ -1329,11 +1351,33 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
return result;
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#pTtl(byte[])
+ */
+ @Override
public Long pTtl(byte[] key) {
+
Long result = delegate.pTtl(key);
if (isFutureConversion()) {
addResultConverter(identityConverter);
}
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#pTtl(byte[], java.util.concurrent.TimeUnit)
+ */
+ @Override
+ public Long pTtl(byte[] key, TimeUnit timeUnit) {
+
+ Long result = delegate.pTtl(key, timeUnit);
+ if (isFutureConversion()) {
+ addResultConverter(identityConverter);
+ }
+
return result;
}
@@ -2059,12 +2103,22 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
return result;
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.StringRedisConnection#ttl(java.lang.String)
+ */
+ @Override
public Long ttl(String key) {
- Long result = delegate.ttl(serialize(key));
- if (isFutureConversion()) {
- addResultConverter(identityConverter);
- }
- return result;
+ return ttl(serialize(key));
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.StringRedisConnection#ttl(java.lang.String, java.util.concurrent.TimeUnit)
+ */
+ @Override
+ public Long ttl(String key, TimeUnit timeUnit) {
+ return ttl(serialize(key), timeUnit);
}
public DataType type(String key) {
@@ -2689,10 +2743,24 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
return pExpireAt(serialize(key), unixTimeInMillis);
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.StringRedisConnection#pTtl(java.lang.String)
+ */
+ @Override
public Long pTtl(String key) {
return pTtl(serialize(key));
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.StringRedisConnection#pTtl(java.lang.String, java.util.concurrent.TimeUnit)
+ */
+ @Override
+ public Long pTtl(String key, TimeUnit timeUnit) {
+ return pTtl(serialize(key), timeUnit);
+ }
+
public String scriptLoad(String script) {
String result = delegate.scriptLoad(serialize(script));
if (isFutureConversion()) {
diff --git a/src/main/java/org/springframework/data/redis/connection/RedisKeyCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisKeyCommands.java
index 1e10027d9..a3c70a708 100644
--- a/src/main/java/org/springframework/data/redis/connection/RedisKeyCommands.java
+++ b/src/main/java/org/springframework/data/redis/connection/RedisKeyCommands.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2014 the original author or authors.
+ * Copyright 2011-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package org.springframework.data.redis.connection;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
@@ -26,6 +27,7 @@ import org.springframework.data.redis.core.ScanOptions;
*
* @author Costin Leau
* @author Christoph Strobl
+ * @author Mark Paluch
*/
public interface RedisKeyCommands {
@@ -186,7 +188,19 @@ public interface RedisKeyCommands {
Long ttl(byte[] key);
/**
- * Get the time to live for {@code key} in milliseconds.
+ * Get the time to live for {@code key} in and convert it to the given {@link TimeUnit}.
+ *
+ * See http://redis.io/commands/ttl
+ *
+ * @param key
+ * @param timeUnit
+ * @return
+ * @since 1.8
+ */
+ Long ttl(byte[] key, TimeUnit timeUnit);
+
+ /**
+ * Get the precise time to live for {@code key} in milliseconds.
*
* See http://redis.io/commands/pttl
*
@@ -195,6 +209,18 @@ public interface RedisKeyCommands {
*/
Long pTtl(byte[] key);
+ /**
+ * Get the precise time to live for {@code key} in and convert it to the given {@link TimeUnit}.
+ *
+ * See http://redis.io/commands/pttl
+ *
+ * @param key
+ * @param timeUnit
+ * @return
+ * @since 1.8
+ */
+ Long pTtl(byte[] key, TimeUnit timeUnit);
+
/**
* Sort the elements for {@code key}.
*
+ * See http://redis.io/commands/del
+ *
+ * @param keys
+ * @return The number of keys that were removed.
+ */
Long del(String... keys);
+ /**
+ * Determine the type stored at {@code key}.
+ *
+ * See http://redis.io/commands/type
+ *
+ * @param key
+ * @return
+ */
DataType type(String key);
+ /**
+ * Find all keys matching the given {@code pattern}.
+ *
+ * See http://redis.io/commands/rename
+ *
+ * @param oldName
+ * @param newName
+ */
void rename(String oldName, String newName);
+ /**
+ * Rename key {@code oleName} to {@code newName} only if {@code newName} does not exist.
+ *
+ * See http://redis.io/commands/renamenx
+ *
+ * @param oldName
+ * @param newName
+ * @return
+ */
Boolean renameNX(String oldName, String newName);
+ /**
+ * Set time to live for given {@code key} in seconds.
+ *
+ * See http://redis.io/commands/expire
+ *
+ * @param key
+ * @param seconds
+ * @return
+ */
Boolean expire(String key, long seconds);
+ /**
+ * Set time to live for given {@code key} in milliseconds.
+ *
+ * See http://redis.io/commands/pexpire
+ *
+ * @param key
+ * @param millis
+ * @return
+ */
Boolean pExpire(String key, long millis);
+ /**
+ * Set the expiration for given {@code key} as a {@literal UNIX} timestamp.
+ *
+ * See http://redis.io/commands/expireat
+ *
+ * @param key
+ * @param unixTime
+ * @return
+ */
Boolean expireAt(String key, long unixTime);
+ /**
+ * Set the expiration for given {@code key} as a {@literal UNIX} timestamp in milliseconds.
+ *
+ * See http://redis.io/commands/pexpireat
+ *
+ * @param key
+ * @param unixTimeInMillis
+ * @return
+ */
Boolean pExpireAt(String key, long unixTimeInMillis);
+ /**
+ * Remove the expiration from given {@code key}.
+ *
+ * See http://redis.io/commands/persist
+ *
+ * @param key
+ * @return
+ */
Boolean persist(String key);
+ /**
+ * Move given {@code key} to database with {@code index}.
+ *
+ * See http://redis.io/commands/move
+ *
+ * @param key
+ * @param dbIndex
+ * @return
+ */
Boolean move(String key, int dbIndex);
+ /**
+ * Get the time to live for {@code key} in seconds.
+ *
+ * See http://redis.io/commands/ttl
+ *
+ * @param key
+ * @return
+ */
Long ttl(String key);
+ /**
+ * Get the time to live for {@code key} in and convert it to the given {@link TimeUnit}.
+ *
+ * See http://redis.io/commands/ttl
+ *
+ * @param key
+ * @param timeUnit
+ * @return
+ * @since 1.8
+ */
+ Long ttl(String key, TimeUnit timeUnit);
+
+ /**
+ * Get the precise time to live for {@code key} in milliseconds.
+ *
+ * See http://redis.io/commands/pttl
+ *
+ * @param key
+ * @return
+ */
Long pTtl(String key);
+ /**
+ * Get the precise time to live for {@code key} in and convert it to the given {@link TimeUnit}.
+ *
+ * See http://redis.io/commands/pttl
+ *
+ * @param key
+ * @param timeUnit
+ * @return
+ * @since 1.8
+ */
+ Long pTtl(String key, TimeUnit timeUnit);
+
String echo(String message);
// sort commands
diff --git a/src/main/java/org/springframework/data/redis/connection/convert/Converters.java b/src/main/java/org/springframework/data/redis/connection/convert/Converters.java
index b462bc091..510d5752d 100644
--- a/src/main/java/org/springframework/data/redis/connection/convert/Converters.java
+++ b/src/main/java/org/springframework/data/redis/connection/convert/Converters.java
@@ -25,6 +25,7 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.geo.Distance;
@@ -43,6 +44,7 @@ import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
import org.springframework.data.redis.connection.RedisNode.NodeType;
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.NumberUtils;
import org.springframework.util.ObjectUtils;
@@ -275,6 +277,80 @@ abstract public class Converters {
+ NumberUtils.parseNumber(microseconds, Long.class) / 1000L;
}
+ /**
+ * Converts {@code seconds} to the given {@link TimeUnit}.
+ *
+ * @param seconds
+ * @param targetUnit must not be {@literal null}.
+ * @return
+ * @since 1.8
+ */
+ public static long secondsToTimeUnit(long seconds, TimeUnit targetUnit) {
+
+ Assert.notNull(targetUnit, "TimeUnit must not be null!");
+
+ if (seconds > 0) {
+ return targetUnit.convert(seconds, TimeUnit.SECONDS);
+ }
+
+ return seconds;
+ }
+
+ /**
+ * Creates a new {@link Converter} to convert from seconds to the given {@link TimeUnit}.
+ *
+ * @param timeUnit muist not be {@literal null}.
+ * @return
+ * @since 1.8
+ */
+ public static Converter secondsToTimeUnit(final TimeUnit timeUnit) {
+
+ return new Converter() {
+
+ @Override
+ public Long convert(Long seconds) {
+ return secondsToTimeUnit(seconds, timeUnit);
+ }
+ };
+ }
+
+ /**
+ * Converts {@code milliseconds} to the given {@link TimeUnit}.
+ *
+ * @param milliseconds
+ * @param targetUnit must not be {@literal null}.
+ * @return
+ * @since 1.8
+ */
+ public static long millisecondsToTimeUnit(long milliseconds, TimeUnit targetUnit) {
+
+ Assert.notNull(targetUnit, "TimeUnit must not be null!");
+
+ if (milliseconds > 0) {
+ return targetUnit.convert(milliseconds, TimeUnit.MILLISECONDS);
+ }
+
+ return milliseconds;
+ }
+
+ /**
+ * Creates a new {@link Converter} to convert from milliseconds to the given {@link TimeUnit}.
+ *
+ * @param timeUnit muist not be {@literal null}.
+ * @return
+ * @since 1.8
+ */
+ public static Converter millisecondsToTimeUnit(final TimeUnit timeUnit) {
+
+ return new Converter() {
+
+ @Override
+ public Long convert(Long seconds) {
+ return millisecondsToTimeUnit(seconds, timeUnit);
+ }
+ };
+ }
+
/**
* {@link Converter} capable of deserializing {@link GeoResults}.
*
diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java
index e3b272bb5..03dc6948c 100644
--- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java
@@ -450,6 +450,19 @@ public class JedisClusterConnection implements RedisClusterConnection {
throw convertJedisAccessException(ex);
}
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#ttl(byte[], java.util.concurrent.TimeUnit)
+ */
+ @Override
+ public Long ttl(byte[] key, TimeUnit timeUnit) {
+
+ try {
+ return Converters.secondsToTimeUnit(cluster.ttl(key), timeUnit);
+ } catch (Exception ex) {
+ throw convertJedisAccessException(ex);
+ }
+ }
/*
* (non-Javadoc)
@@ -467,6 +480,22 @@ public class JedisClusterConnection implements RedisClusterConnection {
}, topologyProvider.getTopology().getKeyServingMasterNode(key)).getValue();
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#pTtl(byte[], java.util.concurrent.TimeUnit)
+ */
+ @Override
+ public Long pTtl(final byte[] key, final TimeUnit timeUnit) {
+
+ return clusterCommandExecutor.executeCommandOnSingleNode(new JedisClusterCommandCallback() {
+
+ @Override
+ public Long doInCluster(Jedis client) {
+ return Converters.millisecondsToTimeUnit(client.pttl(key), timeUnit);
+ }
+ }, topologyProvider.getTopology().getKeyServingMasterNode(key)).getValue();
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisKeyCommands#sort(byte[], org.springframework.data.redis.connection.SortParameters)
diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java
index 10331e35b..6a7f75183 100644
--- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java
@@ -53,6 +53,7 @@ import org.springframework.data.redis.connection.RedisZSetCommands;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.SortParameters;
import org.springframework.data.redis.connection.Subscription;
+import org.springframework.data.redis.connection.convert.Converters;
import org.springframework.data.redis.connection.convert.ListConverter;
import org.springframework.data.redis.connection.convert.TransactionResultConverter;
import org.springframework.data.redis.core.Cursor;
@@ -968,7 +969,15 @@ public class JedisConnection extends AbstractRedisConnection {
}
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#ttl(byte[])
+ */
+ @Override
public Long ttl(byte[] key) {
+
+ Assert.notNull(key, "Key must not be null!");
+
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.ttl(key)));
@@ -978,12 +987,38 @@ public class JedisConnection extends AbstractRedisConnection {
transaction(new JedisResult(transaction.ttl(key)));
return null;
}
+
return jedis.ttl(key);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#ttl(byte[], java.util.concurrent.TimeUnit)
+ */
+ @Override
+ public Long ttl(byte[] key, TimeUnit timeUnit) {
+
+ Assert.notNull(key, "Key must not be null!");
+
+ try {
+ if (isPipelined()) {
+ pipeline(new JedisResult(pipeline.ttl(key), Converters.secondsToTimeUnit(timeUnit)));
+ return null;
+ }
+ if (isQueueing()) {
+ transaction(new JedisResult(transaction.ttl(key), Converters.secondsToTimeUnit(timeUnit)));
+ return null;
+ }
+
+ return Converters.secondsToTimeUnit(jedis.ttl(key), timeUnit);
+ } catch (Exception ex) {
+ throw convertJedisAccessException(ex);
+ }
+ }
+
public Boolean pExpire(byte[] key, long millis) {
try {
@@ -1017,7 +1052,15 @@ public class JedisConnection extends AbstractRedisConnection {
}
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#pTtl(byte[])
+ */
+ @Override
public Long pTtl(byte[] key) {
+
+ Assert.notNull(key, "Key must not be null!");
+
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.pttl(key)));
@@ -1027,12 +1070,38 @@ public class JedisConnection extends AbstractRedisConnection {
transaction(new JedisResult(transaction.pttl(key)));
return null;
}
+
return jedis.pttl(key);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#pTtl(byte[], java.util.concurrent.TimeUnit)
+ */
+ @Override
+ public Long pTtl(byte[] key, TimeUnit timeUnit) {
+
+ Assert.notNull(key, "Key must not be null!");
+
+ try {
+ if (isPipelined()) {
+ pipeline(new JedisResult(pipeline.pttl(key), Converters.millisecondsToTimeUnit(timeUnit)));
+ return null;
+ }
+ if (isQueueing()) {
+ transaction(new JedisResult(transaction.pttl(key), Converters.millisecondsToTimeUnit(timeUnit)));
+ return null;
+ }
+
+ return Converters.millisecondsToTimeUnit(jedis.pttl(key), timeUnit);
+ } catch (Exception ex) {
+ throw convertJedisAccessException(ex);
+ }
+ }
+
public byte[] dump(byte[] key) {
try {
if (isPipelined()) {
diff --git a/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java b/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java
index d67f703f9..155dcab68 100644
--- a/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java
@@ -25,6 +25,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
import org.jredis.ClientRuntimeException;
import org.jredis.JRedis;
@@ -50,6 +51,7 @@ import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.SortParameters;
import org.springframework.data.redis.connection.Subscription;
+import org.springframework.data.redis.connection.convert.Converters;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.types.Expiration;
@@ -67,6 +69,7 @@ import org.springframework.util.ReflectionUtils;
* @author Thomas Darimont
* @author David Liu
* @author Ninad Divadkar
+ * @author Mark Paluch
* @deprecated since 1.7. Will be removed in subsequent version.
*/
@Deprecated
@@ -369,10 +372,24 @@ public class JredisConnection extends AbstractRedisConnection {
throw new UnsupportedOperationException();
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#pTtl(byte[])
+ */
+ @Override
public Long pTtl(byte[] key) {
throw new UnsupportedOperationException();
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#pTtl(byte[], java.util.concurrent.TimeUnit)
+ */
+ @Override
+ public Long pTtl(byte[] key, TimeUnit timeUnit) {
+ throw new UnsupportedOperationException();
+ }
+
public byte[] dump(byte[] key) {
throw new UnsupportedOperationException();
}
@@ -433,7 +450,15 @@ public class JredisConnection extends AbstractRedisConnection {
throw new UnsupportedOperationException();
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#ttl(byte[])
+ */
+ @Override
public Long ttl(byte[] key) {
+
+ Assert.notNull(key, "Key must not be null!");
+
try {
return jredis.ttl(key);
} catch (Exception ex) {
@@ -441,6 +466,22 @@ public class JredisConnection extends AbstractRedisConnection {
}
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#ttl(byte[], java.util.concurrent.TimeUnit)
+ */
+ @Override
+ public Long ttl(byte[] key, TimeUnit timeUnit) {
+
+ Assert.notNull(key, "Key must not be null!");
+
+ try {
+ return Converters.secondsToTimeUnit(jredis.ttl(key), timeUnit);
+ } catch (Exception ex) {
+ throw convertJredisAccessException(ex);
+ }
+ }
+
public DataType type(byte[] key) {
try {
return JredisUtils.convertDataType(jredis.type(key));
diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java
index e3fc5cab5..643c30480 100644
--- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java
@@ -60,6 +60,7 @@ import org.springframework.data.redis.connection.RedisSubscribedConnectionExcept
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.SortParameters;
import org.springframework.data.redis.connection.Subscription;
+import org.springframework.data.redis.connection.convert.Converters;
import org.springframework.data.redis.connection.convert.ListConverter;
import org.springframework.data.redis.connection.convert.TransactionResultConverter;
import org.springframework.data.redis.core.Cursor;
@@ -949,7 +950,15 @@ public class LettuceConnection extends AbstractRedisConnection {
}
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#pTtl(byte[])
+ */
+ @Override
public Long pTtl(byte[] key) {
+
+ Assert.notNull(key, "Key must not be null!");
+
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().pttl(key)));
@@ -959,12 +968,38 @@ public class LettuceConnection extends AbstractRedisConnection {
transaction(new LettuceTxResult(getConnection().pttl(key)));
return null;
}
+
return getConnection().pttl(key);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#pTtl(byte[], java.util.concurrent.TimeUnit)
+ */
+ @Override
+ public Long pTtl(byte[] key, TimeUnit timeUnit) {
+
+ Assert.notNull(key, "Key must not be null!");
+
+ try {
+ if (isPipelined()) {
+ pipeline(new LettuceResult(getAsyncConnection().pttl(key), Converters.millisecondsToTimeUnit(timeUnit)));
+ return null;
+ }
+ if (isQueueing()) {
+ transaction(new LettuceTxResult(getConnection().pttl(key), Converters.millisecondsToTimeUnit(timeUnit)));
+ return null;
+ }
+
+ return Converters.millisecondsToTimeUnit(getConnection().pttl(key), timeUnit);
+ } catch (Exception ex) {
+ throw convertLettuceAccessException(ex);
+ }
+ }
+
public byte[] dump(byte[] key) {
try {
if (isPipelined()) {
@@ -1131,7 +1166,15 @@ public class LettuceConnection extends AbstractRedisConnection {
}
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#ttl(byte[])
+ */
+ @Override
public Long ttl(byte[] key) {
+
+ Assert.notNull(key, "Key must not be null!");
+
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().ttl(key)));
@@ -1141,12 +1184,38 @@ public class LettuceConnection extends AbstractRedisConnection {
transaction(new LettuceTxResult(getConnection().ttl(key)));
return null;
}
+
return getConnection().ttl(key);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#ttl(byte[], java.util.concurrent.TimeUnit)
+ */
+ @Override
+ public Long ttl(byte[] key, TimeUnit timeUnit) {
+
+ Assert.notNull(key, "Key must not be null!");
+
+ try {
+ if (isPipelined()) {
+ pipeline(new LettuceResult(getAsyncConnection().ttl(key), Converters.secondsToTimeUnit(timeUnit)));
+ return null;
+ }
+ if (isQueueing()) {
+ transaction(new LettuceTxResult(getConnection().ttl(key), Converters.secondsToTimeUnit(timeUnit)));
+ return null;
+ }
+
+ return Converters.secondsToTimeUnit(getConnection().ttl(key), timeUnit);
+ } catch (Exception ex) {
+ throw convertLettuceAccessException(ex);
+ }
+ }
+
public DataType type(byte[] key) {
try {
if (isPipelined()) {
diff --git a/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java b/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java
index d02b92660..960b1d3fd 100644
--- a/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java
@@ -28,6 +28,7 @@ import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
import org.springframework.core.convert.converter.Converter;
import org.springframework.dao.DataAccessException;
@@ -49,6 +50,7 @@ import org.springframework.data.redis.connection.RedisSubscribedConnectionExcept
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.SortParameters;
import org.springframework.data.redis.connection.Subscription;
+import org.springframework.data.redis.connection.convert.Converters;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.types.Expiration;
@@ -77,6 +79,7 @@ import redis.reply.Reply;
* @author Thomas Darimont
* @author David Liu
* @author Ninad Divadkar
+ * @author Mark Paluch
* @deprecated since 1.7. Will be removed in subsequent version.
*/
@Deprecated
@@ -765,18 +768,52 @@ public class SrpConnection extends AbstractRedisConnection {
}
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#ttl(byte[])
+ */
+ @Override
public Long ttl(byte[] key) {
+
+ Assert.notNull(key, "Key must not be null!");
+
try {
if (isPipelined()) {
pipeline(new SrpResult(pipeline.ttl(key)));
return null;
}
+
return client.ttl(key).data();
} catch (Exception ex) {
throw convertSrpAccessException(ex);
}
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#ttl(byte[], java.util.concurrent.TimeUnit)
+ */
+ @Override
+ public Long ttl(byte[] key, TimeUnit timeUnit) {
+
+ Assert.notNull(key, "Key must not be null!");
+
+ try {
+ if (isPipelined()) {
+ pipeline(new SrpResult(pipeline.ttl(key), Converters.secondsToTimeUnit(timeUnit)));
+ return null;
+ }
+ return Converters.secondsToTimeUnit(client.ttl(key).data(), timeUnit);
+ } catch (Exception ex) {
+ throw convertSrpAccessException(ex);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#pTtl(byte[])
+ */
+ @Override
public Long pTtl(byte[] key) {
try {
if (isPipelined()) {
@@ -789,6 +826,23 @@ public class SrpConnection extends AbstractRedisConnection {
}
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisKeyCommands#pTtl(byte[], java.util.concurrent.TimeUnit)
+ */
+ @Override
+ public Long pTtl(byte[] key, TimeUnit timeUnit) {
+ try {
+ if (isPipelined()) {
+ pipeline(new SrpResult(pipeline.pttl(key), Converters.millisecondsToTimeUnit(timeUnit)));
+ return null;
+ }
+ return Converters.millisecondsToTimeUnit(client.pttl(key).data(), timeUnit);
+ } catch (Exception ex) {
+ throw convertSrpAccessException(ex);
+ }
+ }
+
public byte[] dump(byte[] key) {
try {
if (isPipelined()) {
diff --git a/src/main/java/org/springframework/data/redis/core/RedisTemplate.java b/src/main/java/org/springframework/data/redis/core/RedisTemplate.java
index e042b70e4..6ea8b595e 100644
--- a/src/main/java/org/springframework/data/redis/core/RedisTemplate.java
+++ b/src/main/java/org/springframework/data/redis/core/RedisTemplate.java
@@ -715,14 +715,11 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation
return execute(new RedisCallback() {
public Long doInRedis(RedisConnection connection) {
- Long expire;
try {
- expire = connection.pTtl(rawKey);
- return expire < 0 ? expire : timeUnit.convert(expire, TimeUnit.MILLISECONDS);
+ return connection.pTtl(rawKey, timeUnit);
} catch (Exception e) {
// Driver may not support pTtl or we may be running on Redis 2.4
- expire = connection.ttl(rawKey);
- return expire < 0 ? expire : timeUnit.convert(expire, TimeUnit.SECONDS);
+ return connection.ttl(rawKey, timeUnit);
}
}
}, true);
diff --git a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java
index 394277735..0de0d960e 100644
--- a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java
+++ b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java
@@ -967,6 +967,22 @@ public abstract class AbstractConnectionIntegrationTests {
verifyResults(Arrays.asList(new Object[] { -1L }));
}
+ /**
+ * @see DATAREDIS-526
+ */
+ @Test
+ public void testTtlWithTimeUnit() {
+
+ connection.set("whatup", "yo");
+ actual.add(connection.expire("whatup", 10));
+ actual.add(connection.ttl("whatup", TimeUnit.MILLISECONDS));
+
+ List