feat(json): Deserialize ReJSON format (#2725)

* feat(json): Deserialize ReJSON format

This PR adds support for Redis-based JSON RDB format deserialization.
Since Redis uses ReJSON as a module, serialization is slightly different
from other types, but overall it's not a big change once we know where
all bits should be.

While this change knows how to _read_ Redis-based JSON keys, it does not
_save_ them in Redis format. That will be in a different PR.

This PR also ignores unknown (non-keys) module data instead of failing the load.

Fixes #2718

* Cleanup

* Add tests

* Skip unsupported modules

* Small refactor
This commit is contained in:
Shahar Mike 2024-03-14 17:23:31 +02:00 committed by GitHub
parent 9c6e6a96b7
commit e2b5d48837
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 117 additions and 3 deletions

View file

@ -509,4 +509,29 @@ TEST_F(RdbTest, LoadSmall7) {
ASSERT_THAT(resp, ArgType(RespExpr::ARRAY));
EXPECT_THAT(resp.GetVec(), ElementsAre("einstein", "schrodinger"));
}
TEST_F(RdbTest, RedisJson) {
// RDB file generated via:
// ./redis-server --save "" --appendonly no --loadmodule ../lib/rejson.so
// and then:
// JSON.SET json-str $ '"hello"'
// JSON.SET json-arr $ "[1, true, \"hello\", 3.14]"
// JSON.SET json-obj $
// '{"company":"DragonflyDB","product":"Dragonfly","website":"https://dragondlydb.io","years-active":[2021,2022,2023,2024,"and
// more!"]}'
io::FileSource fs = GetSource("redis_json.rdb");
RdbLoader loader{service_.get()};
// must run in proactor thread in order to avoid polluting the serverstate
// in the main, testing thread.
auto ec = pp_->at(0)->Await([&] { return loader.Load(&fs); });
ASSERT_FALSE(ec) << ec.message();
EXPECT_EQ(Run({"JSON.GET", "json-str"}), "\"hello\"");
EXPECT_EQ(Run({"JSON.GET", "json-arr"}), "[1,true,\"hello\",3.14]");
EXPECT_EQ(Run({"JSON.GET", "json-obj"}),
"{\"company\":\"DragonflyDB\",\"product\":\"Dragonfly\",\"website\":\"https://"
"dragondlydb.io\",\"years-active\":[2021,2022,2023,2024,\"and more!\"]}");
}
} // namespace dfly