对hiredis接口的封装

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)" <


 

 



 

你可能感兴趣的:(redis)