KBEngine挂载Redis服务的两种方式 #1394
sleepangel
started this conversation in
Ideas
Replies: 2 comments 2 replies
-
想不到有人帮我把讨论内容转到这里了,之前贴出来的代码会有一处内存泄漏,我把主要修改的代码贴到这里吧,希望大家参考指正。 1. db_interface_redis.cpp中的修改: (db_interface_redis.zip) static int php_htoi(char* s) {
int value;
int c;
c = ((unsigned char*)s)[0];
if (isupper(c)) {
c = tolower(c);
}
value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;
c = ((unsigned char*)s)[1];
if (isupper(c)) {
c = tolower(c);
}
value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;
return (value);
}
static void urldecode(std::string& buffer)
{
if (buffer.empty()) {
return;
}
size_t len = buffer.size();
char* tmp = new char[buffer.size() + 1];
//memset(tmp, 0, buffer.size() + 1);
const char* dest = tmp;
char* data = (char*)buffer.data();
size_t _len = 0;
while (len--) {
if (*data == '+') {
*tmp = ' ';
}
else if (*data == '%' && len >= 2 && isxdigit((int)*(data + 1))
&& isxdigit((int)*(data + 2))) {
char ch = (char)php_htoi(data + 1);
*tmp = ch;
data += 2;
len -= 2;
}
else {
*tmp = (char)*data;
}
data++;
tmp++;
_len++;
}
*tmp = 0;
buffer = dest;
delete[] dest;
}
static redisReply* execRedisCmd(redisContext* pRedisContext, const std::string &cmdStr)
{
redisReply* pRedisReply = NULL;
size_t spos = 0, epos = 0, count = 0;
do
{
epos = cmdStr.find(';', spos);
std::string cmd = cmdStr.substr(spos, epos - spos);
spos = epos + 1;
++count;
std::vector<std::string> argv;
std::stringstream ss;
ss.str(cmd);
std::string os;
while (ss >> os)
{
urldecode(os);
argv.push_back(os);
}
size_t argc = argv.size();
const char** argvlist = new const char* [argc];
size_t* argvlen = new size_t[argc];
int i = 0;
for (auto const& it : argv)
{
argvlist[i] = it.c_str();
argvlen[i] = it.length();
++i;
}
redisAppendCommandArgv(pRedisContext, argc, argvlist, argvlen);
delete[] argvlist;
delete[] argvlen;
} while (spos < cmdStr.length() && epos != std::string::npos);
for (size_t i = 0; i < count; ++i)
{
if (pRedisReply)
freeReplyObject(pRedisReply);
redisGetReply(pRedisContext, (void**)&pRedisReply);
}
return pRedisReply;
}
//-------------------------------------------------------------------------------------
bool DBInterfaceRedis::query(const char* cmd, uint32 size, bool printlog, MemoryStream * result)
{
KBE_ASSERT(pRedisContext_);
redisReply* pRedisReply = execRedisCmd(pRedisContext_, cmd);
if (!pRedisReply)
{
pRedisReply = (redisReply*)redisCommand(pRedisContext_, cmd);
}
lastquery_ = cmd;
RedisWatcher::querystatistics(lastquery_.c_str(), (uint32)lastquery_.size());
write_query_result(pRedisReply, result);
if (pRedisContext_->err)
{
if(printlog)
{
ERROR_MSG(fmt::format("DBInterfaceRedis::query: cmd={}, errno={}, error={}\n",
cmd, pRedisContext_->err, pRedisContext_->errstr));
}
if(pRedisReply)
freeReplyObject(pRedisReply);
this->throwError(NULL);
return false;
}
freeReplyObject(pRedisReply);
if(printlog)
{
INFO_MSG("DBInterfaceRedis::query: successfully!\n");
}
return true;
} 2. 在python中,传入的redis命令参数如果带有空格或分号,需要先进行转义,比如: def __string_encode(src):
return src.replace(' ', '%20').replace(';', '%3b')
def redisTest():
val = __string_encode('Hello world; I am a test.')
cmd = f'SET tmp {val};'
cmd += 'Get tmp;'
KBEngine.executeRawDatabaseCommand(cmd, callback, -1, 'redis') |
Beta Was this translation helpful? Give feedback.
1 reply
-
有没有同时使用 mysql和 redis的案例 |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
KBEngine挂载Redis服务的两种方式--在837764110群的今晚打老虎大佬分享
第一种挂载方式
KBEngine本身已经加入hiredis,并实现了Redis的适配,只需要一点源码修改,就可以通过在kbengine.xml里面定义Redis的interface来使用KBEngine.executeRawDatabaseCommand函数在脚本中调用简单的Redis指令, 这种实现的Redis调用比较简单,但是对于有空格字符串以及pipline的支持不好,
还可以在dbmgr中加入这样的定义来配置Redis服务器,然后就可以在Python里面使用KBEngine.executeRawDatabaseCommand(cmd, callback, -1, 'redis')来调用你的Redis数据库了
第二种挂载方式
需要修改了一下源码的execRedisCmd函数,让它可以支持使用分号隔开的多行Redis指令
这样可以使用分号来隔开多条指令来然后在一行executeRawDatabaseCommand里面一起调用,比如:
val = "this is a test"
cmd = f'SET tmp {val}; GET tmp'
KBEngine.executeRawDatabaseCommand(cmd, callback, -1, 'redis')
Beta Was this translation helpful? Give feedback.
All reactions