Beispiel #1
0
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;
}
Beispiel #2
0
/* 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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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;
}