Replace Bound…Operations implementation with a proxy factory.
Original Pull Request: #2276
This commit is contained in:
committed by
Christoph Strobl
parent
33e8974578
commit
f5af2cf468
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor;
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.data.redis.connection.stream.ReadOffset;
|
||||
import org.springframework.data.redis.connection.stream.StreamOffset;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Utility to create implementation objects for {@code Bound…Operations} so that bound key interfaces can be implemented
|
||||
* automatically by translating interface calls to actual {@code …Operations} interfaces.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 3.0
|
||||
*/
|
||||
class BoundOperationsProxyFactory {
|
||||
|
||||
private final Map<Method, Method> targetMethodCache = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Create a proxy object that implements {@link Class boundOperationsInterface} using the given {@code key} and
|
||||
* {@link DataType}. Calls to {@code Bound…Operations} methods are bridged by forwarding these either to the
|
||||
* {@code operationsTarget} or a default implementation.
|
||||
*
|
||||
* @param boundOperationsInterface the {@code Bound…Operations} interface.
|
||||
* @param key the bound key.
|
||||
* @param type the {@link DataType} for which to create a proxy object.
|
||||
* @param operations the {@link RedisOperations} instance.
|
||||
* @param operationsTargetFunction function to extract the actual delegate for method calls.
|
||||
* @param <T>
|
||||
* @return the proxy object.
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public <T> T createProxy(Class<T> boundOperationsInterface, Object key, DataType type,
|
||||
RedisOperations<?, ?> operations, Function<RedisOperations<?, ?>, Object> operationsTargetFunction) {
|
||||
|
||||
DefaultBoundKeyOperations delegate = new DefaultBoundKeyOperations(type, key, (RedisOperations) operations);
|
||||
Object operationsTarget = operationsTargetFunction.apply(operations);
|
||||
|
||||
ProxyFactory proxyFactory = new ProxyFactory();
|
||||
proxyFactory.addInterface(boundOperationsInterface);
|
||||
proxyFactory.addAdvice(new DefaultMethodInvokingMethodInterceptor());
|
||||
proxyFactory.addAdvice(
|
||||
new BoundOperationsMethodInterceptor(key, operations, boundOperationsInterface, operationsTarget, delegate));
|
||||
|
||||
return (T) proxyFactory.getProxy();
|
||||
}
|
||||
|
||||
Method lookupRequiredMethod(Method method, Class<?> targetClass, boolean considerKeyArgument) {
|
||||
|
||||
Method target = lookupMethod(method, targetClass, considerKeyArgument);
|
||||
|
||||
if (target == null) {
|
||||
throw new IllegalArgumentException("Cannot lookup target method for %s in class %s. This appears to be a bug."
|
||||
.formatted(method, targetClass.getName()));
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Method lookupMethod(Method method, Class<?> targetClass, boolean considerKeyArgument) {
|
||||
|
||||
return targetMethodCache.computeIfAbsent(method, it -> {
|
||||
|
||||
Class[] paramTypes;
|
||||
|
||||
if (isStreamRead(method)) {
|
||||
paramTypes = new Class[it.getParameterCount()];
|
||||
System.arraycopy(it.getParameterTypes(), 0, paramTypes, 0, paramTypes.length - 1);
|
||||
paramTypes[paramTypes.length - 1] = StreamOffset[].class;
|
||||
} else if (considerKeyArgument) {
|
||||
|
||||
paramTypes = new Class[it.getParameterCount() + 1];
|
||||
paramTypes[0] = Object.class;
|
||||
System.arraycopy(it.getParameterTypes(), 0, paramTypes, 1, paramTypes.length - 1);
|
||||
} else {
|
||||
paramTypes = it.getParameterTypes();
|
||||
}
|
||||
|
||||
return ReflectionUtils.findMethod(targetClass, method.getName(), paramTypes);
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isStreamRead(Method method) {
|
||||
return method.getName().equals("read")
|
||||
&& method.getParameterTypes()[method.getParameterCount() - 1].equals(ReadOffset.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link MethodInterceptor} to delegate proxy calls to either {@link RedisOperations}, {@code key},
|
||||
* {@link DefaultBoundKeyOperations} or the {@code operationsTarget} such as {@link ValueOperations}.
|
||||
*/
|
||||
class BoundOperationsMethodInterceptor implements MethodInterceptor {
|
||||
|
||||
private final Class<?> boundOperationsInterface;
|
||||
private final Object operationsTarget;
|
||||
private final DefaultBoundKeyOperations delegate;
|
||||
|
||||
public BoundOperationsMethodInterceptor(Object key, RedisOperations<?, ?> operations,
|
||||
Class<?> boundOperationsInterface, Object operationsTarget, DefaultBoundKeyOperations delegate) {
|
||||
|
||||
this.boundOperationsInterface = boundOperationsInterface;
|
||||
this.operationsTarget = operationsTarget;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
|
||||
Method method = invocation.getMethod();
|
||||
|
||||
switch (method.getName()) {
|
||||
case "getKey":
|
||||
return delegate.getKey();
|
||||
|
||||
case "rename":
|
||||
delegate.rename(invocation.getArguments()[0]);
|
||||
return null;
|
||||
|
||||
case "getOperations":
|
||||
return delegate.getOps();
|
||||
}
|
||||
|
||||
if (method.getDeclaringClass() == boundOperationsInterface) {
|
||||
return doInvoke(invocation, method, operationsTarget, true);
|
||||
}
|
||||
|
||||
return doInvoke(invocation, method, delegate, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object doInvoke(MethodInvocation invocation, Method method, Object target, boolean considerKeyArgument) {
|
||||
|
||||
Method backingMethod = lookupRequiredMethod(method, target.getClass(), considerKeyArgument);
|
||||
|
||||
Object[] args;
|
||||
Object[] invocationArguments = invocation.getArguments();
|
||||
|
||||
if (isStreamRead(method)) {
|
||||
// stream.read requires translation to StreamOffset using the bound key.
|
||||
args = new Object[backingMethod.getParameterCount()];
|
||||
System.arraycopy(invocationArguments, 0, args, 0, args.length - 1);
|
||||
args[args.length - 1] = new StreamOffset[] {
|
||||
StreamOffset.create(delegate.getKey(), (ReadOffset) invocationArguments[invocationArguments.length - 1]) };
|
||||
} else if (backingMethod.getParameterCount() > 0 && backingMethod.getParameterTypes()[0].equals(Object.class)) {
|
||||
|
||||
args = new Object[backingMethod.getParameterCount()];
|
||||
args[0] = delegate.getKey();
|
||||
System.arraycopy(invocationArguments, 0, args, 1, args.length - 1);
|
||||
} else {
|
||||
args = invocationArguments;
|
||||
}
|
||||
|
||||
try {
|
||||
return backingMethod.invoke(target, args);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
ReflectionUtils.handleReflectionException(e);
|
||||
throw new UnsupportedOperationException("Should not happen", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default {@link BoundKeyOperations} implementation. Meant for internal usage.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
static class DefaultBoundKeyOperations implements BoundKeyOperations<Object> {
|
||||
|
||||
private final DataType type;
|
||||
private Object key;
|
||||
private final RedisOperations<Object, ?> ops;
|
||||
|
||||
DefaultBoundKeyOperations(DataType type, Object key, RedisOperations<Object, ?> operations) {
|
||||
this.type = type;
|
||||
|
||||
this.key = key;
|
||||
this.ops = operations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean expire(long timeout, TimeUnit unit) {
|
||||
return ops.expire(key, timeout, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean expireAt(Date date) {
|
||||
return ops.expireAt(key, date);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getExpire() {
|
||||
return ops.getExpire(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean persist() {
|
||||
return ops.persist(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rename(Object newKey) {
|
||||
if (ops.hasKey(key)) {
|
||||
ops.rename(key, newKey);
|
||||
}
|
||||
key = newKey;
|
||||
}
|
||||
|
||||
public DataType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public RedisOperations<Object, ?> getOps() {
|
||||
return ops;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,9 +182,23 @@ public interface BoundSetOperations<K, V> extends BoundKeyOperations<K> {
|
||||
* @param key must not be {@literal null}.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/commands/sdiff">Redis Documentation: SDIFF</a>
|
||||
* @deprecated since 3.0, use {@link #difference(Object)} instead to follow a consistent method naming scheme.
|
||||
*/
|
||||
@Nullable
|
||||
Set<V> diff(K key);
|
||||
default Set<V> diff(K key) {
|
||||
return difference(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Diff all sets for given the bound key and {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 3.0
|
||||
* @see <a href="https://redis.io/commands/sdiff">Redis Documentation: SDIFF</a>
|
||||
*/
|
||||
@Nullable
|
||||
Set<V> difference(K key);
|
||||
|
||||
/**
|
||||
* Diff all sets for given the bound key and {@code keys}.
|
||||
@@ -192,9 +206,23 @@ public interface BoundSetOperations<K, V> extends BoundKeyOperations<K> {
|
||||
* @param keys must not be {@literal null}.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @see <a href="https://redis.io/commands/sdiff">Redis Documentation: SDIFF</a>
|
||||
* @deprecated since 3.0, use {@link #difference(Collection)} instead to follow a consistent method naming scheme.
|
||||
*/
|
||||
@Nullable
|
||||
Set<V> diff(Collection<K> keys);
|
||||
default Set<V> diff(Collection<K> keys) {
|
||||
return difference(keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Diff all sets for given the bound key and {@code keys}.
|
||||
*
|
||||
* @param keys must not be {@literal null}.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 3.0
|
||||
* @see <a href="https://redis.io/commands/sdiff">Redis Documentation: SDIFF</a>
|
||||
*/
|
||||
@Nullable
|
||||
Set<V> difference(Collection<K> keys);
|
||||
|
||||
/**
|
||||
* Diff all sets for given the bound key and {@code keys} and store result in {@code destKey}.
|
||||
@@ -202,8 +230,23 @@ public interface BoundSetOperations<K, V> extends BoundKeyOperations<K> {
|
||||
* @param keys must not be {@literal null}.
|
||||
* @param destKey must not be {@literal null}.
|
||||
* @see <a href="https://redis.io/commands/sdiffstore">Redis Documentation: SDIFFSTORE</a>
|
||||
* @deprecated since 3.0, use {@link #differenceAndStore(Object, Object)} instead to follow a consistent method naming
|
||||
* scheme..
|
||||
*/
|
||||
void diffAndStore(K keys, K destKey);
|
||||
@Deprecated
|
||||
default void diffAndStore(K keys, K destKey) {
|
||||
differenceAndStore(keys, destKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Diff all sets for given the bound key and {@code keys} and store result in {@code destKey}.
|
||||
*
|
||||
* @param keys must not be {@literal null}.
|
||||
* @param destKey must not be {@literal null}.
|
||||
* @since 3.0
|
||||
* @see <a href="https://redis.io/commands/sdiffstore">Redis Documentation: SDIFFSTORE</a>
|
||||
*/
|
||||
void differenceAndStore(K keys, K destKey);
|
||||
|
||||
/**
|
||||
* Diff all sets for given the bound key and {@code keys} and store result in {@code destKey}.
|
||||
@@ -211,8 +254,23 @@ public interface BoundSetOperations<K, V> extends BoundKeyOperations<K> {
|
||||
* @param keys must not be {@literal null}.
|
||||
* @param destKey must not be {@literal null}.
|
||||
* @see <a href="https://redis.io/commands/sdiffstore">Redis Documentation: SDIFFSTORE</a>
|
||||
* @deprecated since 3.0, use {@link #differenceAndStore(Collection, Object)} instead to follow a consistent method
|
||||
* naming scheme.
|
||||
*/
|
||||
void diffAndStore(Collection<K> keys, K destKey);
|
||||
@Deprecated
|
||||
default void diffAndStore(Collection<K> keys, K destKey) {
|
||||
differenceAndStore(keys, destKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Diff all sets for given the bound key and {@code keys} and store result in {@code destKey}.
|
||||
*
|
||||
* @param keys must not be {@literal null}.
|
||||
* @param destKey must not be {@literal null}.
|
||||
* @since 3.0
|
||||
* @see <a href="https://redis.io/commands/sdiffstore">Redis Documentation: SDIFFSTORE</a>
|
||||
*/
|
||||
void differenceAndStore(Collection<K> keys, K destKey);
|
||||
|
||||
/**
|
||||
* Get all elements of set at the bound key.
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-2022 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link BoundGeoOperations}.
|
||||
*
|
||||
* @author Ninad Divadkar
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @since 1.8
|
||||
*/
|
||||
class DefaultBoundGeoOperations<K, M> extends DefaultBoundKeyOperations<K> implements BoundGeoOperations<K, M> {
|
||||
|
||||
private final GeoOperations<K, M> ops;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code DefaultBoundGeoOperations}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param operations must not be {@literal null}.
|
||||
*/
|
||||
DefaultBoundGeoOperations(K key, RedisOperations<K, M> operations) {
|
||||
|
||||
super(key, operations);
|
||||
this.ops = operations.opsForGeo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long add(Point point, M member) {
|
||||
return ops.add(getKey(), point, member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long add(GeoLocation<M> location) {
|
||||
return ops.add(getKey(), location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long add(Map<M, Point> memberCoordinateMap) {
|
||||
return ops.add(getKey(), memberCoordinateMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long add(Iterable<GeoLocation<M>> locations) {
|
||||
return ops.add(getKey(), locations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance distance(M member1, M member2) {
|
||||
return ops.distance(getKey(), member1, member2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance distance(M member1, M member2, Metric unit) {
|
||||
return ops.distance(getKey(), member1, member2, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> hash(M... members) {
|
||||
return ops.hash(getKey(), members);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Point> position(M... members) {
|
||||
return ops.position(getKey(), members);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeoResults<GeoLocation<M>> radius(Circle within) {
|
||||
return ops.radius(getKey(), within);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeoResults<GeoLocation<M>> radius(Circle within, GeoRadiusCommandArgs param) {
|
||||
return ops.radius(getKey(), within, param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeoResults<GeoLocation<M>> radius(M member, double radius) {
|
||||
return ops.radius(getKey(), member, radius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeoResults<GeoLocation<M>> radius(M member, Distance distance) {
|
||||
return ops.radius(getKey(), member, distance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeoResults<GeoLocation<M>> radius(M member, Distance distance, GeoRadiusCommandArgs param) {
|
||||
return ops.radius(getKey(), member, distance, param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long remove(M... members) {
|
||||
return ops.remove(getKey(), members);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeoResults<GeoLocation<M>> search(GeoReference<M> reference,
|
||||
GeoShape geoPredicate, RedisGeoCommands.GeoSearchCommandArgs args) {
|
||||
return ops.search(getKey(), reference, geoPredicate, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long searchAndStore(K destKey, GeoReference<M> reference,
|
||||
GeoShape geoPredicate, RedisGeoCommands.GeoSearchStoreCommandArgs args) {
|
||||
return ops.searchAndStore(getKey(), destKey, reference, geoPredicate, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType getType() {
|
||||
return DataType.ZSET;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2022 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Default implementation for {@link HashOperations}.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Christoph Strobl
|
||||
* @author Ninad Divadkar
|
||||
*/
|
||||
class DefaultBoundHashOperations<H, HK, HV> extends DefaultBoundKeyOperations<H>
|
||||
implements BoundHashOperations<H, HK, HV> {
|
||||
|
||||
private final HashOperations<H, HK, HV> ops;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>DefaultBoundHashOperations</code> instance.
|
||||
*
|
||||
* @param key
|
||||
* @param operations
|
||||
*/
|
||||
DefaultBoundHashOperations(H key, RedisOperations<H, ?> operations) {
|
||||
super(key, operations);
|
||||
this.ops = operations.opsForHash();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long delete(Object... keys) {
|
||||
return ops.delete(getKey(), keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HV get(Object key) {
|
||||
return ops.get(getKey(), key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HV> multiGet(Collection<HK> hashKeys) {
|
||||
return ops.multiGet(getKey(), hashKeys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedisOperations<H, ?> getOperations() {
|
||||
return ops.getOperations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean hasKey(Object key) {
|
||||
return ops.hasKey(getKey(), key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long increment(HK key, long delta) {
|
||||
return ops.increment(getKey(), key, delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double increment(HK key, double delta) {
|
||||
return ops.increment(getKey(), key, delta);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public HK randomKey() {
|
||||
return ops.randomKey(getKey());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Entry<HK, HV> randomEntry() {
|
||||
return ops.randomEntry(getKey());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<HK> randomKeys(long count) {
|
||||
return ops.randomKeys(getKey(), count);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Map<HK, HV> randomEntries(long count) {
|
||||
return ops.randomEntries(getKey(), count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<HK> keys() {
|
||||
return ops.keys(getKey());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Long lengthOfValue(HK hashKey) {
|
||||
return ops.lengthOfValue(getKey(), hashKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long size() {
|
||||
return ops.size(getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends HK, ? extends HV> m) {
|
||||
ops.putAll(getKey(), m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(HK key, HV value) {
|
||||
ops.put(getKey(), key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean putIfAbsent(HK key, HV value) {
|
||||
return ops.putIfAbsent(getKey(), key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HV> values() {
|
||||
return ops.values(getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<HK, HV> entries() {
|
||||
return ops.entries(getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType getType() {
|
||||
return DataType.HASH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor<Entry<HK, HV>> scan(ScanOptions options) {
|
||||
return ops.scan(getKey(), options);
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2022 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Default {@link BoundKeyOperations} implementation. Meant for internal usage.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
abstract class DefaultBoundKeyOperations<K> implements BoundKeyOperations<K> {
|
||||
|
||||
private K key;
|
||||
private final RedisOperations<K, ?> ops;
|
||||
|
||||
DefaultBoundKeyOperations(K key, RedisOperations<K, ?> operations) {
|
||||
|
||||
this.key = key;
|
||||
this.ops = operations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean expire(long timeout, TimeUnit unit) {
|
||||
return ops.expire(key, timeout, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean expireAt(Date date) {
|
||||
return ops.expireAt(key, date);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getExpire() {
|
||||
return ops.getExpire(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean persist() {
|
||||
return ops.persist(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rename(K newKey) {
|
||||
if (ops.hasKey(key)) {
|
||||
ops.rename(key, newKey);
|
||||
}
|
||||
key = newKey;
|
||||
}
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2022 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.data.redis.connection.RedisListCommands.Direction;
|
||||
|
||||
/**
|
||||
* Default implementation for {@link BoundListOperations}.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
class DefaultBoundListOperations<K, V> extends DefaultBoundKeyOperations<K> implements BoundListOperations<K, V> {
|
||||
|
||||
private final ListOperations<K, V> ops;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>DefaultBoundListOperations</code> instance.
|
||||
*
|
||||
* @param key
|
||||
* @param operations
|
||||
*/
|
||||
DefaultBoundListOperations(K key, RedisOperations<K, V> operations) {
|
||||
|
||||
super(key, operations);
|
||||
this.ops = operations.opsForList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedisOperations<K, V> getOperations() {
|
||||
return ops.getOperations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V index(long index) {
|
||||
return ops.index(getKey(), index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long indexOf(V value) {
|
||||
return ops.indexOf(getKey(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long lastIndexOf(V value) {
|
||||
return ops.lastIndexOf(getKey(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V leftPop() {
|
||||
return ops.leftPop(getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<V> leftPop(long count) {
|
||||
return ops.leftPop(getKey(), count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V leftPop(long timeout, TimeUnit unit) {
|
||||
return ops.leftPop(getKey(), timeout, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long leftPush(V value) {
|
||||
return ops.leftPush(getKey(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long leftPushAll(V... values) {
|
||||
return ops.leftPushAll(getKey(), values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long leftPushIfPresent(V value) {
|
||||
return ops.leftPushIfPresent(getKey(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long leftPush(V pivot, V value) {
|
||||
return ops.leftPush(getKey(), pivot, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long size() {
|
||||
return ops.size(getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<V> range(long start, long end) {
|
||||
return ops.range(getKey(), start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long remove(long i, Object value) {
|
||||
return ops.remove(getKey(), i, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V rightPop() {
|
||||
return ops.rightPop(getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<V> rightPop(long count) {
|
||||
return ops.rightPop(getKey(), count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V rightPop(long timeout, TimeUnit unit) {
|
||||
return ops.rightPop(getKey(), timeout, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long rightPushIfPresent(V value) {
|
||||
return ops.rightPushIfPresent(getKey(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long rightPush(V value) {
|
||||
return ops.rightPush(getKey(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long rightPushAll(V... values) {
|
||||
return ops.rightPushAll(getKey(), values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long rightPush(V pivot, V value) {
|
||||
return ops.rightPush(getKey(), pivot, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V move(Direction from, K destinationKey, Direction to) {
|
||||
return ops.move(getKey(), from, destinationKey, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V move(Direction from, K destinationKey, Direction to, Duration timeout) {
|
||||
return ops.move(getKey(), from, destinationKey, to, timeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V move(Direction from, K destinationKey, Direction to, long timeout, TimeUnit unit) {
|
||||
return ops.move(getKey(), from, destinationKey, to, timeout, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trim(long start, long end) {
|
||||
ops.trim(getKey(), start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(long index, V value) {
|
||||
ops.set(getKey(), index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType getType() {
|
||||
return DataType.LIST;
|
||||
}
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2022 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
|
||||
/**
|
||||
* Default implementation for {@link BoundSetOperations}.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
class DefaultBoundSetOperations<K, V> extends DefaultBoundKeyOperations<K> implements BoundSetOperations<K, V> {
|
||||
|
||||
private final SetOperations<K, V> ops;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>DefaultBoundSetOperations</code> instance.
|
||||
*
|
||||
* @param key
|
||||
* @param operations
|
||||
*/
|
||||
DefaultBoundSetOperations(K key, RedisOperations<K, V> operations) {
|
||||
|
||||
super(key, operations);
|
||||
this.ops = operations.opsForSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long add(V... values) {
|
||||
return ops.add(getKey(), values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> diff(K key) {
|
||||
return ops.difference(getKey(), key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> diff(Collection<K> keys) {
|
||||
return ops.difference(getKey(), keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void diffAndStore(K key, K destKey) {
|
||||
ops.differenceAndStore(getKey(), key, destKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void diffAndStore(Collection<K> keys, K destKey) {
|
||||
ops.differenceAndStore(getKey(), keys, destKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedisOperations<K, V> getOperations() {
|
||||
return ops.getOperations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> intersect(K key) {
|
||||
return ops.intersect(getKey(), key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> intersect(Collection<K> keys) {
|
||||
return ops.intersect(getKey(), keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void intersectAndStore(K key, K destKey) {
|
||||
ops.intersectAndStore(getKey(), key, destKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void intersectAndStore(Collection<K> keys, K destKey) {
|
||||
ops.intersectAndStore(getKey(), keys, destKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isMember(Object o) {
|
||||
return ops.isMember(getKey(), o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Object, Boolean> isMember(Object... objects) {
|
||||
return ops.isMember(getKey(), objects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> members() {
|
||||
return ops.members(getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean move(K destKey, V value) {
|
||||
return ops.move(getKey(), value, destKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V randomMember() {
|
||||
return ops.randomMember(getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> distinctRandomMembers(long count) {
|
||||
return ops.distinctRandomMembers(getKey(), count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<V> randomMembers(long count) {
|
||||
return ops.randomMembers(getKey(), count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long remove(Object... values) {
|
||||
return ops.remove(getKey(), values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V pop() {
|
||||
return ops.pop(getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long size() {
|
||||
return ops.size(getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> union(K key) {
|
||||
return ops.union(getKey(), key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> union(Collection<K> keys) {
|
||||
return ops.union(getKey(), keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unionAndStore(K key, K destKey) {
|
||||
ops.unionAndStore(getKey(), key, destKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unionAndStore(Collection<K> keys, K destKey) {
|
||||
ops.unionAndStore(getKey(), keys, destKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType getType() {
|
||||
return DataType.SET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor<V> scan(ScanOptions options) {
|
||||
return ops.scan(getKey(), options);
|
||||
}
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018-2022 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.domain.Range;
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.data.redis.connection.Limit;
|
||||
import org.springframework.data.redis.connection.stream.Consumer;
|
||||
import org.springframework.data.redis.connection.stream.MapRecord;
|
||||
import org.springframework.data.redis.connection.stream.ReadOffset;
|
||||
import org.springframework.data.redis.connection.stream.RecordId;
|
||||
import org.springframework.data.redis.connection.stream.StreamOffset;
|
||||
import org.springframework.data.redis.connection.stream.StreamReadOptions;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Default implementation for {@link BoundStreamOperations}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
* @since 2.2
|
||||
*/
|
||||
class DefaultBoundStreamOperations<K, HK, HV> extends DefaultBoundKeyOperations<K>
|
||||
implements BoundStreamOperations<K, HK, HV> {
|
||||
|
||||
private final StreamOperations<K, HK, HV> ops;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>DefaultBoundSetOperations</code> instance.
|
||||
*
|
||||
* @param key
|
||||
* @param operations
|
||||
*/
|
||||
DefaultBoundStreamOperations(K key, RedisOperations<K, ?> operations) {
|
||||
|
||||
super(key, operations);
|
||||
this.ops = operations.opsForStream();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Long acknowledge(String group, String... recordIds) {
|
||||
return ops.acknowledge(getKey(), group, recordIds);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public RecordId add(Map<HK, HV> body) {
|
||||
return ops.add(getKey(), body);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Long delete(String... recordIds) {
|
||||
return ops.delete(getKey(), recordIds);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String createGroup(ReadOffset readOffset, String group) {
|
||||
return ops.createGroup(getKey(), readOffset, group);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Boolean deleteConsumer(Consumer consumer) {
|
||||
return ops.deleteConsumer(getKey(), consumer);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Boolean destroyGroup(String group) {
|
||||
return ops.destroyGroup(getKey(), group);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Long size() {
|
||||
return ops.size(getKey());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<MapRecord<K, HK, HV>> range(Range<String> range, Limit limit) {
|
||||
return ops.range(getKey(), range, limit);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<MapRecord<K, HK, HV>> read(StreamReadOptions readOptions, ReadOffset readOffset) {
|
||||
return ops.read(readOptions, StreamOffset.create(getKey(), readOffset));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<MapRecord<K, HK, HV>> read(Consumer consumer, StreamReadOptions readOptions, ReadOffset readOffset) {
|
||||
return ops.read(consumer, readOptions, StreamOffset.create(getKey(), readOffset));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<MapRecord<K, HK, HV>> reverseRange(Range<String> range, Limit limit) {
|
||||
return ops.reverseRange(getKey(), range, limit);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Long trim(long count) {
|
||||
return trim(count, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Long trim(long count, boolean approximateTrimming) {
|
||||
return ops.trim(getKey(), count, approximateTrimming);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DataType getType() {
|
||||
return DataType.STREAM;
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2022 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
* @author Jiahe Cai
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
class DefaultBoundValueOperations<K, V> extends DefaultBoundKeyOperations<K> implements BoundValueOperations<K, V> {
|
||||
|
||||
private final ValueOperations<K, V> ops;
|
||||
|
||||
/**
|
||||
* Constructs a new {@link DefaultBoundValueOperations} instance.
|
||||
*
|
||||
* @param key
|
||||
* @param operations
|
||||
*/
|
||||
DefaultBoundValueOperations(K key, RedisOperations<K, V> operations) {
|
||||
|
||||
super(key, operations);
|
||||
this.ops = operations.opsForValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get() {
|
||||
return ops.get(getKey());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public V getAndDelete() {
|
||||
return ops.getAndDelete(getKey());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public V getAndExpire(long timeout, TimeUnit unit) {
|
||||
return ops.getAndExpire(getKey(), timeout, unit);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public V getAndExpire(Duration timeout) {
|
||||
return ops.getAndExpire(getKey(), timeout);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public V getAndPersist() {
|
||||
return ops.getAndPersist(getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public V getAndSet(V value) {
|
||||
return ops.getAndSet(getKey(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long increment() {
|
||||
return ops.increment(getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long increment(long delta) {
|
||||
return ops.increment(getKey(), delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double increment(double delta) {
|
||||
return ops.increment(getKey(), delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long decrement() {
|
||||
return ops.decrement(getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long decrement(long delta) {
|
||||
return ops.decrement(getKey(), delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer append(String value) {
|
||||
return ops.append(getKey(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(long start, long end) {
|
||||
return ops.get(getKey(), start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(V value, long timeout, TimeUnit unit) {
|
||||
ops.set(getKey(), value, timeout, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(V value) {
|
||||
ops.set(getKey(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean setIfAbsent(V value) {
|
||||
return ops.setIfAbsent(getKey(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean setIfAbsent(V value, long timeout, TimeUnit unit) {
|
||||
return ops.setIfAbsent(getKey(), value, timeout, unit);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Boolean setIfPresent(V value) {
|
||||
return ops.setIfPresent(getKey(), value);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Boolean setIfPresent(V value, long timeout, TimeUnit unit) {
|
||||
return ops.setIfPresent(getKey(), value, timeout, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(V value, long offset) {
|
||||
ops.set(getKey(), value, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long size() {
|
||||
return ops.size(getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedisOperations<K, V> getOperations() {
|
||||
return ops.getOperations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType getType() {
|
||||
return DataType.STRING;
|
||||
}
|
||||
}
|
||||
@@ -1,370 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2022 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.data.redis.connection.Limit;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Range;
|
||||
import org.springframework.data.redis.connection.zset.Weights;
|
||||
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Default implementation for {@link BoundZSetOperations}.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Wongoo (望哥)
|
||||
* @author Andrey Shlykov
|
||||
*/
|
||||
class DefaultBoundZSetOperations<K, V> extends DefaultBoundKeyOperations<K> implements BoundZSetOperations<K, V> {
|
||||
|
||||
private final ZSetOperations<K, V> ops;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>DefaultBoundZSetOperations</code> instance.
|
||||
*
|
||||
* @param key
|
||||
* @param operations
|
||||
*/
|
||||
DefaultBoundZSetOperations(K key, RedisOperations<K, V> operations) {
|
||||
|
||||
super(key, operations);
|
||||
this.ops = operations.opsForZSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean add(V value, double score) {
|
||||
return ops.add(getKey(), value, score);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean addIfAbsent(V value, double score) {
|
||||
return ops.addIfAbsent(getKey(), value, score);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long add(Set<TypedTuple<V>> tuples) {
|
||||
return ops.add(getKey(), tuples);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long addIfAbsent(Set<TypedTuple<V>> tuples) {
|
||||
return ops.addIfAbsent(getKey(), tuples);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double incrementScore(V value, double delta) {
|
||||
return ops.incrementScore(getKey(), value, delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V randomMember() {
|
||||
return ops.randomMember(getKey());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<V> distinctRandomMembers(long count) {
|
||||
return ops.distinctRandomMembers(getKey(), count);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<V> randomMembers(long count) {
|
||||
return ops.randomMembers(getKey(), count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypedTuple<V> randomMemberWithScore() {
|
||||
return ops.randomMemberWithScore(getKey());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<TypedTuple<V>> distinctRandomMembersWithScore(long count) {
|
||||
return ops.distinctRandomMembersWithScore(getKey(), count);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<TypedTuple<V>> randomMembersWithScore(long count) {
|
||||
return ops.randomMembersWithScore(getKey(), count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedisOperations<K, V> getOperations() {
|
||||
return ops.getOperations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> range(long start, long end) {
|
||||
return ops.range(getKey(), start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> rangeByScore(double min, double max) {
|
||||
return ops.rangeByScore(getKey(), min, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TypedTuple<V>> rangeByScoreWithScores(double min, double max) {
|
||||
return ops.rangeByScoreWithScores(getKey(), min, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TypedTuple<V>> rangeWithScores(long start, long end) {
|
||||
return ops.rangeWithScores(getKey(), start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> reverseRangeByScore(double min, double max) {
|
||||
return ops.reverseRangeByScore(getKey(), min, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TypedTuple<V>> reverseRangeByScoreWithScores(double min, double max) {
|
||||
return ops.reverseRangeByScoreWithScores(getKey(), min, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TypedTuple<V>> reverseRangeWithScores(long start, long end) {
|
||||
return ops.reverseRangeWithScores(getKey(), start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> rangeByLex(Range range, Limit limit) {
|
||||
return ops.rangeByLex(getKey(), range, limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> reverseRangeByLex(Range range, Limit limit) {
|
||||
return ops.reverseRangeByLex(getKey(), range, limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long rank(Object o) {
|
||||
return ops.rank(getKey(), o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long reverseRank(Object o) {
|
||||
return ops.reverseRank(getKey(), o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double score(Object o) {
|
||||
return ops.score(getKey(), o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Double> score(Object... o) {
|
||||
return ops.score(getKey(), o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long remove(Object... values) {
|
||||
return ops.remove(getKey(), values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long removeRange(long start, long end) {
|
||||
return ops.removeRange(getKey(), start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long removeRangeByLex(Range range) {
|
||||
return ops.removeRangeByLex(getKey(), range);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long removeRangeByScore(double min, double max) {
|
||||
return ops.removeRangeByScore(getKey(), min, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> reverseRange(long start, long end) {
|
||||
return ops.reverseRange(getKey(), start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long count(double min, double max) {
|
||||
return ops.count(getKey(), min, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long lexCount(Range range) {
|
||||
return ops.lexCount(getKey(), range);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TypedTuple<V> popMin() {
|
||||
return ops.popMin(getKey());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<TypedTuple<V>> popMin(long count) {
|
||||
return ops.popMin(getKey(), count);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TypedTuple<V> popMin(long timeout, TimeUnit unit) {
|
||||
return ops.popMin(getKey(), timeout, unit);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TypedTuple<V> popMax() {
|
||||
return ops.popMax(getKey());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<TypedTuple<V>> popMax(long count) {
|
||||
return ops.popMax(getKey(), count);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TypedTuple<V> popMax(long timeout, TimeUnit unit) {
|
||||
return ops.popMax(getKey(), timeout, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long size() {
|
||||
return zCard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long zCard() {
|
||||
return ops.zCard(getKey());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<V> difference(Collection<K> otherKeys) {
|
||||
return ops.difference(getKey(), otherKeys);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<TypedTuple<V>> differenceWithScores(Collection<K> otherKeys) {
|
||||
return ops.differenceWithScores(getKey(), otherKeys);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Long differenceAndStore(Collection<K> otherKeys, K destKey) {
|
||||
return ops.differenceAndStore(getKey(), otherKeys, destKey);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<V> intersect(Collection<K> otherKeys) {
|
||||
return ops.intersect(getKey(), otherKeys);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<TypedTuple<V>> intersectWithScores(Collection<K> otherKeys) {
|
||||
return ops.intersectWithScores(getKey(), otherKeys);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<TypedTuple<V>> intersectWithScores(Collection<K> otherKeys, Aggregate aggregate, Weights weights) {
|
||||
return ops.intersectWithScores(getKey(), otherKeys, aggregate, weights);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long intersectAndStore(K otherKey, K destKey) {
|
||||
return ops.intersectAndStore(getKey(), otherKey, destKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long intersectAndStore(Collection<K> otherKeys, K destKey) {
|
||||
return ops.intersectAndStore(getKey(), otherKeys, destKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long intersectAndStore(Collection<K> otherKeys, K destKey, Aggregate aggregate) {
|
||||
return ops.intersectAndStore(getKey(), otherKeys, destKey, aggregate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long intersectAndStore(Collection<K> otherKeys, K destKey, Aggregate aggregate, Weights weights) {
|
||||
return ops.intersectAndStore(getKey(), otherKeys, destKey, aggregate, weights);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<V> union(Collection<K> otherKeys) {
|
||||
return ops.union(getKey(), otherKeys);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<TypedTuple<V>> unionWithScores(Collection<K> otherKeys) {
|
||||
return ops.unionWithScores(getKey(), otherKeys);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<TypedTuple<V>> unionWithScores(Collection<K> otherKeys, Aggregate aggregate, Weights weights) {
|
||||
return ops.unionWithScores(getKey(), otherKeys, aggregate, weights);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long unionAndStore(K otherKey, K destKey) {
|
||||
return ops.unionAndStore(getKey(), otherKey, destKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long unionAndStore(Collection<K> otherKeys, K destKey) {
|
||||
return ops.unionAndStore(getKey(), otherKeys, destKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long unionAndStore(Collection<K> otherKeys, K destKey, Aggregate aggregate) {
|
||||
return ops.unionAndStore(getKey(), otherKeys, destKey, aggregate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long unionAndStore(Collection<K> otherKeys, K destKey, Aggregate aggregate, Weights weights) {
|
||||
return ops.unionAndStore(getKey(), otherKeys, destKey, aggregate, weights);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType getType() {
|
||||
return DataType.ZSET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor<TypedTuple<V>> scan(ScanOptions options) {
|
||||
return ops.scan(getKey(), options);
|
||||
}
|
||||
}
|
||||
@@ -105,6 +105,7 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
|
||||
private @Nullable ScriptExecutor<K> scriptExecutor;
|
||||
|
||||
private final BoundOperationsProxyFactory boundOperations = new BoundOperationsProxyFactory();
|
||||
private final ValueOperations<K, V> valueOps = new DefaultValueOperations<>(this);
|
||||
private final ListOperations<K, V> listOps = new DefaultListOperations<>(this);
|
||||
private final SetOperations<K, V> setOps = new DefaultSetOperations<>(this);
|
||||
@@ -1056,12 +1057,12 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
|
||||
@Override
|
||||
public BoundGeoOperations<K, V> boundGeoOps(K key) {
|
||||
return new DefaultBoundGeoOperations<>(key, this);
|
||||
return boundOperations.createProxy(BoundGeoOperations.class, key, DataType.ZSET, this, RedisOperations::opsForGeo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <HK, HV> BoundHashOperations<K, HK, HV> boundHashOps(K key) {
|
||||
return new DefaultBoundHashOperations<>(key, this);
|
||||
return boundOperations.createProxy(BoundHashOperations.class, key, DataType.HASH, this, it -> it.opsForHash());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1081,12 +1082,13 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
|
||||
@Override
|
||||
public BoundListOperations<K, V> boundListOps(K key) {
|
||||
return new DefaultBoundListOperations<>(key, this);
|
||||
return boundOperations.createProxy(BoundListOperations.class, key, DataType.LIST, this,
|
||||
RedisOperations::opsForList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoundSetOperations<K, V> boundSetOps(K key) {
|
||||
return new DefaultBoundSetOperations<>(key, this);
|
||||
return boundOperations.createProxy(BoundSetOperations.class, key, DataType.SET, this, RedisOperations::opsForSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1101,18 +1103,18 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
|
||||
@Override
|
||||
public <HK, HV> StreamOperations<K, HK, HV> opsForStream(HashMapper<? super K, ? super HK, ? super HV> hashMapper) {
|
||||
|
||||
return new DefaultStreamOperations<>(this, hashMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <HK, HV> BoundStreamOperations<K, HK, HV> boundStreamOps(K key) {
|
||||
return new DefaultBoundStreamOperations<>(key, this);
|
||||
return boundOperations.createProxy(BoundStreamOperations.class, key, DataType.STREAM, this, it -> opsForStream());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoundValueOperations<K, V> boundValueOps(K key) {
|
||||
return new DefaultBoundValueOperations<>(key, this);
|
||||
return boundOperations.createProxy(BoundValueOperations.class, key, DataType.STRING, this,
|
||||
RedisOperations::opsForValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1122,7 +1124,8 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
|
||||
@Override
|
||||
public BoundZSetOperations<K, V> boundZSetOps(K key) {
|
||||
return new DefaultBoundZSetOperations<>(key, this);
|
||||
return boundOperations.createProxy(BoundZSetOperations.class, key, DataType.ZSET, this,
|
||||
RedisOperations::opsForZSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user