static int push_reply(lua_State *L, redisReply *redisReply) { switch(redisReply->type) { case REDIS_REPLY_ERROR: luv_push_async_error_raw(L, NULL, redisReply->str, "push_reply", NULL); break; case REDIS_REPLY_STATUS: lua_pushlstring(L, redisReply->str, redisReply->len); break; case REDIS_REPLY_INTEGER: lua_pushinteger(L, redisReply->integer); break; case REDIS_REPLY_NIL: lua_pushnil(L); break; case REDIS_REPLY_STRING: lua_pushlstring(L, redisReply->str, redisReply->len); break; case REDIS_REPLY_ARRAY: { unsigned int i; lua_createtable(L, redisReply->elements, 0); for (i = 0; i < redisReply->elements; ++i) { push_reply(L, redisReply->element[i]); lua_rawseti(L, -2, i + 1); /* Store sub-reply */ } break; } default: return luaL_error(L, "Unknown reply type: %d", redisReply->type); } return 1; }
/* Pushes an error object onto the stack */ void luv_push_async_error(lua_State* L, uv_err_t err, const char* source, const char* path) { const char* code = uv_err_name(err); const char* msg = uv_strerror(err); luv_push_async_error_raw(L, code, msg, source, path); }
static void luv_push_async_hiredis_error(lua_State *L, const redisAsyncContext *context, const char* source) { luv_push_async_error_raw(L, NULL, context->errstr, source, NULL); }
static int lua_client_command(lua_State *L) { lua_redis_client_t *lua_redis_client = (lua_redis_client_t *) luaL_checkudata(L, 1, LUA_REDIS_CLIENT_MT); static const char *argv[LUA_REDIS_MAX_ARGS]; static size_t argvlen[LUA_REDIS_MAX_ARGS]; int nargs, ltop, i; luv_ref_t *ref = NULL; int commandStatus; redisCallbackFn *redisCallback = NULL; if (lua_redis_client->redis_async_context == NULL) { return luaL_error(L, "RedisAsyncContext is null"); } /* consume callback, if any */ if (lua_isfunction(L, -1)) { ref = ref_alloc(); ref->L = L; ref->r = luaL_ref(L, LUA_REGISTRYINDEX); redisCallback = on_redis_response; } /* get arguments */ ltop = lua_gettop(L); nargs = 0; for (i = 2; i <= ltop; ++i) { /* unpack tables of arguments */ if (lua_istable(L, i)) { int j; for (j = 1; j <= lua_objlen(L, i); ++j) { lua_rawgeti(L, i, j); argv[nargs] = lua_tolstring(L, -1, &argvlen[nargs]); lua_pop(L, 1); if (argv[nargs] == NULL) { return luaL_argerror(L, i, "expected an array table of string or number values" ); } if (++nargs >= LUA_REDIS_MAX_ARGS) { return luaL_error(L, "too many arguments"); } } } else { argv[nargs] = lua_tolstring(L, i, &argvlen[nargs]); if (argv[nargs] == NULL) { return luaL_argerror(L, i, "expected a string or number value"); } if (++nargs >= LUA_REDIS_MAX_ARGS) { return luaL_error(L, "too many arguments"); } } } if (nargs <= 0) { return luaL_error(L, "missing command name"); } commandStatus = redisAsyncCommandArgv(lua_redis_client->redis_async_context, redisCallback, ref, nargs, argv, argvlen); if (commandStatus != REDIS_OK) { lua_rawgeti(L, LUA_REGISTRYINDEX, ref->r); luaL_unref(L, LUA_REGISTRYINDEX, ref->r); ref_free(ref); luv_push_async_error_raw(L, NULL, "Redis connection problem", "client_command", NULL); lua_pushnil(L); lua_call(L, 2, 0); } return 0; }