更新 src/redis.cpp
This commit is contained in:
@@ -206,7 +206,77 @@ sol::object module::redis::command(const std::string& cmd, sol::this_state ts)
|
||||
|
||||
|
||||
}
|
||||
|
||||
sol::object module::redis::command_ex(const sol::table& args, sol::this_state ts)
|
||||
{
|
||||
if (!args.valid()) {
|
||||
throw ylib::exception("redis.command_ex: invalid arguments table");
|
||||
}
|
||||
|
||||
size_t table_size = args.size();
|
||||
if (table_size == 0) {
|
||||
throw ylib::exception("redis.command_ex: empty arguments table");
|
||||
}
|
||||
|
||||
// 使用智能指针自动管理内存
|
||||
std::vector<std::unique_ptr<char[]>> buffers;
|
||||
std::vector<const char*> argv;
|
||||
std::vector<size_t> argvlen;
|
||||
|
||||
buffers.reserve(table_size);
|
||||
argv.reserve(table_size);
|
||||
argvlen.reserve(table_size);
|
||||
|
||||
// 构建参数数组
|
||||
for (size_t i = 1; i <= table_size; ++i) {
|
||||
sol::object arg = args[i];
|
||||
if (!arg.is<std::string>()) {
|
||||
throw ylib::exception("redis.command_ex: argument at index "+std::to_string(i)+" is not a string");
|
||||
}
|
||||
|
||||
std::string str = arg.as<std::string>();
|
||||
auto buffer = std::make_unique<char[]>(str.length() + 1);
|
||||
std::strcpy(buffer.get(), str.c_str());
|
||||
|
||||
argv.push_back(buffer.get());
|
||||
argvlen.push_back(str.length());
|
||||
buffers.push_back(std::move(buffer)); // 转移所有权
|
||||
}
|
||||
|
||||
// 执行命令
|
||||
redisReply* reply = (redisReply*)redisCommandArgv(
|
||||
m_context,
|
||||
table_size,
|
||||
argv.data(),
|
||||
argvlen.data()
|
||||
);
|
||||
|
||||
// 处理错误
|
||||
if (reply == NULL) {
|
||||
if (m_context->err) {
|
||||
m_context = m_pool->reget(m_context);
|
||||
if (m_context == NULL || m_context->err) {
|
||||
throw ylib::exception("Failed to reacquire Redis connection");
|
||||
}
|
||||
|
||||
// 重新执行(buffers仍然持有内存,可以重用)
|
||||
reply = (redisReply*)redisCommandArgv(
|
||||
m_context,
|
||||
table_size,
|
||||
argv.data(),
|
||||
argvlen.data()
|
||||
);
|
||||
|
||||
if (reply == NULL) {
|
||||
throw ylib::exception(std::string("Redis command failed after retry: ") + m_context->errstr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw ylib::exception("Unknown error: reply is NULL but context has no error");
|
||||
}
|
||||
}
|
||||
|
||||
return m_pool->reply(&ts, m_context, reply);
|
||||
}
|
||||
void module::redis_regist(sol::state* lua)
|
||||
{
|
||||
lua->new_usertype<module::redis_pool>("fw_redis_pool",
|
||||
@@ -217,6 +287,7 @@ void module::redis_regist(sol::state* lua)
|
||||
"self", &module::redis_pool::self
|
||||
);
|
||||
lua->new_usertype<module::redis>("fw_redis_conn",
|
||||
"command", &module::redis::command
|
||||
"command", &module::redis::command,
|
||||
"command_ex", &module::redis::command_ex
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user