All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.data.redis.connection.ReactiveKeyCommands Maven / Gradle / Ivy

There is a newer version: 3.2.5
Show newest version
/*
 * Copyright 2016-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.redis.connection;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.ByteBuffer;
import java.time.Duration;
import java.time.Instant;
import java.util.Collection;
import java.util.List;

import org.reactivestreams.Publisher;
import org.springframework.data.redis.connection.ReactiveRedisConnection.BooleanResponse;
import org.springframework.data.redis.connection.ReactiveRedisConnection.CommandResponse;
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyCommand;
import org.springframework.data.redis.connection.ReactiveRedisConnection.MultiValueResponse;
import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

/**
 * Redis Key commands executed using reactive infrastructure.
 *
 * @author Christoph Strobl
 * @author Mark Paluch
 * @since 2.0
 */
public interface ReactiveKeyCommands {

	/**
	 * Determine if given {@literal key} exists.
	 *
	 * @param key must not be {@literal null}.
	 * @return
	 * @see Redis Documentation: EXISTS
	 */
	default Mono exists(ByteBuffer key) {

		Assert.notNull(key, "Key must not be null!");

		return exists(Mono.just(new KeyCommand(key))).next().map(BooleanResponse::getOutput);
	}

	/**
	 * Determine if given {@literal key} exists.
	 *
	 * @param keys must not be {@literal null}.
	 * @return
	 * @see Redis Documentation: EXISTS
	 */
	Flux> exists(Publisher keys);

	/**
	 * Determine the type stored at {@literal key}.
	 *
	 * @param key must not be {@literal null}.
	 * @return
	 * @see Redis Documentation: TYPE
	 */
	default Mono type(ByteBuffer key) {

		Assert.notNull(key, "Key must not be null!");

		return type(Mono.just(new KeyCommand(key))).next().map(CommandResponse::getOutput);
	}

	/**
	 * Determine the type stored at {@literal key}.
	 *
	 * @param keys must not be {@literal null}.
	 * @return
	 * @see Redis Documentation: TYPE
	 */
	Flux> type(Publisher keys);

	/**
	 * Alter the last access time of given {@code key(s)}.
	 *
	 * @param keys must not be {@literal null}.
	 * @return {@link Mono} emitting the number of keys touched.
	 * @see Redis Documentation: TOUCH
	 * @since 2.1
	 */
	default Mono touch(Collection keys) {
		return touch(Mono.just(keys)).next().map(NumericResponse::getOutput);
	}

	/**
	 * Alter the last access time of given {@code key(s)}.
	 *
	 * @param keys must not be {@literal null}.
	 * @return
	 * @see Redis Documentation: TOUCH
	 * @since 2.1
	 */
	Flux, Long>> touch(Publisher> keys);

	/**
	 * Find all keys matching the given {@literal pattern}.
* It is recommended to use {@link #scan(ScanOptions)} to iterate over the keyspace as {@link #keys(ByteBuffer)} is a * non-interruptible and expensive Redis operation. * * @param pattern must not be {@literal null}. * @return * @see Redis Documentation: KEYS */ default Mono> keys(ByteBuffer pattern) { Assert.notNull(pattern, "Pattern must not be null!"); return keys(Mono.just(pattern)).next().map(MultiValueResponse::getOutput); } /** * Find all keys matching the given {@literal pattern}.
* It is recommended to use {@link #scan(ScanOptions)} to iterate over the keyspace as {@link #keys(Publisher)} is a * non-interruptible and expensive Redis operation. * * @param patterns must not be {@literal null}. * @return * @see Redis Documentation: KEYS */ Flux> keys(Publisher patterns); /** * Use a {@link Flux} to iterate over keys. The resulting {@link Flux} acts as a cursor and issues {@code SCAN} * commands itself as long as the subscriber signals demand. * * @return never {@literal null}. * @see Redis Documentation: SCAN * @since 2.1 */ default Flux scan() { return scan(ScanOptions.NONE); } /** * Use a {@link Flux} to iterate over keys. The resulting {@link Flux} acts as a cursor and issues {@code SCAN} * commands itself as long as the subscriber signals demand. * * @param options must not be {@literal null}. * @return the {@link Flux} emitting {@link ByteBuffer keys} one by one. * @throws IllegalArgumentException when options is {@literal null}. * @see Redis Documentation: SCAN * @since 2.1 */ Flux scan(ScanOptions options); /** * Return a random key from the keyspace. * * @return * @see Redis Documentation: RANDOMKEY */ Mono randomKey(); /** * {@code RENAME} command parameters. * * @author Christoph Strobl * @see Redis Documentation: RENAME */ class RenameCommand extends KeyCommand { private @Nullable ByteBuffer newName; private RenameCommand(ByteBuffer key, @Nullable ByteBuffer newName) { super(key); this.newName = newName; } /** * Creates a new {@link RenameCommand} given a {@link ByteBuffer key}. * * @param key must not be {@literal null}. * @return a new {@link RenameCommand} for {@link ByteBuffer key}. */ public static RenameCommand key(ByteBuffer key) { Assert.notNull(key, "Key must not be null!"); return new RenameCommand(key, null); } /** * Applies the {@literal newName}. Constructs a new command instance with all previously configured properties. * * @param newName must not be {@literal null}. * @return a new {@link RenameCommand} with {@literal newName} applied. */ public RenameCommand to(ByteBuffer newName) { Assert.notNull(newName, "New name must not be null!"); return new RenameCommand(getKey(), newName); } /** * @return can be {@literal null}. */ @Nullable public ByteBuffer getNewName() { return newName; } } /** * Rename key {@literal oleName} to {@literal newName}. * * @param key must not be {@literal null}. * @param newName must not be {@literal null}. * @return * @see Redis Documentation: RENAME */ default Mono rename(ByteBuffer key, ByteBuffer newName) { Assert.notNull(key, "Key must not be null!"); return rename(Mono.just(RenameCommand.key(key).to(newName))).next().map(BooleanResponse::getOutput); } /** * Rename key {@literal oleName} to {@literal newName}. * * @param command must not be {@literal null}. * @return * @see Redis Documentation: RENAME */ Flux> rename(Publisher command); /** * Rename key {@literal oleName} to {@literal newName} only if {@literal newName} does not exist. * * @param key must not be {@literal null}. * @param newName must not be {@literal null}. * @return * @see Redis Documentation: RENAMENX */ default Mono renameNX(ByteBuffer key, ByteBuffer newName) { Assert.notNull(key, "Key must not be null!"); return renameNX(Mono.just(RenameCommand.key(key).to(newName))).next().map(BooleanResponse::getOutput); } /** * Rename key {@literal oleName} to {@literal newName} only if {@literal newName} does not exist. * * @param command must not be {@literal null}. * @return * @see Redis Documentation: RENAMENX */ Flux> renameNX(Publisher command); /** * Delete {@literal key}. * * @param key must not be {@literal null}. * @return * @see Redis Documentation: DEL */ default Mono del(ByteBuffer key) { Assert.notNull(key, "Key must not be null!"); return del(Mono.just(new KeyCommand(key))).next().map(NumericResponse::getOutput); } /** * Delete {@literal keys} one by one. * * @param keys must not be {@literal null}. * @return {@link Flux} of {@link NumericResponse} holding the {@literal key} removed along with the deletion result. * @see Redis Documentation: DEL */ Flux> del(Publisher keys); /** * Delete multiple {@literal keys} one in one batch. * * @param keys must not be {@literal null}. * @return * @see Redis Documentation: DEL */ default Mono mDel(List keys) { Assert.notEmpty(keys, "Keys must not be empty or null!"); return mDel(Mono.just(keys)).next().map(NumericResponse::getOutput); } /** * Delete multiple {@literal keys} in batches. * * @param keys must not be {@literal null}. * @return {@link Flux} of {@link NumericResponse} holding the {@literal keys} removed along with the deletion result. * @see Redis Documentation: DEL */ Flux, Long>> mDel(Publisher> keys); /** * Unlink the {@code key} from the keyspace. Unlike with {@link #del(ByteBuffer)} the actual memory reclaiming here * happens asynchronously. * * @param key must not be {@literal null}. * @return * @see Redis Documentation: UNLINK * @since 2.1 */ default Mono unlink(ByteBuffer key) { Assert.notNull(key, "Keys must not be null!"); return unlink(Mono.just(key).map(KeyCommand::new)).next().map(NumericResponse::getOutput); } /** * Unlink the {@code key} from the keyspace. Unlike with {@link #del(ByteBuffer)} the actual memory reclaiming here * happens asynchronously. * * @param keys must not be {@literal null}. * @return {@link Flux} of {@link NumericResponse} holding the {@literal key} removed along with the unlink result. * @see Redis Documentation: UNLINK * @since 2.1 */ Flux> unlink(Publisher keys); /** * Unlink the {@code keys} from the keyspace. Unlike with {@link #mDel(List)} the actual memory reclaiming here * happens asynchronously. * * @param keys must not be {@literal null}. * @return * @see Redis Documentation: UNLINK * @since 2.1 */ default Mono mUnlink(List keys) { Assert.notNull(keys, "Keys must not be null!"); return mUnlink(Mono.just(keys)).next().map(NumericResponse::getOutput); } /** * Unlink the {@code keys} from the keyspace. Unlike with {@link #mDel(Publisher)} the actual memory reclaiming here * happens asynchronously. * * @param keys must not be {@literal null}. * @return {@link Flux} of {@link NumericResponse} holding the {@literal key} removed along with the deletion result. * @see Redis Documentation: UNLINK * @since 2.1 */ Flux, Long>> mUnlink(Publisher> keys); /** * {@code EXPIRE}/{@code PEXPIRE} command parameters. * * @author Mark Paluch * @see Redis Documentation: EXPIRE * @see Redis Documentation: PEXPIRE */ class ExpireCommand extends KeyCommand { private @Nullable Duration timeout; private ExpireCommand(ByteBuffer key, @Nullable Duration timeout) { super(key); this.timeout = timeout; } /** * Creates a new {@link ExpireCommand} given a {@link ByteBuffer key}. * * @param key must not be {@literal null}. * @return a new {@link ExpireCommand} for {@link ByteBuffer key}. */ public static ExpireCommand key(ByteBuffer key) { Assert.notNull(key, "Key must not be null!"); return new ExpireCommand(key, null); } /** * Applies the {@literal timeout}. Constructs a new command instance with all previously configured properties. * * @param timeout must not be {@literal null}. * @return a new {@link ExpireCommand} with {@literal timeout} applied. */ public ExpireCommand timeout(Duration timeout) { Assert.notNull(timeout, "Timeout must not be null!"); return new ExpireCommand(getKey(), timeout); } /** * @return can be {@literal null}. */ @Nullable public Duration getTimeout() { return timeout; } } /** * Set time to live for given {@code key} in seconds. * * @param key must not be {@literal null}. * @param timeout must not be {@literal null}. * @return * @see Redis Documentation: EXPIRE */ default Mono expire(ByteBuffer key, Duration timeout) { Assert.notNull(key, "Key must not be null!"); Assert.notNull(timeout, "Timeout must not be null!"); return expire(Mono.just(new ExpireCommand(key, timeout))).next().map(BooleanResponse::getOutput); } /** * Expire {@literal keys} one by one. * * @param commands must not be {@literal null}. * @return {@link Flux} of {@link BooleanResponse} holding the {@literal key} removed along with the expiration * result. * @see Redis Documentation: EXPIRE */ Flux> expire(Publisher commands); /** * Set time to live for given {@code key} in milliseconds. * * @param key must not be {@literal null}. * @param timeout must not be {@literal null}. * @return * @see Redis Documentation: PEXPIRE */ default Mono pExpire(ByteBuffer key, Duration timeout) { Assert.notNull(key, "Key must not be null!"); Assert.notNull(timeout, "Timeout must not be null!"); return expire(Mono.just(new ExpireCommand(key, timeout))).next().map(BooleanResponse::getOutput); } /** * Expire {@literal keys} one by one. * * @param commands must not be {@literal null}. * @return {@link Flux} of {@link BooleanResponse} holding the {@literal key} removed along with the expiration * result. * @see Redis Documentation: PEXPIRE */ Flux> pExpire(Publisher commands); /** * {@code EXPIREAT}/{@code PEXPIREAT} command parameters. * * @author Mark Paluch * @see Redis Documentation: EXPIREAT * @see Redis Documentation: PEXPIREAT */ class ExpireAtCommand extends KeyCommand { private @Nullable Instant expireAt; private ExpireAtCommand(ByteBuffer key, @Nullable Instant expireAt) { super(key); this.expireAt = expireAt; } /** * Creates a new {@link ExpireAtCommand} given a {@link ByteBuffer key}. * * @param key must not be {@literal null}. * @return a new {@link ExpireCommand} for {@link ByteBuffer key}. */ public static ExpireAtCommand key(ByteBuffer key) { Assert.notNull(key, "Key must not be null!"); return new ExpireAtCommand(key, null); } /** * Applies the {@literal expireAt}. Constructs a new command instance with all previously configured properties. * * @param expireAt must not be {@literal null}. * @return a new {@link ExpireAtCommand} with {@literal expireAt} applied. */ public ExpireAtCommand timeout(Instant expireAt) { Assert.notNull(expireAt, "Expire at must not be null!"); return new ExpireAtCommand(getKey(), expireAt); } /** * @return can be {@literal null}. */ @Nullable public Instant getExpireAt() { return expireAt; } } /** * Set the expiration for given {@code key} as a {@literal UNIX} timestamp. * * @param key must not be {@literal null}. * @param expireAt must not be {@literal null}. * @return * @see Redis Documentation: EXPIREAT */ default Mono expireAt(ByteBuffer key, Instant expireAt) { Assert.notNull(key, "Key must not be null!"); Assert.notNull(expireAt, "Expire at must not be null!"); return expireAt(Mono.just(new ExpireAtCommand(key, expireAt))).next().map(BooleanResponse::getOutput); } /** * Set one-by-one the expiration for given {@code key} as a {@literal UNIX} timestamp. * * @param commands must not be {@literal null}. * @return {@link Flux} of {@link BooleanResponse} holding the {@literal key} removed along with the expiration * result. * @see Redis Documentation: EXPIREAT */ Flux> expireAt(Publisher commands); /** * Set the expiration for given {@code key} as a {@literal UNIX} timestamp. * * @param key must not be {@literal null}. * @param expireAt must not be {@literal null}. * @return * @see Redis Documentation: PEXPIREAT */ default Mono pExpireAt(ByteBuffer key, Instant expireAt) { Assert.notNull(key, "Key must not be null!"); Assert.notNull(expireAt, "Expire at must not be null!"); return pExpireAt(Mono.just(new ExpireAtCommand(key, expireAt))).next().map(BooleanResponse::getOutput); } /** * Set one-by-one the expiration for given {@code key} as a {@literal UNIX} timestamp in milliseconds. * * @param commands must not be {@literal null}. * @return {@link Flux} of {@link BooleanResponse} holding the {@literal key} removed along with the expiration * result. * @see Redis Documentation: PEXPIREAT */ Flux> pExpireAt(Publisher commands); /** * Remove the expiration from given {@code key}. * * @param key must not be {@literal null}. * @return * @see Redis Documentation: PERSIST */ default Mono persist(ByteBuffer key) { Assert.notNull(key, "Key must not be null!"); return persist(Mono.just(new KeyCommand(key))).next().map(BooleanResponse::getOutput); } /** * Remove one-by-one the expiration from given {@code key}. * * @param commands must not be {@literal null}. * @return {@link Flux} of {@link BooleanResponse} holding the {@literal key} persisted along with the persist result. * @see Redis Documentation: PERSIST */ Flux> persist(Publisher commands); /** * Get the time to live for {@code key} in seconds. * * @param key must not be {@literal null}. * @return * @see Redis Documentation: TTL */ default Mono ttl(ByteBuffer key) { Assert.notNull(key, "Key must not be null!"); return ttl(Mono.just(new KeyCommand(key))).next().map(NumericResponse::getOutput); } /** * Get one-by-one the time to live for keys. * * @param commands must not be {@literal null}. * @return {@link Flux} of {@link NumericResponse} holding the {@literal key} along with the time to live result. * @see Redis Documentation: TTL */ Flux> ttl(Publisher commands); /** * Get the time to live for {@code key} in milliseconds. * * @param key must not be {@literal null}. * @return * @see Redis Documentation: TTL */ default Mono pTtl(ByteBuffer key) { Assert.notNull(key, "Key must not be null!"); return pTtl(Mono.just(new KeyCommand(key))).next().map(NumericResponse::getOutput); } /** * Get one-by-one the time to live for keys. * * @param commands must not be {@literal null}. * @return {@link Flux} of {@link NumericResponse} holding the {@literal key} along with the time to live result. * @see Redis Documentation: PTTL */ Flux> pTtl(Publisher commands); /** * {@code MOVE} command parameters. * * @author Mark Paluch * @see Redis Documentation: MOVE */ class MoveCommand extends KeyCommand { private @Nullable Integer database; private MoveCommand(ByteBuffer key, @Nullable Integer database) { super(key); this.database = database; } /** * Creates a new {@link MoveCommand} given a {@link ByteBuffer key}. * * @param key must not be {@literal null}. * @return a new {@link ExpireCommand} for {@link ByteBuffer key}. */ public static MoveCommand key(ByteBuffer key) { Assert.notNull(key, "Key must not be null!"); return new MoveCommand(key, null); } /** * Applies the {@literal database} index. Constructs a new command instance with all previously configured * properties. * * @param database * @return a new {@link MoveCommand} with {@literal database} applied. */ public MoveCommand timeout(int database) { return new MoveCommand(getKey(), database); } /** * @return can be {@literal null}. */ @Nullable public Integer getDatabase() { return database; } } /** * Move given {@code key} to database with {@code index}. * * @param key must not be {@literal null}. * @return * @see Redis Documentation: MOVE */ default Mono move(ByteBuffer key, int database) { Assert.notNull(key, "Key must not be null!"); return move(Mono.just(new MoveCommand(key, database))).next().map(BooleanResponse::getOutput); } /** * Move keys one-by-one between databases. * * @param commands must not be {@literal null}. * @return {@link Flux} of {@link BooleanResponse} holding the {@literal key} to move along with the move result. * @see Redis Documentation: MOVE */ Flux> move(Publisher commands); /** * Get the type of internal representation used for storing the value at the given {@code key}. * * @param key must not be {@literal null}. * @return the {@link Mono} emitting {@link org.springframework.data.redis.connection.ValueEncoding}. * @throws IllegalArgumentException if {@code key} is {@literal null}. * @see Redis Documentation: OBJECT ENCODING * @since 2.1 */ Mono encodingOf(ByteBuffer key); /** * Get the {@link Duration} since the object stored at the given {@code key} is idle. * * @param key must not be {@literal null}. * @return the {@link Mono} emitting the idletime of the key of {@link Mono#empty()} if the key does not exist. * @throws IllegalArgumentException if {@code key} is {@literal null}. * @see Redis Documentation: OBJECT IDLETIME * @since 2.1 */ Mono idletime(ByteBuffer key); /** * Get the number of references of the value associated with the specified {@code key}. * * @param key must not be {@literal null}. * @return {@link Mono#empty()} if key does not exist. * @throws IllegalArgumentException if {@code key} is {@literal null}. * @see Redis Documentation: OBJECT REFCOUNT * @since 2.1 */ Mono refcount(ByteBuffer key); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy