pika_command.h 13.4 KB
Newer Older
B
baotiao 已提交
1 2 3 4 5
// Copyright (c) 2015-present, Qihoo, Inc.  All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree. An additional grant
// of patent rights can be found in the PATENTS file in the same directory.

6 7
#ifndef PIKA_COMMAND_H_
#define PIKA_COMMAND_H_
W
wangkang-xy 已提交
8 9 10

#include <deque>
#include <string>
W
wangkang-xy 已提交
11 12
#include <memory>
#include <redis_conn.h>
W
wangkang-xy 已提交
13 14
#include <unordered_map>
#include "slash_string.h"
W
wangkang-xy 已提交
15

W
wangkang-xy 已提交
16

W
wangkang-xy 已提交
17
//Constant for command name
18 19
//Admin
const std::string kCmdNameSlaveof = "slaveof";
20
const std::string kCmdNameTrysync = "trysync";
C
CatKang 已提交
21
const std::string kCmdNameAuth = "auth";
C
CatKang 已提交
22 23
const std::string kCmdNameBgsave = "bgsave";
const std::string kCmdNameBgsaveoff = "bgsaveoff";
C
CatKang 已提交
24
const std::string kCmdNameCompact = "compact";
C
CatKang 已提交
25
const std::string kCmdNamePurgelogsto = "purgelogsto";
K
KernelMaker 已提交
26 27 28 29 30
const std::string kCmdNamePing = "ping";
const std::string kCmdNameSelect = "select";
const std::string kCmdNameFlushall = "flushall";
const std::string kCmdNameReadonly = "readonly";
const std::string kCmdNameClient = "client";
31
const std::string kCmdNameShutdown = "shutdown";
J
JacketWoo 已提交
32
const std::string kCmdNameInfo = "info";
33
const std::string kCmdNameConfig = "config";
J
JacketWoo 已提交
34
const std::string kCmdNameMonitor = "monitor";
35
const std::string kCmdNameDbsize = "dbsize";
36

S
SongZhao 已提交
37 38 39 40 41 42 43 44 45 46 47 48
//Migrate slot
const std::string kCmdNameSlotsMgrtSlot = "slotsmgrtslot";
const std::string kCmdNameSlotsMgrtTagSlot = "slotsmgrttagslot";
const std::string kCmdNameSlotsMgrtOne = "slotsmgrtone";
const std::string kCmdNameSlotsMgrtTagOne = "slotsmgrttagone";
const std::string kCmdNameSlotsInfo = "slotsinfo";
const std::string kCmdNameSlotsHashKey = "slotshashkey";
const std::string kCmdNameSlotsReload = "slotsreload";
const std::string kCmdNameSlotsReloadOff = "slotsreloadoff";
const std::string kCmdNameSlotsDel = "slotsdel";
const std::string kCmdNameSlotsScan = "slotsscan";

49
//Kv
W
wangkang-xy 已提交
50
const std::string kCmdNameSet = "set";
W
wangkang-xy 已提交
51
const std::string kCmdNameGet = "get";
J
JacketWoo 已提交
52 53 54 55 56 57 58 59 60
const std::string kCmdNameDel = "del";
const std::string kCmdNameIncr = "incr";
const std::string kCmdNameIncrby = "incrby";
const std::string kCmdNameIncrbyfloat = "incrbyfloat";
const std::string kCmdNameDecr = "decr";
const std::string kCmdNameDecrby = "decrby";
const std::string kCmdNameGetset = "getset";
const std::string kCmdNameAppend = "append";
const std::string kCmdNameMget = "mget";
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
const std::string kCmdNameKeys = "keys";
const std::string kCmdNameSetnx = "setnx";
const std::string kCmdNameSetex = "setex";
const std::string kCmdNameMset = "mset";
const std::string kCmdNameMsetnx = "msetnx";
const std::string kCmdNameGetrange = "getrange";
const std::string kCmdNameSetrange = "setrange";
const std::string kCmdNameStrlen = "strlen";
const std::string kCmdNameExists = "exists";
const std::string kCmdNameExpire = "expire";
const std::string kCmdNamePexpire = "pexpire";
const std::string kCmdNameExpireat = "expireat";
const std::string kCmdNamePexpireat = "pexpireat";
const std::string kCmdNameTtl = "ttl";
const std::string kCmdNamePttl = "pttl";
const std::string kCmdNamePersist = "persist";
const std::string kCmdNameType = "type";
const std::string kCmdNameScan = "scan";
79
//Hash
80 81 82
const std::string kCmdNameHDel = "hdel";
const std::string kCmdNameHSet = "hset";
const std::string kCmdNameHGet = "hget";
J
JacketWoo 已提交
83 84 85 86 87 88 89 90 91 92 93 94
const std::string kCmdNameHGetall = "hgetall";
const std::string kCmdNameHExists = "hexists";
const std::string kCmdNameHIncrby = "hincrby";
const std::string kCmdNameHIncrbyfloat = "hincrbyfloat";
const std::string kCmdNameHKeys = "hkeys";
const std::string kCmdNameHLen = "hlen";
const std::string kCmdNameHMget = "hmget";
const std::string kCmdNameHMset = "hmset";
const std::string kCmdNameHSetnx = "hsetnx";
const std::string kCmdNameHStrlen = "hstrlen";
const std::string kCmdNameHVals = "hvals";
const std::string kCmdNameHScan = "hscan";
95 96

//List
C
CatKang 已提交
97 98 99 100 101 102 103 104 105 106 107 108 109 110
const std::string kCmdNameLIndex = "lindex";
const std::string kCmdNameLInsert = "linsert";
const std::string kCmdNameLLen = "llen";
const std::string kCmdNameLPop = "lpop";
const std::string kCmdNameLPush = "lpush";
const std::string kCmdNameLPushx = "lpushx";
const std::string kCmdNameLRange = "lrange";
const std::string kCmdNameLRem = "lrem";
const std::string kCmdNameLSet = "lset";
const std::string kCmdNameLTrim = "ltrim";
const std::string kCmdNameRPop = "rpop";
const std::string kCmdNameRPopLPush = "rpoplpush";
const std::string kCmdNameRPush = "rpush";
const std::string kCmdNameRPushx = "rpushx";
111

W
wenduo 已提交
112 113 114 115 116 117 118
//BitMap
const std::string kCmdNameBitSet = "setbit";
const std::string kCmdNameBitGet = "getbit";
const std::string kCmdNameBitPos = "bitpos";
const std::string kCmdNameBitOp = "bitop";
const std::string kCmdNameBitCount = "bitcount";

119
//Zset
J
JacketWoo 已提交
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
const std::string kCmdNameZAdd = "zadd";
const std::string kCmdNameZCard = "zcard";
const std::string kCmdNameZScan = "zscan";
const std::string kCmdNameZIncrby = "zincrby";
const std::string kCmdNameZRange = "zrange";
const std::string kCmdNameZRangebyscore = "zrangebyscore";
const std::string kCmdNameZCount = "zcount";
const std::string kCmdNameZRem = "zrem";
const std::string kCmdNameZUnionstore = "zunionstore";
const std::string kCmdNameZInterstore = "zinterstore";
const std::string kCmdNameZRank = "zrank";
const std::string kCmdNameZRevrank = "zrevrank";
const std::string kCmdNameZScore = "zscore";
const std::string kCmdNameZRevrange = "zrevrange";
const std::string kCmdNameZRevrangebyscore = "zrevrangebyscore";
const std::string kCmdNameZRangebylex = "zrangebylex";
const std::string kCmdNameZRevrangebylex = "zrevrangebylex";
const std::string kCmdNameZLexcount = "zlexcount";
const std::string kCmdNameZRemrangebyrank = "zremrangebyrank";
const std::string kCmdNameZRemrangebylex = "zremrangebylex";
const std::string kCmdNameZRemrangebyscore = "zremrangebyscore";
141 142

//Set
J
JacketWoo 已提交
143 144 145 146 147 148 149 150 151 152 153 154
const std::string kCmdNameSAdd = "sadd";
const std::string kCmdNameSPop = "spop";
const std::string kCmdNameSCard = "scard";
const std::string kCmdNameSMembers = "smembers";
const std::string kCmdNameSScan = "sscan";
const std::string kCmdNameSRem = "srem";
const std::string kCmdNameSUnion = "sunion";
const std::string kCmdNameSUnionstore = "sunionstore";
const std::string kCmdNameSInter = "sinter";
const std::string kCmdNameSInterstore = "sinterstore";
const std::string kCmdNameSIsmember = "sismember";
const std::string kCmdNameSDiff = "sdiff";
L
Leviathan 已提交
155 156 157 158 159 160 161 162
const std::string kCmdNameSDiffstore = "sdiffstore";
const std::string kCmdNameSMove = "smove";
const std::string kCmdNameSRandmember = "srandmember";

//HyperLogLog
const std::string kCmdNamePfAdd = "pfadd";
const std::string kCmdNamePfCount = "pfcount";
const std::string kCmdNamePfMerge = "pfmerge";
163

L
leviathan 已提交
164 165 166 167 168
//GEO
const std::string kCmdNameGeoAdd = "geoadd";
const std::string kCmdNameGeoPos = "geopos";
const std::string kCmdNameGeoDist = "geodist";
const std::string kCmdNameGeoHash = "geohash";
169 170
const std::string kCmdNameGeoRadius = "georadius";
const std::string kCmdNameGeoRadiusByMember = "georadiusbymember";
L
leviathan 已提交
171

W
wangkang-xy 已提交
172
typedef pink::RedisCmdArgsType PikaCmdArgsType;
W
wangkang-xy 已提交
173 174

enum CmdFlagsMask {
C
CatKang 已提交
175
  kCmdFlagsMaskRW               = 1,
176 177 178 179
  kCmdFlagsMaskType             = 28,
  kCmdFlagsMaskLocal            = 32,
  kCmdFlagsMaskSuspend          = 64,
  kCmdFlagsMaskPrior            = 128,
L
bugfix  
leviathan 已提交
180
  kCmdFlagsMaskAdminRequire     = 256
W
wangkang-xy 已提交
181 182 183
};

enum CmdFlags {
W
wangkang-xy 已提交
184
  kCmdFlagsRead           = 0, //default rw
W
wangkang-xy 已提交
185
  kCmdFlagsWrite          = 1,
W
wangkang-xy 已提交
186
  kCmdFlagsAdmin          = 0, //default type
W
wangkang-xy 已提交
187 188 189 190 191
  kCmdFlagsKv             = 2,
  kCmdFlagsHash           = 4,
  kCmdFlagsList           = 6,
  kCmdFlagsSet            = 8,
  kCmdFlagsZset           = 10,
W
wenduo 已提交
192
  kCmdFlagsBit            = 12,
L
Leviathan 已提交
193
  kCmdFlagsHyperLogLog    = 14,
194
  kCmdFlagsGeo            = 16,
W
wangkang-xy 已提交
195
  kCmdFlagsNoLocal        = 0, //default nolocal
196
  kCmdFlagsLocal          = 32,
W
wangkang-xy 已提交
197
  kCmdFlagsNoSuspend      = 0, //default nosuspend
198
  kCmdFlagsSuspend        = 64,
W
wangkang-xy 已提交
199
  kCmdFlagsNoPrior        = 0, //default noprior
200
  kCmdFlagsPrior          = 128,
C
CatKang 已提交
201
  kCmdFlagsNoAdminRequire = 0, //default no need admin
L
leviathan 已提交
202
  kCmdFlagsAdminRequire   = 256
W
wangkang-xy 已提交
203 204 205
};


W
wangkang-xy 已提交
206 207
class CmdInfo {
public:
W
wangkang-xy 已提交
208 209 210 211 212
  CmdInfo(const std::string _name, int _num, uint16_t _flag)
    : name_(_name), arity_(_num), flag_(_flag) {}
  bool CheckArg(int num) const {
    if ((arity_ > 0 && num != arity_) || (arity_ < 0 && num < -arity_)) {
      return false;
W
wangkang-xy 已提交
213
    }
W
wangkang-xy 已提交
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
    return true;
  }
  bool is_write() const {
    return ((flag_ & kCmdFlagsMaskRW) == kCmdFlagsWrite);
  }
  uint16_t flag_type() const {
    return flag_ & kCmdFlagsMaskType;
  }
  bool is_local() const {
    return ((flag_ & kCmdFlagsMaskLocal) == kCmdFlagsLocal);
  }
  // Others need to be suspended when a suspend command run
  bool is_suspend() const {
    return ((flag_ & kCmdFlagsMaskSuspend) == kCmdFlagsSuspend);
  }
  bool is_prior() const {
    return ((flag_ & kCmdFlagsMaskPrior) == kCmdFlagsPrior);
  }
C
CatKang 已提交
232 233 234 235
  // Must with admin auth
  bool is_admin_require() const {
    return ((flag_ & kCmdFlagsMaskAdminRequire) == kCmdFlagsAdminRequire);
  }
W
wangkang-xy 已提交
236 237 238
  std::string name() const {
    return name_;
  }
W
wangkang-xy 已提交
239
private:
W
wangkang-xy 已提交
240 241 242
  std::string name_;
  int arity_;
  uint16_t flag_;
W
wangkang-xy 已提交
243

W
wangkang-xy 已提交
244 245
  CmdInfo(const CmdInfo&);
  CmdInfo& operator=(const CmdInfo&);
W
wangkang-xy 已提交
246
};
W
wangkang-xy 已提交
247

W
wangkang-xy 已提交
248 249
void inline RedisAppendContent(std::string& str, const std::string& value);
void inline RedisAppendLen(std::string& str, int ori, const std::string &prefix);
W
wangkang-xy 已提交
250

C
CatKang 已提交
251 252
const std::string kNewLine = "\r\n";

W
wangkang-xy 已提交
253 254 255
class CmdRes {
public:
  enum CmdRet {
C
CatKang 已提交
256 257
    kNone = 0,
    kOk,
K
KernelMaker 已提交
258
    kPong,
C
CatKang 已提交
259
    kSyntaxErr,
260
    kInvalidInt,
W
wenduo 已提交
261 262 263 264
    kInvalidBitInt,
    kInvalidBitOffsetInt,
    kInvalidBitPosArgument,
    kWrongBitOpNotNum,
265 266
    kInvalidFloat,
    kOverFlow,
C
CatKang 已提交
267 268
    kNotFound,
    kOutOfRange,
C
CatKang 已提交
269
    kInvalidPwd,
C
CatKang 已提交
270
    kNoneBgsave,
C
CatKang 已提交
271 272
    kPurgeExist,
    kInvalidParameter,
C
CatKang 已提交
273
    kWrongNum,
K
KernelMaker 已提交
274
    kInvalidIndex,
C
CatKang 已提交
275
    kErrOther,
W
wangkang-xy 已提交
276 277
  };

C
CatKang 已提交
278
  CmdRes():ret_(kNone) {}
W
wangkang-xy 已提交
279

C
CatKang 已提交
280 281 282
  bool none() const {
    return ret_ == kNone && message_.empty();
  }
W
wangkang-xy 已提交
283
  bool ok() const {
C
CatKang 已提交
284
    return ret_ == kOk || ret_ == kNone;
W
wangkang-xy 已提交
285 286 287
  }
  void clear() {
    message_.clear();
C
CatKang 已提交
288
    ret_ = kNone;
W
wangkang-xy 已提交
289
  }
C
CatKang 已提交
290 291 292
  std::string raw_message() const {
    return message_;
  }
W
wangkang-xy 已提交
293
  std::string message() const {
C
CatKang 已提交
294 295 296 297 298 299
    std::string result;
    switch (ret_) {
    case kNone:
      return message_;
    case kOk:
      return "+OK\r\n";
K
KernelMaker 已提交
300 301
    case kPong:
      return "+PONG\r\n";
C
CatKang 已提交
302 303
    case kSyntaxErr:
      return "-ERR syntax error\r\n";
304
    case kInvalidInt:
C
CatKang 已提交
305
      return "-ERR value is not an integer or out of range\r\n";
W
wenduo 已提交
306 307 308 309 310 311 312 313 314
    case kInvalidBitInt:
      return "-ERR bit is not an integer or out of range\r\n";
    case kInvalidBitOffsetInt:
      return "-ERR bit offset is not an integer or out of range\r\n";
    case kWrongBitOpNotNum:
      return "-ERR BITOP NOT must be called with a single source key.\r\n";

    case kInvalidBitPosArgument:
      return "-ERR The bit argument must be 1 or 0.\r\n";
315 316 317 318
    case kInvalidFloat:
      return "-ERR value is not an float\r\n";
    case kOverFlow:
      return "-ERR increment or decrement would overflow\r\n";
C
CatKang 已提交
319 320 321 322
    case kNotFound:
      return "-ERR no such key\r\n";
    case kOutOfRange:
      return "-ERR index out of range\r\n";
C
CatKang 已提交
323 324
    case kInvalidPwd:
      return "-ERR invalid password\r\n";
C
CatKang 已提交
325 326
    case kNoneBgsave:
      return "-ERR No BGSave Works now\r\n";
C
CatKang 已提交
327
    case kPurgeExist:
C
CatKang 已提交
328
      return "-ERR binlog already in purging...\r\n";
C
CatKang 已提交
329 330
    case kInvalidParameter:
      return "-ERR Invalid Argument\r\n";
C
CatKang 已提交
331 332 333 334 335
    case kWrongNum:
      result = "-ERR wrong number of arguments for '";
      result.append(message_);
      result.append("' command\r\n");
      break;
K
KernelMaker 已提交
336 337 338
    case kInvalidIndex:
      result = "-ERR invalid DB index\r\n";
      break;
C
CatKang 已提交
339 340 341 342 343 344 345 346 347
    case kErrOther:
      result = "-ERR ";
      result.append(message_);
      result.append(kNewLine);
      break;
    default:
      break;
    }
    return result;
W
wangkang-xy 已提交
348 349 350 351
  }

  // Inline functions for Create Redis protocol
  void AppendStringLen(int ori) {
W
wangkang-xy 已提交
352
    RedisAppendLen(message_, ori, "$");
W
wangkang-xy 已提交
353 354
  }
  void AppendArrayLen(int ori) {
W
wangkang-xy 已提交
355
    RedisAppendLen(message_, ori, "*");
W
wangkang-xy 已提交
356
  }
C
CatKang 已提交
357
  void AppendInteger(int ori) {
C
CatKang 已提交
358
    RedisAppendLen(message_, ori, ":");
C
CatKang 已提交
359
  }
W
wangkang-xy 已提交
360
  void AppendContent(const std::string &value) {
W
wangkang-xy 已提交
361
    RedisAppendContent(message_, value);
W
wangkang-xy 已提交
362
  }
C
CatKang 已提交
363 364 365 366
  void AppendString(const std::string &value) {
    AppendStringLen(value.size());
    AppendContent(value);
  }
367 368 369
  void AppendStringRaw(std::string &value) {
    message_.append(value);
  }
C
CatKang 已提交
370
  void SetRes(CmdRet _ret, const std::string content = "") {
C
CatKang 已提交
371
    ret_ = _ret;
C
CatKang 已提交
372 373 374
    if (!content.empty()) {
      message_ = content;
    }
W
wangkang-xy 已提交
375 376 377 378
  }

private:
  std::string message_;
C
CatKang 已提交
379
  CmdRet ret_;
W
wangkang-xy 已提交
380
};
W
wangkang-xy 已提交
381

W
wangkang-xy 已提交
382 383
class Cmd {
public:
W
wangkang-xy 已提交
384 385
  Cmd() {}
  virtual ~Cmd() {}
C
CatKang 已提交
386
  virtual void Do() = 0;
C
CatKang 已提交
387
  void Initial(PikaCmdArgsType &argvs, const CmdInfo* const ptr_info) {
C
CatKang 已提交
388 389 390 391
    res_.clear(); // Clear res content
    Clear();      // Clear cmd, Derived class can has own implement
    DoInitial(argvs, ptr_info);
  };
W
wangkang-xy 已提交
392 393 394
  CmdRes& res() {
    return res_;
  }
W
wangkang-xy 已提交
395 396

protected:
W
wangkang-xy 已提交
397
  CmdRes res_;
W
wangkang-xy 已提交
398 399

private:
C
CatKang 已提交
400 401
  virtual void DoInitial(PikaCmdArgsType &argvs, const CmdInfo* const ptr_info) = 0;
  virtual void Clear() {};
W
wangkang-xy 已提交
402 403
  Cmd(const Cmd&);
  Cmd& operator=(const Cmd&);
W
wangkang-xy 已提交
404 405
};

W
wangkang-xy 已提交
406 407
// Method for CmdInfo Table
void InitCmdInfoTable();
W
wangkang-xy 已提交
408 409
const CmdInfo* GetCmdInfo(const std::string& opt);
void DestoryCmdInfoTable();
W
wangkang-xy 已提交
410
// Method for Cmd Table
W
wangkang-xy 已提交
411 412
void InitCmdTable(std::unordered_map<std::string, Cmd*> *cmd_table);
Cmd* GetCmdFromTable(const std::string& opt, 
413
    const std::unordered_map<std::string, Cmd*> &cmd_table);
W
wangkang-xy 已提交
414
void DestoryCmdTable(std::unordered_map<std::string, Cmd*> &cmd_table);
W
wangkang-xy 已提交
415

W
wangkang-xy 已提交
416
void inline RedisAppendContent(std::string& str, const std::string& value) {
417 418
  str.append(value.data(), value.size());
  str.append(kNewLine);
W
wangkang-xy 已提交
419 420
}
void inline RedisAppendLen(std::string& str, int ori, const std::string &prefix) {
421 422 423 424 425
  char buf[32];
  slash::ll2string(buf, 32, static_cast<long long>(ori));
  str.append(prefix);
  str.append(buf);
  str.append(kNewLine);
W
wangkang-xy 已提交
426
}
W
wangkang-xy 已提交
427
#endif