pika_command.h 5.5 KB
Newer Older
W
wangkang-xy 已提交
1 2 3 4 5
#ifndef __PIKA_COMMAND_H__
#define __PIKA_COMMAND_H__

#include <deque>
#include <string>
W
wangkang-xy 已提交
6 7
#include <memory>
#include <redis_conn.h>
W
wangkang-xy 已提交
8 9
#include <unordered_map>
#include "slash_string.h"
W
wangkang-xy 已提交
10

W
wangkang-xy 已提交
11

W
wangkang-xy 已提交
12
//Constant for command name
13 14
//Admin
const std::string kCmdNameSlaveof = "slaveof";
15
const std::string kCmdNameTrysync = "trysync";
16 17

//Kv
W
wangkang-xy 已提交
18
const std::string kCmdNameSet = "set";
W
wangkang-xy 已提交
19
const std::string kCmdNameGet = "get";
J
JacketWoo 已提交
20 21 22 23 24 25 26 27 28
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";
29 30 31 32 33 34 35 36
//Hash

//List

//Zset

//Set

W
wangkang-xy 已提交
37
typedef pink::RedisCmdArgsType PikaCmdArgsType;
W
wangkang-xy 已提交
38 39

enum CmdFlagsMask {
W
wangkang-xy 已提交
40 41 42 43 44
  kCmdFlagsMaskRW         = 1,
  kCmdFlagsMaskType       = 14,
  kCmdFlagsMaskLocal      = 16,
  kCmdFlagsMaskSuspend    = 32,
  kCmdFlagsMaskPrior      = 64
W
wangkang-xy 已提交
45 46 47
};

enum CmdFlags {
W
wangkang-xy 已提交
48
  kCmdFlagsRead           = 0, //default rw
W
wangkang-xy 已提交
49
  kCmdFlagsWrite          = 1,
W
wangkang-xy 已提交
50
  kCmdFlagsAdmin          = 0, //default type
W
wangkang-xy 已提交
51 52 53 54 55
  kCmdFlagsKv             = 2,
  kCmdFlagsHash           = 4,
  kCmdFlagsList           = 6,
  kCmdFlagsSet            = 8,
  kCmdFlagsZset           = 10,
W
wangkang-xy 已提交
56
  kCmdFlagsNoLocal        = 0, //default nolocal
W
wangkang-xy 已提交
57
  kCmdFlagsLocal          = 16,
W
wangkang-xy 已提交
58
  kCmdFlagsNoSuspend      = 0, //default nosuspend
W
wangkang-xy 已提交
59
  kCmdFlagsSuspend        = 32,
W
wangkang-xy 已提交
60
  kCmdFlagsNoPrior        = 0, //default noprior
W
wangkang-xy 已提交
61
  kCmdFlagsPrior          = 64
W
wangkang-xy 已提交
62 63 64
};


W
wangkang-xy 已提交
65 66
class CmdInfo {
public:
W
wangkang-xy 已提交
67 68 69 70 71
  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 已提交
72
    }
W
wangkang-xy 已提交
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
    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);
  }
  std::string name() const {
    return name_;
  }
W
wangkang-xy 已提交
94
private:
W
wangkang-xy 已提交
95 96 97
  std::string name_;
  int arity_;
  uint16_t flag_;
W
wangkang-xy 已提交
98

W
wangkang-xy 已提交
99 100
  CmdInfo(const CmdInfo&);
  CmdInfo& operator=(const CmdInfo&);
W
wangkang-xy 已提交
101
};
W
wangkang-xy 已提交
102

W
wangkang-xy 已提交
103 104
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 已提交
105

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

W
wangkang-xy 已提交
108 109 110
class CmdRes {
public:
  enum CmdRet {
C
CatKang 已提交
111 112 113 114 115 116
    kNone = 0,
    kOk,
    kSyntaxErr,
    kOutofRange,
    kWrongNum,
    kErrOther,
W
wangkang-xy 已提交
117 118
  };

C
CatKang 已提交
119
  CmdRes():ret_(kNone) {}
W
wangkang-xy 已提交
120 121

  bool ok() const {
C
CatKang 已提交
122
    return ret_ == kOk || ret_ == kNone;
W
wangkang-xy 已提交
123 124 125
  }
  void clear() {
    message_.clear();
C
CatKang 已提交
126
    ret_ = kNone;
W
wangkang-xy 已提交
127 128
  }
  std::string message() const {
C
CatKang 已提交
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
    std::string result;
    switch (ret_) {
    case kNone:
      return message_;
    case kOk:
      return "+OK\r\n";
    case kSyntaxErr:
      return "-ERR syntax error\r\n";
    case kOutofRange:
      return "-ERR value is not an integer or out of range\r\n";
    case kWrongNum:
      result = "-ERR wrong number of arguments for '";
      result.append(message_);
      result.append("' command\r\n");
      break;
    case kErrOther:
      result = "-ERR ";
      result.append(message_);
      result.append(kNewLine);
      break;
    default:
      break;
    }
    return result;
W
wangkang-xy 已提交
153 154 155 156
  }

  // Inline functions for Create Redis protocol
  void AppendStringLen(int ori) {
W
wangkang-xy 已提交
157
    RedisAppendLen(message_, ori, "$");
W
wangkang-xy 已提交
158 159
  }
  void AppendArrayLen(int ori) {
W
wangkang-xy 已提交
160
    RedisAppendLen(message_, ori, "*");
W
wangkang-xy 已提交
161
  }
C
CatKang 已提交
162
  void AppendInteger(int ori) {
C
CatKang 已提交
163
    RedisAppendLen(message_, ori, ":");
C
CatKang 已提交
164
  }
W
wangkang-xy 已提交
165
  void AppendContent(const std::string &value) {
W
wangkang-xy 已提交
166
    RedisAppendContent(message_, value);
W
wangkang-xy 已提交
167
  }
C
CatKang 已提交
168
  void SetRes(CmdRet _ret, const std::string content = "") {
C
CatKang 已提交
169
    ret_ = _ret;
C
CatKang 已提交
170 171 172
    if (!content.empty()) {
      message_ = content;
    }
W
wangkang-xy 已提交
173 174 175 176
  }

private:
  std::string message_;
C
CatKang 已提交
177
  CmdRet ret_;
W
wangkang-xy 已提交
178
};
W
wangkang-xy 已提交
179

W
wangkang-xy 已提交
180 181
class Cmd {
public:
W
wangkang-xy 已提交
182 183
  Cmd() {}
  virtual ~Cmd() {}
C
CatKang 已提交
184
  virtual void Do() = 0;
C
CatKang 已提交
185
  void Initial(PikaCmdArgsType &argvs, const CmdInfo* const ptr_info) {
C
CatKang 已提交
186 187 188 189
    res_.clear(); // Clear res content
    Clear();      // Clear cmd, Derived class can has own implement
    DoInitial(argvs, ptr_info);
  };
W
wangkang-xy 已提交
190 191 192
  CmdRes& res() {
    return res_;
  }
W
wangkang-xy 已提交
193 194

protected:
W
wangkang-xy 已提交
195
  CmdRes res_;
W
wangkang-xy 已提交
196 197

private:
C
CatKang 已提交
198 199
  virtual void DoInitial(PikaCmdArgsType &argvs, const CmdInfo* const ptr_info) = 0;
  virtual void Clear() {};
W
wangkang-xy 已提交
200 201
  Cmd(const Cmd&);
  Cmd& operator=(const Cmd&);
W
wangkang-xy 已提交
202 203
};

W
wangkang-xy 已提交
204 205
// Method for CmdInfo Table
void InitCmdInfoTable();
W
wangkang-xy 已提交
206 207
const CmdInfo* GetCmdInfo(const std::string& opt);
void DestoryCmdInfoTable();
W
wangkang-xy 已提交
208
// Method for Cmd Table
W
wangkang-xy 已提交
209 210
void InitCmdTable(std::unordered_map<std::string, Cmd*> *cmd_table);
Cmd* GetCmdFromTable(const std::string& opt, 
211
    const std::unordered_map<std::string, Cmd*> &cmd_table);
W
wangkang-xy 已提交
212
void DestoryCmdTable(std::unordered_map<std::string, Cmd*> &cmd_table);
W
wangkang-xy 已提交
213

W
wangkang-xy 已提交
214
void inline RedisAppendContent(std::string& str, const std::string& value) {
215 216
  str.append(value.data(), value.size());
  str.append(kNewLine);
W
wangkang-xy 已提交
217 218
}
void inline RedisAppendLen(std::string& str, int ori, const std::string &prefix) {
219 220 221 222 223
  char buf[32];
  slash::ll2string(buf, 32, static_cast<long long>(ori));
  str.append(prefix);
  str.append(buf);
  str.append(kNewLine);
W
wangkang-xy 已提交
224
}
J
JacketWoo 已提交
225
#define RedisappendInter RedisAppendLen
W
wangkang-xy 已提交
226
#endif