Exemple #1
0
LUALIB_API int luaopen_hiredis(lua_State * L)
{
  /*
  * Register module
  */
  luaL_register(L, "hiredis", E);

  /*
  * Register module information
  */
  lua_pushliteral(L, LUAHIREDIS_VERSION);
  lua_setfield(L, -2, "_VERSION");

  lua_pushliteral(L, LUAHIREDIS_COPYRIGHT);
  lua_setfield(L, -2, "_COPYRIGHT");

  lua_pushliteral(L, LUAHIREDIS_DESCRIPTION);
  lua_setfield(L, -2, "_DESCRIPTION");

  /*
  * Register enums
  */
  reg_enum(L, Errors);
  reg_enum(L, ReplyTypes);

  /*
  * Register constants
  */
  push_new_const(L, "NIL", 3, REDIS_REPLY_NIL);
  lua_setfield(L, -2, LUAHIREDIS_KEY_NIL);

  push_new_const(L, "OK", 2, REDIS_REPLY_STATUS);
  lua_setfield(L, -2, "OK");

  push_new_const(L, "QUEUED", 6, REDIS_REPLY_STATUS);
  lua_setfield(L, -2, "QUEUED");

  push_new_const(L, "PONG", 4, REDIS_REPLY_STATUS);
  lua_setfield(L, -2, "PONG");

  /*
  * Register functions
  */
  lua_pushvalue(L, -1); /* Module table to be set as upvalue */
  setfuncs(L, R, 1);

  return 1;
}
Exemple #2
0
LUALIB_API int luaopen_hiredis(lua_State * L)
{
  /*
  * Register module
  */
  luaL_register(L, "hiredis", E);

  /*
  * Register module information
  */
  lua_pushliteral(L, LUAHIREDIS_VERSION);
  lua_setfield(L, -2, "_VERSION");

  lua_pushliteral(L, LUAHIREDIS_COPYRIGHT);
  lua_setfield(L, -2, "_COPYRIGHT");

  lua_pushliteral(L, LUAHIREDIS_DESCRIPTION);
  lua_setfield(L, -2, "_DESCRIPTION");

  /*
  * Register enums
  */
  reg_enum(L, Errors);
  reg_enum(L, ReplyTypes);

  /*
  * Register constants
  */
  push_new_const(L, "NIL", 3, REDIS_REPLY_NIL);
  lua_setfield(L, -2, LUAHIREDIS_KEY_NIL);

  lua_newtable(L); /* status */

  if (luaL_newmetatable(L, LUAHIREDIS_STATUS_MT))
  {
    luaL_register(L, NULL, STATUS_MT);
    lua_pushliteral(L, LUAHIREDIS_STATUS_MT);
    lua_setfield(L, -2, "__metatable");
  }
  lua_setmetatable(L, -2);

  lua_getfield(L, -1, "OK");
  lua_setfield(L, -3, "OK");     /* hiredis.OK = status.OK */
  lua_getfield(L, -1, "QUEUED");
  lua_setfield(L, -3, "QUEUED"); /* hiredis.QUEUED = status.QUEUED */
  lua_getfield(L, -1, "PONG");
  lua_setfield(L, -3, "PONG");   /* hiredis.PONG = status.PONG */

  lua_setfield(L, -2, "status"); /* hiredis.status = status */

  /*
  * Register functions
  */
  lua_pushvalue(L, -1); /* Module table to be set as upvalue */
  setfuncs(L, R, 1);

  return 1;
}
Exemple #3
0
static int lstatus_index(lua_State * L)
{
  size_t key_len = 0;
  const char * key = NULL;
  luaL_checktype(L, 1, LUA_TTABLE);
  key = luaL_checklstring(L, 2, &key_len);

  push_new_const(
      L, key, key_len, REDIS_REPLY_STATUS /* status */
    );
  lua_rawset(L, 1); /* t[key] = status */

  luaL_checkstack(L, 1, "not enough stack");

  lua_pushlstring(L, key, key_len); /* Push the key again */
  lua_gettable(L, 1); /* return t[key] */

  return 1;
}
Exemple #4
0
static int push_reply(lua_State * L, redisReply * pReply)
{
  switch (pReply->type)
  {
    case REDIS_REPLY_STATUS:
      luaL_checkstack(L, 2, "not enough stack to push reply");

      lua_pushvalue(L, lua_upvalueindex(1)); /* M (module table) */
      lua_getfield(L, -1, "status"); /* status = M.status */
      lua_remove(L, -2); /* Remove module table from stack */

      lua_pushlstring(L, pReply->str, pReply->len); /* name */
      lua_gettable(L, -2); /* status[name] */

      lua_remove(L, -2); /* Remove status table from stack */

      break;

    case REDIS_REPLY_ERROR:
      /* Not caching errors, they are (hopefully) not that common */
      push_new_const(L, pReply->str, pReply->len, REDIS_REPLY_ERROR);
      break;

    case REDIS_REPLY_INTEGER:
      luaL_checkstack(L, 1, "not enough stack to push reply");
      lua_pushinteger(L, pReply->integer);
      break;

    case REDIS_REPLY_NIL:
      luaL_checkstack(L, 2, "not enough stack to push reply");
      lua_pushvalue(L, lua_upvalueindex(1)); /* module table */
      lua_getfield(L, -1, LUAHIREDIS_KEY_NIL);
      lua_remove(L, -2); /* module table */
      break;

    case REDIS_REPLY_STRING:
      luaL_checkstack(L, 1, "not enough stack to push reply");
      lua_pushlstring(L, pReply->str, pReply->len);
      break;

    case REDIS_REPLY_ARRAY:
    {
      unsigned int i = 0;

      luaL_checkstack(L, 2, "not enough stack to push reply");

      lua_createtable(L, pReply->elements, 0);

      for (i = 0; i < pReply->elements; ++i)
      {
        /*
        * Not controlling recursion depth:
        * if we parsed the reply somehow,
        * we hope to be able to push it.
        */

        push_reply(L, pReply->element[i]);
        lua_rawseti(L, -2, i + 1); /* Store sub-reply */
      }

      break;
    }

    default: /* should not happen */
      return luaL_error(L, "command: unknown reply type: %d", pReply->type);
  }

  /*
  * Always returning a single value.
  * If changed, change REDIS_REPLY_ARRAY above.
  */
  return 1;
}
Exemple #5
0
static int push_reply(lua_State * L, redisReply * pReply)
{
  /* int base = lua_gettop(L); */

  switch(pReply->type)
  {
    case REDIS_REPLY_STATUS:
      lua_pushvalue(L, lua_upvalueindex(1)); /* M (module table) */

      lua_pushlstring(L, pReply->str, pReply->len); /* status */
      lua_gettable(L, -2); /* M[status] */

      if (lua_isnil(L, -1)) /* Not bothering with metatables */
      {
        /*
        * TODO: Following code is likely to be broken due to early binding
        * (imagine that RETURN is a command that returns given string
        * as a status):
        *
        *    assert(conn:command("RETURN", "FOO") == hiredis.FOO)
        *
        * Here hiredis.FOO would be nil before conn:command() is called.
        *
        * Note that this is not relevant to the current Redis implementation
        * (that is 2.2 and before), since it seems that it wouldn't
        * return any status code except OK, QUEUED or PONG,
        * all of which are alread covered.
        */
        lua_pushlstring(L, pReply->str, pReply->len); /* status */
        push_new_const(
            L, pReply->str, pReply->len, REDIS_REPLY_STATUS /* const */
          );
        lua_settable(L, -3); /* M[status] = const */

        lua_pushlstring(L, pReply->str, pReply->len); /* status */
        lua_gettable(L, -2); /* return M[status] */
      }

      lua_remove(L, -2); /* Remove module table */

      break;

    case REDIS_REPLY_ERROR:
      /* Not caching errors, they are (hopefully) not that common */
      push_new_const(L, pReply->str, pReply->len, REDIS_REPLY_ERROR);
      break;

    case REDIS_REPLY_INTEGER:
      lua_pushinteger(L, pReply->integer);
      break;

    case REDIS_REPLY_NIL:
      lua_pushvalue(L, lua_upvalueindex(1)); /* module table */
      lua_getfield(L, -1, LUAHIREDIS_KEY_NIL);
      lua_remove(L, -2); /* module table */
      break;

    case REDIS_REPLY_STRING:
      lua_pushlstring(L, pReply->str, pReply->len);
      break;

    case REDIS_REPLY_ARRAY:
    {
      unsigned int i = 0;

      lua_createtable(L, pReply->elements, 0);

      for (i = 0; i < pReply->elements; ++i)
      {
        /*
        * Not controlling recursion depth:
        * if we parsed the reply somehow,
        * we hope to be able to push it.
        */

        push_reply(L, pReply->element[i]);
        lua_rawseti(L, -2, i + 1); /* Store sub-reply */
      }
      break;
    }

    default: /* should not happen */
      return luaL_error(L, "command: unknown reply type: %d", pReply->type);
  }

  /*
  if (lua_gettop(L) != base + 1)
  {
    return luaL_error(L, "pushreplystackerror: actual %d expected %d base %d type %d", lua_gettop(L), base + 1, base, pReply->type);
  }
  */

  /*
  * Always returning a single value.
  * If changed, change REDIS_REPLY_ARRAY above.
  */
  return 1;
}