From 1e7f205d6202f84cf3c6ebc8ed524cd75c4e82ed Mon Sep 17 00:00:00 2001 From: whr1118 <128034558+whr1118@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:21:34 +0800 Subject: [PATCH] feat: add set cmd spop (#129) * improve spop and add spop cmd gotest * change client.Do to client.SPop --- src/base_cmd.h | 1 + src/cmd_set.cc | 41 +++++++++++++++++++++++++++++++++++++++- src/cmd_set.h | 11 +++++++++++ src/cmd_table_manager.cc | 1 + tests/set_test.go | 24 +++++++++++++++++++++++ 5 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/base_cmd.h b/src/base_cmd.h index 0bbbbb193..f7b0f0b6c 100644 --- a/src/base_cmd.h +++ b/src/base_cmd.h @@ -91,6 +91,7 @@ const std::string kCmdNameSUnion = "sunion"; const std::string kCmdNameSCard = "scard"; const std::string kCmdNameSMove = "smove"; const std::string kCmdNameSRandMember = "srandmember"; +const std::string kCmdNameSPop = "spop"; // list cmd const std::string kCmdNameLPush = "lpush"; diff --git a/src/cmd_set.cc b/src/cmd_set.cc index b7bd7f17c..e4a0e366b 100644 --- a/src/cmd_set.cc +++ b/src/cmd_set.cc @@ -8,6 +8,7 @@ #include "cmd_set.h" #include #include +#include "pstd/pstd_string.h" #include "store.h" namespace pikiwidb { @@ -192,7 +193,6 @@ bool SRandMemberCmd::DoInitial(PClient* client) { return false; } } - client->SetKey(client->argv_[1]); return true; } @@ -211,4 +211,43 @@ void SRandMemberCmd::DoCmd(PClient* client) { return; } +SPopCmd::SPopCmd(const std::string& name, int16_t arity) + : BaseCmd(name, arity, kCmdFlagsWrite, kAclCategoryWrite | kAclCategorySet) {} + +bool SPopCmd::DoInitial(PClient* client) { + client->SetKey(client->argv_[1]); + return true; +} + +void SPopCmd::DoCmd(PClient* client) { + std::vector delete_members; + if ((client->argv_.size()) == 2) { + int64_t cnt = 1; + std::vector delete_member; + storage::Status s = PSTORE.GetBackend(client->GetCurrentDB())->SPop(client->Key(), &delete_member, cnt); + if (!s.ok()) { + client->SetRes(CmdRes::kSyntaxErr, "spop cmd error"); + return; + } + client->AppendString(delete_member[0]); + + } else if ((client->argv_.size()) == 3) { + std::vector delete_members; + int64_t cnt = 1; + if (client->argv_[2].find(".") != std::string::npos || !pstd::String2int(client->argv_[2], &cnt)) { + client->SetRes(CmdRes::kInvalidInt); + return; + } + storage::Status s = PSTORE.GetBackend(client->GetCurrentDB())->SPop(client->Key(), &delete_members, cnt); + if (!s.ok()) { + client->SetRes(CmdRes::kSyntaxErr, "spop cmd error"); + return; + } + client->AppendStringVector(delete_members); + + } else { + client->SetRes(CmdRes::kWrongNum, "spop"); + return; + } +} } // namespace pikiwidb diff --git a/src/cmd_set.h b/src/cmd_set.h index 47df1f28d..9a96fda70 100644 --- a/src/cmd_set.h +++ b/src/cmd_set.h @@ -121,4 +121,15 @@ class SRandMemberCmd : public BaseCmd { int num_rand = 1; }; +class SPopCmd : public BaseCmd { + public: + SPopCmd(const std::string &name, int16_t arity); + + protected: + bool DoInitial(PClient *client) override; + + private: + void DoCmd(PClient *client) override; +}; + } // namespace pikiwidb diff --git a/src/cmd_table_manager.cc b/src/cmd_table_manager.cc index 720641e1b..74cce77b5 100644 --- a/src/cmd_table_manager.cc +++ b/src/cmd_table_manager.cc @@ -97,6 +97,7 @@ void CmdTableManager::InitCmdTable() { ADD_COMMAND(SCard, 2); ADD_COMMAND(SMove, 4); ADD_COMMAND(SRandMember, -2); // Added the count argument since Redis 3.2.0 + ADD_COMMAND(SPop, -2); // list ADD_COMMAND(LPush, -3); diff --git a/tests/set_test.go b/tests/set_test.go index 1ecada909..d148fb02a 100644 --- a/tests/set_test.go +++ b/tests/set_test.go @@ -227,6 +227,30 @@ var _ = Describe("Set", Ordered, func() { sCard := client.SCard(ctx, "setScard") Expect(sCard.Err()).NotTo(HaveOccurred()) Expect(sCard.Val()).To(Equal(int64(2))) + }) + + + It("should SPop", func() { + sAdd := client.SAdd(ctx, "setSpop", "one") + Expect(sAdd.Err()).NotTo(HaveOccurred()) + sAdd = client.SAdd(ctx, "setSpop", "two") + Expect(sAdd.Err()).NotTo(HaveOccurred()) + sAdd = client.SAdd(ctx, "setSpop", "three") + Expect(sAdd.Err()).NotTo(HaveOccurred()) + sAdd = client.SAdd(ctx, "setSpop", "four") + Expect(sAdd.Err()).NotTo(HaveOccurred()) + sAdd = client.SAdd(ctx, "setSpop", "five") + Expect(sAdd.Err()).NotTo(HaveOccurred()) + + sPopN := client.SPopN(ctx, "setSpop", 3) + Expect(sPopN.Err()).NotTo(HaveOccurred()) + Expect(sPopN.Val()).To(HaveLen(3)) + /* + sMembers := client.SMembers(ctx, "setSpop") + Expect(sMembers.Err()).NotTo(HaveOccurred()) + Expect(sMembers.Val()).To(HaveLen(2)) + */ + })