redis C++ API

= =琢磨了一下 hiredis 感觉很赞。

用C++封装了一下。

/**
 *	缓存工具
 *	Created on : 2014-05-08
 *		Author : frodo
 */

#ifndef FSCACHEDB_H_
#define FSCACHEDB_H_


#include <stdio.h> /* for size_t */
#include <stdarg.h> /* for va_list */


class FSCacheData{
public:
	virtual bool isNil(int index=0) = 0;
	virtual int getInt(int index=0) = 0;
	virtual float getFloat(int index=0) = 0;
	virtual const char* getString(int index=0) = 0;
	virtual bool getBool(int index=0) = 0;
	virtual char* getBinary(int index=0) = 0;
	virtual size_t getLength(int index=0) = 0;
	virtual size_t getArrayLength() = 0;
	virtual bool isArray() = 0;

};

class FSCacheConfig{

};

class FSCacheDB{
public:
	FSCacheDB();
public:

	/**
	 * 设置一个字符串到key
	 * @key		:  key
	 * @value	:  value
	 * @return : 是否成功
	 */
	virtual bool setString(const char* key, const char* value, unsigned int expire=0) = 0;

	/**
	 * 设置一个二进制数据到key
	 * @key		:  key
	 * @value	:  value
	 * @return : 是否成功
	 */
	virtual bool setBinary(const char* key, unsigned char* data, size_t len) = 0;

	/**
	 * 设置一个字符串到hash
	 * @hash_name : hahs名字
	 * @key		  : hash_key
	 * @value	  : value
	 * @return : 是否成功
	 */
	virtual bool setHashString(const char* hash_name, const char* key, const char* value) = 0;

	/**
	 * 设置一个二进制数据到hash
	 * @hash_name : hash名字
	 * @key		  : hash_key
	 * @value	  : value
	 * @len		  : len
	 * @return : 是否成功
	 */
	virtual bool setHashBinary(const char* hash_name, const char* key, unsigned char* data, size_t len) = 0;


	/**
	 * 添加一个字符串到列表尾
	 * @list_name : 列表名字
	 * @value	  : 数据
	 * @return    : 返回数组长度
	 */
	virtual int  pushStringToList(const char* list_name, const char* value) = 0;


	/**
	 * 插入一个二进制数据到列表
	 * @list_name : 列表名字
	 * @value	  : 数据
	 * @return    : 返回数组长度
	 */
	virtual bool  setBinaryToList(const char* list_name, int index, char* data, size_t len) = 0;


	/**
	 * 插入一个字符串到列表
	 * @list_name : 列表名字
	 * @value	  : 数据
	 * @return    : 返回数组长度
	 */
	virtual bool  setStringToList(const char* list_name, int index, const char* value) = 0;


	/**
	 * 添加一个二进制数据到列表尾
	 * @list_name : 列表名字
	 * @value	  : 数据
	 * @return    : 返回数组长度
	 */
	virtual int  pushBinaryToList(const char* list_name, char* binary, size_t len) = 0;

	/**
	 * 添加一个数据到有序集合中
	 * @set_name : 集合名字
	 * @score	 : 排序值
	 * @value	 : 该排序对应的数据
	 */
	virtual void addSortedSet(const char* set_name, int score, const char* value)=0;

	/**
	 * 根据对应的数据得到一个排名
	 * @set_name : 集合名字
	 * @value	 : 获取该数据的排名
	 * @return : 返回排名
	 */
	virtual int  getSortByString(const char* set_name, const char* value)=0;

public:
	/**
	 * 根据key得到一个value
	 * @key 	: key_name
	 * @outdata : 输出数据
	 * @return : 是否成功
	 */
	virtual bool getDataFromKey(const char* key, FSCacheData* outdata) = 0;
	/**
	 * 获取hash内的value
	 * @hash_name : hash_name
	 * @key		  : key
	 * @outdata : 输出数据
	 * @return : 是否成功
	 */
	virtual bool getDataFromHash(const char* hash_name, const char* key, FSCacheData* outdata) = 0;

	/**
	 * 从有序集合中得到数据
	 * @set_name : set_name
	 * @starr	  : start
	 * @end		  : end
	 * @outdata : 输出数据
	 * @return : 是否成功
	 */
	virtual bool  getDataFromSoctedSet(const char* set_name, size_t start, size_t end, FSCacheData* outdata) = 0;
	/**
	 * 从列表中获取数据
	 * @list_name : list_name
	 * @starr	  : start
	 * @end		  : end
	 * @outdata : 输出数据
	 * @return : 是否成功
	 */
	virtual bool getDataFromList(const char* list_name, size_t start, size_t end, FSCacheData* outdata) = 0;

	/**
	 * 从列表长度
	 * @list_name : list_name
	 * @return : 长度
	 */
	virtual int getListLen(const char* list_name) = 0;

	/**
	 * 弹出list的头部并且返回
	 * @list_name : list_name
	 * @outdata : 输出数据
	 * @return : 是否成功
	 */
	virtual bool shiftDataFromList(const char* list_name, FSCacheData* outdata) = 0;

	/**
	 * 移除list的尾部并且返回
	 * @list_name : list_name
	 * @outdata : 输出数据
	 * @return : 是否成功
	 */
	virtual bool popDataFromList(const char* list_name, FSCacheData* outdata) = 0;

public:
	/**
	 * 获取一个自增的值
	 * @key	: 自增key
	 * @return : 返回自增后的数值
	 */
	virtual int incrKey(const char* key) = 0;


	/**
	 * 删除一个key
	 * @key		:  key
	 * @value	:  value
	 * @return : 是否成功
	 */
	virtual bool delKey(const char* key) = 0;

public:
	/**
	 * 选择DB
	 * @index		:  index	0~16
	 */
	virtual bool selectDB(int index) = 0;
	/**
	 * 获取当前使用中的DB
	 * @return	: 返回使用中的DB
	 */
	virtual int getDBNumber() = 0;

public:
	/**
	 * 初始化链接
	 */
	virtual bool connect(FSCacheConfig* conf)=0;

	/**
	 * 关闭链接
	 */
	virtual bool close()=0;

	static FSCacheDB* sharedCacheDB();
};

#endif /* FSCACHEDB_H_ */



#include "FSCacheDB.h"

static FSCacheDB* s_sharedCache = NULL;
FSCacheDB::FSCacheDB(){
	s_sharedCache = this;
}




FSCacheDB* FSCacheDB::sharedCacheDB(){
	return s_sharedCache;
}

/*
 * FSRedis.h
 *
 *  Created on: 2014-5-8
 *      Author: frodo
 */

#ifndef FSREDIS_H_
#define FSREDIS_H_

#include "FSCacheDB.h"
#include <hiredis/hiredis.h>


class FSRedis;
class FSRedisData : public FSCacheData
{

private:
	redisReply* m_pReply;
	friend class FSRedis;

	void initReply(redisReply*);

private:
	bool checkType(int index);
public:

	FSRedisData();
	~FSRedisData();

private:
	redisReply* getReply(int index=0);

public:

	virtual bool isNil(int index=0) ;
	virtual int getInt(int index=0) ;
	virtual float getFloat(int index=0) ;
	virtual const char* getString(int index=0) ;
	virtual bool getBool(int index=0) ;
	virtual char* getBinary(int index=0) ;
	virtual size_t getLength(int index=0);
	virtual bool isArray();
	virtual size_t getArrayLength();
};

class FSRedisConfig : public FSCacheConfig{

public:
	const char* host;
	int port;
	int db_index;
    struct timeval timeout;
};

class FSRedis : public FSCacheDB{
public:
	FSRedis();
	virtual ~FSRedis();

private:
	int m_iSelectedDB;
	redisContext* m_pContext;

public:
	virtual bool setString(const char* key, const char* value, unsigned int expire=0) ;
	virtual bool setBinary(const char* key, unsigned char* data, size_t len) ;
	virtual bool setHashString(const char* hash_name, const char* key, const char* value) ;
	virtual bool setHashBinary(const char* hash_name, const char* key, unsigned char* data, size_t len) ;
	virtual int  pushStringToList(const char* list_name, const char* value);
	virtual int  pushBinaryToList(const char* list_name, char* binary, size_t len);
	virtual bool setBinaryToList(const char* list_name, int index, char* data, size_t len) ;
	virtual bool setStringToList(const char* list_name, int index, const char* value) ;
	virtual void addSortedSet(const char* set_name, int score, const char* value);
	virtual int  getSortByString(const char* set_name, const char* value);
public:
	virtual int  getListLen(const char* list_name) ;
	virtual bool getDataFromList(const char* list_name, size_t start, size_t end, FSCacheData* outdata);
	virtual bool getDataFromSoctedSet(const char* set_name, size_t start, size_t end, FSCacheData* outdata);
	virtual bool getDataFromKey(const char* key, FSCacheData* outdata) ;
	virtual bool getDataFromHash(const char* hash_name, const char* key, FSCacheData* outdata) ;
	virtual bool shiftDataFromList(const char* list_name, FSCacheData* outdata) ;
	virtual bool popDataFromList(const char* list_name, FSCacheData* outdata) ;
public:
	virtual int incrKey(const char* key) ;
	virtual bool delKey(const char* key) ;
public:
	virtual bool selectDB(int index);
	virtual int getDBNumber();
public:
	bool connect(FSCacheConfig* conf);
	bool close();
public:	// redis
	bool checkReplay(redisReply*);
	bool executeCommand(const char* command, ...);
	bool executeCommand(const char* command, va_list ap);
};

#endif /* FSREDIS_H_ */


/*
 * FSRedis.cpp
 *
 *  Created on: 2014-5-8
 *      Author: frodo
 */

#include "FSRedis.h"

#include <stdlib.h>
#include <string.h>

#define _CHECK_CONNECT if(!m_pContext) return false;

FSRedisData::FSRedisData():m_pReply(NULL){
}

FSRedisData::~FSRedisData(){
	if(m_pReply){
		freeReplyObject(m_pReply);
	}
}

redisReply* FSRedisData::getReply(int index){
	if(m_pReply->type == REDIS_REPLY_ARRAY){
		return m_pReply->element[index];
	}else{
		return m_pReply;
	}
}
void FSRedisData::initReply(redisReply* reply){
	if(m_pReply){
		freeReplyObject(m_pReply);
		m_pReply = NULL;
	}
	m_pReply = reply;
}
bool FSRedisData::checkType(int index){
	return !isNil(index) &&
			(getReply(index)->type == REDIS_REPLY_STRING ||
					getReply(index)->type == REDIS_REPLY_INTEGER ||
					getReply(index)->type == REDIS_REPLY_STATUS);
}
bool FSRedisData::isArray(){
	return m_pReply->type == REDIS_REPLY_ARRAY;
}
bool FSRedisData::isNil(int index){
	return !m_pReply || m_pReply->type == REDIS_REPLY_NIL || m_pReply->type == REDIS_REPLY_ERROR;
}
int  FSRedisData::getInt(int index) {
	if(!checkType(index)){
		return 0;
	}
	return atoi(getString());
}
float  FSRedisData::getFloat(int index) {
	if(!checkType(index)){
		return 0;
	}
	return atof(getString());
}
const char*  FSRedisData::getString(int index) {
	if(!checkType(index)){
		return 0;
	}
	return getReply(index)->str;
}
bool  FSRedisData::getBool(int index) {
	if(!checkType(index)){
		return 0;
	}
	return strcasecmp("true", getReply(index)->str) == 0;
}
char*  FSRedisData::getBinary(int index) {
	return getReply(index)->str;
}
size_t  FSRedisData::getLength(int index){
	return getReply(index)->len;
}

size_t FSRedisData::getArrayLength(){
	if(m_pReply){
		return m_pReply->elements;
	}
	return 1;
}


FSRedis::FSRedis() {


}

FSRedis::~FSRedis() {
	this->close();
}

bool FSRedis::connect(FSCacheConfig* conf){

	FSRedisConfig* config = (FSRedisConfig*)conf;

	m_pContext = redisConnectWithTimeout(config->host, config->port, config->timeout);

	if(!m_pContext || m_pContext->err){
		printf("init redis is erro code[%d], msg[%s]\n", m_pContext->err, m_pContext->errstr);
		goto fail;
	}

	if(!selectDB(config->db_index)){
		goto fail;
	}

	goto success;

success:
	return true;
fail:
	return false;

}


bool FSRedis::close(){
	if(m_pContext){
		redisFree(this->m_pContext);
		m_pContext = NULL;
		return true;
	}
	return false;
}


bool FSRedis::selectDB(int index){
	if( executeCommand("SELECT %d", index) ){
		m_iSelectedDB = index;
		return true;
	}
	return false;
}
int FSRedis::getDBNumber(){
	return m_iSelectedDB;
}

bool FSRedis::checkReplay(redisReply* replay){
	return replay != NULL;
}
bool FSRedis::executeCommand(const char* command, ...){
	va_list ap;
	va_start(ap,command);
	bool ret = executeCommand(command, ap);
    va_end(ap);
	return ret;
}

bool FSRedis::executeCommand(const char* command, va_list ap){
	_CHECK_CONNECT
	redisReply* reply = (redisReply*)redisCommand(m_pContext, command, ap);
	if(!checkReplay(reply)){
		return false;
	}
	freeReplyObject(reply);
	return true;
}


bool FSRedis::setString(const char* key, const char* value, unsigned int expire){
	_CHECK_CONNECT
	redisReply* reply = NULL;
	if(expire != 0){
		reply = (redisReply*)redisCommand(m_pContext, "SETEX %s %d %s", key, expire, value);
	}else{
		reply = (redisReply*)redisCommand(m_pContext, "SET %s %s", key, value);
	}
	if(!checkReplay(reply)){
		return false;
	}
	freeReplyObject(reply);
	return true;
}
bool FSRedis::setBinary(const char* key, unsigned char* data, size_t len){
	_CHECK_CONNECT
	redisReply* reply = (redisReply*)redisCommand(m_pContext, "SET %s %b", key, data, len);
	if(!checkReplay(reply)){
		return false;
	}
	freeReplyObject(reply);
	return true;
}
bool FSRedis::setHashString(const char* hash_name, const char* key, const char* value){
	_CHECK_CONNECT
	redisReply* reply = (redisReply*)redisCommand(m_pContext, "HSET %s %s %s", hash_name, key, value);
	if(!checkReplay(reply)){
		return false;
	}
	freeReplyObject(reply);
	return true;
}
bool FSRedis::setHashBinary(const char* hash_name, const char* key, unsigned char* data, size_t len){
	_CHECK_CONNECT
	redisReply* reply = (redisReply*)redisCommand(m_pContext, "HSET %s %s %b", hash_name, key, data, len);
	if(!checkReplay(reply)){
		return false;
	}
	freeReplyObject(reply);
	return true;
}

bool  FSRedis::setBinaryToList(const char* list_name, int index, char* data, size_t len) {
	_CHECK_CONNECT
	redisReply* reply = (redisReply*) redisCommand(m_pContext, "LSET %s %d %b", list_name, index, data, len);
	if (!checkReplay(reply)) {
		return false;
	}
	freeReplyObject(reply);
	return true;
}
bool  FSRedis::setStringToList(const char* list_name, int index, const char* value) {
	_CHECK_CONNECT
	redisReply* reply = (redisReply*) redisCommand(m_pContext, "LSET %s %d %s", list_name, index, value);
	if(!checkReplay(reply)){ return false; }
	freeReplyObject(reply);
	return true;
}
int  FSRedis::pushStringToList(const char* list_name, const char* value){
	_CHECK_CONNECT
	redisReply* reply = (redisReply*)redisCommand(m_pContext, "RPUSH %s %s", list_name, value);
	if(!checkReplay(reply)){
		return -1;
	}
	int len = reply->integer;
	freeReplyObject(reply);
	return len;
}

int  FSRedis::pushBinaryToList(const char* list_name, char* binary, size_t len){
	_CHECK_CONNECT
	redisReply* reply = (redisReply*)redisCommand(m_pContext, "RPUSH %s %b", list_name, binary, len);
	if(!checkReplay(reply)){
		return -1;
	}
	int ret = reply->integer;
	freeReplyObject(reply);
	return ret;
}
void FSRedis::addSortedSet(const char* set_name, int score, const char* value){
	if(!m_pContext) return;
	redisReply* reply = (redisReply*)redisCommand(m_pContext, "ZADD %s %d %s", set_name, score, value);
	freeReplyObject(reply);
}
int  FSRedis::getSortByString(const char* set_name, const char* value){
	_CHECK_CONNECT
	redisReply* reply = (redisReply*)redisCommand(m_pContext, "ZRANK %s %s", set_name,  value);
	if(!checkReplay(reply)){
		return -1;
	}
	int ret = reply->integer;
	freeReplyObject(reply);
	return ret;
}
bool FSRedis::getDataFromKey(const char* key, FSCacheData* outdata){
	_CHECK_CONNECT
	redisReply* reply = (redisReply*)redisCommand(m_pContext, "GET %s", key);
	if(!checkReplay(reply)){ return false; }
	((FSRedisData*)outdata)->initReply(reply);
	return true;
}
bool FSRedis::getDataFromHash(const char* hash_name, const char* key, FSCacheData* outdata){
	_CHECK_CONNECT
	redisReply* reply = (redisReply*)redisCommand(m_pContext, "HGET %s %s", hash_name, key);
	if(!checkReplay(reply)){ return false; }
	((FSRedisData*)outdata)->initReply(reply);
	return true;
}

int  FSRedis::getListLen(const char* list_name) {
	_CHECK_CONNECT
	redisReply* reply = (redisReply*)redisCommand(m_pContext, "LLEN %s", list_name);
	if(!checkReplay(reply)){ return 0; }
	int ret = reply->integer;
	freeReplyObject(reply);
	return ret;
}
bool FSRedis::getDataFromList(const char* list_name, size_t start, size_t end, FSCacheData* outdata){
	_CHECK_CONNECT
	redisReply* reply = (redisReply*)redisCommand(m_pContext, "LRANGE %s %d %d", list_name, start, end);
	if(!checkReplay(reply)){ return false; }
	((FSRedisData*)outdata)->initReply(reply);
	return true;
}
bool  FSRedis::getDataFromSoctedSet(const char* set_name, size_t start, size_t end, FSCacheData* outdata){
	_CHECK_CONNECT
	redisReply* reply = (redisReply*) redisCommand(m_pContext, "ZRANGE %s %d %d", set_name, start, end);
	if (!checkReplay(reply)) {
		return false;
	}
	((FSRedisData*) outdata)->initReply(reply);
	return true;
}
bool FSRedis::shiftDataFromList(const char* list_name, FSCacheData* outdata){
	_CHECK_CONNECT
	redisReply* reply = (redisReply*)redisCommand(m_pContext, "LPOP %s %s", list_name);
	if(!checkReplay(reply)){ return false; }
	((FSRedisData*)outdata)->initReply(reply);
	return true;
}
bool FSRedis::popDataFromList(const char* list_name, FSCacheData* outdata){
	_CHECK_CONNECT
	redisReply* reply = (redisReply*)redisCommand(m_pContext, "RPOP %s %s", list_name);
	if(!checkReplay(reply)){ return false; }
	((FSRedisData*)outdata)->initReply(reply);
	return true;
}
int FSRedis::incrKey(const char* key){
	_CHECK_CONNECT
	redisReply* reply = (redisReply*)redisCommand(m_pContext, "INCR %s", key);
	if(!checkReplay(reply)) return false;
	int ret = reply->integer;
	freeReplyObject(reply);
	return ret;
}

bool FSRedis::delKey(const char* key) {
	_CHECK_CONNECT
	redisReply* reply = (redisReply*)redisCommand(m_pContext, "DEL %s", key);
	if(!checkReplay(reply)) return false;
	int ret = reply->integer;
	freeReplyObject(reply);
	return ret > 0;
}



test


#include <iostream>
#include <memory.h>
#include <string.h>
#include "FSOutputStream.h"
#include "FSInputStream.h"
#include <hiredis/hiredis.h>
#include "FSRedis.h"

using namespace std;

void test(){



	FSRedisData data;
	FSRedisConfig conf;
	conf.db_index = 0;
	conf.host = "127.0.0.1";
	conf.port = 6379;
	conf.timeout.tv_sec = 3;
	conf.timeout.tv_usec = 0;

	FSRedis db;
	db.connect(&conf);

	db.setString("MYNAME", "FRODO");
	db.setString("MYLOVE", "QIAO");

	db.getDataFromKey("MYNAME", &data);
	printf("%s\n", data.getString());
	db.getDataFromKey("MYLOVE", &data);
	printf("%s\n", data.getString());

	FSOutputStream fos;
	for(int i = 0 ; i < 50 ; i++){
		fos.writeInt32(i);
	}
	db.setBinary("IDS", fos.getData(), fos.getLength());
	db.getDataFromKey("IDS", &data);
	FSInputStream fis(data.getBinary(), data.getLength());

	for(int i = 0 ; i< 50 ; i++){
		printf("%d \n", fis.readUInt32());
	}

	if(db.getDataFromKey("MYLOVE", &data)){
		printf("%s\n", data.getString());
	}else{
		printf("get data fail\n");
	}


}

int main() {
	test();



	return 0;
}



  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值