mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2024-12-15 17:51:06 +00:00
Address HSET bugs
1. add hmset 2. hmget returns nulls when key not found 3. test for valid number of arguments in hset
This commit is contained in:
parent
a845e9bce1
commit
8a1396de31
6 changed files with 31 additions and 43 deletions
|
@ -87,7 +87,7 @@ void DebugCmd::Run(CmdArgList args) {
|
|||
|
||||
string reply = absl::StrCat("Unknown subcommand or wrong number of arguments for '", subcmd,
|
||||
"'. Try DEBUG HELP.");
|
||||
return (*cntx_)->SendError(reply);
|
||||
return (*cntx_)->SendError(reply, kSyntaxErr);
|
||||
}
|
||||
|
||||
void DebugCmd::Reload(CmdArgList args) {
|
||||
|
|
|
@ -196,7 +196,7 @@ void GenericFamily::Del(CmdArgList args, ConnectionContext* cntx) {
|
|||
|
||||
void GenericFamily::Ping(CmdArgList args, ConnectionContext* cntx) {
|
||||
if (args.size() > 2) {
|
||||
return (*cntx)->SendError("wrong number of arguments for 'ping' command");
|
||||
return (*cntx)->SendError(facade::WrongNumArgsError("ping"), kSyntaxErr);
|
||||
}
|
||||
|
||||
// We synchronously block here until the engine sends us the payload and notifies that
|
||||
|
|
|
@ -158,6 +158,11 @@ void HSetFamily::HMGet(CmdArgList args, ConnectionContext* cntx) {
|
|||
(*cntx)->SendNull();
|
||||
}
|
||||
}
|
||||
} else if (result.status() == OpStatus::KEY_NOTFOUND) {
|
||||
(*cntx)->StartArray(args.size());
|
||||
for (unsigned i = 0; i < args.size(); ++i) {
|
||||
(*cntx)->SendNull();
|
||||
}
|
||||
} else {
|
||||
(*cntx)->SendError(result.status());
|
||||
}
|
||||
|
@ -253,6 +258,10 @@ void HSetFamily::HSet(CmdArgList args, ConnectionContext* cntx) {
|
|||
string_view key = ArgS(args, 1);
|
||||
|
||||
args.remove_prefix(2);
|
||||
if (args.size() % 2 != 0) {
|
||||
return (*cntx)->SendError(facade::WrongNumArgsError("hset"), kSyntaxErr);
|
||||
}
|
||||
|
||||
auto cb = [&](Transaction* t, EngineShard* shard) {
|
||||
return OpSet(OpArgs{shard, t->db_index()}, key, args, false);
|
||||
};
|
||||
|
@ -265,20 +274,6 @@ void HSetFamily::HSet(CmdArgList args, ConnectionContext* cntx) {
|
|||
}
|
||||
}
|
||||
|
||||
void HSetFamily::HMSet(CmdArgList args, ConnectionContext* cntx) {
|
||||
string_view key = ArgS(args, 1);
|
||||
|
||||
args.remove_prefix(2);
|
||||
auto cb = [&](Transaction* t, EngineShard* shard) {
|
||||
return OpSet(OpArgs{shard, t->db_index()}, key, args, false);
|
||||
};
|
||||
|
||||
OpResult<uint32_t> result = cntx->transaction->ScheduleSingleHopT(std::move(cb));
|
||||
|
||||
// Returns "OK", that's all the difference from HSet.
|
||||
(*cntx)->SendError(result.status());
|
||||
}
|
||||
|
||||
void HSetFamily::HSetNx(CmdArgList args, ConnectionContext* cntx) {
|
||||
LOG(DFATAL) << "TBD";
|
||||
}
|
||||
|
@ -647,6 +642,7 @@ void HSetFamily::Register(CommandRegistry* registry) {
|
|||
<< CI{"HGET", CO::FAST | CO::READONLY, 3, 1, 1, 1}.HFUNC(HGet)
|
||||
<< CI{"HGETALL", CO::FAST | CO::READONLY, 2, 1, 1, 1}.HFUNC(HGetAll)
|
||||
<< CI{"HMGET", CO::FAST | CO::READONLY, -3, 1, 1, 1}.HFUNC(HMGet)
|
||||
<< CI{"HMSET", CO::WRITE | CO::FAST | CO::DENYOOM, -4, 1, 1, 1}.HFUNC(HSet)
|
||||
<< CI{"HINCRBY", CO::WRITE | CO::DENYOOM | CO::FAST, 4, 1, 1, 1}.HFUNC(HIncrBy)
|
||||
<< CI{"HKEYS", CO::READONLY, 2, 1, 1, 1}.HFUNC(HKeys)
|
||||
<< CI{"HVALS", CO::READONLY, 2, 1, 1, 1}.HFUNC(HVals)
|
||||
|
|
|
@ -34,8 +34,6 @@ class HSetFamily {
|
|||
static void HGetAll(CmdArgList args, ConnectionContext* cntx);
|
||||
|
||||
static void HSet(CmdArgList args, ConnectionContext* cntx);
|
||||
static void HMSet(CmdArgList args, ConnectionContext* cntx);
|
||||
|
||||
static void HSetNx(CmdArgList args, ConnectionContext* cntx);
|
||||
static void HStrLen(CmdArgList args, ConnectionContext* cntx);
|
||||
|
||||
|
|
|
@ -41,31 +41,19 @@ TEST_F(HSetFamilyTest, Basic) {
|
|||
auto resp = Run({"hset", "x", "a"});
|
||||
EXPECT_THAT(resp[0], ErrArg("wrong number"));
|
||||
|
||||
resp = Run({"hset", "x", "a", "b"});
|
||||
EXPECT_THAT(resp[0], IntArg(1));
|
||||
resp = Run({"hlen", "x"});
|
||||
EXPECT_THAT(resp[0], IntArg(1));
|
||||
EXPECT_THAT(Run({"HSET", "hs", "key1", "val1", "key2"}), ElementsAre(ErrArg("wrong number")));
|
||||
|
||||
resp = Run({"hexists", "x", "a"});
|
||||
EXPECT_THAT(resp[0], IntArg(1));
|
||||
EXPECT_EQ(1, CheckedInt({"hset", "x", "a", "b"}));
|
||||
EXPECT_EQ(1, CheckedInt({"hlen", "x"}));
|
||||
|
||||
resp = Run({"hexists", "x", "b"});
|
||||
EXPECT_THAT(resp[0], IntArg(0));
|
||||
EXPECT_EQ(1, CheckedInt({"hexists", "x", "a"}));
|
||||
EXPECT_EQ(0, CheckedInt({"hexists", "x", "b"}));
|
||||
EXPECT_EQ(0, CheckedInt({"hexists", "y", "a"}));
|
||||
|
||||
resp = Run({"hexists", "y", "a"});
|
||||
EXPECT_THAT(resp[0], IntArg(0));
|
||||
|
||||
resp = Run({"hset", "x", "a", "b"});
|
||||
EXPECT_THAT(resp[0], IntArg(0));
|
||||
|
||||
resp = Run({"hset", "x", "a", "c"});
|
||||
EXPECT_THAT(resp[0], IntArg(0));
|
||||
|
||||
resp = Run({"hset", "y", "a", "c", "d", "e"});
|
||||
EXPECT_THAT(resp[0], IntArg(2));
|
||||
|
||||
resp = Run({"hdel", "y", "a", "d"});
|
||||
EXPECT_THAT(resp[0], IntArg(2));
|
||||
EXPECT_EQ(0, CheckedInt({"hset", "x", "a", "b"}));
|
||||
EXPECT_EQ(0, CheckedInt({"hset", "x", "a", "c"}));
|
||||
EXPECT_EQ(2, CheckedInt({"hset", "y", "a", "c", "d", "e"}));
|
||||
EXPECT_EQ(2, CheckedInt({"hdel", "y", "a", "d"}));
|
||||
}
|
||||
|
||||
TEST_F(HSetFamilyTest, HSetLarge) {
|
||||
|
@ -81,6 +69,9 @@ TEST_F(HSetFamilyTest, Get) {
|
|||
auto resp = Run({"hset", "x", "a", "1", "b", "2", "c", "3"});
|
||||
EXPECT_THAT(resp[0], IntArg(3));
|
||||
|
||||
resp = Run({"hmget", "unkwn", "a", "c"});
|
||||
EXPECT_THAT(resp, ElementsAre(ArgType(RespExpr::NIL), ArgType(RespExpr::NIL)));
|
||||
|
||||
resp = Run({"hkeys", "x"});
|
||||
EXPECT_THAT(resp, UnorderedElementsAre("a", "b", "c"));
|
||||
|
||||
|
|
|
@ -8,11 +8,13 @@
|
|||
|
||||
#include "base/logging.h"
|
||||
#include "core/interpreter.h"
|
||||
#include "facade/error.h"
|
||||
#include "server/server_state.h"
|
||||
|
||||
namespace dfly {
|
||||
|
||||
using namespace std;
|
||||
using namespace facade;
|
||||
|
||||
ScriptMgr::ScriptMgr(EngineShardSet* ess) : ess_(ess) {
|
||||
}
|
||||
|
@ -55,9 +57,10 @@ void ScriptMgr::Run(CmdArgList args, ConnectionContext* cntx) {
|
|||
return (*cntx)->SendBulkString(error_or_id);
|
||||
}
|
||||
|
||||
cntx->reply_builder()->SendError(absl::StrCat(
|
||||
"Unknown subcommand or wrong number of arguments for '", subcmd, "'. Try SCRIPT HELP."));
|
||||
} // namespace dfly
|
||||
string err = absl::StrCat("Unknown subcommand or wrong number of arguments for '", subcmd,
|
||||
"'. Try SCRIPT HELP.");
|
||||
cntx->reply_builder()->SendError(err, kSyntaxErr);
|
||||
}
|
||||
|
||||
bool ScriptMgr::InsertFunction(std::string_view id, std::string_view body) {
|
||||
ScriptKey key;
|
||||
|
|
Loading…
Reference in a new issue