DATAREDIS-226 - Syntax exceptions using lettuce should be reported immediately.

If running in transaction mode we now do a rudimentary check if the provided number of arguments matches the ones defined for the RedisCommand to execute.

If the command passes this first check and causes an error on redis server one has to check results for Command.getOutput().hasError().

Original Pull Request: #66.
This commit is contained in:
Christoph Strobl
2014-04-28 09:07:21 +02:00
committed by Thomas Darimont
parent bc1bbd1d39
commit ce8d932a46
3 changed files with 27 additions and 8 deletions

View File

@@ -49,6 +49,7 @@ import org.springframework.data.redis.connection.SortParameters;
import org.springframework.data.redis.connection.Subscription;
import org.springframework.data.redis.connection.convert.Converters;
import org.springframework.data.redis.connection.convert.TransactionResultConverter;
import org.springframework.data.redis.core.RedisCommand;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -294,18 +295,22 @@ public class LettuceConnection implements RedisConnection {
try {
String name = command.trim().toUpperCase();
CommandType cmd = CommandType.valueOf(name);
CommandArgs<byte[], byte[]> cmdArg = new CommandArgs<byte[], byte[]>(CODEC);
validateCommandIfRunningInTransactionMode(cmd, args);
CommandArgs<byte[], byte[]> cmdArg = new CommandArgs<byte[], byte[]>(CODEC);
if (!ObjectUtils.isEmpty(args)) {
cmdArg.addKeys(args);
}
CommandOutput expectedOutput = commandOutputTypeHint != null ? commandOutputTypeHint : typeHints.getTypeHint(cmd);
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().dispatch(cmd, expectedOutput, cmdArg)));
return null;
} else if (isQueueing()) {
transaction(new LettuceResult(getAsyncConnection().dispatch(cmd, expectedOutput, cmdArg)));
transaction(new LettuceTxResult(getAsyncConnection().dispatch(cmd, expectedOutput, cmdArg)));
return null;
} else {
return await(getAsyncConnection().dispatch(cmd, expectedOutput, cmdArg));
@@ -3168,6 +3173,25 @@ public class LettuceConnection implements RedisConnection {
return args;
}
private void validateCommandIfRunningInTransactionMode(CommandType cmd, byte[]... args) {
if (this.isQueueing()) {
validateCommand(cmd, args);
}
}
private void validateCommand(CommandType cmd, byte[]... args) {
RedisCommand redisCommand = RedisCommand.failsafeCommandLookup(cmd.name());
if (!RedisCommand.UNKNOWN.equals(redisCommand) && redisCommand.requiresArguments()) {
try {
redisCommand.validateArgumentCount(args != null ? args.length : 0);
} catch (IllegalArgumentException e) {
throw new InvalidDataAccessApiUsageException(String.format("Validation failed for %s command.", cmd), e);
}
}
}
/**
* {@link TypeHints} provide {@link CommandOutput} information for a given {@link CommandType}.
*

View File

@@ -32,7 +32,7 @@ import org.springframework.util.StringUtils;
* @see Redis command list:
* https://github.com/antirez/redis/blob/93e7a130fc9594e41ccfc996b5eca7626ae5356a/src/redis.c#L119
*/
enum RedisCommand {
public enum RedisCommand {
// -- A
APPEND("rw", 2, 2), //
AUTH("rw", 1, 1), //