diff --git a/src/base_cmd.h b/src/base_cmd.h index 79874b3a2..03f3cdcd1 100644 --- a/src/base_cmd.h +++ b/src/base_cmd.h @@ -42,6 +42,7 @@ const std::string kCmdNamePSetEx = "psetex"; const std::string kCmdNameBitOp = "bitop"; const std::string kCmdNameGetBit = "getbit"; const std::string kCmdNameBitCount = "bitcount"; +const std::string kCmdNameIncr = "incr"; // multi const std::string kCmdNameMulti = "multi"; diff --git a/src/cmd_kv.cc b/src/cmd_kv.cc index 5bb64709f..10f76c1ea 100644 --- a/src/cmd_kv.cc +++ b/src/cmd_kv.cc @@ -217,6 +217,39 @@ void BitCountCmd::DoCmd(PClient* client) { client->AppendInteger(static_cast(count)); } +IncrCmd::IncrCmd(const std::string& name, int16_t arity) + : BaseCmd(name, arity, kCmdFlagsReadonly, kAclCategoryRead | kAclCategoryString) {} + +bool IncrCmd::DoInitial(pikiwidb::PClient* client) { + client->SetKey(client->argv_[1]); + return true; +} + +void IncrCmd::DoCmd(pikiwidb::PClient* client) { + PObject* value = nullptr; + PError err = PSTORE.GetValueByType(client->Key(), value, kPTypeString); + if (err == kPErrorNotExist) { + value = PSTORE.SetValue(client->Key(), PObject::CreateString(1)); + client->AppendInteger(1); + return; + } + + if (err != kPErrorOK) { + client->SetRes(CmdRes::kErrOther); + return; + } + + if (value->encoding != kPEncodeInt) { + client->SetRes(CmdRes::kInvalidInt); + return; + } + + intptr_t oldVal = static_cast(reinterpret_cast(value->value)); + value->Reset(reinterpret_cast(oldVal + 1)); + + client->AppendInteger(oldVal + 1); +} + BitOpCmd::BitOpCmd(const std::string& name, int16_t arity) : BaseCmd(name, arity, kCmdFlagsWrite, kAclCategoryWrite | kAclCategoryString) {} diff --git a/src/cmd_kv.h b/src/cmd_kv.h index b94c53ed4..3c273d7aa 100644 --- a/src/cmd_kv.h +++ b/src/cmd_kv.h @@ -149,6 +149,17 @@ class BitCountCmd : public BaseCmd { void DoCmd(PClient *client) override; }; +class IncrCmd : public BaseCmd { + public: + IncrCmd(const std::string &name, int16_t arity); + + protected: + bool DoInitial(PClient *client) override; + + private: + void DoCmd(PClient *client) override; +}; + class IncrbyCmd : public BaseCmd { public: IncrbyCmd(const std::string &name, int16_t arity); diff --git a/src/cmd_table_manager.cc b/src/cmd_table_manager.cc index 8556a8f5b..fa255065a 100644 --- a/src/cmd_table_manager.cc +++ b/src/cmd_table_manager.cc @@ -50,6 +50,7 @@ void CmdTableManager::InitCmdTable() { ADD_COMMAND(SetNX, 3); ADD_COMMAND(Append, 3); ADD_COMMAND(Strlen, 2); + ADD_COMMAND(Incr, 2); ADD_COMMAND(Incrby, 3); ADD_COMMAND(Decrby, 3); ADD_COMMAND(IncrbyFloat, 3); diff --git a/src/command.cc b/src/command.cc index 5828ccbda..619e6a395 100644 --- a/src/command.cc +++ b/src/command.cc @@ -62,7 +62,7 @@ const PCommandInfo PCommandTable::s_info[] = { {"mget", kPAttrRead, -2, &mget}, {"append", kPAttrWrite, 3, &append}, {"bitcount", kPAttrRead, -2, &bitcount}, - // {"bitop", PAttr_write, -4, &bitop}, + // {"bitop", PAttr_write, -4, &bitop}, {"getbit", kPAttrRead, 3, &getbit}, {"setbit", kPAttrWrite, 4, &setbit}, {"incr", kPAttrWrite, 2, &incr},