diff --git a/src/main/java/org/springframework/data/redis/connection/RedisStringCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisStringCommands.java index 305629e9c..fa53386c9 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisStringCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisStringCommands.java @@ -75,8 +75,10 @@ public interface RedisStringCommands { /** * Set {@code value} for {@code key} applying timeouts from {@code expiration} if set and inserting/updating values - * depending on {@code options}. - * + * depending on {@code option}. + *

+ * See http://redis.io/commands/set + * * @param key must not be {@literal null}. * @param value must not be {@literal null}. * @param expiration can be {@literal null}. Defaulted to {@link Expiration#persistent()}. diff --git a/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java index b776bceef..a2f89ad53 100644 --- a/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java @@ -98,7 +98,9 @@ public interface StringRedisConnection extends RedisConnection { /** * Set {@code value} for {@code key} applying timeouts from {@code expiration} if set and inserting/updating values - * depending on {@code options}. + * depending on {@code option}. + *

+ * See http://redis.io/commands/set * * @param key must not be {@literal null}. * @param value must not be {@literal null}. 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 11aab7af5..841ee7e7a 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 @@ -604,7 +604,7 @@ public class JedisClusterConnection implements RedisClusterConnection { @Override public void set(byte[] key, byte[] value, Expiration expiration, SetOption option) { - if (expiration == null || expiration.isPersitent()) { + if (expiration == null || expiration.isPersistent()) { if (option == null || ObjectUtils.nullSafeEquals(SetOption.UPSERT, option)) { set(key, value); 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 f9d8f83ea..44761a1a0 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 @@ -1147,7 +1147,7 @@ public class JedisConnection extends AbstractRedisConnection { @Override public void set(byte[] key, byte[] value, Expiration expiration, SetOption option) { - if (expiration == null || expiration.isPersitent()) { + if (expiration == null || expiration.isPersistent()) { if (option == null || ObjectUtils.nullSafeEquals(SetOption.UPSERT, option)) { set(key, value); @@ -1194,7 +1194,7 @@ public class JedisConnection extends AbstractRedisConnection { if (expiration.getExpirationTime() > Integer.MAX_VALUE) { throw new IllegalArgumentException( - "Expiration.exprirationTime must be less than equals Integer.MAX_VALUE for pipeline in Jedis."); + "Expiration.expirationTime must be less than Integer.MAX_VALUE for pipeline in Jedis."); } pipeline(new JedisStatusResult(pipeline.set(key, value, nxxx, expx, (int) expiration.getExpirationTime()))); @@ -1204,7 +1204,7 @@ public class JedisConnection extends AbstractRedisConnection { if (expiration.getExpirationTime() > Integer.MAX_VALUE) { throw new IllegalArgumentException( - "Expiration.exprirationTime must be less than equals Integer.MAX_VALUE for transactions in Jedis."); + "Expiration.expirationTime must be less than Integer.MAX_VALUE for transactions in Jedis."); } transaction(new JedisStatusResult(transaction.set(key, value, nxxx, expx, diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java index b83b5da2c..6913073ae 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java @@ -131,7 +131,7 @@ abstract public class JedisConverters extends Converters { @Override public byte[] convert(Expiration source) { - if (source == null || source.isPersitent()) { + if (source == null || source.isPersistent()) { return new byte[0]; } diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java index cabc0ed4a..675568dad 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java @@ -628,7 +628,7 @@ abstract public class LettuceConverters extends Converters { public static SetArgs toSetArgs(Expiration expiration, SetOption option) { SetArgs args = new SetArgs(); - if (expiration != null && !expiration.isPersitent()) { + if (expiration != null && !expiration.isPersistent()) { switch (expiration.getTimeUnit()) { case SECONDS: diff --git a/src/main/java/org/springframework/data/redis/core/types/Expiration.java b/src/main/java/org/springframework/data/redis/core/types/Expiration.java index cad5606b2..d6471b0d9 100644 --- a/src/main/java/org/springframework/data/redis/core/types/Expiration.java +++ b/src/main/java/org/springframework/data/redis/core/types/Expiration.java @@ -18,11 +18,13 @@ package org.springframework.data.redis.core.types; import java.util.concurrent.TimeUnit; import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; /** * Expiration holds a value with its associated {@link TimeUnit}. * * @author Christoph Strobl + * @author Mark Paluch * @since 1.7 */ public class Expiration { @@ -111,6 +113,31 @@ public class Expiration { return new Expiration(expirationTime, TimeUnit.MILLISECONDS); } + /** + * Creates new {@link Expiration} with the provided {@link TimeUnit}. Greater units than {@link TimeUnit#SECONDS} are + * converted to {@link TimeUnit#SECONDS}. Units smaller than {@link TimeUnit#MILLISECONDS} are converted to + * {@link TimeUnit#MILLISECONDS} and can lose precision since {@link TimeUnit#MILLISECONDS} is the smallest granularity + * supported by Redis. + * + * @param expirationTime + * @param timeUnit can be {@literal null}. Defaulted to {@link TimeUnit#SECONDS} + * @return + */ + public static Expiration from(long expirationTime, TimeUnit timeUnit) { + + if (ObjectUtils.nullSafeEquals(timeUnit, TimeUnit.MICROSECONDS) + || ObjectUtils.nullSafeEquals(timeUnit, TimeUnit.NANOSECONDS) + || ObjectUtils.nullSafeEquals(timeUnit, TimeUnit.MILLISECONDS)) { + return new Expiration(timeUnit.toMillis(expirationTime), TimeUnit.MILLISECONDS); + } + + if (timeUnit != null) { + return new Expiration(timeUnit.toSeconds(expirationTime), TimeUnit.SECONDS); + } + + return new Expiration(expirationTime, TimeUnit.SECONDS); + } + /** * Creates new persistent {@link Expiration}. * @@ -123,7 +150,7 @@ public class Expiration { /** * @return {@literal true} if {@link Expiration} is set to persistent. */ - public boolean isPersitent() { + public boolean isPersistent() { return expirationTime == -1; } } diff --git a/src/test/java/org/springframework/data/redis/core/types/ExpirationUnitTests.java b/src/test/java/org/springframework/data/redis/core/types/ExpirationUnitTests.java new file mode 100644 index 000000000..590d0ecec --- /dev/null +++ b/src/test/java/org/springframework/data/redis/core/types/ExpirationUnitTests.java @@ -0,0 +1,66 @@ +/* + * Copyright 2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.redis.core.types; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.TimeUnit; + +import org.junit.Test; + +/** + * @author Mark Paluch + */ +public class ExpirationUnitTests { + + /** + * @see DATAREDIS-316 + */ + @Test + public void fromDefault() throws Exception { + + Expiration expiration = Expiration.from(5, null); + + assertThat(expiration.getExpirationTime(), is(5L)); + assertThat(expiration.getTimeUnit(), is(TimeUnit.SECONDS)); + } + + /** + * @see DATAREDIS-316 + */ + @Test + public void fromNanos() throws Exception { + + Expiration expiration = Expiration.from(5L * 1000 * 1000, TimeUnit.NANOSECONDS); + + assertThat(expiration.getExpirationTime(), is(5L)); + assertThat(expiration.getTimeUnit(), is(TimeUnit.MILLISECONDS)); + } + + /** + * @see DATAREDIS-316 + */ + @Test + public void fromMinutes() throws Exception { + + Expiration expiration = Expiration.from(5, TimeUnit.MINUTES); + + assertThat(expiration.getExpirationTime(), is(5L * 60)); + assertThat(expiration.getTimeUnit(), is(TimeUnit.SECONDS)); + } +}