diff --git a/lib/redis/rediswriter.cpp b/lib/redis/rediswriter.cpp index 3eca8ec40..b89e59bf1 100644 --- a/lib/redis/rediswriter.cpp +++ b/lib/redis/rediswriter.cpp @@ -334,5 +334,62 @@ boost::shared_ptr RedisWriter::ExecuteQuery(const std::vector(reply); + return boost::shared_ptr(reply, freeReplyObject); +} + +std::vector > RedisWriter::ExecuteQueries(const std::vector >& queries) +{ + const char **argv; + size_t *argvlen; + + for (const auto& query : queries) { + argv = new const char *[query.size()]; + argvlen = new size_t[query.size()]; + + for (std::vector::size_type i = 0; i < query.size(); i++) { + argv[i] = query[i].CStr(); + argvlen[i] = query[i].GetLength(); + } + + redisAppendCommandArgv(m_Context, query.size(), argv, argvlen); + + delete [] argv; + delete [] argvlen; + } + + std::vector > replies; + + for (size_t i = 0; i < queries.size(); i++) { + redisReply *rawReply; + + if (redisGetReply(m_Context, reinterpret_cast(&rawReply)) == REDIS_ERR) { + BOOST_THROW_EXCEPTION( + redis_error() + << errinfo_message("redisGetReply() failed") + ); + } + + boost::shared_ptr reply(rawReply, freeReplyObject); + replies.push_back(reply); + } + + for (size_t i = 0; i < queries.size(); i++) { + const auto& query = queries[i]; + const auto& reply = replies[i]; + + if (reply->type == REDIS_REPLY_ERROR) { + Log(LogCritical, "RedisWriter") + << "Redis query failed: " << reply->str; + + String msg = reply->str; + + BOOST_THROW_EXCEPTION( + redis_error() + << errinfo_message(msg) + << errinfo_redis_query(Utility::Join(Array::FromVector(query), ' ', false)) + ); + } + } + + return replies; } diff --git a/lib/redis/rediswriter.hpp b/lib/redis/rediswriter.hpp index 48ea8d238..ca43a476a 100644 --- a/lib/redis/rediswriter.hpp +++ b/lib/redis/rediswriter.hpp @@ -88,6 +88,7 @@ private: void ExceptionHandler(boost::exception_ptr exp); boost::shared_ptr ExecuteQuery(const std::vector& query); + std::vector > ExecuteQueries(const std::vector >& queries); Timer::Ptr m_StatsTimer; Timer::Ptr m_ReconnectTimer;