数据库连接池DBPool分析(七):Redis连接控制 RedisObj

因为这个连接控制的class当中使用了大量的引用,所以设置一个宏IN和OUT,仅仅只是一个标志,标记是输出还是输入。
这个class的设计和MysqlObj的设计非常像,但是不同的是这里并不需要一个对象来专门保存查询值,就因为Redis是key-value的,查询是直接返回一个字符串或者数字。
所以这里只需要一个成员变量来保存查询值,就是redisReply* r_pResult;
redisReply是定义在hiredis.h头文件当中的。
另外一个设计上的需求是这里还没有加上登陆密码。Redis是可以设置密码的。

和MysqlObj相比的大差距是这些函数:

public: 
    // 从redis当中获取返回值
    int IntegerResult(OUT long long &result);
    int StringResult(OUT string &result);
    int StatusResult(OUT string &result);
    int StringArrayResult(OUT vector<string> &result);
    int ArrayResult(OUT vector<redisReply*> &result);

同样也是因为Redis不是关系型数据库,所以需要对返回值的pResult的type进行检查。检查之后再执行对应的函数。


#ifndef _REDIS_OBJ_H
#define _REDIS_OBJ_H

#include <hiredis/hiredis.h>
#include <string>
#include <vector>
#include "debug.h"

using std::string;
using std::vector;

// 设置一个标志,函数参数列表当中带有OUT的就是输出引用,带有IN的就是输入参数
#define OUT
#define IN

class RedisObj
{
 public:
    RedisObj(string HostIP, string pPassword, unsigned iPort);
    virtual ~RedisObj();
    // Dump指的是把m_pRedis的指针指向的值打印出来
    void Dump() const;

    string ErrorMessage();

    // 根据成员变量来建立Redis连接
    bool Connect();
    void Close();

    int ExecuteCmd(const char* pCmd);

    //返回Redis的指针
    redisContext* get() const;

 public: 
    // 从redis当中获取返回值
    int IntegerResult(OUT long long &result);
    int StringResult(OUT string &result);
    int StatusResult(OUT string &result);
    int StringArrayResult(OUT vector<string> &result);
    int ArrayResult(OUT vector<redisReply*> &result);

 private:
    // 从redis当中获取返回值
    int IntegerResult(OUT long long &result, IN redisReply* reply);
    int StringResult(OUT string &result, IN redisReply* reply);
    int StatusResult(OUT string &result, IN redisReply* reply);
    int StringArrayResult(OUT vector<std::string> &result, IN redisReply* reply);
    int ArrayResult(OUT vector<redisReply*> &result, IN redisReply* reply);

 private:
    // 代表了一条数据库连接
    redisContext* r_pRedis;
    redisReply* r_pResult;
 private:
    // 连接必备的参数:IP地址,用户,密码,数据库名称,端口号
    string r_strHost;
    string r_strPassword;
    unsigned r_iPort;

    //错误信息
    string r_strErrorMessage;
};

#endif /* REDIS_OBJ_H */

#include "../include/redis_obj.h"
#include <assert.h>
#include <cstring>

RedisObj::RedisObj(string host, string password, unsigned port)
: r_strHost(host), r_strPassword(password), r_iPort(port)
{
    r_pRedis = NULL;
}

RedisObj::~RedisObj()
{
    Close();
}

void RedisObj::Dump() const
{
    printf("r_pRedis=%p", r_pRedis);
}

string RedisObj::ErrorMessage()
{
    return "";
}

bool RedisObj::Connect()
{
    r_pRedis = redisConnect(r_strHost.c_str(), r_iPort);  
    if ( r_pRedis->err )
    {
        return false;
    }
    return true;
}

void RedisObj::Close() 
{
    if ( r_pRedis ) 
    {
        redisFree(r_pRedis);
        r_pRedis = NULL;
    }
}

int RedisObj::ExecuteCmd(IN const char* pCmd)
{
    r_pResult = (redisReply*)redisCommand(r_pRedis, pCmd);  
    if( r_pResult == NULL)
    {
        return -1;
    }   
    return 0;
}


redisContext* RedisObj::get() const
{
    return r_pRedis;
}


int RedisObj::IntegerResult(OUT long long &result)
{
    return IntegerResult(result, r_pResult);
}

int RedisObj::StringResult(OUT string &result)
{
    return StringResult(result, r_pResult);
}

int RedisObj::StatusResult(OUT string &result)
{
    return StatusResult(result, r_pResult);
}

int RedisObj::StringArrayResult(OUT vector<string> &result)
{
    return StringArrayResult(result, r_pResult);
}

int RedisObj::ArrayResult(OUT vector<redisReply*> &result)
{
    return ArrayResult(result, r_pResult);
}

// 从redis当中获取返回值
int RedisObj::IntegerResult(OUT long long &result, IN redisReply* reply)
{
    if(reply == NULL)
        return -1;
    if(reply->type != REDIS_REPLY_INTEGER)
        return -1;

    result = reply->integer;
    return 1;
}

int RedisObj::StringResult(OUT std::string &result, IN redisReply* reply)
{
    if(reply == NULL)
        return -1;
    if(reply->type == REDIS_REPLY_NIL)
        return 0;
    if(reply->type != REDIS_REPLY_STRING)
        return -1;

    result.clear();
    result.assign(reply->str, reply->len);
    return 1;
}

int RedisObj::StatusResult(OUT std::string &result, IN redisReply* reply)
{
    if(reply == NULL)
        return -1;
    if(reply->type != REDIS_REPLY_STATUS)
        return -1;

    result.clear();
    result.assign(reply->str, reply->len);
    return 1;
}

int RedisObj::StringArrayResult(OUT std::vector<std::string> &result, IN redisReply* reply)
{
    if(reply == NULL)
        return -1;
    if(reply->type == REDIS_REPLY_NIL)
        return 0;
    if(reply->type != REDIS_REPLY_ARRAY)
        return -1;

    result.clear();
    for(size_t i=0; i<reply->elements; i++)
    {
        redisReply* r = reply->element[i];
        if(r->type == REDIS_REPLY_STRING)
        {
            result.emplace_back(r->str, r->len);
        }
    }
    if(result.size() == 0)
        return 0;
    return 1;
}
int RedisObj::ArrayResult(OUT std::vector<redisReply*> &result, IN redisReply* reply)
{
    if(reply == NULL)
        return -1;
    if(reply->type != REDIS_REPLY_ARRAY)
        return -1;

    result.clear();
    for(size_t i=0; i<reply->elements; i++)
    {
        redisReply* r = reply->element[i];
        result.emplace_back(r);
    }
    if(result.size() == 0)
        return 0;
    return 1;
}

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值