From 31c1787fcfd0178503a5f36fa00f1cb4323a8a6b Mon Sep 17 00:00:00 2001 From: Tihomir Mateev Date: Tue, 23 Apr 2024 21:50:57 +0300 Subject: [PATCH] Move new commands to RedisHashCommands, added HEXPIREAT, HEXPIRETIME and HPERSIST --- .../core/AbstractRedisAsyncCommands.java | 87 +++++-- .../core/AbstractRedisReactiveCommands.java | 88 +++++-- .../io/lettuce/core/RedisCommandBuilder.java | 221 ++++++++++++++++-- .../api/async/RedisHashAsyncCommands.java | 158 ++++++++++++- .../core/api/async/RedisKeyAsyncCommands.java | 68 ++---- .../reactive/RedisHashReactiveCommands.java | 160 ++++++++++++- .../reactive/RedisKeyReactiveCommands.java | 51 ---- .../core/api/sync/RedisHashCommands.java | 158 ++++++++++++- .../core/api/sync/RedisKeyCommands.java | 50 ---- .../async/NodeSelectionHashAsyncCommands.java | 158 ++++++++++++- .../async/NodeSelectionKeyAsyncCommands.java | 50 ---- .../api/sync/NodeSelectionHashCommands.java | 158 ++++++++++++- .../api/sync/NodeSelectionKeyCommands.java | 60 +---- .../io/lettuce/core/protocol/CommandType.java | 2 +- .../coroutines/RedisHashCoroutinesCommands.kt | 159 ++++++++++++- .../RedisHashCoroutinesCommandsImpl.kt | 58 +++++ .../coroutines/RedisKeyCoroutinesCommands.kt | 62 +---- .../RedisKeyCoroutinesCommandsImpl.kt | 18 -- .../lettuce/core/api/RedisHashCommands.java | 147 ++++++++++++ .../io/lettuce/core/api/RedisKeyCommands.java | 50 ---- .../core/RedisCommandBuilderUnitTests.java | 65 ++++-- .../commands/HashCommandIntegrationTests.java | 117 ++++++++-- .../commands/KeyCommandIntegrationTests.java | 80 ++----- 23 files changed, 1686 insertions(+), 539 deletions(-) diff --git a/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java b/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java index 03d0e69f28..10331085fb 100644 --- a/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java +++ b/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java @@ -19,18 +19,21 @@ */ package io.lettuce.core; -import static io.lettuce.core.protocol.CommandType.*; - -import java.time.Duration; -import java.time.Instant; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; - import io.lettuce.core.GeoArgs.Unit; import io.lettuce.core.api.StatefulConnection; -import io.lettuce.core.api.async.*; +import io.lettuce.core.api.async.BaseRedisAsyncCommands; +import io.lettuce.core.api.async.RedisAclAsyncCommands; +import io.lettuce.core.api.async.RedisGeoAsyncCommands; +import io.lettuce.core.api.async.RedisHLLAsyncCommands; +import io.lettuce.core.api.async.RedisHashAsyncCommands; +import io.lettuce.core.api.async.RedisKeyAsyncCommands; +import io.lettuce.core.api.async.RedisListAsyncCommands; +import io.lettuce.core.api.async.RedisScriptingAsyncCommands; +import io.lettuce.core.api.async.RedisServerAsyncCommands; +import io.lettuce.core.api.async.RedisSetAsyncCommands; +import io.lettuce.core.api.async.RedisSortedSetAsyncCommands; +import io.lettuce.core.api.async.RedisStringAsyncCommands; +import io.lettuce.core.api.async.RedisTransactionalAsyncCommands; import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands; import io.lettuce.core.codec.Base16; import io.lettuce.core.codec.RedisCodec; @@ -50,6 +53,19 @@ import io.lettuce.core.protocol.ProtocolKeyword; import io.lettuce.core.protocol.RedisCommand; +import java.time.Duration; +import java.time.Instant; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static io.lettuce.core.protocol.CommandType.EXEC; +import static io.lettuce.core.protocol.CommandType.GEORADIUS; +import static io.lettuce.core.protocol.CommandType.GEORADIUSBYMEMBER; +import static io.lettuce.core.protocol.CommandType.GEORADIUSBYMEMBER_RO; +import static io.lettuce.core.protocol.CommandType.GEORADIUS_RO; + /** * An asynchronous and thread-safe API for a Redis connection. * @@ -795,22 +811,22 @@ public RedisFuture expire(K key, Duration seconds, ExpireArgs expireArg } @Override - public RedisFuture hexpire(K key, long seconds, List fields) { + public RedisFuture hexpire(K key, long seconds, K... fields) { return hexpire(key, seconds, null, fields); } @Override - public RedisFuture hexpire(K key, long seconds, ExpireArgs expireArgs, List fields) { + public RedisFuture hexpire(K key, long seconds, ExpireArgs expireArgs, K... fields) { return dispatch(commandBuilder.hexpire(key, seconds, expireArgs, fields)); } @Override - public RedisFuture hexpire(K key, Duration seconds, List fields) { + public RedisFuture hexpire(K key, Duration seconds, K... fields) { return hexpire(key, seconds, null, fields); } @Override - public RedisFuture hexpire(K key, Duration seconds, ExpireArgs expireArgs, List fields) { + public RedisFuture hexpire(K key, Duration seconds, ExpireArgs expireArgs, K... fields) { LettuceAssert.notNull(seconds, "Timeout must not be null"); return hexpire(key, seconds.toMillis() / 1000, expireArgs, fields); } @@ -847,11 +863,49 @@ public RedisFuture expireat(K key, Instant timestamp, ExpireArgs expire return expireat(key, timestamp.toEpochMilli() / 1000, expireArgs); } + @Override + public RedisFuture hexpireat(K key, long timestamp, K... fields) { + return hexpireat(key, timestamp, null, fields); + } + + @Override + public RedisFuture hexpireat(K key, long timestamp, ExpireArgs expireArgs, K... fields) { + return dispatch(commandBuilder.hexpireat(key, timestamp, expireArgs, fields)); + + } + + @Override + public RedisFuture hexpireat(K key, Date timestamp, K... fields) { + return hexpireat(key, timestamp, null, fields); + } + + @Override + public RedisFuture hexpireat(K key, Date timestamp, ExpireArgs expireArgs, K... fields) { + LettuceAssert.notNull(timestamp, "Timestamp must not be null"); + return hexpireat(key, timestamp.getTime() / 1000, expireArgs, fields); + } + + @Override + public RedisFuture hexpireat(K key, Instant timestamp, K... fields) { + return hexpireat(key, timestamp, null, fields); + } + + @Override + public RedisFuture hexpireat(K key, Instant timestamp, ExpireArgs expireArgs, K... fields) { + LettuceAssert.notNull(timestamp, "Timestamp must not be null"); + return hexpireat(key, timestamp.toEpochMilli() / 1000, expireArgs, fields); + } + @Override public RedisFuture expiretime(K key) { return dispatch(commandBuilder.expiretime(key)); } + @Override + public RedisFuture hexpiretime(K key, K... fields) { + return dispatch(commandBuilder.hexpiretime(key, fields)); + } + @Override public RedisFuture fcall(String function, ScriptOutputType type, K... keys) { return dispatch(commandBuilder.fcall(function, type, false, keys)); @@ -1510,6 +1564,11 @@ public RedisFuture persist(K key) { return dispatch(commandBuilder.persist(key)); } + @Override + public RedisFuture hpersist(K key, K... fields) { + return dispatch(commandBuilder.hpersist(key, fields)); + } + @Override public RedisFuture pexpire(K key, long milliseconds) { return pexpire(key, milliseconds, null); diff --git a/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java b/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java index 567401bc97..42efa41acf 100644 --- a/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java +++ b/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java @@ -19,19 +19,21 @@ */ package io.lettuce.core; -import static io.lettuce.core.protocol.CommandType.*; - -import java.time.Duration; -import java.time.Instant; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Supplier; - import io.lettuce.core.GeoArgs.Unit; import io.lettuce.core.api.StatefulConnection; -import io.lettuce.core.api.reactive.*; +import io.lettuce.core.api.reactive.BaseRedisReactiveCommands; +import io.lettuce.core.api.reactive.RedisAclReactiveCommands; +import io.lettuce.core.api.reactive.RedisGeoReactiveCommands; +import io.lettuce.core.api.reactive.RedisHLLReactiveCommands; +import io.lettuce.core.api.reactive.RedisHashReactiveCommands; +import io.lettuce.core.api.reactive.RedisKeyReactiveCommands; +import io.lettuce.core.api.reactive.RedisListReactiveCommands; +import io.lettuce.core.api.reactive.RedisScriptingReactiveCommands; +import io.lettuce.core.api.reactive.RedisServerReactiveCommands; +import io.lettuce.core.api.reactive.RedisSetReactiveCommands; +import io.lettuce.core.api.reactive.RedisSortedSetReactiveCommands; +import io.lettuce.core.api.reactive.RedisStringReactiveCommands; +import io.lettuce.core.api.reactive.RedisTransactionalReactiveCommands; import io.lettuce.core.cluster.api.reactive.RedisClusterReactiveCommands; import io.lettuce.core.codec.Base16; import io.lettuce.core.codec.RedisCodec; @@ -59,6 +61,20 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import java.time.Duration; +import java.time.Instant; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; + +import static io.lettuce.core.protocol.CommandType.EXEC; +import static io.lettuce.core.protocol.CommandType.GEORADIUS; +import static io.lettuce.core.protocol.CommandType.GEORADIUSBYMEMBER; +import static io.lettuce.core.protocol.CommandType.GEORADIUSBYMEMBER_RO; +import static io.lettuce.core.protocol.CommandType.GEORADIUS_RO; + /** * A reactive and thread-safe API for a Redis connection. * @@ -855,22 +871,22 @@ public Mono expire(K key, Duration seconds, ExpireArgs expireArgs) { } @Override - public Mono hexpire(K key, long seconds, List fields) { + public Mono hexpire(K key, long seconds, K... fields) { return hexpire(key, seconds, null, fields); } @Override - public Mono hexpire(K key, long seconds, ExpireArgs expireArgs, List fields) { + public Mono hexpire(K key, long seconds, ExpireArgs expireArgs, K... fields) { return createMono(() -> commandBuilder.hexpire(key, seconds, expireArgs, fields)); } @Override - public Mono hexpire(K key, Duration seconds, List fields) { + public Mono hexpire(K key, Duration seconds, K... fields) { return hexpire(key, seconds, null, fields); } @Override - public Mono hexpire(K key, Duration seconds, ExpireArgs expireArgs, List fields) { + public Mono hexpire(K key, Duration seconds, ExpireArgs expireArgs, K... fields) { LettuceAssert.notNull(seconds, "Timeout must not be null"); return hexpire(key, seconds.toMillis() / 1000, expireArgs, fields); } @@ -907,11 +923,48 @@ public Mono expireat(K key, Instant timestamp, ExpireArgs expireArgs) { return expireat(key, timestamp.toEpochMilli() / 1000, expireArgs); } + @Override + public Mono hexpireat(K key, long timestamp, K... fields) { + return hexpireat(key, timestamp, null, fields); + } + + @Override + public Mono hexpireat(K key, long timestamp, ExpireArgs expireArgs, K... fields) { + return createMono(() -> commandBuilder.hexpireat(key, timestamp, expireArgs, fields)); + } + + @Override + public Mono hexpireat(K key, Date timestamp, K... fields) { + return hexpireat(key, timestamp, null, fields); + } + + @Override + public Mono hexpireat(K key, Date timestamp, ExpireArgs expireArgs, K... fields) { + LettuceAssert.notNull(timestamp, "Timestamp must not be null"); + return hexpireat(key, timestamp.getTime() / 1000, expireArgs, fields); + } + + @Override + public Mono hexpireat(K key, Instant timestamp, K... fields) { + return hexpireat(key, timestamp, null, fields); + } + + @Override + public Mono hexpireat(K key, Instant timestamp, ExpireArgs expireArgs, K... fields) { + LettuceAssert.notNull(timestamp, "Timestamp must not be null"); + return hexpireat(key, timestamp.toEpochMilli() / 1000, expireArgs, fields); + } + @Override public Mono expiretime(K key) { return createMono(() -> commandBuilder.expiretime(key)); } + @Override + public Mono hexpiretime(K key, K... fields) { + return createMono(() -> commandBuilder.hexpiretime(key, fields)); + } + @Override public Flux fcall(String function, ScriptOutputType type, K... keys) { return createFlux(() -> commandBuilder.fcall(function, type, false, keys)); @@ -1577,6 +1630,11 @@ public Mono persist(K key) { return createMono(() -> commandBuilder.persist(key)); } + @Override + public Mono hpersist(K key, K... fields) { + return createMono(() -> commandBuilder.hpersist(key, fields)); + } + @Override public Mono pexpire(K key, long milliseconds) { return pexpire(key, milliseconds, null); diff --git a/src/main/java/io/lettuce/core/RedisCommandBuilder.java b/src/main/java/io/lettuce/core/RedisCommandBuilder.java index 9b82a026e8..48b68fe1df 100644 --- a/src/main/java/io/lettuce/core/RedisCommandBuilder.java +++ b/src/main/java/io/lettuce/core/RedisCommandBuilder.java @@ -19,19 +19,6 @@ */ package io.lettuce.core; -import static io.lettuce.core.internal.LettuceStrings.*; -import static io.lettuce.core.protocol.CommandKeyword.*; -import static io.lettuce.core.protocol.CommandType.*; -import static io.lettuce.core.protocol.CommandType.COPY; -import static io.lettuce.core.protocol.CommandType.SAVE; - -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; - import io.lettuce.core.Range.Boundary; import io.lettuce.core.XReadArgs.StreamOffset; import io.lettuce.core.codec.RedisCodec; @@ -40,7 +27,64 @@ import io.lettuce.core.models.stream.ClaimedMessages; import io.lettuce.core.models.stream.PendingMessage; import io.lettuce.core.models.stream.PendingMessages; -import io.lettuce.core.output.*; +import io.lettuce.core.output.ArrayOutput; +import io.lettuce.core.output.BooleanListOutput; +import io.lettuce.core.output.BooleanOutput; +import io.lettuce.core.output.ByteArrayOutput; +import io.lettuce.core.output.ClaimedMessagesOutput; +import io.lettuce.core.output.CommandOutput; +import io.lettuce.core.output.DateOutput; +import io.lettuce.core.output.DoubleListOutput; +import io.lettuce.core.output.DoubleOutput; +import io.lettuce.core.output.EnumSetOutput; +import io.lettuce.core.output.GenericMapOutput; +import io.lettuce.core.output.GeoCoordinatesListOutput; +import io.lettuce.core.output.GeoCoordinatesValueListOutput; +import io.lettuce.core.output.GeoWithinListOutput; +import io.lettuce.core.output.IntegerListOutput; +import io.lettuce.core.output.IntegerOutput; +import io.lettuce.core.output.KeyListOutput; +import io.lettuce.core.output.KeyOutput; +import io.lettuce.core.output.KeyScanOutput; +import io.lettuce.core.output.KeyScanStreamingOutput; +import io.lettuce.core.output.KeyStreamingChannel; +import io.lettuce.core.output.KeyStreamingOutput; +import io.lettuce.core.output.KeyValueListOutput; +import io.lettuce.core.output.KeyValueListScoredValueOutput; +import io.lettuce.core.output.KeyValueOfScoredValueOutput; +import io.lettuce.core.output.KeyValueOutput; +import io.lettuce.core.output.KeyValueScanStreamingOutput; +import io.lettuce.core.output.KeyValueScoredValueOutput; +import io.lettuce.core.output.KeyValueStreamingChannel; +import io.lettuce.core.output.KeyValueStreamingOutput; +import io.lettuce.core.output.KeyValueValueListOutput; +import io.lettuce.core.output.ListOfGenericMapsOutput; +import io.lettuce.core.output.MapOutput; +import io.lettuce.core.output.MapScanOutput; +import io.lettuce.core.output.NestedMultiOutput; +import io.lettuce.core.output.ObjectOutput; +import io.lettuce.core.output.PendingMessageListOutput; +import io.lettuce.core.output.PendingMessagesOutput; +import io.lettuce.core.output.ScoredValueListOutput; +import io.lettuce.core.output.ScoredValueOutput; +import io.lettuce.core.output.ScoredValueScanOutput; +import io.lettuce.core.output.ScoredValueScanStreamingOutput; +import io.lettuce.core.output.ScoredValueStreamingChannel; +import io.lettuce.core.output.ScoredValueStreamingOutput; +import io.lettuce.core.output.StatusOutput; +import io.lettuce.core.output.StreamMessageListOutput; +import io.lettuce.core.output.StreamReadOutput; +import io.lettuce.core.output.StringListOutput; +import io.lettuce.core.output.StringMatchResultOutput; +import io.lettuce.core.output.StringValueListOutput; +import io.lettuce.core.output.ValueListOutput; +import io.lettuce.core.output.ValueOutput; +import io.lettuce.core.output.ValueScanOutput; +import io.lettuce.core.output.ValueScanStreamingOutput; +import io.lettuce.core.output.ValueSetOutput; +import io.lettuce.core.output.ValueStreamingChannel; +import io.lettuce.core.output.ValueStreamingOutput; +import io.lettuce.core.output.ValueValueListOutput; import io.lettuce.core.protocol.BaseRedisCommandBuilder; import io.lettuce.core.protocol.Command; import io.lettuce.core.protocol.CommandArgs; @@ -48,6 +92,111 @@ import io.lettuce.core.protocol.CommandType; import io.lettuce.core.protocol.RedisCommand; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static io.lettuce.core.internal.LettuceStrings.string; +import static io.lettuce.core.protocol.CommandKeyword.ADDSLOTS; +import static io.lettuce.core.protocol.CommandKeyword.ADDSLOTSRANGE; +import static io.lettuce.core.protocol.CommandKeyword.AFTER; +import static io.lettuce.core.protocol.CommandKeyword.AND; +import static io.lettuce.core.protocol.CommandKeyword.BEFORE; +import static io.lettuce.core.protocol.CommandKeyword.BUMPEPOCH; +import static io.lettuce.core.protocol.CommandKeyword.BYLEX; +import static io.lettuce.core.protocol.CommandKeyword.BYSCORE; +import static io.lettuce.core.protocol.CommandKeyword.CACHING; +import static io.lettuce.core.protocol.CommandKeyword.CAT; +import static io.lettuce.core.protocol.CommandKeyword.CHANNELS; +import static io.lettuce.core.protocol.CommandKeyword.CONSUMERS; +import static io.lettuce.core.protocol.CommandKeyword.COUNT; +import static io.lettuce.core.protocol.CommandKeyword.COUNTKEYSINSLOT; +import static io.lettuce.core.protocol.CommandKeyword.CREATE; +import static io.lettuce.core.protocol.CommandKeyword.DELSLOTS; +import static io.lettuce.core.protocol.CommandKeyword.DELSLOTSRANGE; +import static io.lettuce.core.protocol.CommandKeyword.DELUSER; +import static io.lettuce.core.protocol.CommandKeyword.DRYRUN; +import static io.lettuce.core.protocol.CommandKeyword.ENCODING; +import static io.lettuce.core.protocol.CommandKeyword.FAILOVER; +import static io.lettuce.core.protocol.CommandKeyword.FLUSH; +import static io.lettuce.core.protocol.CommandKeyword.FLUSHSLOTS; +import static io.lettuce.core.protocol.CommandKeyword.FORCE; +import static io.lettuce.core.protocol.CommandKeyword.FORGET; +import static io.lettuce.core.protocol.CommandKeyword.FREQ; +import static io.lettuce.core.protocol.CommandKeyword.GENPASS; +import static io.lettuce.core.protocol.CommandKeyword.GETKEYSINSLOT; +import static io.lettuce.core.protocol.CommandKeyword.GETNAME; +import static io.lettuce.core.protocol.CommandKeyword.GETREDIR; +import static io.lettuce.core.protocol.CommandKeyword.GETUSER; +import static io.lettuce.core.protocol.CommandKeyword.GROUPS; +import static io.lettuce.core.protocol.CommandKeyword.HARD; +import static io.lettuce.core.protocol.CommandKeyword.HTSTATS; +import static io.lettuce.core.protocol.CommandKeyword.ID; +import static io.lettuce.core.protocol.CommandKeyword.IDLETIME; +import static io.lettuce.core.protocol.CommandKeyword.IMPORTING; +import static io.lettuce.core.protocol.CommandKeyword.KEYSLOT; +import static io.lettuce.core.protocol.CommandKeyword.KILL; +import static io.lettuce.core.protocol.CommandKeyword.LEN; +import static io.lettuce.core.protocol.CommandKeyword.LIMIT; +import static io.lettuce.core.protocol.CommandKeyword.LIST; +import static io.lettuce.core.protocol.CommandKeyword.LOAD; +import static io.lettuce.core.protocol.CommandKeyword.LOG; +import static io.lettuce.core.protocol.CommandKeyword.MAXLEN; +import static io.lettuce.core.protocol.CommandKeyword.MEET; +import static io.lettuce.core.protocol.CommandKeyword.MIGRATING; +import static io.lettuce.core.protocol.CommandKeyword.NO; +import static io.lettuce.core.protocol.CommandKeyword.NODE; +import static io.lettuce.core.protocol.CommandKeyword.NODES; +import static io.lettuce.core.protocol.CommandKeyword.NOSAVE; +import static io.lettuce.core.protocol.CommandKeyword.NOT; +import static io.lettuce.core.protocol.CommandKeyword.NOVALUES; +import static io.lettuce.core.protocol.CommandKeyword.NUMPAT; +import static io.lettuce.core.protocol.CommandKeyword.NUMSUB; +import static io.lettuce.core.protocol.CommandKeyword.OFF; +import static io.lettuce.core.protocol.CommandKeyword.ON; +import static io.lettuce.core.protocol.CommandKeyword.ONE; +import static io.lettuce.core.protocol.CommandKeyword.OR; +import static io.lettuce.core.protocol.CommandKeyword.PAUSE; +import static io.lettuce.core.protocol.CommandKeyword.REFCOUNT; +import static io.lettuce.core.protocol.CommandKeyword.RELOAD; +import static io.lettuce.core.protocol.CommandKeyword.REPLACE; +import static io.lettuce.core.protocol.CommandKeyword.REPLICAS; +import static io.lettuce.core.protocol.CommandKeyword.REPLICATE; +import static io.lettuce.core.protocol.CommandKeyword.RESET; +import static io.lettuce.core.protocol.CommandKeyword.RESETSTAT; +import static io.lettuce.core.protocol.CommandKeyword.RESTART; +import static io.lettuce.core.protocol.CommandKeyword.REV; +import static io.lettuce.core.protocol.CommandKeyword.REWRITE; +import static io.lettuce.core.protocol.CommandKeyword.SAVECONFIG; +import static io.lettuce.core.protocol.CommandKeyword.SEGFAULT; +import static io.lettuce.core.protocol.CommandKeyword.SETINFO; +import static io.lettuce.core.protocol.CommandKeyword.SETNAME; +import static io.lettuce.core.protocol.CommandKeyword.SETSLOT; +import static io.lettuce.core.protocol.CommandKeyword.SETUSER; +import static io.lettuce.core.protocol.CommandKeyword.SHARDCHANNELS; +import static io.lettuce.core.protocol.CommandKeyword.SHARDNUMSUB; +import static io.lettuce.core.protocol.CommandKeyword.SHARDS; +import static io.lettuce.core.protocol.CommandKeyword.SLAVES; +import static io.lettuce.core.protocol.CommandKeyword.SLOTS; +import static io.lettuce.core.protocol.CommandKeyword.SOFT; +import static io.lettuce.core.protocol.CommandKeyword.STABLE; +import static io.lettuce.core.protocol.CommandKeyword.STREAM; +import static io.lettuce.core.protocol.CommandKeyword.TAKEOVER; +import static io.lettuce.core.protocol.CommandKeyword.TRACKING; +import static io.lettuce.core.protocol.CommandKeyword.UNBLOCK; +import static io.lettuce.core.protocol.CommandKeyword.USAGE; +import static io.lettuce.core.protocol.CommandKeyword.USERS; +import static io.lettuce.core.protocol.CommandKeyword.WHOAMI; +import static io.lettuce.core.protocol.CommandKeyword.WITHSCORE; +import static io.lettuce.core.protocol.CommandKeyword.WITHSCORES; +import static io.lettuce.core.protocol.CommandKeyword.WITHVALUES; +import static io.lettuce.core.protocol.CommandKeyword.XOR; +import static io.lettuce.core.protocol.CommandKeyword.YES; +import static io.lettuce.core.protocol.CommandType.*; + /** * @param * @param @@ -978,9 +1127,9 @@ Command expire(K key, long seconds, ExpireArgs expireArgs) { return createCommand(EXPIRE, new BooleanOutput<>(codec), args); } - Command hexpire(K key, long seconds, ExpireArgs expireArgs, List fields) { + Command hexpire(K key, long seconds, ExpireArgs expireArgs, K... fields) { notNullKey(key); - notEmpty(fields == null ? new Object[]{} : fields.toArray()); + notEmpty(fields); CommandArgs args = new CommandArgs<>(codec).addKey(key).add(seconds); @@ -988,13 +1137,28 @@ Command hexpire(K key, long seconds, ExpireArgs expireArgs, List< expireArgs.build(args); } - args.add(fields.size()); - - fields.forEach(args::addValue); + args.add(fields.length); + args.addKeys(fields); return createCommand(HEXPIRE, new BooleanOutput<>(codec), args); } + Command hexpireat(K key, long seconds, ExpireArgs expireArgs, K... fields) { + notNullKey(key); + notEmpty(fields); + + CommandArgs args = new CommandArgs<>(codec).addKey(key).add(seconds); + + if (expireArgs != null) { + expireArgs.build(args); + } + + args.add(fields.length); + args.addKeys(fields); + + return createCommand(HEXPIREAT, new BooleanOutput<>(codec), args); + } + Command expireat(K key, long timestamp, ExpireArgs expireArgs) { notNullKey(key); @@ -1014,6 +1178,15 @@ Command expiretime(K key) { return createCommand(EXPIRETIME, new IntegerOutput<>(codec), args); } + Command hexpiretime(K key, K... fields) { + notNullKey(key); + + CommandArgs args = new CommandArgs<>(codec).addKey(key); + args.add(fields.length); + args.addKeys(fields); + return createCommand(HEXPIRETIME, new IntegerOutput<>(codec), args); + } + Command flushall() { return createCommand(FLUSHALL, new StatusOutput<>(codec)); } @@ -2060,6 +2233,16 @@ Command persist(K key) { return createCommand(PERSIST, new BooleanOutput<>(codec), key); } + Command hpersist(K key, K... fields) { + notNullKey(key); + + CommandArgs args = new CommandArgs<>(codec).addKey(key); + args.add(fields.length); + args.addKeys(fields); + + return createCommand(HPERSIST, new BooleanOutput<>(codec), args); + } + Command pexpire(K key, long milliseconds, ExpireArgs expireArgs) { notNullKey(key); diff --git a/src/main/java/io/lettuce/core/api/async/RedisHashAsyncCommands.java b/src/main/java/io/lettuce/core/api/async/RedisHashAsyncCommands.java index cc9b8b1489..9f514450fa 100644 --- a/src/main/java/io/lettuce/core/api/async/RedisHashAsyncCommands.java +++ b/src/main/java/io/lettuce/core/api/async/RedisHashAsyncCommands.java @@ -19,9 +19,7 @@ */ package io.lettuce.core.api.async; -import java.util.List; -import java.util.Map; - +import io.lettuce.core.ExpireArgs; import io.lettuce.core.KeyScanCursor; import io.lettuce.core.KeyValue; import io.lettuce.core.MapScanCursor; @@ -33,6 +31,12 @@ import io.lettuce.core.output.KeyValueStreamingChannel; import io.lettuce.core.output.ValueStreamingChannel; +import java.time.Duration; +import java.time.Instant; +import java.util.Date; +import java.util.List; +import java.util.Map; + /** * Asynchronous executed commands for Hashes (Key-Value pairs). * @@ -429,4 +433,152 @@ public interface RedisHashAsyncCommands { * @return Long count of the keys. */ RedisFuture hvals(ValueStreamingChannel channel, K key); + + /** + * Set the time to live (in seconds) for one or more fields, belonging to a certain key. + * + * @param key the key of the fields. + * @param seconds the seconds type: long. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + RedisFuture hexpire(K key, long seconds, K... fields); + + /** + * Set the time to live (in seconds) for one or more fields, belonging to a certain key. + * + * @param key the key of the fields. + * @param seconds the seconds type: long. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + RedisFuture hexpire(K key, long seconds, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key. + * + * @param key the key. + * @param seconds the TTL {@link Duration} + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + RedisFuture hexpire(K key, Duration seconds, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key. + * + * @param key the key. + * @param seconds the TTL {@link Duration} + * @param expireArgs the {@link ExpireArgs}. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + RedisFuture hexpire(K key, Duration seconds, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + RedisFuture hexpireat(K key, long timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + RedisFuture hexpireat(K key, long timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + RedisFuture hexpireat(K key, Date timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + RedisFuture hexpireat(K key, Date timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + RedisFuture hexpireat(K key, Instant timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + RedisFuture hexpireat(K key, Instant timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Get the time to live for one or more fields in as unix timestamp in seconds. + * + * @param key the key. + * @param fields one or more fields to get the TTL for. + * @return Long integer-reply in seconds, or a negative value in order to signal an error. The command returns {@code -1} if + * the key exists but has no associated expiration time. The command returns {@code -2} if the key does not exist. + * @since 7.0 + */ + RedisFuture hexpiretime(K key, K... fields); + + /** + * Remove the expiration from one or more fields. + * + * @param key the key. + * @param fields one or more fields to remove the TTL for. + * @return Boolean integer-reply specifically: + * + * {@code true} if the timeout was removed. {@code false} if {@code key} does not exist or does not have an + * associated timeout. + */ + RedisFuture hpersist(K key, K... fields); } diff --git a/src/main/java/io/lettuce/core/api/async/RedisKeyAsyncCommands.java b/src/main/java/io/lettuce/core/api/async/RedisKeyAsyncCommands.java index 5a6078d5b6..b5253b4e9d 100644 --- a/src/main/java/io/lettuce/core/api/async/RedisKeyAsyncCommands.java +++ b/src/main/java/io/lettuce/core/api/async/RedisKeyAsyncCommands.java @@ -19,15 +19,25 @@ */ package io.lettuce.core.api.async; +import io.lettuce.core.CopyArgs; +import io.lettuce.core.ExpireArgs; +import io.lettuce.core.KeyScanArgs; +import io.lettuce.core.KeyScanCursor; +import io.lettuce.core.MigrateArgs; +import io.lettuce.core.RedisFuture; +import io.lettuce.core.RestoreArgs; +import io.lettuce.core.ScanArgs; +import io.lettuce.core.ScanCursor; +import io.lettuce.core.SortArgs; +import io.lettuce.core.StreamScanCursor; +import io.lettuce.core.output.KeyStreamingChannel; +import io.lettuce.core.output.ValueStreamingChannel; + import java.time.Duration; import java.time.Instant; import java.util.Date; import java.util.List; -import io.lettuce.core.*; -import io.lettuce.core.output.KeyStreamingChannel; -import io.lettuce.core.output.ValueStreamingChannel; - /** * Asynchronous executed commands for Keys (Key manipulation/querying). * @@ -137,56 +147,6 @@ public interface RedisKeyAsyncCommands { */ RedisFuture expire(K key, Duration seconds, ExpireArgs expireArgs); - /** - * Set the time to live (in seconds) for a {@link List} of fields, belonging to a certain key. - * - * @param key the key of the fields. - * @param seconds the seconds type: long. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - RedisFuture hexpire(K key, long seconds, List fields); - - /** - * Set the time to live (in seconds) for a {@link List} of fields, belonging to a certain key. - * - * @param key the key of the fields. - * @param seconds the seconds type: long. - * @param expireArgs the expire arguments. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - RedisFuture hexpire(K key, long seconds, ExpireArgs expireArgs, List fields); - - /** - * Set the time to live for a {@link List} of fields, belonging to a certain key. - * - * @param key the key. - * @param seconds the TTL {@link Duration} - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - RedisFuture hexpire(K key, Duration seconds, List fields); - - /** - * Set the time to live for a {@link List} of fields, belonging to a certain key. - * - * @param key the key. - * @param seconds the TTL {@link Duration} - * @param expireArgs the {@link ExpireArgs}. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - RedisFuture hexpire(K key, Duration seconds, ExpireArgs expireArgs, List fields); - /** * Set the expiration for a key as a UNIX timestamp. * diff --git a/src/main/java/io/lettuce/core/api/reactive/RedisHashReactiveCommands.java b/src/main/java/io/lettuce/core/api/reactive/RedisHashReactiveCommands.java index 080087510a..e02fe5b80a 100644 --- a/src/main/java/io/lettuce/core/api/reactive/RedisHashReactiveCommands.java +++ b/src/main/java/io/lettuce/core/api/reactive/RedisHashReactiveCommands.java @@ -19,10 +19,7 @@ */ package io.lettuce.core.api.reactive; -import java.util.Map; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; +import io.lettuce.core.ExpireArgs; import io.lettuce.core.KeyScanCursor; import io.lettuce.core.KeyValue; import io.lettuce.core.MapScanCursor; @@ -32,6 +29,13 @@ import io.lettuce.core.output.KeyStreamingChannel; import io.lettuce.core.output.KeyValueStreamingChannel; import io.lettuce.core.output.ValueStreamingChannel; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.Duration; +import java.time.Instant; +import java.util.Date; +import java.util.Map; /** * Reactive executed commands for Hashes (Key-Value pairs). @@ -451,4 +455,152 @@ public interface RedisHashReactiveCommands { */ @Deprecated Mono hvals(ValueStreamingChannel channel, K key); + + /** + * Set the time to live (in seconds) for one or more fields, belonging to a certain key. + * + * @param key the key of the fields. + * @param seconds the seconds type: long. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Mono hexpire(K key, long seconds, K... fields); + + /** + * Set the time to live (in seconds) for one or more fields, belonging to a certain key. + * + * @param key the key of the fields. + * @param seconds the seconds type: long. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Mono hexpire(K key, long seconds, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key. + * + * @param key the key. + * @param seconds the TTL {@link Duration} + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Mono hexpire(K key, Duration seconds, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key. + * + * @param key the key. + * @param seconds the TTL {@link Duration} + * @param expireArgs the {@link ExpireArgs}. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Mono hexpire(K key, Duration seconds, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Mono hexpireat(K key, long timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Mono hexpireat(K key, long timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Mono hexpireat(K key, Date timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Mono hexpireat(K key, Date timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Mono hexpireat(K key, Instant timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Mono hexpireat(K key, Instant timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Get the time to live for one or more fields in as unix timestamp in seconds. + * + * @param key the key. + * @param fields one or more fields to get the TTL for. + * @return Long integer-reply in seconds, or a negative value in order to signal an error. The command returns {@code -1} if + * the key exists but has no associated expiration time. The command returns {@code -2} if the key does not exist. + * @since 7.0 + */ + Mono hexpiretime(K key, K... fields); + + /** + * Remove the expiration from one or more fields. + * + * @param key the key. + * @param fields one or more fields to remove the TTL for. + * @return Boolean integer-reply specifically: + * + * {@code true} if the timeout was removed. {@code false} if {@code key} does not exist or does not have an + * associated timeout. + */ + Mono hpersist(K key, K... fields); } diff --git a/src/main/java/io/lettuce/core/api/reactive/RedisKeyReactiveCommands.java b/src/main/java/io/lettuce/core/api/reactive/RedisKeyReactiveCommands.java index b3f1ef89f8..1fbfdda1a8 100644 --- a/src/main/java/io/lettuce/core/api/reactive/RedisKeyReactiveCommands.java +++ b/src/main/java/io/lettuce/core/api/reactive/RedisKeyReactiveCommands.java @@ -22,7 +22,6 @@ import java.time.Duration; import java.time.Instant; import java.util.Date; -import java.util.List; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -148,56 +147,6 @@ public interface RedisKeyReactiveCommands { */ Mono expire(K key, Duration seconds, ExpireArgs expireArgs); - /** - * Set the time to live (in seconds) for a {@link List} of fields, belonging to a certain key. - * - * @param key the key of the fields. - * @param seconds the seconds type: long. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Mono hexpire(K key, long seconds, List fields); - - /** - * Set the time to live (in seconds) for a {@link List} of fields, belonging to a certain key. - * - * @param key the key of the fields. - * @param seconds the seconds type: long. - * @param expireArgs the expire arguments. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Mono hexpire(K key, long seconds, ExpireArgs expireArgs, List fields); - - /** - * Set the time to live for a {@link List} of fields, belonging to a certain key. - * - * @param key the key. - * @param seconds the TTL {@link Duration} - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Mono hexpire(K key, Duration seconds, List fields); - - /** - * Set the time to live for a {@link List} of fields, belonging to a certain key. - * - * @param key the key. - * @param seconds the TTL {@link Duration} - * @param expireArgs the {@link ExpireArgs}. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Mono hexpire(K key, Duration seconds, ExpireArgs expireArgs, List fields); - /** * Set the expiration for a key as a UNIX timestamp. * diff --git a/src/main/java/io/lettuce/core/api/sync/RedisHashCommands.java b/src/main/java/io/lettuce/core/api/sync/RedisHashCommands.java index 816ec08227..ab41a1cafd 100644 --- a/src/main/java/io/lettuce/core/api/sync/RedisHashCommands.java +++ b/src/main/java/io/lettuce/core/api/sync/RedisHashCommands.java @@ -19,9 +19,7 @@ */ package io.lettuce.core.api.sync; -import java.util.List; -import java.util.Map; - +import io.lettuce.core.ExpireArgs; import io.lettuce.core.KeyScanCursor; import io.lettuce.core.KeyValue; import io.lettuce.core.MapScanCursor; @@ -32,6 +30,12 @@ import io.lettuce.core.output.KeyValueStreamingChannel; import io.lettuce.core.output.ValueStreamingChannel; +import java.time.Duration; +import java.time.Instant; +import java.util.Date; +import java.util.List; +import java.util.Map; + /** * Synchronous executed commands for Hashes (Key-Value pairs). * @@ -430,4 +434,152 @@ public interface RedisHashCommands { * @return Long count of the keys. */ Long hvals(ValueStreamingChannel channel, K key); + + /** + * Set the time to live (in seconds) for one or more fields, belonging to a certain key. + * + * @param key the key of the fields. + * @param seconds the seconds type: long. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Boolean hexpire(K key, long seconds, K... fields); + + /** + * Set the time to live (in seconds) for one or more fields, belonging to a certain key. + * + * @param key the key of the fields. + * @param seconds the seconds type: long. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Boolean hexpire(K key, long seconds, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key. + * + * @param key the key. + * @param seconds the TTL {@link Duration} + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Boolean hexpire(K key, Duration seconds, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key. + * + * @param key the key. + * @param seconds the TTL {@link Duration} + * @param expireArgs the {@link ExpireArgs}. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Boolean hexpire(K key, Duration seconds, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Boolean hexpireat(K key, long timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Boolean hexpireat(K key, long timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Boolean hexpireat(K key, Date timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Boolean hexpireat(K key, Date timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Boolean hexpireat(K key, Instant timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Boolean hexpireat(K key, Instant timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Get the time to live for one or more fields in as unix timestamp in seconds. + * + * @param key the key. + * @param fields one or more fields to get the TTL for. + * @return Long integer-reply in seconds, or a negative value in order to signal an error. The command returns {@code -1} if + * the key exists but has no associated expiration time. The command returns {@code -2} if the key does not exist. + * @since 7.0 + */ + Long hexpiretime(K key, K... fields); + + /** + * Remove the expiration from one or more fields. + * + * @param key the key. + * @param fields one or more fields to remove the TTL for. + * @return Boolean integer-reply specifically: + * + * {@code true} if the timeout was removed. {@code false} if {@code key} does not exist or does not have an + * associated timeout. + */ + Boolean hpersist(K key, K... fields); } diff --git a/src/main/java/io/lettuce/core/api/sync/RedisKeyCommands.java b/src/main/java/io/lettuce/core/api/sync/RedisKeyCommands.java index 07faab4c2e..516e4ab072 100644 --- a/src/main/java/io/lettuce/core/api/sync/RedisKeyCommands.java +++ b/src/main/java/io/lettuce/core/api/sync/RedisKeyCommands.java @@ -146,56 +146,6 @@ public interface RedisKeyCommands { */ Boolean expire(K key, Duration seconds, ExpireArgs expireArgs); - /** - * Set the time to live (in seconds) for a {@link List} of fields, belonging to a certain key. - * - * @param key the key of the fields. - * @param seconds the seconds type: long. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Boolean hexpire(K key, long seconds, List fields); - - /** - * Set the time to live (in seconds) for a {@link List} of fields, belonging to a certain key. - * - * @param key the key of the fields. - * @param seconds the seconds type: long. - * @param expireArgs the expire arguments. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Boolean hexpire(K key, long seconds, ExpireArgs expireArgs, List fields); - - /** - * Set the time to live for a {@link List} of fields, belonging to a certain key. - * - * @param key the key. - * @param seconds the TTL {@link Duration} - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Boolean hexpire(K key, Duration seconds, List fields); - - /** - * Set the time to live for a {@link List} of fields, belonging to a certain key. - * - * @param key the key. - * @param seconds the TTL {@link Duration} - * @param expireArgs the {@link ExpireArgs}. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Boolean hexpire(K key, Duration seconds, ExpireArgs expireArgs, List fields); - /** * Set the expiration for a key as a UNIX timestamp. * diff --git a/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionHashAsyncCommands.java b/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionHashAsyncCommands.java index dd99fd23b0..442444c6ed 100644 --- a/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionHashAsyncCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionHashAsyncCommands.java @@ -19,9 +19,7 @@ */ package io.lettuce.core.cluster.api.async; -import java.util.List; -import java.util.Map; - +import io.lettuce.core.ExpireArgs; import io.lettuce.core.KeyScanCursor; import io.lettuce.core.KeyValue; import io.lettuce.core.MapScanCursor; @@ -32,6 +30,12 @@ import io.lettuce.core.output.KeyValueStreamingChannel; import io.lettuce.core.output.ValueStreamingChannel; +import java.time.Duration; +import java.time.Instant; +import java.util.Date; +import java.util.List; +import java.util.Map; + /** * Asynchronous executed commands on a node selection for Hashes (Key-Value pairs). * @@ -428,4 +432,152 @@ public interface NodeSelectionHashAsyncCommands { * @return Long count of the keys. */ AsyncExecutions hvals(ValueStreamingChannel channel, K key); + + /** + * Set the time to live (in seconds) for one or more fields, belonging to a certain key. + * + * @param key the key of the fields. + * @param seconds the seconds type: long. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + AsyncExecutions hexpire(K key, long seconds, K... fields); + + /** + * Set the time to live (in seconds) for one or more fields, belonging to a certain key. + * + * @param key the key of the fields. + * @param seconds the seconds type: long. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + AsyncExecutions hexpire(K key, long seconds, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key. + * + * @param key the key. + * @param seconds the TTL {@link Duration} + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + AsyncExecutions hexpire(K key, Duration seconds, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key. + * + * @param key the key. + * @param seconds the TTL {@link Duration} + * @param expireArgs the {@link ExpireArgs}. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + AsyncExecutions hexpire(K key, Duration seconds, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + AsyncExecutions hexpireat(K key, long timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + AsyncExecutions hexpireat(K key, long timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + AsyncExecutions hexpireat(K key, Date timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + AsyncExecutions hexpireat(K key, Date timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + AsyncExecutions hexpireat(K key, Instant timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + AsyncExecutions hexpireat(K key, Instant timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Get the time to live for one or more fields in as unix timestamp in seconds. + * + * @param key the key. + * @param fields one or more fields to get the TTL for. + * @return Long integer-reply in seconds, or a negative value in order to signal an error. The command returns {@code -1} if + * the key exists but has no associated expiration time. The command returns {@code -2} if the key does not exist. + * @since 7.0 + */ + AsyncExecutions hexpiretime(K key, K... fields); + + /** + * Remove the expiration from one or more fields. + * + * @param key the key. + * @param fields one or more fields to remove the TTL for. + * @return Boolean integer-reply specifically: + * + * {@code true} if the timeout was removed. {@code false} if {@code key} does not exist or does not have an + * associated timeout. + */ + AsyncExecutions hpersist(K key, K... fields); } diff --git a/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionKeyAsyncCommands.java b/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionKeyAsyncCommands.java index 422111c0ea..44bbd168a3 100644 --- a/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionKeyAsyncCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionKeyAsyncCommands.java @@ -146,56 +146,6 @@ public interface NodeSelectionKeyAsyncCommands { */ AsyncExecutions expire(K key, Duration seconds, ExpireArgs expireArgs); - /** - * Set the time to live (in seconds) for a {@link List} of fields, belonging to a certain key. - * - * @param key the key of the fields. - * @param seconds the seconds type: long. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - AsyncExecutions hexpire(K key, long seconds, List fields); - - /** - * Set the time to live (in seconds) for a {@link List} of fields, belonging to a certain key. - * - * @param key the key of the fields. - * @param seconds the seconds type: long. - * @param expireArgs the expire arguments. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - AsyncExecutions hexpire(K key, long seconds, ExpireArgs expireArgs, List fields); - - /** - * Set the time to live for a {@link List} of fields, belonging to a certain key. - * - * @param key the key. - * @param seconds the TTL {@link Duration} - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - AsyncExecutions hexpire(K key, Duration seconds, List fields); - - /** - * Set the time to live for a {@link List} of fields, belonging to a certain key. - * - * @param key the key. - * @param seconds the TTL {@link Duration} - * @param expireArgs the {@link ExpireArgs}. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - AsyncExecutions hexpire(K key, Duration seconds, ExpireArgs expireArgs, List fields); - /** * Set the expiration for a key as a UNIX timestamp. * diff --git a/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionHashCommands.java b/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionHashCommands.java index 4d9a3c694b..f2aeaf52b4 100644 --- a/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionHashCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionHashCommands.java @@ -19,9 +19,7 @@ */ package io.lettuce.core.cluster.api.sync; -import java.util.List; -import java.util.Map; - +import io.lettuce.core.ExpireArgs; import io.lettuce.core.KeyScanCursor; import io.lettuce.core.KeyValue; import io.lettuce.core.MapScanCursor; @@ -32,6 +30,12 @@ import io.lettuce.core.output.KeyValueStreamingChannel; import io.lettuce.core.output.ValueStreamingChannel; +import java.time.Duration; +import java.time.Instant; +import java.util.Date; +import java.util.List; +import java.util.Map; + /** * Synchronous executed commands on a node selection for Hashes (Key-Value pairs). * @@ -428,4 +432,152 @@ public interface NodeSelectionHashCommands { * @return Long count of the keys. */ Executions hvals(ValueStreamingChannel channel, K key); + + /** + * Set the time to live (in seconds) for one or more fields, belonging to a certain key. + * + * @param key the key of the fields. + * @param seconds the seconds type: long. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Executions hexpire(K key, long seconds, K... fields); + + /** + * Set the time to live (in seconds) for one or more fields, belonging to a certain key. + * + * @param key the key of the fields. + * @param seconds the seconds type: long. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Executions hexpire(K key, long seconds, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key. + * + * @param key the key. + * @param seconds the TTL {@link Duration} + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Executions hexpire(K key, Duration seconds, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key. + * + * @param key the key. + * @param seconds the TTL {@link Duration} + * @param expireArgs the {@link ExpireArgs}. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Executions hexpire(K key, Duration seconds, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Executions hexpireat(K key, long timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Executions hexpireat(K key, long timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Executions hexpireat(K key, Date timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Executions hexpireat(K key, Date timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Executions hexpireat(K key, Instant timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Executions hexpireat(K key, Instant timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Get the time to live for one or more fields in as unix timestamp in seconds. + * + * @param key the key. + * @param fields one or more fields to get the TTL for. + * @return Long integer-reply in seconds, or a negative value in order to signal an error. The command returns {@code -1} if + * the key exists but has no associated expiration time. The command returns {@code -2} if the key does not exist. + * @since 7.0 + */ + Executions hexpiretime(K key, K... fields); + + /** + * Remove the expiration from one or more fields. + * + * @param key the key. + * @param fields one or more fields to remove the TTL for. + * @return Boolean integer-reply specifically: + * + * {@code true} if the timeout was removed. {@code false} if {@code key} does not exist or does not have an + * associated timeout. + */ + Executions hpersist(K key, K... fields); } diff --git a/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionKeyCommands.java b/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionKeyCommands.java index b523434d24..398fcf1f65 100644 --- a/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionKeyCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionKeyCommands.java @@ -19,11 +19,6 @@ */ package io.lettuce.core.cluster.api.sync; -import java.time.Duration; -import java.time.Instant; -import java.util.Date; -import java.util.List; - import io.lettuce.core.CopyArgs; import io.lettuce.core.ExpireArgs; import io.lettuce.core.KeyScanArgs; @@ -37,6 +32,11 @@ import io.lettuce.core.output.KeyStreamingChannel; import io.lettuce.core.output.ValueStreamingChannel; +import java.time.Duration; +import java.time.Instant; +import java.util.Date; +import java.util.List; + /** * Synchronous executed commands on a node selection for Keys (Key manipulation/querying). * @@ -146,56 +146,6 @@ public interface NodeSelectionKeyCommands { */ Executions expire(K key, Duration seconds, ExpireArgs expireArgs); - /** - * Set the time to live (in seconds) for a {@link List} of fields, belonging to a certain key. - * - * @param key the key of the fields. - * @param seconds the seconds type: long. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Executions hexpire(K key, long seconds, List fields); - - /** - * Set the time to live (in seconds) for a {@link List} of fields, belonging to a certain key. - * - * @param key the key of the fields. - * @param seconds the seconds type: long. - * @param expireArgs the expire arguments. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Executions hexpire(K key, long seconds, ExpireArgs expireArgs, List fields); - - /** - * Set the time to live for a {@link List} of fields, belonging to a certain key. - * - * @param key the key. - * @param seconds the TTL {@link Duration} - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Executions hexpire(K key, Duration seconds, List fields); - - /** - * Set the time to live for a {@link List} of fields, belonging to a certain key. - * - * @param key the key. - * @param seconds the TTL {@link Duration} - * @param expireArgs the {@link ExpireArgs}. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Executions hexpire(K key, Duration seconds, ExpireArgs expireArgs, List fields); - /** * Set the expiration for a key as a UNIX timestamp. * diff --git a/src/main/java/io/lettuce/core/protocol/CommandType.java b/src/main/java/io/lettuce/core/protocol/CommandType.java index bd4c04c982..7207a50dab 100644 --- a/src/main/java/io/lettuce/core/protocol/CommandType.java +++ b/src/main/java/io/lettuce/core/protocol/CommandType.java @@ -46,7 +46,7 @@ public enum CommandType implements ProtocolKeyword { // Keys - COPY, DEL, DUMP, EXISTS, HEXPIRE, EXPIRE, EXPIREAT, EXPIRETIME, KEYS, MIGRATE, MOVE, OBJECT, PERSIST, PEXPIRE, PEXPIREAT, PEXPIRETIME, PTTL, RANDOMKEY, RENAME, RENAMENX, RESTORE, TOUCH, TTL, TYPE, SCAN, UNLINK, + COPY, DEL, DUMP, EXISTS, HEXPIRE, EXPIRE, HEXPIREAT, EXPIREAT, HEXPIRETIME, EXPIRETIME, KEYS, MIGRATE, MOVE, OBJECT, HPERSIST, PERSIST, PEXPIRE, PEXPIREAT, PEXPIRETIME, PTTL, RANDOMKEY, RENAME, RENAMENX, RESTORE, TOUCH, TTL, TYPE, SCAN, UNLINK, // String diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisHashCoroutinesCommands.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisHashCoroutinesCommands.kt index 6ab7746601..34a4228f49 100644 --- a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisHashCoroutinesCommands.kt +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisHashCoroutinesCommands.kt @@ -20,8 +20,17 @@ package io.lettuce.core.api.coroutines -import io.lettuce.core.* +import io.lettuce.core.ExperimentalLettuceCoroutinesApi +import io.lettuce.core.ExpireArgs import kotlinx.coroutines.flow.Flow +import io.lettuce.core.KeyScanCursor +import io.lettuce.core.KeyValue +import io.lettuce.core.MapScanCursor +import io.lettuce.core.ScanArgs +import io.lettuce.core.ScanCursor +import java.time.Duration +import java.time.Instant +import java.util.* /** * Coroutine executed commands for Hashes (Key-Value pairs). @@ -298,5 +307,153 @@ interface RedisHashCoroutinesCommands { */ fun hvals(key: K): Flow + /** + * Set the time to live (in seconds) for one or more fields, belonging to a certain key. + * + * @param key the key of the fields. + * @param seconds the seconds type: long. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: `true` if the timeout was set. `false` if `key` does not + * exist or the timeout could not be set. + * @since 7.0 + */ + suspend fun hexpire(key: K, seconds: Long, vararg fields: K): Boolean? + + /** + * Set the time to live (in seconds) for one or more fields, belonging to a certain key. + * + * @param key the key of the fields. + * @param seconds the seconds type: long. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: `true` if the timeout was set. `false` if `key` does not + * exist or the timeout could not be set. + * @since 7.0 + */ + suspend fun hexpire(key: K, seconds: Long, expireArgs: ExpireArgs, vararg fields: K): Boolean? + + /** + * Set the time to live for one or more fields, belonging to a certain key. + * + * @param key the key. + * @param seconds the TTL [Duration] + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: `true` if the timeout was set. `false` if `key` does not + * exist or the timeout could not be set. + * @since 7.0 + */ + suspend fun hexpire(key: K, seconds: Duration, vararg fields: K): Boolean? + + /** + * Set the time to live for one or more fields, belonging to a certain key. + * + * @param key the key. + * @param seconds the TTL [Duration] + * @param expireArgs the [ExpireArgs]. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: `true` if the timeout was set. `false` if `key` does not + * exist or the timeout could not be set. + * @since 7.0 + */ + suspend fun hexpire(key: K, seconds: Duration, expireArgs: ExpireArgs, vararg fields: K): Boolean? + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: `true` if the timeout was set. `false` if `key` does not + * exist or the timeout could not be set (see: `EXPIRE`). + * @since 7.0 + */ + suspend fun hexpireat(key: K, timestamp: Long, vararg fields: K): Boolean? + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: `true` if the timeout was set. `false` if `key` does not + * exist or the timeout could not be set (see: `EXPIRE`). + * @since 7.0 + */ + suspend fun hexpireat(key: K, timestamp: Long, expireArgs: ExpireArgs, vararg fields: K): Boolean? + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: `true` if the timeout was set. `false` if `key` does not + * exist or the timeout could not be set (see: `EXPIRE`). + * @since 7.0 + */ + suspend fun hexpireat(key: K, timestamp: Date, vararg fields: K): Boolean? + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: `true` if the timeout was set. `false` if `key` does not + * exist or the timeout could not be set (see: `EXPIRE`). + * @since 7.0 + */ + suspend fun hexpireat(key: K, timestamp: Date, expireArgs: ExpireArgs, vararg fields: K): Boolean? + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: `true` if the timeout was set. `false` if `key` does not + * exist or the timeout could not be set (see: `EXPIRE`). + * @since 7.0 + */ + suspend fun hexpireat(key: K, timestamp: Instant, vararg fields: K): Boolean? + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: `true` if the timeout was set. `false` if `key` does not + * exist or the timeout could not be set (see: `EXPIRE`). + * @since 7.0 + */ + suspend fun hexpireat(key: K, timestamp: Instant, expireArgs: ExpireArgs, vararg fields: K): Boolean? + + /** + * Get the time to live for one or more fields in as unix timestamp in seconds. + * + * @param key the key. + * @param fields one or more fields to get the TTL for. + * @return Long integer-reply in seconds, or a negative value in order to signal an error. The command returns `-1` if + * the key exists but has no associated expiration time. The command returns `-2` if the key does not exist. + * @since 7.0 + */ + suspend fun hexpiretime(key: K, vararg fields: K): Long? + + /** + * Remove the expiration from one or more fields. + * + * @param key the key. + * @param fields one or more fields to remove the TTL for. + * @return Boolean integer-reply specifically: + * + * `true` if the timeout was removed. `false` if `key` does not exist or does not have an + * associated timeout. + */ + suspend fun hpersist(key: K, vararg fields: K): Boolean? + } diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisHashCoroutinesCommandsImpl.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisHashCoroutinesCommandsImpl.kt index ec1a488735..8a1d959e54 100644 --- a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisHashCoroutinesCommandsImpl.kt +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisHashCoroutinesCommandsImpl.kt @@ -26,6 +26,9 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.toList import kotlinx.coroutines.reactive.asFlow import kotlinx.coroutines.reactive.awaitFirstOrNull +import java.time.Duration +import java.time.Instant +import java.util.* /** @@ -113,5 +116,60 @@ internal class RedisHashCoroutinesCommandsImpl(internal val op override fun hvals(key: K): Flow = ops.hvals(key).asFlow() + override suspend fun hexpire(key: K, seconds: Long, vararg fields: K): Boolean? = + ops.hexpire(key, seconds, *fields).awaitFirstOrNull() + + override suspend fun hexpire(key: K, seconds: Long, expireArgs: ExpireArgs, vararg fields: K): Boolean? = + ops.hexpire(key, seconds, expireArgs, *fields).awaitFirstOrNull() + + override suspend fun hexpire(key: K, seconds: Duration, vararg fields: K): Boolean? = + ops.hexpire(key, seconds, *fields).awaitFirstOrNull() + + override suspend fun hexpire( + key: K, + seconds: Duration, + expireArgs: ExpireArgs, + vararg fields: K + ): Boolean? = + ops.hexpire(key, seconds, expireArgs, *fields).awaitFirstOrNull() + + override suspend fun hexpireat(key: K, timestamp: Date, vararg fields: K): Boolean? = + ops.hexpireat(key, timestamp, *fields).awaitFirstOrNull() + + override suspend fun hexpireat( + key: K, + timestamp: Long, + expireArgs: ExpireArgs, + vararg fields: K + ): Boolean? = + ops.hexpireat(key, timestamp, expireArgs, *fields).awaitFirstOrNull() + + override suspend fun hexpireat(key: K, timestamp: Instant, vararg fields: K): Boolean? = + ops.hexpireat(key, timestamp, *fields).awaitFirstOrNull() + + override suspend fun hexpireat( + key: K, + timestamp: Instant, + expireArgs: ExpireArgs, + vararg fields: K + ): Boolean? = + ops.hexpireat(key, timestamp, expireArgs, *fields).awaitFirstOrNull() + + override suspend fun hexpireat(key: K, timestamp: Long, vararg fields: K): Boolean? = + ops.hexpireat(key, timestamp, *fields).awaitFirstOrNull() + + override suspend fun hexpireat( + key: K, + timestamp: Date, + expireArgs: ExpireArgs, + vararg fields: K + ): Boolean? = + ops.hexpireat(key, timestamp, expireArgs, *fields).awaitFirstOrNull() + + override suspend fun hexpiretime(key: K, vararg fields: K): Long? = + ops.hexpiretime(key).awaitFirstOrNull() + + override suspend fun hpersist(key: K, vararg fields: K): Boolean? = ops.hpersist(key).awaitFirstOrNull() + } diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisKeyCoroutinesCommands.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisKeyCoroutinesCommands.kt index f979c8bc4e..72aa35c614 100644 --- a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisKeyCoroutinesCommands.kt +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisKeyCoroutinesCommands.kt @@ -20,11 +20,19 @@ package io.lettuce.core.api.coroutines -import io.lettuce.core.* +import io.lettuce.core.CopyArgs +import io.lettuce.core.ExperimentalLettuceCoroutinesApi +import io.lettuce.core.ExpireArgs +import io.lettuce.core.KeyScanCursor +import io.lettuce.core.MigrateArgs +import io.lettuce.core.RestoreArgs +import io.lettuce.core.ScanArgs +import io.lettuce.core.ScanCursor +import io.lettuce.core.SortArgs import kotlinx.coroutines.flow.Flow import java.time.Duration import java.time.Instant -import java.util.* +import java.util.Date /** * Coroutine executed commands for Keys (Key manipulation/querying). @@ -136,56 +144,6 @@ interface RedisKeyCoroutinesCommands { */ suspend fun expire(key: K, seconds: Duration, expireArgs: ExpireArgs): Boolean? - /** - * Set the time to live (in seconds) for a [List] of fields, belonging to a certain key. - * - * @param key the key of the fields. - * @param seconds the seconds type: long. - * @param fields a [List] of fields to set the TTL for. - * @return Boolean integer-reply specifically: `true` if the timeout was set. `false` if `key` does not - * exist or the timeout could not be set. - * @since 7.0 - */ - suspend fun hexpire(key: K, seconds: Long, fields: List): Boolean? - - /** - * Set the time to live (in seconds) for a [List] of fields, belonging to a certain key. - * - * @param key the key of the fields. - * @param seconds the seconds type: long. - * @param expireArgs the expire arguments. - * @param fields a [List] of fields to set the TTL for. - * @return Boolean integer-reply specifically: `true` if the timeout was set. `false` if `key` does not - * exist or the timeout could not be set. - * @since 7.0 - */ - suspend fun hexpire(key: K, seconds: Long, expireArgs: ExpireArgs, fields: List): Boolean? - - /** - * Set the time to live for a [List] of fields, belonging to a certain key. - * - * @param key the key. - * @param seconds the TTL [Duration] - * @param fields a [List] of fields to set the TTL for. - * @return Boolean integer-reply specifically: `true` if the timeout was set. `false` if `key` does not - * exist or the timeout could not be set. - * @since 7.0 - */ - suspend fun hexpire(key: K, seconds: Duration, fields: List): Boolean? - - /** - * Set the time to live for a [List] of fields, belonging to a certain key. - * - * @param key the key. - * @param seconds the TTL [Duration] - * @param expireArgs the [ExpireArgs]. - * @param fields a [List] of fields to set the TTL for. - * @return Boolean integer-reply specifically: `true` if the timeout was set. `false` if `key` does not - * exist or the timeout could not be set. - * @since 7.0 - */ - suspend fun hexpire(key: K, seconds: Duration, expireArgs: ExpireArgs, fields: List): Boolean? - /** * Set the expiration for a key as a UNIX timestamp. * diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisKeyCoroutinesCommandsImpl.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisKeyCoroutinesCommandsImpl.kt index d088d03ad8..5b62a92d3c 100644 --- a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisKeyCoroutinesCommandsImpl.kt +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisKeyCoroutinesCommandsImpl.kt @@ -74,24 +74,6 @@ internal class RedisKeyCoroutinesCommandsImpl(internal val ops ): Boolean? = ops.expire(key, seconds, expireArgs).awaitFirstOrNull() - override suspend fun hexpire(key: K, seconds: Long, fields: List): Boolean? = - ops.hexpire(key, seconds, fields).awaitFirstOrNull() - - override suspend fun hexpire(key: K, seconds: Long, expireArgs: ExpireArgs, fields: List): Boolean? = - ops.hexpire(key, seconds, expireArgs, fields).awaitFirstOrNull() - - - override suspend fun hexpire(key: K, seconds: Duration, fields: List): Boolean? = - ops.hexpire(key, seconds, fields).awaitFirstOrNull() - - override suspend fun hexpire( - key: K, - seconds: Duration, - expireArgs: ExpireArgs, - fields: List - ): Boolean? = - ops.hexpire(key, seconds, expireArgs, fields).awaitFirstOrNull() - override suspend fun expireat(key: K, timestamp: Date): Boolean? = ops.expireat(key, timestamp).awaitFirstOrNull() diff --git a/src/main/templates/io/lettuce/core/api/RedisHashCommands.java b/src/main/templates/io/lettuce/core/api/RedisHashCommands.java index ddef1ce24f..96dfe525eb 100644 --- a/src/main/templates/io/lettuce/core/api/RedisHashCommands.java +++ b/src/main/templates/io/lettuce/core/api/RedisHashCommands.java @@ -428,4 +428,151 @@ public interface RedisHashCommands { */ Long hvals(ValueStreamingChannel channel, K key); + /** + * Set the time to live (in seconds) for one or more fields, belonging to a certain key. + * + * @param key the key of the fields. + * @param seconds the seconds type: long. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Boolean hexpire(K key, long seconds, K... fields); + + /** + * Set the time to live (in seconds) for one or more fields, belonging to a certain key. + * + * @param key the key of the fields. + * @param seconds the seconds type: long. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Boolean hexpire(K key, long seconds, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key. + * + * @param key the key. + * @param seconds the TTL {@link Duration} + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Boolean hexpire(K key, Duration seconds, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key. + * + * @param key the key. + * @param seconds the TTL {@link Duration} + * @param expireArgs the {@link ExpireArgs}. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set. + * @since 7.0 + */ + Boolean hexpire(K key, Duration seconds, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Boolean hexpireat(K key, long timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Boolean hexpireat(K key, long timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Boolean hexpireat(K key, Date timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Boolean hexpireat(K key, Date timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Boolean hexpireat(K key, Instant timestamp, K... fields); + + /** + * Set the time to live for one or more fields, belonging to a certain key as a UNIX timestamp. + * + * @param key the key. + * @param timestamp the timestamp type: posix time. + * @param expireArgs the expire arguments. + * @param fields one or more fields to set the TTL for. + * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not + * exist or the timeout could not be set (see: {@code EXPIRE}). + * @since 7.0 + */ + Boolean hexpireat(K key, Instant timestamp, ExpireArgs expireArgs, K... fields); + + /** + * Get the time to live for one or more fields in as unix timestamp in seconds. + * + * @param key the key. + * @param fields one or more fields to get the TTL for. + * @return Long integer-reply in seconds, or a negative value in order to signal an error. The command returns {@code -1} if + * the key exists but has no associated expiration time. The command returns {@code -2} if the key does not exist. + * @since 7.0 + */ + Long hexpiretime(K key, K... fields); + + /** + * Remove the expiration from one or more fields. + * + * @param key the key. + * @param fields one or more fields to remove the TTL for. + * @return Boolean integer-reply specifically: + * + * {@code true} if the timeout was removed. {@code false} if {@code key} does not exist or does not have an + * associated timeout. + */ + Boolean hpersist(K key, K... fields); } diff --git a/src/main/templates/io/lettuce/core/api/RedisKeyCommands.java b/src/main/templates/io/lettuce/core/api/RedisKeyCommands.java index 6f8ba3c27b..bdd3568991 100644 --- a/src/main/templates/io/lettuce/core/api/RedisKeyCommands.java +++ b/src/main/templates/io/lettuce/core/api/RedisKeyCommands.java @@ -138,56 +138,6 @@ public interface RedisKeyCommands { */ Boolean expire(K key, Duration seconds, ExpireArgs expireArgs); - /** - * Set the time to live (in seconds) for a {@link List} of fields, belonging to a certain key. - * - * @param key the key of the fields. - * @param seconds the seconds type: long. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Boolean hexpire(K key, long seconds, List fields); - - /** - * Set the time to live (in seconds) for a {@link List} of fields, belonging to a certain key. - * - * @param key the key of the fields. - * @param seconds the seconds type: long. - * @param expireArgs the expire arguments. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Boolean hexpire(K key, long seconds, ExpireArgs expireArgs, List fields); - - /** - * Set the time to live for a {@link List} of fields, belonging to a certain key. - * - * @param key the key. - * @param seconds the TTL {@link Duration} - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Boolean hexpire(K key, Duration seconds, List fields); - - /** - * Set the time to live for a {@link List} of fields, belonging to a certain key. - * - * @param key the key. - * @param seconds the TTL {@link Duration} - * @param expireArgs the {@link ExpireArgs}. - * @param fields a {@link List} of fields to set the TTL for. - * @return Boolean integer-reply specifically: {@code true} if the timeout was set. {@code false} if {@code key} does not - * exist or the timeout could not be set. - * @since 7.0 - */ - Boolean hexpire(K key, Duration seconds, ExpireArgs expireArgs, List fields); - /** * Set the expiration for a key as a UNIX timestamp. * diff --git a/src/test/java/io/lettuce/core/RedisCommandBuilderUnitTests.java b/src/test/java/io/lettuce/core/RedisCommandBuilderUnitTests.java index 2136ff0a92..01b5be2241 100644 --- a/src/test/java/io/lettuce/core/RedisCommandBuilderUnitTests.java +++ b/src/test/java/io/lettuce/core/RedisCommandBuilderUnitTests.java @@ -1,17 +1,14 @@ package io.lettuce.core; -import static org.assertj.core.api.Assertions.*; - -import java.nio.charset.StandardCharsets; -import java.util.Collections; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.EmptyByteBuf; -import org.junit.jupiter.api.Test; - import io.lettuce.core.codec.StringCodec; import io.lettuce.core.protocol.Command; +import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; +import org.junit.jupiter.api.Test; + +import java.nio.charset.StandardCharsets; + +import static org.assertj.core.api.Assertions.assertThat; /** * Unit tests for {@link RedisCommandBuilder}. @@ -20,7 +17,10 @@ */ class RedisCommandBuilderUnitTests { public static final String MY_KEY = "hKey"; - public static final String MY_FIELD = "hField"; + public static final String MY_FIELD1 = "hField1"; + public static final String MY_FIELD2 = "hField2"; + public static final String MY_FIELD3 = "hField3"; + RedisCommandBuilder sut = new RedisCommandBuilder<>(StringCodec.UTF8); @@ -37,11 +37,50 @@ void shouldCorrectlyConstructXreadgroup() { @Test void shouldCorrectlyConstructHexpire() { - Command command = sut.hexpire(MY_KEY, 1, ExpireArgs.Builder.nx(), Collections.singletonList(MY_FIELD)); + Command command = + sut.hexpire(MY_KEY, 1, ExpireArgs.Builder.nx(), MY_FIELD1, MY_FIELD2, MY_FIELD3); + ByteBuf buf = Unpooled.directBuffer(); + command.encode(buf); + + assertThat(buf.toString(StandardCharsets.UTF_8)).isEqualTo("*8\r\n" + "$7\r\n" + "HEXPIRE\r\n" + "$4\r\n" + + "hKey\r\n" + "$1\r\n" + "1\r\n" + "$2\r\n" + "NX\r\n" + "$1\r\n" + "3\r\n" + "$7\r\n" + "hField1\r\n" + + "$7\r\n" + "hField2\r\n" + "$7\r\n" + "hField3\r\n"); + } + + @Test + void shouldCorrectlyConstructHexpireat() { + + Command command = + sut.hexpireat(MY_KEY, 1, ExpireArgs.Builder.nx(), MY_FIELD1, MY_FIELD2, MY_FIELD3); + ByteBuf buf = Unpooled.directBuffer(); + command.encode(buf); + + assertThat(buf.toString(StandardCharsets.UTF_8)).isEqualTo("*8\r\n" + "$9\r\n" + "HEXPIREAT\r\n" + "$4\r\n" + + "hKey\r\n" + "$1\r\n" + "1\r\n" + "$2\r\n" + "NX\r\n" + "$1\r\n" + "3\r\n" + "$7\r\n" + "hField1\r\n" + + "$7\r\n" + "hField2\r\n" + "$7\r\n" + "hField3\r\n"); + } + + @Test + void shouldCorrectlyConstructHexpiretime() { + + Command command = sut.hexpiretime(MY_KEY, MY_FIELD1, MY_FIELD2, MY_FIELD3); + ByteBuf buf = Unpooled.directBuffer(); + command.encode(buf); + + assertThat(buf.toString(StandardCharsets.UTF_8)).isEqualTo("*6\r\n" + "$11\r\n" + "HEXPIRETIME\r\n" + "$4\r\n" + + "hKey\r\n" + "$1\r\n" + "3\r\n" + "$7\r\n" + "hField1\r\n" + "$7\r\n" + "hField2\r\n" + "$7\r\n" + + "hField3\r\n"); + } + + @Test + void shouldCorrectlyConstructHpersist() { + + Command command = sut.hpersist(MY_KEY, MY_FIELD1, MY_FIELD2, MY_FIELD3); ByteBuf buf = Unpooled.directBuffer(); command.encode(buf); - assertThat(buf.toString(StandardCharsets.UTF_8)).isEqualTo("*6\r\n" + "$7\r\n" + "HEXPIRE\r\n" + "$4\r\n" + "hKey\r\n" - + "$1\r\n" + "1\r\n" + "$2\r\n" + "NX\r\n" + "$1\r\n" + "1\r\n" + "$6\r\n" + "hField\r\n"); + assertThat(buf.toString(StandardCharsets.UTF_8)).isEqualTo("*6\r\n" + "$8\r\n" + "HPERSIST\r\n" + "$4\r\n" + + "hKey\r\n" + "$1\r\n" + "3\r\n" + "$7\r\n" + "hField1\r\n" + "$7\r\n" + "hField2\r\n" + "$7\r\n" + + "hField3\r\n"); } } diff --git a/src/test/java/io/lettuce/core/commands/HashCommandIntegrationTests.java b/src/test/java/io/lettuce/core/commands/HashCommandIntegrationTests.java index e346b29128..0ae5c8e820 100644 --- a/src/test/java/io/lettuce/core/commands/HashCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/commands/HashCommandIntegrationTests.java @@ -19,24 +19,9 @@ */ package io.lettuce.core.commands; -import static org.assertj.core.api.Assertions.*; - -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.inject.Inject; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; -import org.junit.jupiter.api.extension.ExtendWith; - -import io.lettuce.core.KeyValue; +import io.lettuce.core.ExpireArgs; import io.lettuce.core.KeyScanCursor; +import io.lettuce.core.KeyValue; import io.lettuce.core.MapScanCursor; import io.lettuce.core.ScanArgs; import io.lettuce.core.ScanCursor; @@ -47,6 +32,25 @@ import io.lettuce.test.LettuceExtension; import io.lettuce.test.ListStreamingAdapter; import io.lettuce.test.condition.EnabledOnCommand; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.extension.ExtendWith; + +import javax.inject.Inject; +import java.time.Duration; +import java.time.Instant; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.offset; +import static org.awaitility.Awaitility.await; /** * Integration tests for {@link io.lettuce.core.api.sync.RedisHashCommands}. @@ -58,6 +62,9 @@ @ExtendWith(LettuceExtension.class) @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class HashCommandIntegrationTests extends TestSupport { + public static final String MY_KEY = "hKey"; + public static final String MY_FIELD = "hField"; + public static final String MY_VALUE = "hValue"; private final RedisCommands redis; @@ -541,6 +548,82 @@ void hscanNoValuesMatch() { assertThat(cursor.getKeys()).hasSize(11); } + @Test + @EnabledOnCommand("HEXPIRE") + void hexpire() { + assertThat(redis.hset(MY_KEY, MY_FIELD, MY_VALUE)).isTrue(); + // the below settings are required until the solution is able to support listpack entries + // see TODOs in https://github.com/redis/redis/pull/13172 for more details + assertThat(redis.configSet("hash-max-listpack-entries","0")).isEqualTo("OK"); + assertThat(redis.configSet("set-max-listpack-value","0")).isEqualTo("OK"); + + assertThat(redis.hexpire(MY_KEY, 1, MY_FIELD)).isTrue(); + + await().until(() -> redis.hget(MY_KEY, MY_FIELD) == null); + } + + @Test + @EnabledOnCommand("HEXPIRE") + void hexpireExpireArgs() { + assertThat(redis.hset(MY_KEY, MY_FIELD, MY_VALUE)).isTrue(); + // the below settings are required until the solution is able to support listpack entries + // see TODOs in https://github.com/redis/redis/pull/13172 for more details + assertThat(redis.configSet("hash-max-listpack-entries","0")).isEqualTo("OK"); + assertThat(redis.configSet("set-max-listpack-value","0")).isEqualTo("OK"); + + assertThat(redis.hexpire(MY_KEY, Duration.ofSeconds(1), ExpireArgs.Builder.nx(), MY_FIELD)).isTrue(); + assertThat(redis.hexpire(MY_KEY, Duration.ofSeconds(1), ExpireArgs.Builder.xx(), MY_FIELD)).isTrue(); + assertThat(redis.hexpire(MY_KEY, Duration.ofSeconds(10), ExpireArgs.Builder.gt(), MY_FIELD)).isTrue(); + assertThat(redis.hexpire(MY_KEY, Duration.ofSeconds(1), ExpireArgs.Builder.lt(), MY_FIELD)).isTrue(); + + await().until(() -> redis.hget(MY_KEY, MY_FIELD) == null); + } + + @Test + @EnabledOnCommand("HEXPIREAT") + void hexpireat() { + // the below settings are required until the solution is able to support listpack entries + // see TODOs in https://github.com/redis/redis/pull/13172 for more details + assertThat(redis.configSet("hash-max-listpack-entries","0")).isEqualTo("OK"); + assertThat(redis.configSet("set-max-listpack-value","0")).isEqualTo("OK"); + + assertThat(redis.hset(MY_KEY, MY_FIELD, MY_VALUE)).isTrue(); + + assertThat(redis.hexpireat(MY_KEY,Instant.now().plusSeconds(1) , MY_FIELD)).isTrue(); + + await().until(() -> redis.hget(MY_KEY, MY_FIELD) == null); + } + + @Test + @EnabledOnCommand("HEXPIRETIME") + void hexpiretime() { + Date expiration = new Date(System.currentTimeMillis() + 10000); + // the below settings are required until the solution is able to support listpack entries + // see TODOs in https://github.com/redis/redis/pull/13172 for more details + assertThat(redis.configSet("hash-max-listpack-entries","0")).isEqualTo("OK"); + assertThat(redis.configSet("set-max-listpack-value","0")).isEqualTo("OK"); + + assertThat(redis.hset(MY_KEY, MY_FIELD, MY_VALUE)).isTrue(); + assertThat(redis.hexpireat(MY_KEY, expiration, MY_FIELD)).isTrue(); + + assertThat(redis.hexpiretime(MY_KEY, MY_FIELD)).isEqualTo(expiration.getTime() / 1000); + } + + @Test + @EnabledOnCommand("HPERSIST") + void persist() { + // the below settings are required until the solution is able to support listpack entries + // see TODOs in https://github.com/redis/redis/pull/13172 for more details + assertThat(redis.configSet("hash-max-listpack-entries","0")).isEqualTo("OK"); + assertThat(redis.configSet("set-max-listpack-value","0")).isEqualTo("OK"); + + assertThat(redis.hpersist(MY_KEY, MY_FIELD)).isFalse(); + assertThat(redis.hset(MY_KEY, MY_FIELD, MY_VALUE)).isTrue(); + assertThat(redis.hpersist(MY_KEY, MY_FIELD)).isFalse(); + assertThat(redis.hexpire(MY_KEY, 1, MY_FIELD)).isTrue(); + assertThat(redis.hpersist(MY_KEY, MY_FIELD)).isTrue(); + } + void setup100KeyValues(Map expect) { for (int i = 0; i < 100; i++) { expect.put(key + i, value + 1); diff --git a/src/test/java/io/lettuce/core/commands/KeyCommandIntegrationTests.java b/src/test/java/io/lettuce/core/commands/KeyCommandIntegrationTests.java index 6a67e9706e..2188595fc1 100644 --- a/src/test/java/io/lettuce/core/commands/KeyCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/commands/KeyCommandIntegrationTests.java @@ -19,20 +19,6 @@ */ package io.lettuce.core.commands; -import static org.assertj.core.api.Assertions.*; -import static org.awaitility.Awaitility.await; - -import java.time.Duration; -import java.time.Instant; -import java.util.*; - -import javax.inject.Inject; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; -import org.junit.jupiter.api.extension.ExtendWith; - import io.lettuce.core.CopyArgs; import io.lettuce.core.ExpireArgs; import io.lettuce.core.KeyScanArgs; @@ -46,6 +32,23 @@ import io.lettuce.test.LettuceExtension; import io.lettuce.test.ListStreamingAdapter; import io.lettuce.test.condition.EnabledOnCommand; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.extension.ExtendWith; + +import javax.inject.Inject; +import java.time.Duration; +import java.time.Instant; +import java.util.Date; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Integration tests for {@link io.lettuce.core.api.sync.RedisKeyCommands}. @@ -58,12 +61,6 @@ @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class KeyCommandIntegrationTests extends TestSupport { - public static final String MY_KEY = "hKey"; - - public static final String MY_FIELD = "hField"; - - public static final String MY_VALUE = "hValue"; - private final RedisCommands redis; @Inject @@ -194,49 +191,6 @@ void expiretime() { assertThat(redis.expiretime(key)).isEqualTo(expiration.getTime() / 1000); } - @Test - @EnabledOnCommand("HEXPIRE") - void hexpire() { - assertThat(redis.hset(MY_KEY, MY_FIELD, MY_VALUE)).isTrue(); - // the below settings are required until the solution is able to support listpack entries - // see TODOs in https://github.com/redis/redis/pull/13172 for more details - assertThat(redis.configSet("hash-max-listpack-entries","0")).isEqualTo("OK"); - assertThat(redis.configSet("set-max-listpack-value","0")).isEqualTo("OK"); - - assertThat(redis.hexpire(MY_KEY, 1, Collections.singletonList(MY_FIELD))).isTrue(); - - await().until(() -> redis.hget(MY_KEY, MY_FIELD) == null); - } - - @Test - @EnabledOnCommand("HEXPIRE") - void hexpireExpireArgs() { - assertThat(redis.hset(MY_KEY, MY_FIELD, MY_VALUE)).isTrue(); - // the below settings are required until the solution is able to support listpack entries - // see TODOs in https://github.com/redis/redis/pull/13172 for more details - assertThat(redis.configSet("hash-max-listpack-entries","0")).isEqualTo("OK"); - assertThat(redis.configSet("set-max-listpack-value","0")).isEqualTo("OK"); - - assertThat(redis.hexpire(MY_KEY, - Duration.ofSeconds(1), - ExpireArgs.Builder.nx(), - Collections.singletonList(MY_FIELD))).isTrue(); - assertThat(redis.hexpire(MY_KEY, - Duration.ofSeconds(1), - ExpireArgs.Builder.xx(), - Collections.singletonList(MY_FIELD))).isTrue(); - assertThat(redis.hexpire(MY_KEY, - Duration.ofSeconds(10), - ExpireArgs.Builder.gt(), - Collections.singletonList(MY_FIELD))).isTrue(); - assertThat(redis.hexpire(MY_KEY, - Duration.ofSeconds(1), - ExpireArgs.Builder.lt(), - Collections.singletonList(MY_FIELD))).isTrue(); - - await().until(() -> redis.hget(MY_KEY, MY_FIELD) == null); - } - @Test void keys() { assertThat(redis.keys("*")).isEqualTo(list());