complete the redis script client command

This commit is contained in:
ubuntu14 2015-01-25 05:03:20 -08:00
parent 5df648ee96
commit bfd4e601c5
17 changed files with 1264 additions and 8 deletions

View File

@ -1,12 +1,16 @@
修改历史列表:
------------------------------------------------------------------------
278) 2015.1.25
278.1) feature: 完成了 redis 客户端命令中 script 的所有功能
277) 2015.1.23
277.1) bugfix: master_threads2.cpp 中 run_once() 函数在 service_on_accept 调用
直接返回时没有释放流对象,导致描述字和内存泄漏
277.2) feature: redis 客户端库的 redis_key, redis_hash, redis_set, redis_zset
类方法增加了 scan 遍历方法
277.3) feature: 完成 了 redis 客户端命令中 pubsub 的所有功能
277.3) feature: 完成了 redis 客户端命令中 pubsub 的所有功能
277.4) feature: 完成了 redis 客户端命令中 server 的几乎全部功能
276) 2015.1.21
276.1) feature: 实现 了redis_zset 全部接口

View File

@ -146,3 +146,4 @@
#include "acl_cpp/redis/redis_zset.hpp"
#include "acl_cpp/redis/redis_script.hpp"
#include "acl_cpp/redis/redis_server.hpp"
#include "acl_cpp/redis/redis_hyperloglog.hpp"

View File

@ -37,7 +37,10 @@ public:
int get_number(const string& req, bool* success = NULL);
long long int get_number64(const string& req, bool* success = NULL);
int get_number(const string& req, std::vector<int>& out);
int get_number64(const string& req, std::vector<long long int>& out);
bool get_status(const string& req, const char* success = "OK");
int get_status(const string& req, std::vector<bool>& out);
const char* get_status_string(const char* req);
int get_string(const string& req, string& buf);
int get_string(const string& req, string* buf);

View File

@ -0,0 +1,31 @@
#pragma once
#include "acl_cpp/acl_cpp_define.hpp"
#include <vector>
#include "acl_cpp/stdlib/string.hpp"
#include "acl_cpp/redis/redis_command.hpp"
namespace acl
{
class redis_client;
class ACL_CPP_API redis_hyperloglog : public redis_command
{
public:
redis_hyperloglog(redis_client* conn = NULL);
~redis_hyperloglog();
int pfadd(const char* key, const char* first_element, ...);
int pfadd(const char* key, const std::vector<const char*>& elements);
int pfadd(const char* key, const std::vector<string>& elements);
int pfcount(const char* first_key, ...);
int pfcount(const std::vector<const char*>& keys);
int pfcount(const std::vector<string>& keys);
bool pfmerge(const char* dst, const char* first_src, ...);
bool pfmerge(const char* dst, const std::vector<const char*>& keys);
bool pfmerge(const char* dst, const std::vector<string>& keys);
};
} // namespace acl

View File

@ -6,7 +6,7 @@
namespace acl {
class redis_result;
class redis_client;
// redis 服务支持的数据类型分类
typedef enum
@ -112,6 +112,28 @@ public:
*/
int move(const char* key, unsigned dest_db);
/**
* key
* @param key {const char*}
* @return {int} 0 key < 0
*/
int object_refcount(const char* key);
/**
* key 使
* @param key {const char*}
* @param out {string&}
* @return {bool}
*/
bool object_encoding(const char* key, string& out);
/**
* key (idle )
* @param key {const char*}
* @return {int} < 0
*/
int object_idletime(const char* key);
/**
* key key "易失的"( key )
* "持久的"( key )

View File

@ -6,7 +6,6 @@ namespace acl
{
class redis_client;
class redis_result;
class ACL_CPP_API redis_list : public redis_command
{

View File

@ -1,5 +1,7 @@
#pragma once
#include "acl_cpp/acl_cpp_define.hpp"
#include <vector>
#include "acl_cpp/stdlib/string.hpp"
#include "acl_cpp/redis/redis_command.hpp"
namespace acl
@ -13,6 +15,135 @@ class ACL_CPP_API redis_script : public redis_command
public:
redis_script(redis_client* conn = NULL);
~redis_script();
/////////////////////////////////////////////////////////////////////
const redis_result* eval(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args);
const redis_result* eval(const char* script,
const std::vector<const char*>& keys,
const std::vector<const char*>& args);
const redis_result* evalsha(const char* sha1,
const std::vector<string>& keys,
const std::vector<string>& args);
const redis_result* evalsha(const char* sha1,
const std::vector<const char*>& keys,
const std::vector<const char*>& args);
int script_exists(const std::vector<string>& scripts,
std::vector<bool>& out);
int script_exists(const std::vector<const char*>& scripts,
std::vector<bool>& out);
bool script_flush();
bool script_load(const string& script, string& out);
bool script_kill();
/////////////////////////////////////////////////////////////////////
bool eval_status(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
const char* success = "OK");
bool eval_number(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
int& out);
bool eval_number64(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
long long int& out);
int eval_string(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
string& out);
bool evalsha_status(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
const char* success = "OK");
bool evalsha_number(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
int& out);
bool evalsha_number64(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
long long int& out);
int evalsha_string(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
string& out);
int eval_status(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<bool>& out,
const char* success = "OK");
int eval_number(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<int>& out,
std::vector<bool>& status);
long long int eval_number64(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<long long int>& out,
std::vector<bool>& status);
int eval_strings(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<string>& out);
int evalsha_status(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<bool>& out,
const char* success = "OK");
int evalsha_number(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<int>& out,
std::vector<bool>& status);
long long int evalsha_number64(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<long long int>& out,
std::vector<bool>& status);
int evalsha_strings(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<string>& out);
private:
int eval_status(const char* cmd, const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<bool>& out,
const char* success = "OK");
int eval_number(const char* cmd, const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<int>& out,
std::vector<bool>& status);
long long int eval_number64(const char* cmd, const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<long long int>& out,
std::vector<bool>& status);
int eval_strings(const char* cmd, const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<string>& out);
const redis_result* eval_cmd(const char* cmd, const char* script,
const std::vector<string>& keys,
const std::vector<string>& args);
const redis_result* eval_cmd(const char* cmd, const char* script,
const std::vector<const char*>& keys,
const std::vector<const char*>& args);
};
} // namespace acl

View File

@ -1,18 +1,44 @@
#pragma once
#include "acl_cpp/acl_cpp_define.hpp"
#include <map>
#include "acl_cpp/stdlib/string.hpp"
#include "acl_cpp/redis/redis_command.hpp"
namespace acl
{
class redis_client;
class redis_result;
class ACL_CPP_API redis_server : public redis_command
{
public:
redis_server(redis_client* conn = NULL);
~redis_server();
/////////////////////////////////////////////////////////////////////
bool bgsave();
bool client_getname(string& buf);
bool client_kill(const char* addr);
int client_list(string& buf);
bool client_setname(const char* name);
int config_get(const char* parameter, std::map<string, string>& out);
bool config_resetstat();
bool config_rewrite();
bool config_set(const char* name, const char* value);
int dbsize();
bool flushall();
bool flushdb();
int info(string& buf);
time_t lastsave();
bool monitor();
bool get_command(string& buf);
bool save();
void shutdown(bool save_data = true);
bool slaveof(const char* ip, int port);
bool get_time(time_t& stamp, int& escape);
};
} // namespace acl

View File

@ -8,7 +8,6 @@ namespace acl
{
class redis_client;
class redis_result;
class ACL_CPP_API redis_set : public redis_command
{

View File

@ -9,7 +9,6 @@ namespace acl
{
class redis_client;
class redis_result;
class ACL_CPP_API redis_zset : public redis_command
{

View File

@ -303,6 +303,7 @@ copy $(TargetName).pdb ..\dist\lib\win32\$(TargetName).pdb /Y
<ClCompile Include="src\redis\redis_client.cpp" />
<ClCompile Include="src\redis\redis_command.cpp" />
<ClCompile Include="src\redis\redis_hash.cpp" />
<ClCompile Include="src\redis\redis_hyperloglog.cpp" />
<ClCompile Include="src\redis\redis_key.cpp" />
<ClCompile Include="src\redis\redis_list.cpp" />
<ClCompile Include="src\redis\redis_manager.cpp" />
@ -466,6 +467,7 @@ copy $(TargetName).pdb ..\dist\lib\win32\$(TargetName).pdb /Y
<ClInclude Include="include\acl_cpp\redis\redis_command.hpp" />
<ClInclude Include="include\acl_cpp\redis\redis_connection.hpp" />
<ClInclude Include="include\acl_cpp\redis\redis_hash.hpp" />
<ClInclude Include="include\acl_cpp\redis\redis_hyperloglog.hpp" />
<ClInclude Include="include\acl_cpp\redis\redis_key.hpp" />
<ClInclude Include="include\acl_cpp\redis\redis_list.hpp" />
<ClInclude Include="include\acl_cpp\redis\redis_manager.hpp" />

View File

@ -463,6 +463,9 @@
<ClCompile Include="src\redis\redis_script.cpp">
<Filter>src\redis</Filter>
</ClCompile>
<ClCompile Include="src\redis\redis_hyperloglog.cpp">
<Filter>src\redis</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\acl_stdafx.hpp">
@ -1020,6 +1023,9 @@
<ClInclude Include="include\acl_cpp\redis\redis_script.hpp">
<Filter>include\redis</Filter>
</ClInclude>
<ClInclude Include="include\acl_cpp\redis\redis_hyperloglog.hpp">
<Filter>include\redis</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="changes.txt" />

View File

@ -341,15 +341,86 @@ long long int redis_client::get_number64(const string& req,
return result->get_integer64();
}
int redis_client::get_number(const string& req, std::vector<int>& out)
{
const redis_result* result = run(req);
if (result == NULL || result->get_type() != REDIS_RESULT_ARRAY)
return -1;
size_t size;
const redis_result** children = result->get_children(&size);
if (children == NULL || size == 0)
return 0;
out.reserve(size);
const redis_result* rr;
for (size_t i = 0; i < size; i++)
{
rr = children[i];
out.push_back(rr->get_integer());
}
return size;
}
int redis_client::get_number64(const string& req,
std::vector<long long int>& out)
{
const redis_result* result = run(req);
if (result == NULL || result->get_type() != REDIS_RESULT_ARRAY)
return -1;
size_t size;
const redis_result** children = result->get_children(&size);
if (children == NULL || size == 0)
return 0;
out.reserve(size);
const redis_result* rr;
for (size_t i = 0; i < size; i++)
{
rr = children[i];
out.push_back(rr->get_integer64());
}
return size;
}
bool redis_client::get_status(const string& req, const char* success /* = "OK" */)
{
const redis_result* result = run(req);
if (result == NULL || result->get_type() != REDIS_RESULT_STATUS)
return false;
const char* status = result->get_status();
if (status == NULL || strcasecmp(status, success) != 0)
if (status == NULL)
return false;
return true;
else if (success == NULL || strcasecmp(status, success) == 0)
return true;
else
return false;
}
int redis_client::get_status(const string& req, std::vector<bool>& out)
{
const redis_result* result = run(req);
if (result == NULL || result->get_type() != REDIS_RESULT_ARRAY)
return -1;
size_t size;
const redis_result** children = result->get_children(&size);
if (children == NULL || size == 0)
return 0;
out.reserve(size);
const redis_result* rr;
for (size_t i = 0; i < size; i++)
{
rr = children[i];
out.push_back(rr->get_integer() > 0 ? true : false);
}
return (int) size;
}
const char* redis_client::get_status_string(const char* req)

View File

@ -0,0 +1,104 @@
#include "acl_stdafx.hpp"
#include "acl_cpp/redis/redis_client.hpp"
#include "acl_cpp/redis/redis_hyperloglog.hpp"
namespace acl
{
redis_hyperloglog::redis_hyperloglog(redis_client* conn /* = NULL */)
: redis_command(conn)
{
}
redis_hyperloglog::~redis_hyperloglog()
{
}
int redis_hyperloglog::pfadd(const char* key, const char* first_element, ...)
{
std::vector<const char*> elements;
elements.push_back(first_element);
va_list ap;
va_start(ap, first_element);
const char* element;
while ((element = va_arg(ap, const char*)) != NULL)
elements.push_back(element);
va_end(ap);
return pfadd(key, elements);
}
int redis_hyperloglog::pfadd(const char* key,
const std::vector<const char*>& elements)
{
const string& req = conn_->build("PFADD", key, elements);
return conn_->get_number(req);
}
int redis_hyperloglog::pfadd(const char* key,
const std::vector<string>& elements)
{
const string& req = conn_->build("PFADD", key, elements);
return conn_->get_number(req);
}
int redis_hyperloglog::pfcount(const char* first_key, ...)
{
std::vector<const char*> keys;
keys.push_back(first_key);
va_list ap;
va_start(ap, first_key);
const char* key;
while ((key = va_arg(ap, const char*)) != NULL)
keys.push_back(key);
va_end(ap);
return pfcount(keys);
}
int redis_hyperloglog::pfcount(const std::vector<const char*>& keys)
{
const string& req = conn_->build("PFCOUNT", NULL, keys);
return conn_->get_number(req);
}
int redis_hyperloglog::pfcount(const std::vector<string>& keys)
{
const string& req = conn_->build("PFCOUNT", NULL, keys);
return conn_->get_number(req);
}
bool redis_hyperloglog::pfmerge(const char* dst, const char* first_src, ...)
{
std::vector<const char*> keys;
keys.push_back(first_src);
va_list ap;
va_start(ap, first_src);
const char* src;
while ((src = va_arg(ap, const char*)) != NULL)
keys.push_back(src);
va_end(ap);
return pfmerge(dst, keys);
}
bool redis_hyperloglog::pfmerge(const char* dst,
const std::vector<const char*>& keys)
{
const string& req = conn_->build("PFMERGE", dst, keys);
return conn_->get_status(req);
}
bool redis_hyperloglog::pfmerge(const char* dst,
const std::vector<string>& keys)
{
const string& req = conn_->build("PFMERGE", dst, keys);
return conn_->get_status(req);
}
} //namespace acl

View File

@ -444,6 +444,60 @@ int redis_key::move(const char* key, unsigned dest_db)
return conn_->get_number(req);
}
int redis_key::object_refcount(const char* key)
{
const char* argv[3];
size_t lens[3];
argv[0] = "OBJECT";
lens[0] = sizeof("OBJECT") - 1;
argv[1] = "REFCOUNT";
lens[1] = sizeof("REFCOUNT") - 1;
argv[2] = key;
lens[2] = strlen(key);
const string& req = conn_->build_request(3, argv, lens);
return conn_->get_number(req);
}
bool redis_key::object_encoding(const char* key, string& out)
{
const char* argv[3];
size_t lens[3];
argv[0] = "OBJECT";
lens[0] = sizeof("OBJECT") - 1;
argv[1] = "ENCODING";
lens[1] = sizeof("ENCODING") - 1;
argv[2] = key;
lens[2] = strlen(key);
const string& req = conn_->build_request(3, argv, lens);
return conn_->get_string(req, out) > 0 ? true : false;
}
int redis_key::object_idletime(const char* key)
{
const char* argv[3];
size_t lens[3];
argv[0] = "OBJECT";
lens[0] = sizeof("OBJECT") - 1;
argv[1] = "IDLETIME";
lens[1] = sizeof("IDLETIME") - 1;
argv[2] = key;
lens[2] = strlen(key);
const string& req = conn_->build_request(3, argv, lens);
return conn_->get_number(req);
}
int redis_key::scan(int cursor, std::vector<string>& out,
const char* pattern /* = NULL */, const size_t* count /* = NULL */)
{

View File

@ -1,4 +1,6 @@
#include "acl_stdafx.hpp"
#include "acl_cpp/stdlib/dbuf_pool.hpp"
#include "acl_cpp/stdlib/snprintf.hpp"
#include "acl_cpp/redis/redis_client.hpp"
#include "acl_cpp/redis/redis_result.hpp"
#include "acl_cpp/redis/redis_script.hpp"
@ -6,6 +8,8 @@
namespace acl
{
#define LONG_LEN 21
redis_script::redis_script(redis_client* conn /* = NULL */)
: redis_command(conn)
{
@ -17,4 +21,495 @@ redis_script::~redis_script()
}
bool redis_script::eval_status(const char* script,
const std::vector<string>& keys, const std::vector<string>& args,
const char* success /* = "OK" */)
{
const redis_result* result = eval_cmd(script, "EVAL", keys, args);
if (result == NULL)
return false;
const char* status = result->get_status();
if (status == NULL || strcasecmp(status, success) != 0)
return false;
return true;
}
bool redis_script::eval_number(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
int& out)
{
const redis_result* result = eval_cmd(script, "EVAL", keys, args);
if (result == NULL)
return false;
bool success;
out = result->get_integer(&success);
return success;
}
bool redis_script::eval_number64(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
long long int& out)
{
const redis_result* result = eval_cmd(script, "EVAL", keys, args);
if (result == NULL)
return false;
bool success;
out = result->get_integer64(&success);
return success;
}
int redis_script::eval_string(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
string& out)
{
const redis_result* result = eval_cmd(script, "EVAL", keys, args);
if (result == NULL)
return -1;
return (int) result->argv_to_string(out);
}
bool redis_script::evalsha_status(const char* script,
const std::vector<string>& keys, const std::vector<string>& args,
const char* success /* = "OK" */)
{
const redis_result* result = eval_cmd(script, "EVALSHA", keys, args);
if (result == NULL)
return false;
const char* status = result->get_status();
if (status == NULL || strcasecmp(status, success) != 0)
return false;
return true;
}
bool redis_script::evalsha_number(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
int& out)
{
const redis_result* result = eval_cmd(script, "EVALSHA", keys, args);
if (result == NULL)
return false;
bool success;
out = result->get_integer(&success);
return success;
}
bool redis_script::evalsha_number64(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
long long int& out)
{
const redis_result* result = eval_cmd(script, "EVALSHA", keys, args);
if (result == NULL)
return false;
bool success;
out = result->get_integer64(&success);
return success;
}
int redis_script::evalsha_string(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
string& out)
{
const redis_result* result = eval_cmd(script, "EVALSHA", keys, args);
if (result == NULL)
return -1;
return (int) result->argv_to_string(out);
}
int redis_script::eval_status(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<bool>& out,
const char* success /* = "OK" */)
{
return eval_status("EVAL", script, keys, args, out, success);
}
int redis_script::eval_number(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<int>& out,
std::vector<bool>& status)
{
return eval_number("EVAL", script, keys, args, out, status);
}
long long int redis_script::eval_number64(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<long long int>& out,
std::vector<bool>& status)
{
return eval_number64("EVAL", script, keys, args, out, status);
}
int redis_script::eval_strings(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<string>& out)
{
return eval_strings("EVAL", script, keys, args, out);
}
int redis_script::evalsha_status(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<bool>& out,
const char* success /* = "OK" */)
{
return eval_status("EVALSHA", script, keys, args, out, success);
}
int redis_script::evalsha_number(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<int>& out,
std::vector<bool>& status)
{
return eval_number("EVALSHA", script, keys, args, out, status);
}
long long int redis_script::evalsha_number64(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<long long int>& out,
std::vector<bool>& status)
{
return eval_number64("EVALSHA", script, keys, args, out, status);
}
int redis_script::evalsha_strings(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<string>& out)
{
return eval_strings("EVALSHA", script, keys, args, out);
}
int redis_script::eval_status(const char* cmd, const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<bool>& out,
const char* success /* = "OK" */)
{
const redis_result* result = eval_cmd(script, cmd, keys, args);
if (result == NULL)
return -1;
size_t size;
const redis_result** children = result->get_children(&size);
if (children == NULL || size == 0)
return -1;
out.reserve(size);
const redis_result* rr;
const char* status;
for (size_t i = 0; i < size; i++)
{
rr = children[i];
status = rr->get_status();
if (status != NULL && strcasecmp(status, success) == 0)
out.push_back(true);
else
out.push_back(false);
}
return (int) size;
}
int redis_script::eval_number(const char* cmd, const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<int>& out,
std::vector<bool>& status)
{
const redis_result* result = eval_cmd(script, cmd, keys, args);
if (result == NULL)
return -1;
size_t size;
const redis_result** children = result->get_children(&size);
if (children == NULL || size == 0)
return 0;
out.reserve(size);
const redis_result* rr;
int number;
bool success;
for (size_t i = 0; i < size; i++)
{
rr = children[i];
number = rr->get_integer(&success);
out.push_back(number);
status.push_back(success);
}
return (int) size;
}
long long int redis_script::eval_number64(const char* cmd, const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<long long int>& out,
std::vector<bool>& status)
{
const redis_result* result = eval_cmd(script, cmd, keys, args);
if (result == NULL)
return -1;
size_t size;
const redis_result** children = result->get_children(&size);
if (children == NULL || size == 0)
return 0;
out.reserve(size);
const redis_result* rr;
long long int number;
bool success;
for (size_t i = 0; i < size; i++)
{
rr = children[i];
number = rr->get_integer64(&success);
out.push_back(number);
status.push_back(success);
}
return (int) size;
}
int redis_script::eval_strings(const char* cmd, const char* script,
const std::vector<string>& keys,
const std::vector<string>& args,
std::vector<string>& out)
{
const redis_result* result = eval_cmd(script, cmd, keys, args);
if (result == NULL)
return -1;
size_t size;
const redis_result** children = result->get_children(&size);
if (children == NULL || size == 0)
return 0;
out.reserve(size);
const redis_result* rr;
string buf;
for (size_t i = 0; i < size; i++)
{
rr = children[i];
rr->argv_to_string(buf);
out.push_back(buf);
buf.clear();
}
return (int) size;
}
const redis_result* redis_script::eval(const char* script,
const std::vector<string>& keys,
const std::vector<string>& args)
{
return eval_cmd("EVAL", script, keys, args);
}
const redis_result* redis_script::eval(const char* script,
const std::vector<const char*>& keys,
const std::vector<const char*>& args)
{
return eval_cmd("EVAL", script, keys, args);
}
const redis_result* redis_script::evalsha(const char* sha1,
const std::vector<string>& keys,
const std::vector<string>& args)
{
return eval_cmd("EVALSHA", sha1, keys, args);
}
const redis_result* redis_script::evalsha(const char* sha1,
const std::vector<const char*>& keys,
const std::vector<const char*>& args)
{
return eval_cmd("EVALSHA", sha1, keys, args);
}
const redis_result* redis_script::eval_cmd(const char* cmd,
const char* script,
const std::vector<string>& keys,
const std::vector<string>& args)
{
size_t argc = 3 + keys.size() + args.size();
dbuf_pool* pool = conn_->get_pool();
const char** argv = (const char**)
pool->dbuf_alloc(argc * sizeof(char*));
size_t* lens = (size_t*) pool->dbuf_alloc(argc * sizeof(size_t));
argv[0] = cmd;
lens[0] = strlen(cmd);
argv[1] = script;
lens[1] = strlen(script);
char argc_s[LONG_LEN];
safe_snprintf(argc_s, sizeof(argc_s), "%lu", (unsigned long) argc);
argv[2] = argc_s;
lens[2] = strlen(argc_s);
size_t i = 3;
std::vector<string>::const_iterator cit = keys.begin();
for (; cit != keys.end(); ++cit)
{
argv[i] = (*cit).c_str();
lens[i] = (*cit).length();
i++;
}
cit = args.begin();
for (; cit != args.end(); ++cit)
{
argv[i] = (*cit).c_str();
lens[i] = (*cit).length();
i++;
}
acl_assert(i == argc);
const string& req = conn_->build_request(argc, argv, lens);
return conn_->run(req);
}
const redis_result* redis_script::eval_cmd(const char* cmd,
const char* script,
const std::vector<const char*>& keys,
const std::vector<const char*>& args)
{
size_t argc = 3 + keys.size() + args.size();
dbuf_pool* pool = conn_->get_pool();
const char** argv = (const char**)
pool->dbuf_alloc(argc * sizeof(char*));
size_t* lens = (size_t*) pool->dbuf_alloc(argc * sizeof(size_t));
argv[0] = cmd;
lens[0] = strlen(cmd);
argv[1] = script;
lens[1] = strlen(script);
char argc_s[LONG_LEN];
safe_snprintf(argc_s, sizeof(argc_s), "%lu", (unsigned long) argc);
argv[2] = argc_s;
lens[2] = strlen(argc_s);
size_t i = 3;
std::vector<const char*>::const_iterator cit = keys.begin();
for (; cit != keys.end(); ++cit)
{
argv[i] = *cit;
lens[i] = strlen(argv[i]);
i++;
}
cit = args.begin();
for (; cit != args.end(); ++cit)
{
argv[i] = *cit;
lens[i] = strlen(argv[i]);
i++;
}
acl_assert(i == argc);
const string& req = conn_->build_request(argc, argv, lens);
return conn_->run(req);
}
int redis_script::script_exists(const std::vector<string>& scripts,
std::vector<bool>& out)
{
const string& req = conn_->build("SCRIPT", "EXISTS", scripts);
int ret = conn_->get_status(req, out);
if (ret != (int) scripts.size())
return -1;
return ret;
}
int redis_script::script_exists(const std::vector<const char*>& scripts,
std::vector<bool>& out)
{
const string& req = conn_->build("SCRIPT", "EXISTS", scripts);
int ret = conn_->get_status(req, out);
if (ret != (int) scripts.size())
return -1;
return ret;
}
bool redis_script::script_flush()
{
const char* argv[2];
size_t lens[2];
argv[0] = "SCRIPT";
lens[0] = sizeof("SCRIPT") - 1;
argv[1] = "FLUSH";
lens[1] = sizeof("FLUSH") - 1;
const string& req = conn_->build_request(2, argv, lens);
return conn_->get_status(req);
}
bool redis_script::script_load(const string& script, string& out)
{
const char* argv[3];
size_t lens[3];
argv[0] = "SCRIPT";
lens[0] = sizeof("SCRIPT") - 1;
argv[1] = "LOAD";
lens[1] = sizeof("LOAD") - 1;
argv[2] = script;
lens[2] = strlen(script);
const string& req = conn_->build_request(3, argv, lens);
return conn_->get_string(req, out) > 0 ? true : false;
}
bool redis_script::script_kill()
{
const char* argv[2];
size_t lens[2];
argv[0] = "SCRIPT";
lens[0] = sizeof("SCRIPT") - 1;
argv[1] = "KILL";
lens[1] = sizeof("KILL") - 1;
const string& req = conn_->build_request(2, argv, lens);
return conn_->get_status(req);
}
} // namespace acl

View File

@ -1,4 +1,5 @@
#include "acl_stdafx.hpp"
#include "acl_cpp/stdlib/snprintf.hpp"
#include "acl_cpp/redis/redis_client.hpp"
#include "acl_cpp/redis/redis_result.hpp"
#include "acl_cpp/redis/redis_server.hpp"
@ -6,6 +7,8 @@
namespace acl
{
#define INT_LEN 11
redis_server::redis_server(redis_client* conn /* = NULL */)
: redis_command(conn)
{
@ -17,4 +20,310 @@ redis_server::~redis_server()
}
bool redis_server::bgsave()
{
const char* argv[1];
size_t lens[1];
argv[0] = "BGSAVE";
lens[0] = sizeof("BGSAVE") - 1;
const string& req = conn_->build_request(1, argv, lens);
return conn_->get_status(req);
}
bool redis_server::client_getname(string& buf)
{
const char* argv[2];
size_t lens[2];
argv[0] = "CLIENT";
lens[0] = sizeof("CLIENT") - 1;
argv[1] = "GETNAME";
lens[1] = sizeof("GETNAME") - 1;
const string& req = conn_->build_request(2, argv, lens);
return conn_->get_string(req, buf) >0 ? true : false;
}
bool redis_server::client_kill(const char* addr)
{
const char* argv[3];
size_t lens[3];
argv[0] = "CLIENT";
lens[0] = sizeof("CLIENT") - 1;
argv[1] = "KILL";
lens[1] = sizeof("KILL") - 1;
argv[2] = addr;
lens[2] = strlen(addr);
const string& req = conn_->build_request(3, argv, lens);
return conn_->get_status(req);
}
int redis_server::client_list(string& buf)
{
const char* argv[2];
size_t lens[2];
argv[0] = "CLIENT";
lens[0] = sizeof("CLIENT") - 1;
argv[1] = "LIST";
lens[1] = sizeof("LIST") - 1;
const string& req = conn_->build_request(2, argv, lens);
return conn_->get_string(req, buf);
}
bool redis_server::client_setname(const char* name)
{
const char* argv[3];
size_t lens[3];
argv[0] = "CLIENT";
lens[0] = sizeof("CLIENT") - 1;
argv[1] = "SETNAME";
lens[1] = sizeof("SETNAME") - 1;
argv[2] = name;
lens[2] = strlen(name);
const string& req = conn_->build_request(3, argv, lens);
return conn_->get_status(req);
}
int redis_server::config_get(const char* parameter,
std::map<string, string>& out)
{
const char* argv[3];
size_t lens[3];
argv[0] = "CONFIG";
lens[0] = sizeof("CONFIG") - 1;
argv[1] = "GET";
lens[1] = sizeof("GET") - 1;
argv[2] = parameter;
lens[2] = strlen(parameter);
const string& req = conn_->build_request(3, argv, lens);
return conn_->get_strings(req, out);
}
bool redis_server::config_resetstat()
{
const char* argv[2];
size_t lens[2];
argv[0] = "CONFIG";
lens[0] = sizeof("CONFIG") - 1;
argv[1] = "RESETSTAT";
lens[1] = sizeof("RESETSTAT") - 1;
const string& req = conn_->build_request(2, argv, lens);
return conn_->get_status(req);
}
bool redis_server::config_rewrite()
{
const char* argv[2];
size_t lens[2];
argv[0] = "CONFIG";
lens[0] = sizeof("CONFIG") - 1;
argv[1] = "REWRITE";
lens[1] = sizeof("REWRITE") -1;
const string& req = conn_->build_request(2, argv, lens);
return conn_->get_status(req);
}
bool redis_server::config_set(const char* name, const char* value)
{
const char* argv[4];
size_t lens[4];
argv[0] = "CONFIG";
lens[0] = sizeof("CONFIG") - 1;
argv[1] = "SET";
lens[1] = sizeof("SET") - 1;
argv[2] = name;
lens[2] = strlen(name);
argv[3] = value;
lens[3] = strlen(value);
const string& req = conn_->build_request(4, argv, lens);
return conn_->get_status(req);
}
int redis_server::dbsize()
{
const char* argv[1];
size_t lens[1];
argv[0] = "DBSIZE";
lens[0] = sizeof("DBSIZE") - 1;
const string& req = conn_->build_request(1, argv, lens);
return conn_->get_number(req);
}
bool redis_server::flushall()
{
const char* argv[1];
size_t lens[1];
argv[0] = "FLUSHALL";
lens[0] = sizeof("FLUSHALL") - 1;
const string& req = conn_->build_request(1, argv, lens);
return conn_->get_status(req);
}
bool redis_server::flushdb()
{
const char* argv[1];
size_t lens[1];
argv[0] = "FLUSHDB";
lens[0] = sizeof("FLUSHDB") - 1;
const string& req = conn_->build_request(1, argv, lens);
return conn_->get_status(req);
}
int redis_server::info(string& buf)
{
const char* argv[1];
size_t lens[1];
argv[0] = "INFO";
lens[0] = sizeof("INFO") - 1;
const string& req = conn_->build_request(1, argv, lens);
return conn_->get_string(req, buf);
}
time_t redis_server::lastsave()
{
const char* argv[1];
size_t lens[1];
argv[0] = "LASTSAVE";
lens[0] = sizeof("LASTSAVE") - 1;
const string& req = conn_->build_request(1, argv, lens);
return conn_->get_number64(req);
}
bool redis_server::monitor()
{
const char* argv[1];
size_t lens[1];
argv[0] = "MONITOR";
lens[0] = sizeof("MONITOR") - 1;
const string& req = conn_->build_request(1, argv, lens);
return conn_->get_status(req);
}
bool redis_server::get_command(string& buf)
{
const redis_result* result = conn_->run("");
if (result == NULL || result->get_type() != REDIS_RESULT_STATUS)
return false;
const char* status = result->get_status();
if (status == NULL)
return false;
buf = status;
return true;
}
bool redis_server::save()
{
const char* argv[1];
size_t lens[1];
argv[0] = "SAVE";
lens[0] = sizeof("SAVE") - 1;
const string& req = conn_->build_request(1, argv, lens);
return conn_->get_status(req);
}
void redis_server::shutdown(bool save_data /* = true */)
{
const char* argv[2];
size_t lens[2];
argv[0] = "SHUTDOWN";
lens[0] = sizeof("SHUTDOWN") - 1;
if (save_data)
{
argv[1] = "save";
lens[1] = sizeof("save") - 1;
}
else
{
argv[1] = "nosave";
lens[1] = sizeof("nosave") - 1;
}
const string& req = conn_->build_request(2, argv, lens);
(void) conn_->get_status(req);
}
bool redis_server::slaveof(const char* ip, int port)
{
const char* argv[3];
size_t lens[3];
argv[0] = "SLAVEOF";
lens[0] = sizeof("SLAVEOF") - 1;
argv[1] = ip;
lens[1] = strlen(ip);
char port_s[INT_LEN];
safe_snprintf(port_s, sizeof(port_s), "%d", port);
argv[2] = port_s;
lens[2] = strlen(port_s);
const string& req = conn_->build_request(3, argv, lens);
return conn_->get_status(req);
}
bool redis_server::get_time(time_t& stamp, int& escape)
{
const char* argv[1];
size_t lens[1];
argv[0] = "TIME";
lens[0] = sizeof("TIME") - 1;
const string& req = conn_->build_request(1, argv, lens);
std::vector<string> tokens;
if (conn_->get_strings(req, tokens) <= 0 || tokens.size() < 2)
return false;
stamp = atol(tokens[0].c_str());
escape = atoi(tokens[1].c_str());
return true;
}
} // namespace acl