mirror of https://github.com/redis/redis.git
				
				
				
			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] = '_';
 | 
			
		||||
    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