Skip to content

Commit

Permalink
feat: allow querying of json objects stored as strings
Browse files Browse the repository at this point in the history
Signed-off-by: Roman Gershman <[email protected]>
  • Loading branch information
romange committed Jan 5, 2025
1 parent 6e9409c commit 5b67b35
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 3 deletions.
24 changes: 21 additions & 3 deletions src/server/json_family.cc
Original file line number Diff line number Diff line change
Expand Up @@ -657,11 +657,29 @@ bool LegacyModeIsEnabled(const std::vector<std::pair<std::string_view, WrappedJs

OpResult<std::string> OpJsonGet(const OpArgs& op_args, string_view key,
const JsonGetParams& params) {
OpResult<JsonType*> result = GetJson(op_args, key);
RETURN_ON_BAD_STATUS(result);
auto it = op_args.GetDbSlice().FindReadOnly(op_args.db_cntx, key).it;
if (!IsValid(it))
return OpStatus::KEY_NOTFOUND;

const JsonType* json_ptr = nullptr;
JsonType json;
if (it->second.ObjType() == OBJ_JSON) {
json_ptr = it->second.GetJson();
} else if (it->second.ObjType() == OBJ_STRING) {
string tmp;
it->second.GetString(&tmp);
auto parsed_json = ShardJsonFromString(tmp);
if (!parsed_json) {
return OpStatus::WRONG_TYPE;
}
json.swap(*parsed_json);
json_ptr = &json;
} else {
return OpStatus::WRONG_TYPE;
}

const auto& paths = params.paths;
const JsonType& json_entry = *(result.value());
const JsonType& json_entry = *json_ptr;

if (paths.empty()) {
// this implicitly means that we're using . which
Expand Down
19 changes: 19 additions & 0 deletions src/server/json_family_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2998,4 +2998,23 @@ TEST_F(JsonFamilyTest, MergeLegacy) {
EXPECT_EQ(resp, R"({"y":{"doubled":true},"z":{"answers":["xxx","yyy"],"doubled":false}})");
}

TEST_F(JsonFamilyTest, GetString) {
string json = R"(
{ "a": "b",
"c": {
"d": "e",
"f": "g"
}
}
)";

auto resp = Run({"SET", "json", json});
EXPECT_THAT(resp, "OK");
resp = Run({"JSON.GET", "json", "$.c"});
EXPECT_EQ(resp, R"([{"d":"e","f":"g"}])");
Run({"SET", "not_json", "not_json"});
resp = Run({"JSON.GET", "not_json", "$.c"});
EXPECT_THAT(resp, ErrArg("WRONGTYPE"));
}

} // namespace dfly

0 comments on commit 5b67b35

Please sign in to comment.