mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 08:08:53 -05:00
EVALSHA implemented
This commit is contained in:
parent
82c6b8257a
commit
7229d60d03
@ -194,7 +194,8 @@ struct redisCommand redisCommandTable[] = {
|
||||
{"dump",dumpCommand,2,0,NULL,0,0,0,0,0},
|
||||
{"object",objectCommand,-2,0,NULL,0,0,0,0,0},
|
||||
{"client",clientCommand,-2,0,NULL,0,0,0,0,0},
|
||||
{"eval",evalCommand,-3,REDIS_CMD_DENYOOM,zunionInterGetKeys,0,0,0,0,0}
|
||||
{"eval",evalCommand,-3,REDIS_CMD_DENYOOM,zunionInterGetKeys,0,0,0,0,0},
|
||||
{"evalsha",evalShaCommand,-3,REDIS_CMD_DENYOOM,zunionInterGetKeys,0,0,0,0,0}
|
||||
};
|
||||
|
||||
/*============================ Utility functions ============================ */
|
||||
@ -781,6 +782,8 @@ void createSharedObjects(void) {
|
||||
"-ERR source and destination objects are the same\r\n"));
|
||||
shared.outofrangeerr = createObject(REDIS_STRING,sdsnew(
|
||||
"-ERR index out of range\r\n"));
|
||||
shared.noscripterr = createObject(REDIS_STRING,sdsnew(
|
||||
"-NOSCRIPT No matching script. Please use EVAL.\r\n"));
|
||||
shared.loadingerr = createObject(REDIS_STRING,sdsnew(
|
||||
"-LOADING Redis is loading the dataset in memory\r\n"));
|
||||
shared.space = createObject(REDIS_STRING,sdsnew(" "));
|
||||
|
@ -365,7 +365,7 @@ struct sharedObjectsStruct {
|
||||
robj *crlf, *ok, *err, *emptybulk, *czero, *cone, *cnegone, *pong, *space,
|
||||
*colon, *nullbulk, *nullmultibulk, *queued,
|
||||
*emptymultibulk, *wrongtypeerr, *nokeyerr, *syntaxerr, *sameobjecterr,
|
||||
*outofrangeerr, *loadingerr, *plus,
|
||||
*outofrangeerr, *noscripterr, *loadingerr, *plus,
|
||||
*select0, *select1, *select2, *select3, *select4,
|
||||
*select5, *select6, *select7, *select8, *select9,
|
||||
*messagebulk, *pmessagebulk, *subscribebulk, *unsubscribebulk, *mbulk3,
|
||||
@ -1217,6 +1217,7 @@ void dumpCommand(redisClient *c);
|
||||
void objectCommand(redisClient *c);
|
||||
void clientCommand(redisClient *c);
|
||||
void evalCommand(redisClient *c);
|
||||
void evalShaCommand(redisClient *c);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
void *calloc(size_t count, size_t size) __attribute__ ((deprecated));
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
char *redisProtocolToLuaType_Int(lua_State *lua, char *reply);
|
||||
char *redisProtocolToLuaType_Bulk(lua_State *lua, char *reply);
|
||||
@ -320,7 +321,7 @@ void luaSetGlobalArray(lua_State *lua, char *var, robj **elev, int elec) {
|
||||
lua_setglobal(lua,var);
|
||||
}
|
||||
|
||||
void evalCommand(redisClient *c) {
|
||||
void evalGenericCommand(redisClient *c, int evalsha) {
|
||||
lua_State *lua = server.lua;
|
||||
char funcname[43];
|
||||
long long numkeys;
|
||||
@ -337,11 +338,32 @@ void evalCommand(redisClient *c) {
|
||||
* defined into the Lua state */
|
||||
funcname[0] = 'f';
|
||||
funcname[1] = '_';
|
||||
hashScript(funcname+2,c->argv[1]->ptr,sdslen(c->argv[1]->ptr));
|
||||
if (!evalsha) {
|
||||
/* Hash the code if this is an EVAL call */
|
||||
hashScript(funcname+2,c->argv[1]->ptr,sdslen(c->argv[1]->ptr));
|
||||
} else {
|
||||
/* We already have the SHA if it is a EVALSHA */
|
||||
int j;
|
||||
char *sha = c->argv[1]->ptr;
|
||||
|
||||
for (j = 0; j < 40; j++)
|
||||
funcname[j+2] = tolower(sha[j]);
|
||||
funcname[42] = '\0';
|
||||
}
|
||||
|
||||
lua_getglobal(lua, funcname);
|
||||
if (lua_isnil(lua,1)) {
|
||||
/* Function not defined... let's define it. */
|
||||
sds funcdef = sdsempty();
|
||||
sds funcdef;
|
||||
|
||||
/* Function not defined... let's define it if we have the
|
||||
* body of the funciton. If this is an EVALSHA call we can just
|
||||
* return an error. */
|
||||
if (evalsha) {
|
||||
addReply(c, shared.noscripterr);
|
||||
lua_pop(lua,1); /* remove the nil from the stack */
|
||||
return;
|
||||
}
|
||||
funcdef = sdsempty();
|
||||
|
||||
lua_pop(lua,1); /* remove the nil from the stack */
|
||||
funcdef = sdscat(funcdef,"function ");
|
||||
@ -402,3 +424,19 @@ void evalCommand(redisClient *c) {
|
||||
luaReplyToRedisReply(c,lua);
|
||||
lua_gc(lua,LUA_GCSTEP,1);
|
||||
}
|
||||
|
||||
void evalCommand(redisClient *c) {
|
||||
evalGenericCommand(c,0);
|
||||
}
|
||||
|
||||
void evalShaCommand(redisClient *c) {
|
||||
if (sdslen(c->argv[1]->ptr) != 40) {
|
||||
/* We know that a match is not possible if the provided SHA is
|
||||
* not the right length. So we return an error ASAP, this way
|
||||
* evalGenericCommand() can be implemented without string length
|
||||
* sanity check */
|
||||
addReply(c, shared.noscripterr);
|
||||
return;
|
||||
}
|
||||
evalGenericCommand(c,1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user