This is an automated email from the ASF dual-hosted git repository.
twice pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/kvrocks.git
The following commit(s) were added to refs/heads/unstable by this push:
new c17a8cb2 Improve the command JSON.MERGE via jsonpath::remove (#1919)
c17a8cb2 is described below
commit c17a8cb2b484a004f4188bfb66692f05507f0c3f
Author: 2rueSid <[email protected]>
AuthorDate: Tue Dec 5 05:30:29 2023 -0500
Improve the command JSON.MERGE via jsonpath::remove (#1919)
---
src/types/json.h | 36 +++++++++++++++++++-----------------
tests/cppunit/types/json_test.cc | 8 +++++++-
2 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/src/types/json.h b/src/types/json.h
index 672437e9..854a1d7d 100644
--- a/src/types/json.h
+++ b/src/types/json.h
@@ -31,6 +31,8 @@
#include <jsoncons_ext/jsonpath/flatten.hpp>
#include <jsoncons_ext/jsonpath/json_query.hpp>
#include <jsoncons_ext/jsonpath/jsonpath_error.hpp>
+#include <jsoncons_ext/jsonpointer/jsonpointer.hpp>
+#include <jsoncons_ext/jsonpointer/jsonpointer_error.hpp>
#include <jsoncons_ext/mergepatch/mergepatch.hpp>
#include <limits>
#include <string>
@@ -362,11 +364,20 @@ struct JsonValue {
bool not_exists = jsoncons::jsonpath::json_query(value, path).empty();
if (not_exists) {
- // TODO:: Add ability to create an object from path.
- return {Status::NotOK, "Path does not exist."};
- }
+ jsoncons::jsonpath::json_location location =
jsoncons::jsonpath::json_location::parse(path);
+ jsoncons::jsonpointer::json_pointer ptr{};
+
+ for (const auto &element : location) {
+ if (element.has_name())
+ ptr /= element.name();
+ else {
+ ptr /= element.index();
+ }
+ }
+ jsoncons::jsonpointer::replace(value, ptr, patch_value, true);
- if (path == json_root_path) {
+ is_updated = true;
+ } else if (path == json_root_path) {
// Merge with the root. Patch function complies with RFC7396 Json
Merge Patch
jsoncons::mergepatch::apply_merge_patch(value, patch_value);
is_updated = true;
@@ -379,20 +390,11 @@ struct JsonValue {
});
} else {
// Handle null case
- // Unify path expression.
- auto expr = jsoncons::jsonpath::make_expression<jsoncons::json>(path);
- std::string converted_path;
- expr.evaluate(
- value, [&](const jsoncons::string_view &p, const jsoncons::json
&val) { converted_path = p; },
- jsoncons::jsonpath::result_options::path);
- // Unify object state
- jsoncons::json flattened = jsoncons::jsonpath::flatten(value);
- if (flattened.contains(converted_path)) {
- flattened.erase(converted_path);
- value = jsoncons::jsonpath::unflatten(flattened);
- is_updated = true;
- }
+ jsoncons::jsonpath::remove(value, path);
+ is_updated = true;
}
+ } catch (const jsoncons::jsonpointer::jsonpointer_error &e) {
+ return {Status::NotOK, e.what()};
} catch (const jsoncons::jsonpath::jsonpath_error &e) {
return {Status::NotOK, e.what()};
} catch (const jsoncons::ser_error &e) {
diff --git a/tests/cppunit/types/json_test.cc b/tests/cppunit/types/json_test.cc
index 56290451..4ba08fe9 100644
--- a/tests/cppunit/types/json_test.cc
+++ b/tests/cppunit/types/json_test.cc
@@ -192,10 +192,16 @@ TEST_F(RedisJsonTest, Merge) {
ASSERT_EQ(json_val_.Dump().GetValue(), "{\"a\":3}");
ASSERT_EQ(result, true);
+ ASSERT_TRUE(json_->Set(key_, "$", R"({"a":2})").ok());
+ ASSERT_TRUE(json_->Merge(key_, "$.b", "3", result).ok());
+ ASSERT_TRUE(json_->Get(key_, {}, &json_val_).ok());
+ ASSERT_EQ(json_val_.Dump().GetValue(), "{\"a\":2,\"b\":3}");
+ ASSERT_EQ(result, true);
+
ASSERT_TRUE(json_->Set(key_, "$", R"({"v": {"b": "cc"}})").ok());
ASSERT_TRUE(json_->Merge(key_, "$.v.b", "null", result).ok());
ASSERT_TRUE(json_->Get(key_, {}, &json_val_).ok());
- ASSERT_EQ(json_val_.Dump().GetValue(), "{}");
+ ASSERT_EQ(json_val_.Dump().GetValue(), "{\"v\":{}}");
ASSERT_EQ(result, true);
ASSERT_TRUE(json_->Set(key_, "$", R"({"arr":[2,4,6,8]})").ok());