common/rediscommand.cpp (122 lines of code) (raw):
#include <vector>
#include <hiredis/hiredis.h>
#include "rediscommand.h"
#include "stringutility.h"
using namespace std;
namespace swss {
RedisCommand::RedisCommand()
: temp(NULL),
len(0)
{
}
RedisCommand::~RedisCommand()
{
redisFreeCommand(temp);
}
void RedisCommand::format(const char *fmt, ...)
{
if (temp != nullptr)
{
redisFreeCommand(temp);
temp = nullptr;
}
len = 0;
va_list ap;
va_start(ap, fmt);
int ret = redisvFormatCommand(&temp, fmt, ap);
va_end(ap);
if (ret == -1) {
throw std::bad_alloc();
} else if (ret == -2) {
throw std::invalid_argument("fmt");
}
len = ret;
}
void RedisCommand::formatArgv(int argc, const char **argv, const size_t *argvlen)
{
if (temp != nullptr)
{
redisFreeCommand(temp);
temp = nullptr;
}
len = 0;
int ret = redisFormatCommandArgv(&temp, argc, argv, argvlen);
if (ret == -1) {
throw std::bad_alloc();
}
len = ret;
}
void RedisCommand::format(const vector<string> &commands)
{
vector<const char*> args;
vector<size_t> lens;
for (auto& command : commands)
{
args.push_back(command.c_str());
lens.push_back(command.size());
}
formatArgv(static_cast<int>(args.size()), args.data(), lens.data());
}
/* Format HSET key multiple field value command */
void RedisCommand::formatHSET(const std::string &key,
const std::vector<FieldValueTuple> &values)
{
formatHSET(key, values.begin(), values.end());
}
void RedisCommand::formatHSET(const std::string &key,
const std::map<std::string, std::string> &values)
{
formatHSET(key, values.begin(), values.end());
}
/* Format HSET key field value command */
void RedisCommand::formatHSET(const std::string& key, const std::string& field,
const std::string& value)
{
format("HSET %s %s %s", key.c_str(), field.c_str(), value.c_str());
}
/* Format HGET key field command */
void RedisCommand::formatHGET(const std::string& key, const std::string& field)
{
format("HGET %s %s", key.c_str(), field.c_str());
}
/* Format HDEL key field command */
void RedisCommand::formatHDEL(const std::string& key, const std::string& field)
{
return format("HDEL %s %s", key.c_str(), field.c_str());
}
/* Format HDEL key multiple fields command */
void RedisCommand::formatHDEL(const std::string& key, const std::vector<std::string>& fields)
{
if (fields.empty()) throw std::invalid_argument("empty values");
std::vector<string> args = {"HDEL", key};
args.insert(args.end(), fields.begin(), fields.end());
format(args);
}
/* Format EXPIRE key field command */
void RedisCommand::formatEXPIRE(const std::string& key, const int64_t& ttl)
{
return format("EXPIRE %s %lld", key.c_str(), ttl);
}
/* Format TTL key command */
void RedisCommand::formatTTL(const std::string& key)
{
return format("TTL %s", key.c_str());
}
/* Format DEL key command */
void RedisCommand::formatDEL(const std::string& key)
{
return format("DEL %s", key.c_str());
}
int RedisCommand::appendTo(redisContext *ctx) const
{
return redisAppendFormattedCommand(ctx, c_str(), length());
}
std::string RedisCommand::toPrintableString() const
{
return binary_to_printable(temp, len);
}
const char *RedisCommand::c_str() const
{
if (len == 0)
return nullptr;
return temp;
}
size_t RedisCommand::length() const
{
if (len <= 0)
return 0;
return static_cast<size_t>(len);
}
}