diff --git a/src/storage/rdb/rdb.cc b/src/storage/rdb/rdb.cc index 5adf48f059d..5896ab345d2 100644 --- a/src/storage/rdb/rdb.cc +++ b/src/storage/rdb/rdb.cc @@ -35,6 +35,7 @@ #include "types/redis_bitmap.h" #include "types/redis_bitmap_string.h" #include "types/redis_hash.h" +#include "types/redis_json.h" #include "types/redis_list.h" #include "types/redis_set.h" #include "types/redis_sortedint.h" @@ -723,7 +724,7 @@ Status RDB::Dump(const std::string &key, const RedisType type) { Status RDB::SaveObjectType(const RedisType type) { int robj_type = -1; - if (type == kRedisString || type == kRedisBitmap) { + if (type == kRedisString || type == kRedisBitmap || type == kRedisJson) { robj_type = RDBTypeString; } else if (type == kRedisHash) { robj_type = RDBTypeHash; @@ -798,6 +799,20 @@ Status RDB::SaveObject(const std::string &key, const RedisType type) { return {Status::RedisExecErr, s.ToString()}; } return SaveStringObject(value); + } else if (type == kRedisJson) { + redis::Json json_db(storage_, ns_); + JsonValue value; + auto s = json_db.Get(ctx, key, {}, &value); + if (!s.ok() && !s.IsNotFound()) { + return {Status::RedisExecErr, s.ToString()}; + } + std::string json_str; + Config *config = storage_->GetConfig(); + auto dump_status = value.Dump(&json_str, config->json_max_nesting_depth); + if (!dump_status.IsOK()) { + return {Status::RedisExecErr, dump_status.Msg()}; + } + return SaveStringObject(json_str); } else if (type == kRedisSortedint) { redis::Sortedint sortedint_db(storage_, ns_); std::vector ids; diff --git a/tests/gocase/unit/dump/dump_test.go b/tests/gocase/unit/dump/dump_test.go index 27846703325..6855e19c8a2 100644 --- a/tests/gocase/unit/dump/dump_test.go +++ b/tests/gocase/unit/dump/dump_test.go @@ -220,3 +220,32 @@ func TestDump_SortedInt(t *testing.T) { expectedMembers := []string{"5", "12", "23", "89", "100"} require.ElementsMatch(t, expectedMembers, members) } + +func TestDump_JSON(t *testing.T) { + srv := util.StartServer(t, map[string]string{}) + defer srv.Close() + + ctx := context.Background() + rdb := srv.NewClient() + defer func() { require.NoError(t, rdb.Close()) }() + + key := "test_json_key" + + jsonData := `{"name":"Alice","age":30,"city":"NYC"}` + require.NoError(t, rdb.Do(ctx, "JSON.SET", key, "$", jsonData).Err()) + + require.EqualValues(t, "ReJSON-RL", rdb.Type(ctx, key).Val()) + + serialized, err := rdb.Dump(ctx, key).Result() + require.NoError(t, err) + + restoredKey := fmt.Sprintf("restore_%s", key) + require.NoError(t, rdb.RestoreReplace(ctx, restoredKey, 0, serialized).Err()) + + require.EqualValues(t, "string", rdb.Type(ctx, restoredKey).Val()) + + content := rdb.Get(ctx, restoredKey).Val() + require.Contains(t, content, "Alice") + require.Contains(t, content, "30") + require.Contains(t, content, "NYC") +}