更新 src/redis.cpp

This commit is contained in:
2026-01-02 16:57:01 +08:00
parent c452107755
commit 5dcf7ca079

View File

@@ -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
);
}