Skip to content

Commit

Permalink
Add method to read JSON from storage for simplifying code (apache#1843)
Browse files Browse the repository at this point in the history
  • Loading branch information
PragmaTwice authored Oct 21, 2023
1 parent 0276f39 commit 968551d
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 31 deletions.
5 changes: 5 additions & 0 deletions kvrocks.conf
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,11 @@ max-bitmap-to-string-mb 16
# Default: no
redis-cursor-compatible no

# Maximum nesting depth allowed when parsing and serializing
# JSON documents while using JSON commands like JSON.SET.
# Default: 1024
json-max-nesting-depth 1024

################################## TLS ###################################

# By default, TLS/SSL is disabled, i.e. `tls-port` is set to 0.
Expand Down
55 changes: 24 additions & 31 deletions src/types/redis_json.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,31 @@ rocksdb::Status Json::write(Slice ns_key, JsonMetadata *metadata, const JsonValu
return storage_->Write(storage_->DefaultWriteOptions(), batch->GetWriteBatch());
}

rocksdb::Status Json::read(const Slice &ns_key, JsonMetadata *metadata, JsonValue *value) {
std::string bytes;
Slice rest;

auto s = GetMetadata(kRedisJson, ns_key, &bytes, metadata, &rest);
if (!s.ok()) return s;

if (metadata->format != JsonStorageFormat::JSON)
return rocksdb::Status::NotSupported("JSON storage format not supported");

auto origin_res = JsonValue::FromString(rest.ToStringView());
if (!origin_res) return rocksdb::Status::Corruption(origin_res.Msg());
*value = *std::move(origin_res);

return rocksdb::Status::OK();
}

rocksdb::Status Json::Set(const std::string &user_key, const std::string &path, const std::string &value) {
auto ns_key = AppendNamespacePrefix(user_key);

LockGuard guard(storage_->GetLockManager(), ns_key);

std::string bytes;
JsonMetadata metadata;
Slice rest;
auto s = GetMetadata(kRedisJson, ns_key, &bytes, &metadata, &rest);
JsonValue origin;
auto s = read(ns_key, &metadata, &origin);

if (s.IsNotFound()) {
if (path != "$") return rocksdb::Status::InvalidArgument("new objects must be created at the root");
Expand All @@ -67,17 +83,10 @@ rocksdb::Status Json::Set(const std::string &user_key, const std::string &path,

if (!s.ok()) return s;

if (metadata.format != JsonStorageFormat::JSON)
return rocksdb::Status::NotSupported("JSON storage format not supported");

auto new_res = JsonValue::FromString(value, storage_->GetConfig()->json_max_nesting_depth);
if (!new_res) return rocksdb::Status::InvalidArgument(new_res.Msg());
auto new_val = *std::move(new_res);

auto origin_res = JsonValue::FromString(rest.ToStringView());
if (!origin_res) return rocksdb::Status::Corruption(origin_res.Msg());
auto origin = *std::move(origin_res);

auto set_res = origin.Set(path, std::move(new_val));
if (!set_res) return rocksdb::Status::InvalidArgument(set_res.Msg());

Expand All @@ -87,19 +96,11 @@ rocksdb::Status Json::Set(const std::string &user_key, const std::string &path,
rocksdb::Status Json::Get(const std::string &user_key, const std::vector<std::string> &paths, JsonValue *result) {
auto ns_key = AppendNamespacePrefix(user_key);

std::string bytes;
JsonMetadata metadata;
Slice rest;
auto s = GetMetadata(kRedisJson, ns_key, &bytes, &metadata, &rest);
JsonValue json_val;
auto s = read(ns_key, &metadata, &json_val);
if (!s.ok()) return s;

if (metadata.format != JsonStorageFormat::JSON)
return rocksdb::Status::NotSupported("JSON storage format not supported");

auto json_res = JsonValue::FromString(rest.ToStringView());
if (!json_res) return rocksdb::Status::Corruption(json_res.Msg());
auto json_val = *std::move(json_res);

JsonValue res;

if (paths.empty()) {
Expand Down Expand Up @@ -127,27 +128,19 @@ rocksdb::Status Json::ArrAppend(const std::string &user_key, const std::string &
std::vector<jsoncons::json> append_values;
append_values.reserve(values.size());
for (auto &v : values) {
auto value_res = JsonValue::FromString(v);
auto value_res = JsonValue::FromString(v, storage_->GetConfig()->json_max_nesting_depth);
if (!value_res) return rocksdb::Status::InvalidArgument(value_res.Msg());
auto value = *std::move(value_res);
append_values.emplace_back(std::move(value.value));
}

LockGuard guard(storage_->GetLockManager(), ns_key);

std::string bytes;
JsonMetadata metadata;
Slice rest;
auto s = GetMetadata(kRedisJson, ns_key, &bytes, &metadata, &rest);
JsonValue value;
auto s = read(ns_key, &metadata, &value);
if (!s.ok()) return s;

if (metadata.format != JsonStorageFormat::JSON)
return rocksdb::Status::NotSupported("JSON storage format not supported");

auto value_res = JsonValue::FromString(rest.ToStringView());
if (!value_res) return rocksdb::Status::Corruption(value_res.Msg());
auto value = *std::move(value_res);

auto append_res = value.ArrAppend(path, append_values, result_count);
if (!append_res) return rocksdb::Status::InvalidArgument(append_res.Msg());

Expand Down
2 changes: 2 additions & 0 deletions src/types/redis_json.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <string>

#include "json.h"
#include "storage/redis_metadata.h"

namespace redis {

Expand All @@ -39,6 +40,7 @@ class Json : public Database {

private:
rocksdb::Status write(Slice ns_key, JsonMetadata *metadata, const JsonValue &json_val);
rocksdb::Status read(const Slice &ns_key, JsonMetadata *metadata, JsonValue *value);
};

} // namespace redis

0 comments on commit 968551d

Please sign in to comment.