diff --git a/conf/command.conf b/conf/command.conf index 750187a..da17dc1 100644 --- a/conf/command.conf +++ b/conf/command.conf @@ -1,65 +1,83 @@ # CustomCommand section must be defined before Latency monitor to support all commands # # NOTE: only support maximum 16 custom commands +# +# [...] must be specify +# (...) optional. it has default value +# +# CustomCommand [alias1] { ## module alias. just a delimter +# [command1] { ## command string, must be lower case. i.e. setnx, expire, ... +# (minArgs) (val) ## minimum arguments(including command itself). default is 2(key only) +# (maxArgs) (val) ## maximum arguments(including command itself). default is 2(key only) +# (mode) (val) ## a command mode Read/Write/Admin is exclusive. default is Write. +# } +# [command2] { +# ... +# } +# ... +# } +# +# default key position is first parameter. i.e. command1 key ... +# if you want to use other position, add KeyAt2(key is second) or KeyAt3(key is third) to mode with '|' +# i.e. mode Write|KeyAt2 +# +# in case of 'mode KeyAt2', it will resolved as Write|KeyAt2 -CustomCommand { - # from redis source src/modules/hello.c +# from redis source src/modules/hello.c +CustomCommand hello { # hello.push.native key value - hello.push.native { # name of command, must be lowercase. - # key parameter is located at first argument. i.e. command key ... - # Currently support only 1 key with first argument. - minArgs 3 # minimum arguments(including command itself), default is 2(key only) - maxArgs 3 # maximum arguments(including command itself), default is 2(key only) - mode Write # a command mode Read/Write/Admin is exclusive, default is Write + hello.push.native { + minArgs 3 + maxArgs 3 + mode Write } # hello.repl2 # just skipped since minArgs = 2, maxArgs = 2, mode = Write are default values hello.repl2 { } # hello.toggle.case key + # same as hello.repl2 hello.toggle.case { - mode Write } # hello.more.expire key milliseconds hello.more.expire { minArgs 3 maxArgs 3 - mode Write } # hello.zsumrange key startscore endscore hello.zsumrange { minArgs 4 maxArgs 4 - mode Write + mode Read } # hello.lexrange key min_lex max_lex min_age max_age hello.lexrange { minArgs 6 maxArgs 6 - mode Write + mode Read } # hello.hcopy key srcfield dstfield hello.hcopy { minArgs 4 maxArgs 4 - mode Write } +} - # from redis source src/modules/hellotype.c +# from redis source src/modules/hellotype.c +CustomCommand hellotype { # hellotype.insert key value - hello.insert { + hellotype.insert { minArgs 3 maxArgs 3 - mode Write } # hellotype.range key first count hellotype.range { minArgs 4 maxArgs 4 - mode Write + mode Read } # hellotype.len key hello.len { - mode Write + mode Read } } diff --git a/src/Conf.cpp b/src/Conf.cpp index 6772f61..df406af 100644 --- a/src/Conf.cpp +++ b/src/Conf.cpp @@ -380,9 +380,6 @@ void Conf::setCustomCommand(const ConfParser::Node* node) auto& cc = mCustomCommands.back(); CustomCommandConf::init(cc, p->key.c_str(), Command::Sentinel); auto s = p->sub; - if (!s) { - Throw(InvalidValue, "%s:%d CustomCommand.Command require scope value", node->file, node->line); - } for (;s ; s = s->next) { if (setInt(cc.cmd.minArgs, "minArgs", s, 2)) { } else if (setInt(cc.cmd.maxArgs, "maxArgs", s, 2, 9999)) { @@ -405,18 +402,14 @@ bool Conf::setCommandMode(int& mode, const char* name, const ConfParser::Node* n mode = defaultMode; } else { mode = 0; - int used = 0; std::string mask; std::istringstream is(n->val); - while (std::getline(is, mask, ',')) { + while (std::getline(is, mask, '|')) { if ((strcasecmp(mask.c_str(), "Write") == 0)) { - used++; mode |= Command::Write; } else if ((strcasecmp(mask.c_str(), "Read") == 0)) { - used++; mode |= Command::Read; } else if ((strcasecmp(mask.c_str(), "Admin") == 0)) { - used++; mode |= Command::Admin; } else if ((strcasecmp(mask.c_str(), "KeyAt2") == 0)) { mode |= Command::KeyAt2; @@ -426,10 +419,24 @@ bool Conf::setCommandMode(int& mode, const char* name, const ConfParser::Node* n Throw(InvalidValue, "%s:%d unknown mode %s", n->file, n->line, mask.c_str()); } } - if (used == 0) { - Throw(InvalidValue, "%s:%d %s command require exclusive mode", n->file, n->line, name); - } else if (used > 1) { - Throw(InvalidValue, "%s:%d %s command duplicated exclusive mode", n->file, n->line, name); + switch (mode & Command::KeyMask) { + case 0: + case Command::KeyAt2: + case Command::KeyAt3: + break; + default: + Throw(InvalidValue, "%s:%d %s require exclusive key pos", n->file, n->line, name); + } + switch (mode & Command::AuthMask) { + case 0: + mode |= Command::Write; + break; + case Command::Read: + case Command::Write: + case Command::Admin: + break; + default: + Throw(InvalidValue, "%s:%d %s require exclusive mode", n->file, n->line, name); } } return true; diff --git a/src/LatencyMonitor.h b/src/LatencyMonitor.h index 866a400..55dc3a3 100644 --- a/src/LatencyMonitor.h +++ b/src/LatencyMonitor.h @@ -98,7 +98,7 @@ public: Buffer* output(Buffer* buf) const; private: String mName; - const std::bitset* mCmds; + const std::bitset* mCmds; std::vector mTimeSpan; TimeSpan mLast; };