tg_redis.h
#ifndef TG_REDIS_H
#define TG_REDIS_H
#include
#include
#include
#include"string"
#include
#include
#include
struct tg_redis_param
{
std::string host;
int port;
int db_index;
std::string pwd;
struct timeval timeout;
};
class tg_redis_result
{
private:
redisReply* _reply;
public:
tg_redis_result(redisReply* reply):_reply(reply)
{
}
~tg_redis_result()
{
if(_reply)
{
freeReplyObject(_reply);
_reply=nullptr;
}
}
public:
bool is_null()
{
return !_reply || _reply->type == REDIS_REPLY_NIL;
}
bool is_error()
{
return _reply->type == REDIS_REPLY_ERROR;
}
bool is_ok()
{
return !is_null() && !is_error();
}
const redisReply* get_reply()
{
return _reply;
}
bool try_get_value(int64_t& out_val)
{
if(is_error())
{
return false;
}
out_val = std::atoll(_reply->str);
return true;
}
bool try_get_value(double& out_val)
{
if(is_error())
{
return false;
}
out_val = std::atof(_reply->str);
return true;
}
bool try_get_value(std::string& out_val)
{
if(is_error())
{
return false;
}
out_val = _reply->str;
return true;
}
bool try_get_value(bool& out_val)
{
if(is_error())
{
return false;
}
out_val = strcasecmp("true", _reply->str) == 0;
return true;
}
uint64_t get_len()
{
return _reply->len;
}
bool is_arr()
{
return _reply->type == REDIS_REPLY_ARRAY;
}
uint64_t get_len_arr()
{
return _reply->elements;
}
int64_t get_integer()
{
return _reply->integer;
}
const char* get_str()
{
return _reply->str;
}
};
class tg_redis_conn
{
private:
redisContext* _context_ptr;
int _db_no;
std::shared_ptr _param_ptr;
std::string _last_error;
public:
tg_redis_conn(const std::shared_ptr& param)
:_context_ptr(nullptr)
,_param_ptr(param)
{
}
~tg_redis_conn()
{
close();
}
bool connect()
{
close();
_context_ptr = redisConnectWithTimeout(_param_ptr->host.c_str(), _param_ptr->port, _param_ptr->timeout);
if(!_context_ptr || _context_ptr->err)
{
char buf[1024]={0};
if (_context_ptr)
{
sprintf(buf, "init redis is error: errcode=%d, errstr=%s", _context_ptr->err, _context_ptr->errstr);
_last_error=buf;
}
else
{
sprintf(buf, "connect error: can't allocate redis context. host=%s, port=%d",
_param_ptr->host.c_str(), _param_ptr->port);
_last_error=buf;
}
return false;
}
if(!_param_ptr->pwd.empty() && !exec_cmd("auth %s", _param_ptr->pwd.c_str()))
{
return false;
}
if(!exec_cmd("SELECT %d", _param_ptr->db_index))
{
return false;
}
_db_no = _param_ptr->db_index;
return true;
}
void close()
{
if(_context_ptr)
{
redisFree(_context_ptr);
_context_ptr = nullptr;
}
}
std::shared_ptr exec_cmd(const char* command, ...)
{
va_list ap;
va_start(ap,command);
auto reply = std::make_shared(static_cast(redisvCommand(_context_ptr, command, ap)));
va_end(ap);
if(reply->is_null())
{
_last_error = "Reply is null!";
return nullptr;
}
if(reply->is_error())
{
_last_error = reply->get_str();
return nullptr;
}
return reply;
}
std::string& get_last_err()
{
return _last_error;
}
bool rpush(std::string key,std::vector& value)
{
int64_t len=0;
auto reply = exec_cmd("llen %s", key.c_str());
if(!reply || reply->get_reply()->type != REDIS_REPLY_INTEGER)
{
return false;
}
len=reply->get_integer();
for(int i=0; iget_reply()->type != REDIS_REPLY_INTEGER)
{
return false;
}
if(++len != reply->get_integer())
{
return false;
}
}
return true;
}
bool lrange_all(std::string key, std::vector& out_data)
{
int64_t len=0;
auto reply = exec_cmd("llen %s", key.c_str());
if(!reply || reply->get_reply()->type != REDIS_REPLY_INTEGER)
{
return false;
}
len=reply->get_integer();
reply = exec_cmd("LRANGE %s %d %d", key.c_str(),0,len-1);
if(!reply || reply->get_reply()->type != REDIS_REPLY_ARRAY)
{
return false;
}
redisReply** replyVector = reply->get_reply()->element;//获取数组指针
out_data.reserve(len);
for(int i=0;istr;//遍历redisReply*数组,存入vector向量
int a =std::atoi(temp.c_str());
out_data.push_back(a);
replyVector++;
}
return true;
}
///设置一个字符串到key
bool set(const char* key, const char* value, unsigned int expire=0)
{
return (expire && exec_cmd("SETEX %s %d %s", key, expire, value))
|| (expire==0 && exec_cmd("SET %s %s", key, value) );
}
///设置一个字符串到hash
bool hset(const char* hash_name, const char* key, const char* value)
{
return nullptr != exec_cmd("HSET %s %s %s", hash_name, key, value);
}
bool rpush(const char* list_name, const char* value)
{
return nullptr != exec_cmd("RPUSH %s %s", list_name, value);
}
bool lset(const char* list_name, int index, const char* value)
{
return nullptr != exec_cmd("LSET %s %d %s", list_name, index, value);
}
///添加一个数据到有序集合中
bool zadd(const char* set_name, int score, const char* value)
{
return nullptr != exec_cmd("ZADD %s %d %s", set_name, score, value);
}
///根据对应的数据得到一个排名
int64_t zrank(const char* set_name, const char* value)
{
auto ptr = exec_cmd("ZRANK %s %s", set_name, value);
if(ptr->is_ok())
{
return ptr->get_integer();
}
return -1;
}
///根据key得到一个value
std::shared_ptr get(const char* key)
{
return exec_cmd("GET %s", key);
}
///获取hash内的value
std::shared_ptr hget(const char* hash_name, const char* key)
{
return exec_cmd("HGET %s %s", hash_name, key);
}
///从有序集合中得到数据
std::shared_ptr zrange(const char* set_name, uint64_t start, uint64_t end)
{
return exec_cmd("ZRANGE %s %d %d", set_name, start, end);
}
///从列表中获取数据
std::shared_ptr lrange(const char* list_name, size_t start, size_t end)
{
return exec_cmd("LRANGE %s %d %d", list_name, start, end);
}
///列表长度
uint64_t llen(const char* list_name)
{
auto tmp = exec_cmd("LLEN %s", list_name);
if(tmp)
{
return tmp->get_len();
}
return 0;
}
std::shared_ptr lpop(const char* list_name)
{
return exec_cmd("LPOP %s %s", list_name);
}
///移除list的尾部并且返回
std::shared_ptr rpop(const char* list_name)
{
return exec_cmd("RPOP %s %s", list_name);
}
bool exists(const char* key)
{
return nullptr != exec_cmd("exists %s", key);
}
bool del(const char* key)
{
return nullptr != exec_cmd("DEL %s", key);
}
///当前使用中的DB
int db_no()
{
return _db_no;
}
};
#endif // TG_REDIS_H
测试:
#include
#include
#include
#include
#include "tg_redis.h"
void test()
{
auto param_ptr = std::make_shared();
param_ptr->db_index = 0;
param_ptr->host = "192.168.0.105";
param_ptr->port = 6379;
param_ptr->timeout.tv_sec = 3;
param_ptr->timeout.tv_usec = 0;
param_ptr->pwd = "123456";
tg_redis_conn conn(param_ptr);
if(!conn.connect())
{
std::cout<< conn.get_last_err() <get_str() <try_get_value(hao);
std::cout<< hao < arr;
for(int i=0; i<5; i++)
{
arr.push_back(i);
}
if(!conn.rpush("list8", arr))
{
std::cout<< "conn.rpush(\"list8\", arr)" < out;
if(!conn.lrange_all("list8", out))
{
std::cout<< "conn.lrange_all(\"list8\", out)" <