您的位置:首页 > 数据库 > Redis

redis C++ API

2014-05-08 13:13 447 查看
= =琢磨了一下 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)
c297
){
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息