From 3791000f15ad793854fac48aa4840914970048db Mon Sep 17 00:00:00 2001 From: antirez Date: Sun, 1 May 2011 15:26:47 +0200 Subject: [PATCH] Fixed arity detection of Redis command executed from Lua script. Error reporting from Lua fixed. More work on the Redis reply to lua conversion code. --- src/SCRIPTING.txt | 4 ++++ src/scripting.c | 53 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 src/SCRIPTING.txt diff --git a/src/SCRIPTING.txt b/src/SCRIPTING.txt new file mode 100644 index 00000000..64d47580 --- /dev/null +++ b/src/SCRIPTING.txt @@ -0,0 +1,4 @@ +TODO: + + redis('get',1) => crash + Fix multi bulk replies, redis('lrange', ...) diff --git a/src/scripting.c b/src/scripting.c index 5f169037..9269cbf1 100644 --- a/src/scripting.c +++ b/src/scripting.c @@ -8,6 +8,8 @@ char *redisProtocolToLuaType_Int(lua_State *lua, char *reply); char *redisProtocolToLuaType_Bulk(lua_State *lua, char *reply); char *redisProtocolToLuaType_Status(lua_State *lua, char *reply); +char *redisProtocolToLuaType_Error(lua_State *lua, char *reply); +char *redisProtocolToLuaType_MultiBulk(lua_State *lua, char *reply); /* Take a Redis reply in the Redis protocol format and convert it into a * Lua type. Thanks to this function, and the introduction of not connected @@ -41,6 +43,12 @@ char *redisProtocolToLuaType(lua_State *lua, char* reply) { case '+': p = redisProtocolToLuaType_Status(lua,reply); break; + case '-': + p = redisProtocolToLuaType_Error(lua,reply); + break; + case '*': + p = redisProtocolToLuaType_MultiBulk(lua,reply); + break; } return p; } @@ -75,6 +83,38 @@ char *redisProtocolToLuaType_Status(lua_State *lua, char *reply) { return p+2; } +char *redisProtocolToLuaType_Error(lua_State *lua, char *reply) { + char *p = strchr(reply+1,'\r'); + + lua_newtable(lua); + lua_pushstring(lua,"err"); + lua_pushlstring(lua,reply+1,p-reply-1); + lua_settable(lua,-3); + return p+2; +} + +char *redisProtocolToLuaType_MultiBulk(lua_State *lua, char *reply) { + char *p = strchr(reply+1,'\r'); + long long mbulklen; + int j = 0; + + printf("--%s-- (%d)\n", reply,(int)(p-reply-1)); + string2ll(reply+1,p-reply-1,&mbulklen); + p += 2; + if (mbulklen == -1) { + lua_pushnil(lua); + return p; + } + printf("BL: %lld\n", mbulklen); + lua_newtable(lua); + for (j = 0; j < mbulklen; j++) { + lua_pushnumber(lua,j); + p = redisProtocolToLuaType(lua,p); + lua_settable(lua,-3); + } + return p; +} + int luaRedisCommand(lua_State *lua) { int j, argc = lua_gettop(lua); struct redisCommand *cmd; @@ -90,12 +130,18 @@ int luaRedisCommand(lua_State *lua) { /* Command lookup */ cmd = lookupCommand(argv[0]->ptr); - if (!cmd) { + if (!cmd || ((cmd->arity > 0 && cmd->arity != argc) || + (argc < -cmd->arity))) + { for (j = 0; j < argc; j++) decrRefCount(argv[j]); zfree(argv); lua_newtable(lua); lua_pushstring(lua,"err"); - lua_pushstring(lua,"Unknown Redis command called from Lua script"); + if (cmd) + lua_pushstring(lua, + "Wrong number of args calling Redis command From Lua script"); + else + lua_pushstring(lua,"Unknown Redis command called from Lua script"); lua_settable(lua,-3); return 1; } @@ -187,7 +233,8 @@ void luaReplyToRedisReply(redisClient *c, lua_State *lua) { lua_gettable(lua,-2); t = lua_type(lua,-1); if (t == LUA_TSTRING) { - addReplyError(c,(char*)lua_tostring(lua,-1)); + addReplySds(c,sdscatprintf(sdsempty(), + "-%s\r\n",(char*)lua_tostring(lua,-1))); lua_pop(lua,1); } else { void *replylen = addDeferredMultiBulkLength(c); -- 2.47.2