acl/lib_acl_cpp/src/redis/redis_key.cpp

562 lines
10 KiB
C++

#include "acl_stdafx.hpp"
#include "acl_cpp/stdlib/snprintf.hpp"
#include "acl_cpp/stdlib/log.hpp"
#include "acl_cpp/redis/redis_result.hpp"
#include "acl_cpp/redis/redis_client.hpp"
#include "acl_cpp/redis/redis_key.hpp"
namespace acl
{
#define INT_LEN 11
#define LONG_LEN 21
redis_key::redis_key()
: redis_command(NULL)
{
}
redis_key::redis_key(redis_client* conn)
: redis_command(conn)
{
}
redis_key::redis_key(redis_client_cluster* cluster, size_t max_conns)
: redis_command(cluster, max_conns)
{
}
redis_key::~redis_key()
{
}
/////////////////////////////////////////////////////////////////////////////
int redis_key::del_one(const char* key)
{
return del_one(key, strlen(key));
}
int redis_key::del_one(const char* key, size_t len)
{
const char* argv[2];
size_t lens[2];
argv[0] = "DEL";
lens[0] = sizeof("DEL") - 1;
argv[1] = key;
lens[1] = len;
hash_slot(key);
build_request(2, argv, lens);
return get_number();
}
int redis_key::del(const char* first_key, ...)
{
std::vector<const char*> keys;
keys.push_back(first_key);
const char* key;
va_list ap;
va_start(ap, first_key);
while ((key = va_arg(ap, const char*)) != NULL)
keys.push_back(key);
va_end(ap);
return del(keys);
}
int redis_key::del(const std::vector<string>& keys)
{
if (keys.size() == 1)
hash_slot(keys[0].c_str());
build("DEL", NULL, keys);
return get_number();
}
int redis_key::del(const std::vector<const char*>& keys)
{
if (keys.size() == 1)
hash_slot(keys[0]);
build("DEL", NULL, keys);
return get_number();
}
int redis_key::del(const char* keys[], size_t argc)
{
if (argc == 1)
hash_slot(keys[0]);
build("DEL", NULL, keys, argc);
return get_number();
}
int redis_key::del(const char* keys[], const size_t lens[], size_t argc)
{
if (argc == 1)
hash_slot(keys[0], lens[0]);
build("DEL", NULL, keys, lens, argc);
return get_number();
}
int redis_key::dump(const char* key, string& out)
{
const char* argv[2];
size_t lens[2];
argv[0] = "DUMP";
lens[0] = sizeof("DUMP") - 1;
argv[1] = key;
lens[1] = strlen(key);
hash_slot(key);
build_request(2, argv, lens);
return get_string(out);
}
bool redis_key::exists(const char* key)
{
const char* argv[2];
size_t lens[2];
argv[0] = "EXISTS";
lens[0] = sizeof("EXISTS") - 1;
argv[1] = key;
lens[1] = strlen(key);
hash_slot(key);
build_request(2, argv, lens);
return get_number() > 0 ? true : false;
}
int redis_key::expire(const char* key, int n)
{
const char* argv[3];
size_t lens[3];
argv[0] = "EXPIRE";
lens[0] = sizeof("EXPIRE") - 1;
argv[1] = key;
lens[1] = strlen(key);
char buf[INT_LEN];
(void) safe_snprintf(buf, INT_LEN, "%d", n);
argv[2] = buf;
lens[2] = strlen(buf);
hash_slot(key);
build_request(3, argv, lens);
return get_number();
}
int redis_key::expireat(const char* key, time_t stamp)
{
const char* argv[3];
size_t lens[3];
argv[0] = "EXPIREAT";
lens[0] = sizeof("EXPIREAT") - 1;
argv[1] = key;
lens[1] = strlen(key);
char stamp_s[LONG_LEN];
safe_snprintf(stamp_s, sizeof(stamp_s), "%lu", (unsigned long) stamp);
argv[2] = stamp_s;
lens[2] = strlen(stamp_s);
hash_slot(key);
build_request(3, argv, lens);
return get_number();
}
int redis_key::keys_pattern(const char* pattern, std::vector<string>* out)
{
const char* argv[2];
size_t lens[2];
argv[0] = "KEYS";
lens[0] = sizeof("KEYS") - 1;
argv[1] = pattern;
lens[1] = strlen(pattern);
build_request(2, argv, lens);
return get_strings(out);
}
int redis_key::persist(const char* key)
{
const char* argv[2];
size_t lens[2];
argv[0] = "PERSIST";
lens[0] = sizeof("PERSIST") - 1;
argv[1] = key;
lens[1] = strlen(key);
hash_slot(key);
build_request(2, argv, lens);
return get_number();
}
int redis_key::pexpire(const char* key, int n)
{
const char* argv[3];
size_t lens[3];
argv[0] = "PEXPIRE";
lens[0] = sizeof("PEXPIRE") - 1;
argv[1] = key;
lens[1] = strlen(key);
char buf[INT_LEN];
(void) safe_snprintf(buf, INT_LEN, "%d", n);
argv[2] = buf;
lens[2] = strlen(buf);
hash_slot(key);
build_request(3, argv, lens);
return get_number();
}
int redis_key::pexpireat(const char* key, long long int stamp)
{
const char* argv[3];
size_t lens[3];
argv[0] = "PEXPIREAT";
lens[0] = sizeof("PEXPIREAT") - 1;
argv[1] = key;
lens[1] = strlen(key);
char stamp_s[LONG_LEN];
acl_i64toa(stamp, stamp_s, sizeof(stamp_s));
argv[2] = stamp_s;
lens[2] = strlen(stamp_s);
hash_slot(key);
build_request(3, argv, lens);
return get_number();
}
long long int redis_key::pttl(const char* key)
{
const char* argv[2];
size_t lens[2];
argv[0] = "PTTL";
lens[0] = sizeof("PTTL") - 1;
argv[1] = key;
lens[1] = strlen(key);
hash_slot(key);
build_request(2, argv, lens);
bool success;
long long int ret = get_number64(&success);
if (success == false)
return -3;
else
return ret;
}
bool redis_key::randmkey(string& buf)
{
const char* argv[1];
size_t lens[1];
argv[0] = "RANDOMKEY";
lens[0] = sizeof("RANDOMKEY") - 1;
build_request(1, argv, lens);
return get_string(buf) > 0 ? true : false;
}
bool redis_key::rename_key(const char* key, const char* newkey)
{
const char* argv[3];
size_t lens[3];
argv[0] = "RENAME";
lens[0] = sizeof("RENAME") - 1;
argv[1] = key;
lens[1] = strlen(key);
argv[2] = newkey;
lens[2] = strlen(newkey);
build_request(3, argv, lens);
return check_status();
}
bool redis_key::renamenx(const char* key, const char* newkey)
{
const char* argv[3];
size_t lens[3];
argv[0] = "RENAMENX";
lens[0] = sizeof("RENAMENX") - 1;
argv[1] = key;
lens[1] = strlen(key);
argv[2] = newkey;
lens[2] = strlen(newkey);
build_request(3, argv, lens);
return check_status();
}
bool redis_key::restore(const char* key, const char* value, size_t len,
int nttl, bool replace /* = false */)
{
const char* argv[5];
size_t lens[5];
argv[0] = "RESTORE";
lens[0] = sizeof("RESTORE") - 1;
argv[1] = key;
lens[1] = strlen(key);
char ttl_s[INT_LEN];
safe_snprintf(ttl_s, sizeof(ttl_s), "%d", nttl);
argv[2] = ttl_s;
lens[2] = strlen(ttl_s);
argv[3] = value;
lens[3] = len;
size_t argc = 4;
if (replace)
{
argv[4] = "REPLACE";
lens[4] = sizeof("REPLACE") - 1;
argc++;
}
hash_slot(key);
build_request(argc, argv, lens);
return check_status();
}
int redis_key::ttl(const char* key)
{
const char* argv[2];
size_t lens[2];
argv[0] = "TTL";
lens[0] = sizeof("TTL") - 1;
argv[1] = key;
lens[1] = strlen(key);
hash_slot(key);
build_request(2, argv, lens);
bool success;
int ret = get_number(&success);
if (success == false)
return -3;
else
return ret;
}
redis_key_t redis_key::type(const char* key)
{
const char* argv[2];
size_t lens[2];
argv[0] = "TYPE";
lens[0] = sizeof("TYPE") - 1;
argv[1] = key;
lens[1] = strlen(key);
hash_slot(key);
build_request(2, argv, lens);
const char* ptr = get_status();
if (ptr == NULL || *ptr == 0 || strcasecmp(ptr, "none") == 0)
return REDIS_KEY_NONE;
else if (strcasecmp(ptr, "string") == 0)
return REDIS_KEY_STRING;
else if (strcasecmp(ptr, "list") == 0)
return REDIS_KEY_LIST;
else if (strcasecmp(ptr, "set") == 0)
return REDIS_KEY_SET;
else if (strcasecmp(ptr, "zset") == 0)
return REDIS_KEY_ZSET;
else
{
logger_error("unknown type: %s, key: %s", ptr, key);
return REDIS_KEY_NONE;
}
}
bool redis_key::migrate(const char* key, const char* addr, unsigned dest_db,
unsigned timeout, const char* option /* = NULL */)
{
char addrbuf[64];
safe_snprintf(addrbuf, sizeof(addrbuf), "%s", addr);
char* at = strchr(addrbuf, ':');
if (at == NULL || *(at + 1) == 0)
return false;
*at++ = 0;
int port = atoi(at);
if (port >= 65535 || port <= 0)
return false;
const char* argv[7];
size_t lens[7];
size_t argc = 6;
argv[0] = "MIGRATE";
lens[0] = sizeof("MIGRATE") - 1;
argv[1] = addrbuf;
lens[1] = strlen(addrbuf);
argv[2] = at;
lens[2] = strlen(at);
argv[3] = key;
lens[3] = strlen(key);
char db_s[11];
safe_snprintf(db_s, sizeof(db_s), "%u", dest_db);
argv[4] = db_s;
lens[4] = strlen(db_s);
char timeout_s[11];
safe_snprintf(timeout_s, sizeof(timeout_s), "%u", timeout);
argv[5] = timeout_s;
lens[5] = strlen(timeout_s);
if (option && *option)
{
argv[6] = option;
lens[6] = strlen(option);
argc++;
}
build_request(argc, argv, lens);
return check_status();
}
int redis_key::move(const char* key, unsigned dest_db)
{
const char* argv[3];
size_t lens[3];
argv[0] = "MOVE";
lens[0] = sizeof("MOVE") - 1;
argv[1] = key;
lens[1] = strlen(key);
char db_s[11];
safe_snprintf(db_s, sizeof(db_s), "%u", dest_db);
argv[2] = db_s;
lens[2] = strlen(db_s);
build_request(3, argv, lens);
return get_number();
}
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);
hash_slot(key);
build_request(3, argv, lens);
return get_number();
}
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);
hash_slot(key);
build_request(3, argv, lens);
return get_string(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);
hash_slot(key);
build_request(3, argv, lens);
return get_number();
}
int redis_key::scan(int cursor, std::vector<string>& out,
const char* pattern /* = NULL */, const size_t* count /* = NULL */)
{
if (cursor < 0)
return -1;
size_t size;
const redis_result** children = scan_keys("SCAN", NULL, cursor,
size, pattern, count);
if (children == NULL)
return cursor;
const redis_result* rr;
string key_buf(128);
// out.clear();
out.reserve(out.size() + size);
for (size_t i = 0; i < size; i++)
{
rr = children[i];
rr->argv_to_string(key_buf);
out.push_back(key_buf);
key_buf.clear();
}
return cursor;
}
} // namespace acl