coyote/hiredis_wrapper.h

77 lines
2.2 KiB
C++

#pragma once
#include <mutex>
#include <string>
#include <memory>
#include <optional>
#include <exception>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wc99-extensions"
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wpedantic"
#include <hiredis.h>
#pragma GCC diagnostic pop
class RedisException : public std::exception {
public:
RedisException(const char* error_) : error(error_) {}
RedisException(const char* error_, size_t length) : error(error_, length) {}
const char* what() const noexcept {
return this->error.c_str();
}
std::string error;
};
using RedisReply = std::unique_ptr<redisReply, decltype(&freeReplyObject)>;
class Redis {
public:
Redis(const Redis&) = delete;
Redis operator=(const Redis&) = delete;
Redis(const std::string& address, int port);
Redis(const std::string& unix);
~Redis();
template<typename... Args>
RedisReply command(const char* format, Args... args) {
std::lock_guard<std::mutex> guard(this->_mutex);
redisReply* raw_reply = static_cast<redisReply*>(redisCommand(this->_context, format, args...));
if (!raw_reply) {
throw RedisException(this->_context->errstr);
}
RedisReply reply(raw_reply, freeReplyObject);
if (reply->type == REDIS_REPLY_ERROR) {
throw RedisException(reply->str, reply->len);
}
return reply;
}
void auth(const std::string& username, const std::string& password);
void auth(const std::string& password);
time_t ttl(const std::string& key);
bool expire(const std::string& key, time_t expiry);
bool expire_nx(const std::string& key, time_t expiry);
std::optional<std::string> get(const std::string& key);
void set(const std::string& key, const std::string& value, time_t expiry);
std::optional<std::string> hget(const std::string& key, const std::string& field);
void hset(const std::string& key, const std::string& field, const std::string& value);
private:
redisContext* _context;
std::mutex _mutex;
bool _fake_expire_nx = false;
};
extern std::optional<Redis> redis;
void init_redis();