8     int passwordLength = strlen(password);
 
    9     if (passwordLength > 0)
 
   12       return cmdRet->type() == RedisObject::Type::SimpleString && (String)*cmdRet == 
"OK" 
   23 #define TRCMD(t, c, ...) return RedisCommand(c, ArgList{__VA_ARGS__}).issue_typed<t>(conn) 
   25 #define TRCMD_EXPECTOK(c, ...) return (bool)(((String)*RedisCommand(c, ArgList{__VA_ARGS__}).issue(conn)).indexOf("OK") != -1) 
   34   TRCMD(String, 
"GET", key);
 
   39   TRCMD(
bool, 
"DEL", key);
 
   44   TRCMD(
int, 
"APPEND", key, value);
 
   49   TRCMD(
int, 
"PUBLISH", channel, message);
 
   54   TRCMD(
bool, 
"EXISTS", key);
 
   57 bool Redis::_expire_(
const char *key, 
int arg, 
const char *cmd_var)
 
   59   TRCMD(
bool, cmd_var, key, String(arg));
 
   64   TRCMD(
bool, 
"PERSIST", key);
 
   67 int Redis::_ttl_(
const char *key, 
const char *cmd_var)
 
   69   TRCMD(
int, cmd_var, key);
 
   72 bool Redis::_hset_(
const char *key, 
const char *field, 
const char *value, 
const char *cmd_var)
 
   74   TRCMD(
int, cmd_var, key, field, value);
 
   79   TRCMD(String, 
"HGET", key, field);
 
   84   TRCMD(
bool, 
"HDEL", key, field);
 
   89   TRCMD(
int, 
"HLEN", key);
 
   94   TRCMD(
int, 
"HSTRLEN", key, field);
 
   99   TRCMD(
bool, 
"HEXISTS", key, field);
 
  106   if(rv->type() == RedisObject::Type::InternalError)
 
  108     std::vector<String> r = std::vector<String>();
 
  110     r.push_back(error_message);
 
  115     return rv->type() == RedisObject::Type::Array
 
  116              ? (std::vector<String>)*((
RedisArray *)rv.get())
 
  117              : std::vector<String>();
 
  123   TRCMD(String, 
"LINDEX", key, String(index));
 
  128   TRCMD(
int, 
"LLEN", key);
 
  133   TRCMD(String, 
"LPOP", key);
 
  138   TRCMD(
int, 
"LPOS", key, element);
 
  143   TRCMD(
int, (exclusive ? 
"LPUSHX" : 
"LPUSH"), key, value);
 
  148   TRCMD(
int, 
"LREM", key, String(count), element);
 
  169     TRCMD_EXPECTOK(
"TS.ADD", key, String(timestamp) + 
"000", String(value));
 
  173 int Redis::xack(
const char *key, 
const char *group, 
const char *
id)
 
  175   TRCMD(
int, 
"XACK", key, group, 
id);
 
  178 String 
Redis::xadd(
const char *key, 
const char *
id, 
const char *field,
 
  181   TRCMD(String, 
"XADD", key, 
id, field, value);
 
  185     const char* consumer, 
unsigned int min_idle_time, 
const char *start,
 
  186     unsigned int count, 
bool justid)
 
  188   ArgList argList = 
ArgList{key, group, consumer, String(min_idle_time), start};
 
  192     argList.push_back(
"COUNT");
 
  193     argList.push_back(String(count));
 
  198     argList.push_back(
"JUSTID");
 
  203   if(rv->type() == RedisObject::Type::InternalError)
 
  205     std::vector<String> r = std::vector<String>();
 
  207     r.push_back(error_message);
 
  212     return rv->type() == RedisObject::Type::Array
 
  213              ? (std::vector<String>)*((
RedisArray *)rv.get())
 
  214              : std::vector<String>();
 
  219     const char *consumer, 
unsigned int min_idle_time, 
const char *
id,
 
  220     unsigned int idle_ms, 
unsigned int time_ms, 
unsigned int retrycount,
 
  221     bool force, 
bool justid, 
const char *lastid)
 
  223   ArgList argList = 
ArgList{key, group, consumer, String(min_idle_time), 
id};
 
  227     argList.push_back(
"IDLE");
 
  228     argList.push_back(String(idle_ms));
 
  233     argList.push_back(
"TIME");
 
  234     argList.push_back(String(time_ms));
 
  239     argList.push_back(
"RETRYCOUNT");
 
  240     argList.push_back(String(retrycount));
 
  245     argList.push_back(
"FORCE");
 
  250     argList.push_back(
"JUSTID");
 
  253   if(lastid != NULL && strlen(lastid) > 0)
 
  255     argList.push_back(
"LASTID");
 
  256     argList.push_back(lastid);
 
  261   if(rv->type() == RedisObject::Type::InternalError)
 
  263     std::vector<String> r = std::vector<String>();
 
  265     r.push_back(error_message);
 
  270     return rv->type() == RedisObject::Type::Array
 
  271              ? (std::vector<String>)*((
RedisArray *)rv.get())
 
  272              : std::vector<String>();
 
  278   TRCMD(
int, 
"XDEL", key, 
id);
 
  295                                  const char *consumer)
 
  297   TRCMD(
int, 
"XGROUP", 
"CREATECONSUMER", key, group, consumer);
 
  301                               const char *consumer)
 
  303   TRCMD(
int, 
"XGROUP", 
"DELCONSUMER", key, group, consumer);
 
  308   TRCMD(
int, 
"XGROUP", 
"DESTROY", key, group);
 
  320   if(rv->type() == RedisObject::Type::InternalError)
 
  322     std::vector<String> r = std::vector<String>();
 
  324     r.push_back(error_message);
 
  329     return rv->type() == RedisObject::Type::Array
 
  330              ? (std::vector<String>)*((
RedisArray *)rv.get())
 
  331              : std::vector<String>();
 
  339   if(rv->type() == RedisObject::Type::InternalError)
 
  341     std::vector<String> r = std::vector<String>();
 
  343     r.push_back(error_message);
 
  348     return rv->type() == RedisObject::Type::Array
 
  349              ? (std::vector<String>)*((
RedisArray *)rv.get())
 
  350              : std::vector<String>();
 
  361     argList.push_back(
"FULL");
 
  365       argList.push_back(
"COUNT");
 
  366       argList.push_back(String(count));
 
  372   if(rv->type() == RedisObject::Type::InternalError)
 
  374     std::vector<String> r = std::vector<String>();
 
  376     r.push_back(error_message);
 
  381     return rv->type() == RedisObject::Type::Array
 
  382              ? (std::vector<String>)*((
RedisArray *)rv.get())
 
  383              : std::vector<String>();
 
  389   TRCMD(
int, 
"XLEN", key);
 
  393     unsigned int min_idle_time, 
const char *start, 
const char *end,
 
  394     unsigned int count, 
const char *consumer)
 
  398   if(min_idle_time > 0)
 
  400     argList.push_back(
"IDLE");
 
  401     argList.push_back(String(min_idle_time));
 
  404   if(start != NULL && strlen(start) > 0 && end != NULL && strlen(end) > 0)
 
  406     argList.push_back(start);
 
  407     argList.push_back(end);
 
  408     argList.push_back(String(count));
 
  411   if(consumer != NULL && strlen(consumer) > 0)
 
  413     argList.push_back(consumer);
 
  418   if(rv->type() == RedisObject::Type::InternalError)
 
  420     std::vector<String> r = std::vector<String>();
 
  422     r.push_back(error_message);
 
  427     return rv->type() == RedisObject::Type::Array
 
  428              ? (std::vector<String>)*((
RedisArray *)rv.get())
 
  429              : std::vector<String>();
 
  434     const char *end, 
unsigned int count)
 
  440     argList.push_back(
"COUNT");
 
  441     argList.push_back(String(count));
 
  446   if(rv->type() == RedisObject::Type::InternalError)
 
  448     std::vector<String> r = std::vector<String>();
 
  450     r.push_back(error_message);
 
  455     return rv->type() == RedisObject::Type::Array
 
  456              ? (std::vector<String>)*((
RedisArray *)rv.get())
 
  457              : std::vector<String>();
 
  461 std::vector<String> 
Redis::xread(
unsigned int count, 
unsigned int block,
 
  462     const char *key, 
const char *
id)
 
  464   ArgList argList = std::vector<String>();
 
  468     argList.push_back(
"COUNT");
 
  469     argList.push_back(String(count));
 
  474     argList.push_back(
"BLOCK");
 
  475     argList.push_back(String(block));
 
  478   argList.push_back(
"STREAMS");
 
  479   argList.push_back(key);
 
  480   argList.push_back(
id);
 
  484   if(rv->type() == RedisObject::Type::InternalError)
 
  486     std::vector<String> r = std::vector<String>();
 
  488     r.push_back(error_message);
 
  493     return rv->type() == RedisObject::Type::Array
 
  494              ? (std::vector<String>)*((
RedisArray *)rv.get())
 
  495              : std::vector<String>();
 
  500     unsigned int count, 
unsigned int block_ms, 
bool noack, 
const char *key,
 
  507     argList.push_back(
"COUNT");
 
  508     argList.push_back(String(count));
 
  513     argList.push_back(
"BLOCK");
 
  514     argList.push_back(String(block_ms));
 
  519     argList.push_back(
"NOACK");
 
  522   if(key != NULL && strlen(key) > 0)
 
  524     argList.push_back(
"STREAMS");
 
  525     argList.push_back(key);
 
  528   argList.push_back(
id);
 
  532   if(rv->type() == RedisObject::Type::InternalError)
 
  534     std::vector<String> r = std::vector<String>();
 
  536     r.push_back(error_message);
 
  541     return rv->type() == RedisObject::Type::Array
 
  542              ? (std::vector<String>)*((
RedisArray *)rv.get())
 
  543              : std::vector<String>();
 
  548     const char *start, 
unsigned int count)
 
  554     argList.push_back(
"COUNT");
 
  555     argList.push_back(String(count));
 
  560   if(rv->type() == RedisObject::Type::InternalError)
 
  562     std::vector<String> r = std::vector<String>();
 
  564     r.push_back(error_message);
 
  569     return rv->type() == RedisObject::Type::Array
 
  570              ? (std::vector<String>)*((
RedisArray *)rv.get())
 
  571              : std::vector<String>();
 
  576                  const int threshold, 
const int count)
 
  582       TRCMD(
int, 
"XTRIM", key, strategy, String(
char(compare)),
 
  583             String(threshold), 
"LIMIT", String(count));
 
  587       TRCMD(
int, 
"XTRIM", key, strategy, String(threshold));
 
  592       TRCMD(
int, 
"XTRIM", key, strategy, String(
char(compare)),
 
  599   TRCMD(String, 
"INFO", (section ? section : 
""));
 
  604   TRCMD(String, 
"RPOP", key);
 
  609   TRCMD(
int, (exclusive ? 
"RPUSHX" : 
"RPUSH"), key, value);
 
  612 bool Redis::_subscribe(SubscribeSpec spec)
 
  616     subSpec.push_back(spec);
 
  620   const char *cmdName = spec.pattern ? 
"PSUBSCRIBE" : 
"SUBSCRIBE";
 
  622   return rv->type() == RedisObject::Type::Array;
 
  629   if (rv->type() == RedisObject::Type::Array)
 
  631     auto vec = (std::vector<String>)*((
RedisArray *)rv.get());
 
  632     return vec.size() == 3 && vec[1] == String(channelOrPattern);
 
  640   if (!messageCallback)
 
  646   subscriberMode = 
true;
 
  649     for (
auto spec : subSpec)
 
  651       success = _subscribe(spec) && success;
 
  664       errCallback(
this, errCode);
 
  673     if (msg == 
nullptr) {
 
  677     if (msg->type() == RedisObject::Type::InternalError)
 
  689     if (msg->type() != RedisObject::Type::Array)
 
  695     auto msgVec = (std::vector<String>)*((
RedisArray *)msg.get());
 
  697     if (msgVec.size() < 3)
 
  703     if (msgVec[0] != 
"message" && msgVec[0] != 
"pmessage")
 
  710     auto pMsgAdd = msgVec[0] == 
"pmessage" ? 1 : 0;
 
  711     messageCallback(
this, msgVec[1 + pMsgAdd], msgVec[2 + pMsgAdd]);
 
  723   return ((returnVec[0].c_str())[0] == 
'-');