基于hiredis,redis C客户端封装
项目中需要用到redis就封装了一下,基于hiredis,只封装了string和哈希的部分方法。编译时加入-D__USER_LOCK__添加线程安全。
suntelRedisCli.h
#ifndef __SUNTELREDISCLI_H__
#define __SUNTELREDISCLI_H__
#include <hiredis/hiredis.h>
#ifdef __USE_LOCK__
#include <pthread.h>
#endif
#define REDIS_OK 0
#define REDIS_ERROR 0xFFFFFFFF
class CRedisCli
{
public:
CRedisCli();
~CRedisCli();
/*
* 连接到redis server
*/
int ConnectDB(const char *hostName,const int port);
int ConnectDB();
int Auth(const char *password);
/*
* 系统管理
*/
int SelectDB(int no);
int FlushDB();
int FlushAll();
/*
* string类
*/
int Set(const char *key,const char *format,...);
int Get(const char *key,char *value);
int Del(const char *key);
/*
* 哈希类
*/
int HMSet(const char *key,const char *format,...);
int HMGet(const char *key,size_t *elements,char **element);//返回element
int HSetField(const char *key,const char *field,const char *format,...);
int HGetField(const char *key,const char *field,char *value);
int HDel(const char *key);
private:
#ifdef __USE_LOCK__
pthread_mutex_t m_mutex;
#endif
redisContext* m_context;
redisReply* m_reply;
char m_redisHost[32];
int m_redisPort;
char m_redisPswd[32];
};
#endif
suntelRedisCli.cpp
#include <string.h>
#include <stdio.h>
#include "suntelRedisCli.h"
CRedisCli::CRedisCli()
{
m_context = NULL;
m_reply = NULL;
strcpy(m_redisHost,"127.0.0.1");
m_redisPort = 6379;
memset(m_redisPswd,0x00,sizeof(m_redisPswd));
#ifdef __USE_LOCK__
pthread_mutex_init(&m_mutex, NULL);
#endif
}
CRedisCli::~CRedisCli()
{
if(m_context)
redisFree(m_context);
m_reply = NULL;
#ifdef __USE_LOCK__
pthread_mutex_destroy(&m_mutex);
#endif
}
int CRedisCli::ConnectDB(const char *hostName,const int port)
{
#ifdef __USE_LOCK__
pthread_mutex_lock(&m_mutex);
#endif
strncpy(m_redisHost,hostName,sizeof(m_redisHost)-1);
m_redisPort = port;
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return ConnectDB();
}
int CRedisCli::ConnectDB()
{
int ret = REDIS_OK;
#ifdef __USE_LOCK__
pthread_mutex_lock(&m_mutex);
#endif
m_context = redisConnect(m_redisHost,m_redisPort);
if(m_context == NULL || m_context->err)
{
if(m_context){
fprintf(stderr,"Connection error: %s\n",m_context->errstr);
redisFree(m_context);
m_context = NULL;
}
else{
fprintf(stderr,"Connection error: can't allocate redis context\n");
}
ret = REDIS_ERROR;
}
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return ret;
}
int CRedisCli::Auth(const char *password)
{
int ret = REDIS_OK;
#ifdef __USE_LOCK__
pthread_mutex_lock(&m_mutex);
#endif
strncpy(m_redisPswd,password,sizeof(m_redisPswd)-1);
m_reply = (redisReply *)redisCommand(m_context,"auth %s",m_redisPswd);
if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
{
if(m_reply)
{
fprintf(stderr,"redis error: %s\n",m_reply->str);
freeReplyObject(m_reply);
m_reply = NULL;
}
else
{
fprintf(stderr,"redis error with null m_reply");
}
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return REDIS_ERROR;
}
freeReplyObject(m_reply);
m_reply = NULL;
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return ret;
}
int CRedisCli::SelectDB(int no)
{
int ret = REDIS_OK;
#ifdef __USE_LOCK__
pthread_mutex_lock(&m_mutex);
#endif
m_reply = (redisReply *)redisCommand(m_context,"select %d",no);
if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
{
if(m_reply)
{
fprintf(stderr,"redis error: %s\n",m_reply->str);
freeReplyObject(m_reply);
m_reply = NULL;
}
else
{
fprintf(stderr,"redis error with null m_reply");
}
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return REDIS_ERROR;
}
freeReplyObject(m_reply);
m_reply = NULL;
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return ret;
}
int CRedisCli::FlushDB()
{
int ret = REDIS_OK;
#ifdef __USE_LOCK__
pthread_mutex_lock(&m_mutex);
#endif
m_reply = (redisReply *)redisCommand(m_context,"flushdb");
if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
{
if(m_reply)
{
fprintf(stderr,"redis error: %s\n",m_reply->str);
freeReplyObject(m_reply);
m_reply = NULL;
}
else
{
fprintf(stderr,"redis error with null m_reply");
}
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return REDIS_ERROR;
}
freeReplyObject(m_reply);
m_reply = NULL;
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return ret;
}
int CRedisCli::FlushAll()
{
int ret = REDIS_OK;
#ifdef __USE_LOCK__
pthread_mutex_lock(&m_mutex);
#endif
m_reply = (redisReply *)redisCommand(m_context,"flushall");
if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
{
if(m_reply)
{
fprintf(stderr,"redis error: %s\n",m_reply->str);
freeReplyObject(m_reply);
m_reply = NULL;
}
else
{
fprintf(stderr,"redis error with null m_reply");
}
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return REDIS_ERROR;
}
freeReplyObject(m_reply);
m_reply = NULL;
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return ret;
}
int CRedisCli::Set(const char *key,const char *format,...)
{
va_list ap;
va_start(ap,format);
char buf[512]={0x00};
snprintf(buf,512,"SET %s %s",key,format);
int ret = REDIS_OK;
#ifdef __USE_LOCK__
pthread_mutex_lock(&m_mutex);
#endif
m_reply = (redisReply *)redisvCommand(m_context,buf,ap);
va_end(ap);
if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
{
if(m_reply)
{
fprintf(stderr,"redis error: %s\n",m_reply->str);
freeReplyObject(m_reply);
m_reply = NULL;
}
else
{
fprintf(stderr,"redis error with null m_reply");
}
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return REDIS_ERROR;
}
freeReplyObject(m_reply);
m_reply = NULL;
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return ret;
}
int CRedisCli::Get(const char *key,char * value)
{
int ret = REDIS_OK;
#ifdef __USE_LOCK__
pthread_mutex_lock(&m_mutex);
#endif
m_reply = (redisReply *)redisCommand(m_context,"GET %s",key);
if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
{
if(m_reply)
{
fprintf(stderr,"redis error: %s\n",m_reply->str);
freeReplyObject(m_reply);
m_reply = NULL;
}
else
{
fprintf(stderr,"redis error with null m_reply");
}
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return REDIS_ERROR;
}
if(m_reply->type == REDIS_REPLY_STRING)
{
strncpy(value,m_reply->str,m_reply->len);
}
freeReplyObject(m_reply);
m_reply = NULL;
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return ret;
}
int CRedisCli::Del(const char *key)
{
int ret = REDIS_OK;
#ifdef __USE_LOCK__
pthread_mutex_lock(&m_mutex);
#endif
m_reply = (redisReply *)redisCommand(m_context,"DEL %s",key);
if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
{
if(m_reply)
{
fprintf(stderr,"redis error: %s\n",m_reply->str);
freeReplyObject(m_reply);
m_reply = NULL;
}
else
{
fprintf(stderr,"redis error with null m_reply");
}
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return REDIS_ERROR;
}
freeReplyObject(m_reply);
m_reply = NULL;
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return ret;
}
int CRedisCli::HMSet(const char *key,const char *format,...)
{
va_list ap;
va_start(ap,format);
char buf[512]={0x00};
snprintf(buf,512,"HMSet %s %s",key,format);
// printf("%s\n",buf);
int ret = REDIS_OK;
#ifdef __USE_LOCK__
pthread_mutex_lock(&m_mutex);
#endif
m_reply = (redisReply *)redisvCommand(m_context,buf,ap);
va_end(ap);
if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
{
if(m_reply)
{
fprintf(stderr,"redis error: %s\n",m_reply->str);
freeReplyObject(m_reply);
m_reply = NULL;
}
else
{
fprintf(stderr,"redis error with null m_reply");
}
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return REDIS_ERROR;
}
freeReplyObject(m_reply);
m_reply = NULL;
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return ret;
}
int CRedisCli::HMGet(const char *key,size_t *elements,char **element)
{
int ret = REDIS_OK;
#ifdef __USE_LOCK__
pthread_mutex_lock(&m_mutex);
#endif
m_reply = (redisReply *)redisCommand(m_context,"HGETALL %s",key);
if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
{
if(m_reply)
{
fprintf(stderr,"redis error: %s\n",m_reply->str);
freeReplyObject(m_reply);
m_reply = NULL;
}
else
{
fprintf(stderr,"redis error with null m_reply");
}
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return REDIS_ERROR;
}
if(m_reply->type == REDIS_REPLY_ARRAY)
{
int i = 0;
for(i=0;i<m_reply->elements;i++)
{
strncpy(element[i],m_reply->element[i]->str,m_reply->element[i]->len);
}
}
freeReplyObject(m_reply);
m_reply = NULL;
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return ret;
}
int CRedisCli::HSetField(const char *key,const char *field,const char *format,...)
{
va_list ap;
va_start(ap,format);
char buf[512]={0x00};
snprintf(buf,512,"HSet %s %s %s",key,field,format);
//printf("%s\n",buf);
int ret = REDIS_OK;
#ifdef __USE_LOCK__
pthread_mutex_lock(&m_mutex);
#endif
m_reply = (redisReply *)redisvCommand(m_context,buf,ap);
va_end(ap);
if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
{
if(m_reply)
{
fprintf(stderr,"redis error: %s\n",m_reply->str);
freeReplyObject(m_reply);
m_reply = NULL;
}
else
{
fprintf(stderr,"redis error with null m_reply");
}
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return REDIS_ERROR;
}
freeReplyObject(m_reply);
m_reply = NULL;
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return ret;
}
int CRedisCli::HGetField(const char *key,const char *field,char *value)
{
int ret = REDIS_OK;
#ifdef __USE_LOCK__
pthread_mutex_lock(&m_mutex);
#endif
m_reply = (redisReply *)redisCommand(m_context,"HGET %s %s",key,field);
if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
{
if(m_reply)
{
fprintf(stderr,"redis error: %s\n",m_reply->str);
freeReplyObject(m_reply);
m_reply = NULL;
}
else
{
fprintf(stderr,"redis error with null m_reply");
}
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return REDIS_ERROR;
}
if(m_reply->type == REDIS_REPLY_STRING)
{
strncpy(value,m_reply->str,m_reply->len);
}
freeReplyObject(m_reply);
m_reply = NULL;
#ifdef __USE_LOCK__
pthread_mutex_unlock(&m_mutex);
#endif
return ret;
}
int CRedisCli::HDel(const char *key)
{
return Del(key);
}
``
编译:
g++ -shared --fIPC suntelRedisCli.cpp -o lsuntelRedisCli -lhiredis
g++ -shared --fIPC suntelRedisCli.cpp -o lsuntelRedisCli -lhiredis -D__USE_LOCK__
基于hiredis,redis C客户端封装的更多相关文章
- redis web 客户端工具 redis-admin
redis-admin是基于java的redis web客户端(redis client),以方便广大程序员使用redis为宗旨,集五种数据结构增删改查于一身. https://github.com/ ...
- Redis C客户端API - God's blog - 博客频道 - CSDN.NET
Redis C客户端API - God's blog - 博客频道 - CSDN.NET Redis安装步骤: 1.redis server安装 wget http://redis.googlecod ...
- 基于表单数据的封装,泛型,反射以及使用BeanUtils进行处理
在Java Web开发过程中,会遇到很多的表单数据的提交和对表单数据的处理.而每次都需要对这些数据的字段进行一个一个的处理就显得尤为繁琐,在Java语言中,面向对象的存在目的便是为了消除重复代码,减少 ...
- Asp.Net Core 2.0 项目实战(6)Redis配置、封装帮助类RedisHelper及使用实例
本文目录 1. 摘要 2. Redis配置 3. RedisHelper 4.使用实例 5. 总结 1. 摘要 由于內存存取速度远高于磁盘读取的特性,为了程序效率提高性能,通常会把常用的不常变动的数 ...
- 【原创】自己动手写一个能操作redis的客户端
引言 redis大家在项目中经常会使用到.官网也提供了多语言的客户端供大家操作redis,如下图所示 但是,大家有思考过,这些语言操作redis背后的原理么?其实,某些大神会说 只要按照redis的协 ...
- 基于开源SuperSocket实现客户端和服务端通信项目实战
一.课程介绍 本期带给大家分享的是基于SuperSocket的项目实战,阿笨在实际工作中遇到的真实业务场景,请跟随阿笨的视角去如何实现打通B/S与C/S网络通讯,如果您对本期的<基于开源Supe ...
- 适用于app.config与web.config的ConfigUtil读写工具类 基于MongoDb官方C#驱动封装MongoDbCsharpHelper类(CRUD类) 基于ASP.NET WEB API实现分布式数据访问中间层(提供对数据库的CRUD) C# 实现AOP 的几种常见方式
适用于app.config与web.config的ConfigUtil读写工具类 之前文章:<两种读写配置文件的方案(app.config与web.config通用)>,现在重新整理一 ...
- 自荐RedisViewer有情怀的跨平台Redis可视化客户端工具
# **自荐一个有情怀的跨平台Redis可视化客户端工具——RedisViewer**[转载自 最美分享Coder 2019-09-17 06:31:00](https://www.toutiao.c ...
- 自荐RedisViewer一个有情怀的跨平台Redis可视化客户端工具
自荐一个有情怀的跨平台Redis可视化客户端工具--RedisViewer 转载自 最美分享Coder 2019-09-17 06:31:00 介绍 在以往的文章中曾经介绍过几款Redis的可视化工具 ...
随机推荐
- ActiveMQ 的线程池
ActiveMQ 的线程池实质上也是 ThreadPoolExecutor,不过它的任务模型有自己的特点,我们先看一个例子: public static void main(String[] args ...
- pandas报错处理:TypeError: Empty 'DataFrame': no numeric data to plot
Tushare返回的是pandas的DataFrame格式,但是执行以下代码时报错:TypeError: Empty 'DataFrame': no numeric data to plot impo ...
- SecureCRT修改显示行数
Scrollback buffer应该是保留的行数,初始值500,修改成自己想要的数值保存即可. 参考:http://blog.csdn.net/w410589502/article/details/ ...
- 微信小程序自动定位,通过百度地图根据经纬度获取该地点所在城市信息
微信小程序获得经纬度 var that = this wx.getLocation({ type: 'wgs84', success(res) { console.log(res) that.setD ...
- window7下载安装桌面版ubuntu
首先需要下载VMware Workstation 下载地址:http://pan.baidu.com/s/1qXS0rhi 秘钥:bbpn 我的环境是ubuntu-14.10-desktop-a ...
- 学习笔记-AngularJs (一)
最近对AngularJs产生了浓厚的学习兴趣,于是便搜罗所有资料,开始学习起来,也希望把学习过程记录下来. 首先学习之前,需要对AngularJs进行个大概的了解: AngularJS[1] 诞生于 ...
- Win10系列:VC++媒体播放
媒体播放包括视频播放和音频播放,在开发Windows应用商店应用的过程中可以使用MediaElement控件来播放视频文件和音频文件.本节将通过一个具体的示例介绍如何使用MediaElement控件来 ...
- break&&continue
break和continue的区别: 1. 当它们用在循环语句的循环体时,break用于立即退出本层循环,而continue仅仅结束本次循环(本次循环体内不执行continue语句后的其它语句,但下一 ...
- shell script auto generate the relevant header information
first : add follow context in /etc/vim/vimrc set ignorecaseset cursorlineset autoindentautocmd Buf ...
- spring bean 的生命周期
感谢博友,内容源于博友的文章 http://www.cnblogs.com/zrtqsk/p/3735273.html 通过了解spring的bean 的生命周期 ,再结合jdk的注解,继承sprin ...