hiredis中lua脚本调用
来源:互联网 发布:数据库的数据模型包含 编辑:程序博客网 时间:2024/06/07 17:45
想要直接用hiredis调用lua脚本,研究了好久发现hiredis源码好像不支持调用eval,因为hiredis中是用空格来分割各个参数的,但是lua的return和结果之间一定会有空格。
改了一下hiredis的源码,int redisvFormatCommand(char **target, const char *format, va_list ap) 这个接口,
int redisvFormatCommand(char **target, const char *format, va_list ap) { const char *c = format; char *cmd = NULL; /* final command */ int pos; /* position in final command */ sds curarg, newarg; /* current argument */ int touched = 0; /* was the current argument touched? */ char **curargv = NULL, **newargv = NULL; int argc = 0; int totlen = 0; int j;BOOL quote = 0;//用来判断是否是lua脚本 /* Abort if there is not target to set */ if (target == NULL) return -1; /* Build the command string accordingly to protocol */ curarg = sdsempty(); if (curarg == NULL) return -1; while(*c != '\0') { if (*c != '%' || c[1] == '\0') { if (*c == ' ') {if (quote){newarg = sdscatlen(curarg, c, 1);if (newarg == NULL) goto err;curarg = newarg;touched = 1;} else if (touched) { newargv = realloc(curargv,sizeof(char*)*(argc+1)); if (newargv == NULL) goto err; curargv = newargv; curargv[argc++] = curarg; totlen += (int)bulklen(sdslen(curarg)); /* curarg is put in argv so it can be overwritten. */ curarg = sdsempty(); if (curarg == NULL) goto err; touched = 0; } } else { touched = 1;if (*c == '"'){if (!quote){quote = 1;}else{quote = 0;}}else{newarg = sdscatlen(curarg, c, 1);if (newarg == NULL) goto err;curarg = newarg;} } } else { char *arg; size_t size; /* Set newarg so it can be checked even if it is not touched. */ newarg = curarg; switch(c[1]) { case 's': arg = va_arg(ap,char*); size = strlen(arg); if (size > 0) newarg = sdscatlen(curarg,arg,size); break; case 'b': arg = va_arg(ap,char*); size = va_arg(ap,size_t); if (size > 0) newarg = sdscatlen(curarg,arg,size); break; case '%': newarg = sdscat(curarg,"%"); break; default: /* Try to detect printf format */ { static const char intfmts[] = "diouxX"; char _format[16]; const char *_p = c+1; size_t _l = 0; va_list _cpy; /* Flags */ if (*_p != '\0' && *_p == '#') _p++; if (*_p != '\0' && *_p == '0') _p++; if (*_p != '\0' && *_p == '-') _p++; if (*_p != '\0' && *_p == ' ') _p++; if (*_p != '\0' && *_p == '+') _p++; /* Field width */ while (*_p != '\0' && isdigit(*_p)) _p++; /* Precision */ if (*_p == '.') { _p++; while (*_p != '\0' && isdigit(*_p)) _p++; } /* Copy va_list before consuming with va_arg */ va_copy(_cpy,ap); /* Integer conversion (without modifiers) */ if (strchr(intfmts,*_p) != NULL) { va_arg(ap,int); goto fmt_valid; } /* Double conversion (without modifiers) */ if (strchr("eEfFgGaA",*_p) != NULL) { va_arg(ap,double); goto fmt_valid; } /* Size: char */ if (_p[0] == 'h' && _p[1] == 'h') { _p += 2; if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { va_arg(ap,int); /* char gets promoted to int */ goto fmt_valid; } goto fmt_invalid; } /* Size: short */ if (_p[0] == 'h') { _p += 1; if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { va_arg(ap,int); /* short gets promoted to int */ goto fmt_valid; } goto fmt_invalid; } /* Size: long long */ if (_p[0] == 'l' && _p[1] == 'l') { _p += 2; if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { va_arg(ap,long long); goto fmt_valid; } goto fmt_invalid; } /* Size: long */ if (_p[0] == 'l') { _p += 1; if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { va_arg(ap,long); goto fmt_valid; } goto fmt_invalid; } fmt_invalid: va_end(_cpy); goto err; fmt_valid: _l = (_p+1)-c; if (_l < sizeof(_format)-2) { memcpy(_format,c,_l); _format[_l] = '\0'; newarg = sdscatvprintf(curarg,_format,_cpy); /* Update current position (note: outer blocks * increment c twice so compensate here) */ c = _p-1; } va_end(_cpy); break; } } if (newarg == NULL) goto err; curarg = newarg; touched = 1; c++; } c++; } /* Add the last argument if needed */ if (touched) { newargv = realloc(curargv,sizeof(char*)*(argc+1)); if (newargv == NULL) goto err; curargv = newargv; curargv[argc++] = curarg; totlen += (int)bulklen(sdslen(curarg)); } else { sdsfree(curarg); } /* Clear curarg because it was put in curargv or was free'd. */ curarg = NULL; /* Add bytes needed to hold multi bulk count */ totlen += 1+intlen(argc)+2; /* Build the command at protocol level */ cmd = (char *)malloc(totlen+1); if (cmd == NULL) goto err; pos = sprintf(cmd,"*%d\r\n",argc); for (j = 0; j < argc; j++) {#ifdef _WIN32 pos += sprintf(cmd+pos,"$%llu\r\n",(unsigned long long)sdslen(curargv[j]));#else pos += sprintf(cmd+pos,"$%zu\r\n",sdslen(curargv[j]));#endif memcpy(cmd+pos,curargv[j],sdslen(curargv[j])); pos += (int)sdslen(curargv[j]); sdsfree(curargv[j]); cmd[pos++] = '\r'; cmd[pos++] = '\n'; } assert(pos == totlen); cmd[pos] = '\0'; free(curargv); *target = cmd; return totlen;err: while(argc--) sdsfree(curargv[argc]); free(curargv); if (curarg != NULL) sdsfree(curarg); /* No need to check cmd since it is the last statement that can fail, * but do it anyway to be as defensive as possible. */ if (cmd != NULL) free(cmd); return -1;}
redisAppendCommand(c, "EVAL \"redis.call('SET', KEYS[1], ARGV[1]) local result = redis.call('get',KEYS[1]) return result\" 1 foo1 bar1");if (redisGetReply(c, (void**)&r) != REDIS_OK)return;
redisAppendCommand(c, "script load \"redis.call('SET', KEYS[1], ARGV[1]) local result = redis.call('get', KEYS[1]) return result\"");if (redisGetReply(c, (void**)&r) != REDIS_OK)return;
获得SHA1 校验结果,下次执行只需要执行:evalsha 53d14bf87fe54b95654989afb59c43b1c70d2afb 1 foo1 bar1即可。
redisAppendCommand(c, "script load \"redis.call('SET', KEYS[1], ARGV[1]) local result = redis.call('get', KEYS[1]) return result\"");if (redisGetReply(c, (void**)&r) != REDIS_OK)return;printf("------%s\n", r->str);//freeReplyObject(r);std::string tmpstr = "evalsha ";tmpstr += r->str;tmpstr += " 1 foo3 bar3";redisAppendCommand(c, tmpstr.c_str());if (redisGetReply(c, (void**)&r) != REDIS_OK)return;printf("------%s\n", r->str);freeReplyObject(r);
0 0
- hiredis中lua脚本调用
- projectanarchy中 调用Lua 脚本
- c++调用lua脚本中局部函数
- c调用lua脚本
- C++调用Lua脚本
- lua调用shell 脚本
- Redis调用lua脚本
- golang调用lua脚本
- lua学习笔记 1 android 调用Lua, Lua脚本中启动Intent
- lua学习笔记 1 android 调用Lua, Lua脚本中启动Intent
- SLua 中,从一个Lua脚本调用 另一个GameObject上的Lua脚本中的函数
- C语言中调用lua 脚本执行的效率测试
- 在LUA脚本中调用C/C++函数
- [Lua脚本实践3]LuaPlus中类成员的调用
- [Lua脚本实践2]LuaPlus中关于函数的调用
- lua脚本调用cocos2dx项目中自定义的C++类
- windows7环境中java调用lua脚本函数
- 在C/C++中调用LUA脚本简介
- 用并查集判断一个图是否全连通&无回路(1272)
- Chapter_2 算法分析:欧几里得算法
- HDU-2085
- vue2中 h => h(App)是个什么意思呢?
- python 如何操作mysql 数据库
- hiredis中lua脚本调用
- Backtracking
- ajax实现跨域问题
- 视频播放技术汇总(列表播放,小窗播放,跨界面播放,播放中网络切换提示)
- VC++获得当前系统日期和时间问题汇总
- angular.bindbind 用法
- 鼠标点击不同位置触发的事件
- 使用Logback日志保存到相对路径记录
- javamail 邮箱