提交 9ed32ba0 编写于 作者: A antirez

Redis.call is now split into two variants of the same function. Redis.call...

Redis.call is now split into two variants of the same function. Redis.call will raise an error by default. Redis.pcall will return the error object instead.
上级 2f5abbfe
......@@ -128,7 +128,7 @@ void luaPushError(lua_State *lua, char *error) {
lua_settable(lua,-3);
}
int luaRedisCommand(lua_State *lua) {
int luaRedisGenericCommand(lua_State *lua, int raise_error) {
int j, argc = lua_gettop(lua);
struct redisCommand *cmd;
robj **argv;
......@@ -205,6 +205,7 @@ int luaRedisCommand(lua_State *lua) {
reply = sdscatlen(reply,o->ptr,sdslen(o->ptr));
listDelNode(c->reply,listFirst(c->reply));
}
if (raise_error && reply[0] != '-') raise_error = 0;
redisProtocolToLuaType(lua,reply);
sdsfree(reply);
......@@ -215,9 +216,25 @@ cleanup:
decrRefCount(c->argv[j]);
zfree(c->argv);
if (raise_error) {
/* If we are here we should have an error in the stack, in the
* form of a table with an "err" field. Extract the string to
* return the plain error. */
lua_pushstring(lua,"err");
lua_gettable(lua,-2);
return lua_error(lua);
}
return 1;
}
int luaRedisCallCommand(lua_State *lua) {
return luaRedisGenericCommand(lua,1);
}
int luaRedisPCallCommand(lua_State *lua) {
return luaRedisGenericCommand(lua,0);
}
int luaLogCommand(lua_State *lua) {
int j, argc = lua_gettop(lua);
int level;
......@@ -301,7 +318,12 @@ void scriptingInit(void) {
/* redis.call */
lua_pushstring(lua,"call");
lua_pushcfunction(lua,luaRedisCommand);
lua_pushcfunction(lua,luaRedisCallCommand);
lua_settable(lua,-3);
/* redis.pcall */
lua_pushstring(lua,"pcall");
lua_pushcfunction(lua,luaRedisPCallCommand);
lua_settable(lua,-3);
/* redis.log and log levels. */
......
......@@ -54,7 +54,7 @@ start_server {tags {"scripting"}} {
test {EVAL - Redis integer -> Lua type conversion} {
r eval {
local foo = redis.call('incr','x')
local foo = redis.pcall('incr','x')
return {type(foo),foo}
} 0
} {number 1}
......@@ -62,7 +62,7 @@ start_server {tags {"scripting"}} {
test {EVAL - Redis bulk -> Lua type conversion} {
r set mykey myval
r eval {
local foo = redis.call('get','mykey')
local foo = redis.pcall('get','mykey')
return {type(foo),foo}
} 0
} {string myval}
......@@ -73,14 +73,14 @@ start_server {tags {"scripting"}} {
r rpush mylist b
r rpush mylist c
r eval {
local foo = redis.call('lrange','mylist',0,-1)
local foo = redis.pcall('lrange','mylist',0,-1)
return {type(foo),foo[1],foo[2],foo[3],# foo}
} 0
} {table a b c 3}
test {EVAL - Redis status reply -> Lua type conversion} {
r eval {
local foo = redis.call('set','mykey','myval')
local foo = redis.pcall('set','mykey','myval')
return {type(foo),foo['ok']}
} 0
} {table OK}
......@@ -88,7 +88,7 @@ start_server {tags {"scripting"}} {
test {EVAL - Redis error reply -> Lua type conversion} {
r set mykey myval
r eval {
local foo = redis.call('incr','mykey')
local foo = redis.pcall('incr','mykey')
return {type(foo),foo['err']}
} 0
} {table {ERR value is not an integer or out of range}}
......@@ -96,7 +96,7 @@ start_server {tags {"scripting"}} {
test {EVAL - Redis nil bulk reply -> Lua type conversion} {
r del mykey
r eval {
local foo = redis.call('get','mykey')
local foo = redis.pcall('get','mykey')
return {type(foo),foo == false}
} 0
} {boolean 1}
......@@ -105,11 +105,11 @@ start_server {tags {"scripting"}} {
r set mykey "this is DB 9"
r select 10
r set mykey "this is DB 10"
r eval {return redis.call('get','mykey')} 0
r eval {return redis.pcall('get','mykey')} 0
} {this is DB 10}
test {EVAL - Is Lua seleced DB retained?} {
r eval {return redis.call('select','9')} 0
r eval {return redis.pcall('select','9')} 0
r get mykey
} {this is DB 9}
......@@ -126,18 +126,42 @@ start_server {tags {"scripting"}} {
test {EVAL - Scripts can't run certain commands} {
set e {}
catch {r eval {return redis.call('spop','x')} 0} e
catch {r eval {return redis.pcall('spop','x')} 0} e
set e
} {*not allowed*}
test {EVAL - Scripts can't run certain commands} {
set e {}
catch {
r eval "redis.call('randomkey'); return redis.call('set','x','ciao')" 0
r eval "redis.pcall('randomkey'); return redis.pcall('set','x','ciao')" 0
} e
set e
} {*not allowed after*}
test {EVAL - redis.call variant raises a Lua error on Redis cmd error (1)} {
set e {}
catch {
r eval "redis.call('nosuchcommand')" 0
} e
set e
} {*Unknown Redis*}
test {EVAL - redis.call variant raises a Lua error on Redis cmd error (1)} {
set e {}
catch {
r eval "redis.call('get','a','b','c')" 0
} e
set e
} {*number of args*}
test {EVAL - redis.call variant raises a Lua error on Redis cmd error (1)} {
set e {}
r set foo bar
catch {
r eval "redis.call('lpush','foo','val')" 0
} e
set e
} {*against a key*}
}
start_server {tags {"scripting repl"}} {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册