Skip to content

DATAREDIS-698 - Add support for HSTRLEN. #283

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.1.0.BUILD-SNAPSHOT</version>
<version>2.1.0.DATAREDIS-698-SNAPSHOT</version>

<name>Spring Data Redis</name>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,8 @@
*/
package org.springframework.data.redis.connection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.apache.commons.logging.Log;
Expand Down Expand Up @@ -3047,7 +3038,7 @@ public void openPipeline() {
*/
@Override
public Object execute(String command) {
return execute(command, (byte[][]) null);
return execute(command, EMPTY_2D_BYTE_ARRAY);
}

/*
Expand Down Expand Up @@ -3201,6 +3192,16 @@ public Cursor<Entry<byte[], byte[]>> hScan(byte[] key, ScanOptions options) {
return this.delegate.hScan(key, options);
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisSetCommands#hStrLen(byte[], byte[])
*/
@Nullable
@Override
public Long hStrLen(byte[] key, byte[] field) {
return convertAndReturn(delegate.hStrLen(key, field), identityConverter);
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#setClientName(java.lang.String)
Expand Down Expand Up @@ -3263,6 +3264,15 @@ public String setValue(String value) {
});
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.StringRedisConnection#hStrLen(java.lang.String, java.lang.String)
*/
@Override
public Long hStrLen(String key, String field) {
return hStrLen(serialize(key), serialize(field));
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.StringRedisConnection#sScan(java.lang.String, org.springframework.data.redis.core.ScanOptions)
Expand Down Expand Up @@ -3472,8 +3482,8 @@ private <T> T convertAndReturn(@Nullable Object value, Converter converter) {
return null;
}


return value == null ? null : ObjectUtils.nullSafeEquals(converter, identityConverter) ? (T) value : (T) converter.convert(value);
return value == null ? null
: ObjectUtils.nullSafeEquals(converter, identityConverter) ? (T) value : (T) converter.convert(value);
}

private void addResultConverter(Converter<?, ?> converter) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@
*/
package org.springframework.data.redis.connection;

import java.util.Collection;
import java.util.List;
import java.util.Properties;

import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

/**
* @author Christoph Strobl
Expand Down Expand Up @@ -131,4 +134,29 @@ default Long time(RedisClusterNode node) {
default List<RedisClientInfo> getClientList(RedisClusterNode node) {
return serverCommands().getClientList(node);
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#execute(String, byte[], Collection)
*/
@Nullable
@Override
@SuppressWarnings("unchecked")
default <T> T execute(String command, byte[] key, Collection<byte[]> args) {

Assert.notNull(command, "Command must not be null!");
Assert.notNull(key, "Key must not be null!");
Assert.notNull(args, "Args must not be null!");

byte[][] commandArgs = new byte[args.size() + 1][];

commandArgs[0] = key;
int targetIndex = 1;

for (byte[] binaryArgument : args) {
commandArgs[targetIndex++] = binaryArgument;
}

return (T) execute(command, commandArgs);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,13 @@ default Cursor<Entry<byte[], byte[]>> hScan(byte[] key, ScanOptions options) {
return hashCommands().hScan(key, options);
}

/** @deprecated in favor of {@link RedisConnection#hashCommands()}. */
@Override
@Deprecated
default Long hStrLen(byte[] key, byte[] field) {
return hashCommands().hStrLen(key, field);
}

// GEO COMMANDS

/** @deprecated in favor of {@link RedisConnection#geoCommands()}}. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -578,4 +578,82 @@ default Flux<Map.Entry<ByteBuffer, ByteBuffer>> hGetAll(ByteBuffer key) {
* @see <a href="http://redis.io/commands/hgetall">Redis Documentation: HGETALL</a>
*/
Flux<CommandResponse<KeyCommand, Flux<Map.Entry<ByteBuffer, ByteBuffer>>>> hGetAll(Publisher<KeyCommand> commands);

/**
* @author Christoph Strobl
* @see <a href="http://redis.io/commands/hstrlen">Redis Documentation: HSTRLEN</a>
* @since 2.1
*/
class HStrLenCommand extends KeyCommand {

private ByteBuffer field;

/**
* Creates a new {@link HStrLenCommand} given a {@code key}.
*
* @param key can be {@literal null}.
* @param field must not be {@literal null}.
*/
private HStrLenCommand(@Nullable ByteBuffer key, ByteBuffer field) {

super(key);
this.field = field;
}

/**
* Specify the {@code field} within the hash to get the length of the {@code value} of.ø
*
* @param field must not be {@literal null}.
* @return new instance of {@link HStrLenCommand}.
*/
public static HStrLenCommand lengthOf(ByteBuffer field) {

Assert.notNull(field, "Field must not be null!");
return new HStrLenCommand(null, field);
}

/**
* Define the {@code key} the hash is stored at.
*
* @param key must not be {@literal null}.
* @return new instance of {@link HStrLenCommand}.
*/
public HStrLenCommand from(ByteBuffer key) {
return new HStrLenCommand(key, field);
}

/**
* @return the field.
*/
public ByteBuffer getField() {
return field;
}
}

/**
* Get the length of the value associated with {@code field}. If either the {@code key} or the {@code field} do not
* exist, {@code 0} is emitted.
*
* @param key must not be {@literal null}.
* @param field must not be {@literal null}.
* @return never {@literal null}.
* @since 2.1
*/
default Mono<Long> hStrLen(ByteBuffer key, ByteBuffer field) {

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

return hStrLen(Mono.just(HStrLenCommand.lengthOf(field).from(key))).next().map(NumericResponse::getOutput);
}

/**
* Get the length of the value associated with {@code field}. If either the {@code key} or the {@code field} do not
* exist, {@code 0} is emitted.
*
* @param commands must not be {@literal null}.
* @return never {@literal null}.
* @since 2.1
*/
Flux<NumericResponse<HStrLenCommand, Long>> hStrLen(Publisher<HStrLenCommand> commands);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package org.springframework.data.redis.connection;

import java.util.Collection;
import java.util.Set;

import org.springframework.lang.Nullable;
Expand Down Expand Up @@ -56,6 +57,27 @@ public interface RedisClusterConnection extends RedisConnection, RedisClusterCom
@Nullable
byte[] randomKey(RedisClusterNode node);

/**
* Execute the given command for the {@code key} provided potentially appending args. <br />
* This method, other than {@link #execute(String, byte[]...)}, dispatches the command to the {@code key} serving
* master node.
*
* <pre>
* <code>
* // SET foo bar EX 10 NX
* execute("SET", "foo".getBytes(), asBinaryList("bar", "EX", 10, "NX"))
* </code>
* </pre>
*
* @param command must not be {@literal null}.
* @param key must not be {@literal null}.
* @param args must not be {@literal null}.
* @return command result as delivered by the underlying Redis driver. Can be {@literal null}.
* @since 2.1
*/
@Nullable
<T> T execute(String command, byte[] key, Collection<byte[]> args);

/**
* Get {@link RedisClusterServerCommands}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,16 @@ public interface RedisHashCommands {
* @see <a href="http://redis.io/commands/hscan">Redis Documentation: HSCAN</a>
*/
Cursor<Map.Entry<byte[], byte[]>> hScan(byte[] key, ScanOptions options);

/**
* Returns the length of the value associated with {@code field} in the hash stored at {@code key}. If the key or the
* field do not exist, {@code 0} is returned.
*
* @param key must not be {@literal null}.
* @param field must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 2.1
*/
@Nullable
Long hStrLen(byte[] key, byte[] field);
}
Original file line number Diff line number Diff line change
Expand Up @@ -1509,6 +1509,18 @@ interface StringTuple extends Tuple {
*/
Cursor<Map.Entry<String, String>> hScan(String key, ScanOptions options);

/**
* Returns the length of the value associated with {@code field} in the hash stored at {@code key}. If the key or the
* field do not exist, {@code 0} is returned.
*
* @param key must not be {@literal null}.
* @param field must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 2.1
*/
@Nullable
Long hStrLen(String key, String field);

// -------------------------------------------------------------------------
// Methods dealing with HyperLogLog
// -------------------------------------------------------------------------
Expand Down
Loading