chore(json_family): Clean up code. FIRST PR (#5049)

* chore(json_family): Clean up code

Signed-off-by: Stepan Bagritsevich <stefan@dragonflydb.io>

* refactor: address comments

Signed-off-by: Stepan Bagritsevich <stefan@dragonflydb.io>

* chore(json_family): Remove const ref for mutate operations

Signed-off-by: Stepan Bagritsevich <stefan@dragonflydb.io>

* refactor: address comments 2

Signed-off-by: Stepan Bagritsevich <stefan@dragonflydb.io>

* chore(json_family): Remove GetJson method

Signed-off-by: Stepan Bagritsevich <stefan@dragonflydb.io>

* refactor: revert const modifiers removing

Signed-off-by: Stepan Bagritsevich <stefan@dragonflydb.io>

---------

Signed-off-by: Stepan Bagritsevich <stefan@dragonflydb.io>
This commit is contained in:
Stepan Bagritsevich 2025-05-04 15:09:59 +02:00 committed by GitHub
parent 9f7b11628a
commit 0a33f28bd4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 286 additions and 253 deletions

View file

@ -21,17 +21,17 @@ using facade::OpStatus;
using Nothing = std::monostate;
using JsonExpression = jsoncons::jsonpath::jsonpath_expression<JsonType>;
namespace details {
template <typename T>
using JsonPathEvaluateCallback = absl::FunctionRef<T(std::string_view, const JsonType&)>;
void OptionalEmplace(bool keep_defined, std::optional<T> src, std::optional<T>* dest);
template <typename T> void OptionalEmplace(bool keep_defined, T src, T* dest);
} // namespace details
template <typename T>
using JsonPathReadOnlyCallback = absl::FunctionRef<T(std::string_view, const JsonType&)>;
template <typename T = Nothing> struct MutateCallbackResult {
MutateCallbackResult() {
}
MutateCallbackResult(bool should_be_deleted_, T value_)
: should_be_deleted(should_be_deleted_), value(std::move(value_)) {
}
bool should_be_deleted = false;
std::optional<T> value;
};
@ -40,6 +40,101 @@ template <typename T>
using JsonPathMutateCallback =
absl::FunctionRef<MutateCallbackResult<T>(std::optional<std::string_view>, JsonType*)>;
enum class JsonPathType { kV2, kLegacy /*Or V1*/ };
constexpr JsonPathType kDefaultJsonPathType = JsonPathType::kV2;
struct CallbackResultOptions {
public:
enum class SavingOrder { kSaveFirst, kSaveLast };
enum class OnEmpty { kSendNil, kSendWrongType };
// Default options for WrappedJsonPath::ExecuteReadOnlyCallback
static CallbackResultOptions DefaultReadOnlyOptions(
SavingOrder saving_order = SavingOrder::kSaveLast);
// Default options for WrappedJsonPath::ExecuteMutateCallback
static CallbackResultOptions DefaultMutateOptions();
OnEmpty on_empty;
SavingOrder saving_order{SavingOrder::kSaveLast};
std::optional<JsonPathType> path_type{std::nullopt};
};
template <typename T> class JsonCallbackResult {
private:
template <typename V> struct is_optional : std::false_type {};
template <typename V> struct is_optional<std::optional<V>> : std::true_type {};
public:
using SavingOrder = CallbackResultOptions::SavingOrder;
using OnEmpty = CallbackResultOptions::OnEmpty;
JsonCallbackResult() = default;
explicit JsonCallbackResult(CallbackResultOptions options);
void AddValue(T value);
bool Empty() const;
bool IsV1() const;
const T& AsV1() const;
const auto& AsV2() const;
bool ShouldSendNil() const;
bool ShouldSendWrongType() const;
private:
std::vector<T> result_;
CallbackResultOptions options_{OnEmpty::kSendWrongType, SavingOrder::kSaveLast,
kDefaultJsonPathType};
};
class WrappedJsonPath {
public:
static constexpr std::string_view kV1PathRootElement = ".";
static constexpr std::string_view kV2PathRootElement = "$";
WrappedJsonPath(json::Path json_path, StringOrView path, JsonPathType path_type);
WrappedJsonPath(JsonExpression expression, StringOrView path, JsonPathType path_type);
template <typename T>
JsonCallbackResult<T> ExecuteReadOnlyCallback(const JsonType* json_entry,
JsonPathReadOnlyCallback<T> cb,
CallbackResultOptions options) const;
template <typename T>
OpResult<JsonCallbackResult<std::optional<T>>> ExecuteMutateCallback(
JsonType* json_entry, JsonPathMutateCallback<T> cb, CallbackResultOptions options) const;
bool IsLegacyModePath() const;
bool RefersToRootElement() const;
// Returns true if this is internal implementation of json path
// Check AsJsonPath
bool HoldsJsonPath() const;
// Internal implementation of json path
const json::Path& AsJsonPath() const;
// Jsoncons implementation of json path
const JsonExpression& AsJsonExpression() const;
// Returns the path as a string_view.
std::string_view Path() const;
private:
CallbackResultOptions InitializePathType(CallbackResultOptions options) const;
private:
std::variant<json::Path, JsonExpression> parsed_path_;
StringOrView path_;
JsonPathType path_type_ = kDefaultJsonPathType;
};
// Implementation
/******************************************************************/
namespace details {
template <typename T>
@ -57,234 +152,177 @@ template <typename T> void OptionalEmplace(bool keep_defined, T src, T* dest) {
} // namespace details
enum class JsonPathType { kV2, kLegacy /*Or V1*/ };
constexpr JsonPathType kDefaultJsonPathType = JsonPathType::kV2;
inline CallbackResultOptions CallbackResultOptions::DefaultReadOnlyOptions(
SavingOrder saving_order) {
return CallbackResultOptions{OnEmpty::kSendNil, saving_order};
}
struct CallbackResultOptions {
public:
enum class SavingOrder { kSaveFirst, kSaveLast };
enum class OnEmpty { kSendNil, kSendWrongType };
inline CallbackResultOptions CallbackResultOptions::DefaultMutateOptions() {
return CallbackResultOptions{OnEmpty::kSendWrongType};
}
// Default options for WrappedJsonPath::Evaluate
static CallbackResultOptions DefaultEvaluateOptions() {
return CallbackResultOptions{OnEmpty::kSendNil};
template <typename T>
JsonCallbackResult<T>::JsonCallbackResult(CallbackResultOptions options) : options_(options) {
}
template <typename T> void JsonCallbackResult<T>::AddValue(T value) {
if (result_.empty() || !IsV1()) {
result_.push_back(std::move(value));
return;
}
static CallbackResultOptions DefaultEvaluateOptions(SavingOrder saving_order) {
return {saving_order, OnEmpty::kSendNil};
details::OptionalEmplace(options_.saving_order == SavingOrder::kSaveFirst, std::move(value),
&result_.front());
}
template <typename T> bool JsonCallbackResult<T>::Empty() const {
return result_.empty();
}
template <typename T> bool JsonCallbackResult<T>::IsV1() const {
return options_.path_type == JsonPathType::kLegacy;
}
template <typename T> const T& JsonCallbackResult<T>::AsV1() const {
return result_.front();
}
template <typename T> const auto& JsonCallbackResult<T>::AsV2() const {
return result_;
}
template <typename T> bool JsonCallbackResult<T>::ShouldSendNil() const {
return IsV1() && options_.on_empty == OnEmpty::kSendNil && result_.empty();
}
template <typename T> bool JsonCallbackResult<T>::ShouldSendWrongType() const {
if (IsV1()) {
if (result_.empty() && options_.on_empty == OnEmpty::kSendWrongType)
return true;
if constexpr (is_optional<T>::value) {
return !result_.front().has_value();
}
}
return false;
}
inline WrappedJsonPath::WrappedJsonPath(json::Path json_path, StringOrView path,
JsonPathType path_type)
: parsed_path_(std::move(json_path)), path_(std::move(path)), path_type_(path_type) {
}
inline WrappedJsonPath::WrappedJsonPath(JsonExpression expression, StringOrView path,
JsonPathType path_type)
: parsed_path_(std::move(expression)), path_(std::move(path)), path_type_(path_type) {
}
template <typename T>
JsonCallbackResult<T> WrappedJsonPath::ExecuteReadOnlyCallback(
const JsonType* json_entry, JsonPathReadOnlyCallback<T> cb,
CallbackResultOptions options) const {
JsonCallbackResult<T> read_result{InitializePathType(options)};
auto eval_callback = [&cb, &read_result](std::string_view path, const JsonType& val) {
read_result.AddValue(cb(path, val));
};
if (HoldsJsonPath()) {
const auto& json_path = AsJsonPath();
json::EvaluatePath(json_path, *json_entry,
[&eval_callback](std::optional<std::string_view> key, const JsonType& val) {
eval_callback(key ? *key : std::string_view{}, val);
});
} else {
const auto& json_expression = AsJsonExpression();
json_expression.evaluate(*json_entry, eval_callback);
}
// Default options for WrappedJsonPath::Mutate
static CallbackResultOptions DefaultMutateOptions() {
return CallbackResultOptions{OnEmpty::kSendWrongType};
}
return read_result;
}
explicit CallbackResultOptions(OnEmpty on_empty_) : on_empty(on_empty_) {
}
template <typename T>
OpResult<JsonCallbackResult<std::optional<T>>> WrappedJsonPath::ExecuteMutateCallback(
JsonType* json_entry, JsonPathMutateCallback<T> cb, CallbackResultOptions options) const {
JsonCallbackResult<std::optional<T>> mutate_result{InitializePathType(options)};
CallbackResultOptions(JsonPathType path_type_, SavingOrder saving_order_, OnEmpty on_empty_)
: path_type(path_type_), saving_order(saving_order_), on_empty(on_empty_) {
}
auto mutate_callback = [&cb, &mutate_result](std::optional<std::string_view> path,
JsonType* val) -> bool {
auto res = cb(path, val);
if (res.value.has_value()) {
mutate_result.AddValue(std::move(res.value).value());
} else if (!mutate_result.IsV1()) {
mutate_result.AddValue(std::nullopt);
}
return res.should_be_deleted;
};
std::optional<JsonPathType> path_type;
SavingOrder saving_order{SavingOrder::kSaveLast};
OnEmpty on_empty;
if (HoldsJsonPath()) {
const auto& json_path = AsJsonPath();
json::MutatePath(json_path, mutate_callback, json_entry);
} else {
using namespace jsoncons::jsonpath;
using namespace jsoncons::jsonpath::detail;
using Evaluator = jsonpath_evaluator<JsonType, JsonType&>;
using ValueType = Evaluator::value_type;
using Reference = Evaluator::reference;
using JsonSelector = Evaluator::path_expression_type;
private:
CallbackResultOptions(SavingOrder saving_order_, OnEmpty on_empty_)
: saving_order(saving_order_), on_empty(on_empty_) {
}
};
custom_functions<JsonType> funcs = custom_functions<JsonType>();
template <typename T> class JsonCallbackResult {
template <typename V> struct is_optional : std::false_type {};
std::error_code ec;
static_resources<ValueType, Reference> static_resources(funcs);
Evaluator e;
template <typename V> struct is_optional<std::optional<V>> : std::true_type {};
public:
using SavingOrder = CallbackResultOptions::SavingOrder;
using OnEmpty = CallbackResultOptions::OnEmpty;
JsonCallbackResult()
: options_(kDefaultJsonPathType, SavingOrder::kSaveLast, OnEmpty::kSendWrongType) {
}
explicit JsonCallbackResult(CallbackResultOptions options) : options_(options) {
}
void AddValue(T value) {
if (result_.empty() || !IsV1()) {
result_.push_back(std::move(value));
return;
JsonSelector expr = e.compile(static_resources, path_.view(), ec);
if (ec) {
VLOG(1) << "Failed to mutate json with error: " << ec.message();
return OpStatus::SYNTAX_ERR;
}
details::OptionalEmplace(options_.saving_order == SavingOrder::kSaveFirst, std::move(value),
&result_.front());
}
dynamic_resources<ValueType, Reference> resources;
bool IsV1() const {
return options_.path_type == JsonPathType::kLegacy;
}
const T& AsV1() const {
return result_.front();
}
const auto& AsV2() const {
return result_;
}
bool Empty() const {
return result_.empty();
}
bool ShouldSendNil() const {
return IsV1() && options_.on_empty == OnEmpty::kSendNil && result_.empty();
}
bool ShouldSendWrongType() const {
if (IsV1()) {
if (result_.empty() && options_.on_empty == OnEmpty::kSendWrongType)
return true;
if constexpr (is_optional<T>::value) {
return !result_.front().has_value();
}
}
return false;
}
private:
std::vector<T> result_;
CallbackResultOptions options_;
};
class WrappedJsonPath {
public:
static constexpr std::string_view kV1PathRootElement = ".";
static constexpr std::string_view kV2PathRootElement = "$";
WrappedJsonPath(json::Path json_path, StringOrView path, JsonPathType path_type)
: parsed_path_(std::move(json_path)), path_(std::move(path)), path_type_(path_type) {
}
WrappedJsonPath(JsonExpression expression, StringOrView path, JsonPathType path_type)
: parsed_path_(std::move(expression)), path_(std::move(path)), path_type_(path_type) {
}
template <typename T>
JsonCallbackResult<T> Evaluate(const JsonType* json_entry, JsonPathEvaluateCallback<T> cb,
CallbackResultOptions options) const {
JsonCallbackResult<T> eval_result{InitializePathType(options)};
auto eval_callback = [&cb, &eval_result](std::string_view path, const JsonType& val) {
eval_result.AddValue(cb(path, val));
auto f = [&mutate_callback](const basic_path_node<char>& path, JsonType& val) {
mutate_callback(to_string(path), &val);
};
if (HoldsJsonPath()) {
const auto& json_path = AsJsonPath();
json::EvaluatePath(
json_path, *json_entry,
[&eval_callback](std::optional<std::string_view> key, const JsonType& val) {
eval_callback(key ? *key : std::string_view{}, val);
});
} else {
const auto& json_expression = AsJsonExpression();
json_expression.evaluate(*json_entry, eval_callback);
}
return eval_result;
expr.evaluate(resources, *json_entry, JsonSelector::path_node_type{}, *json_entry, std::move(f),
result_options::nodups | result_options::path);
}
return mutate_result;
}
template <typename T>
OpResult<JsonCallbackResult<std::optional<T>>> Mutate(JsonType* json_entry,
JsonPathMutateCallback<T> cb,
CallbackResultOptions options) const {
JsonCallbackResult<std::optional<T>> mutate_result{InitializePathType(options)};
inline bool WrappedJsonPath::IsLegacyModePath() const {
return path_type_ == JsonPathType::kLegacy;
}
auto mutate_callback = [&cb, &mutate_result](std::optional<std::string_view> path,
JsonType* val) -> bool {
auto res = cb(path, val);
if (res.value.has_value()) {
mutate_result.AddValue(std::move(res.value).value());
} else if (!mutate_result.IsV1()) {
mutate_result.AddValue(std::nullopt);
}
return res.should_be_deleted;
};
inline bool WrappedJsonPath::RefersToRootElement() const {
auto path = path_.view();
return path.empty() || path == kV1PathRootElement || path == kV2PathRootElement;
}
if (HoldsJsonPath()) {
const auto& json_path = AsJsonPath();
json::MutatePath(json_path, mutate_callback, json_entry);
} else {
using namespace jsoncons::jsonpath;
using namespace jsoncons::jsonpath::detail;
using Evaluator = jsonpath_evaluator<JsonType, JsonType&>;
using ValueType = Evaluator::value_type;
using Reference = Evaluator::reference;
using JsonSelector = Evaluator::path_expression_type;
inline bool WrappedJsonPath::HoldsJsonPath() const {
return std::holds_alternative<json::Path>(parsed_path_);
}
custom_functions<JsonType> funcs = custom_functions<JsonType>();
inline const json::Path& WrappedJsonPath::AsJsonPath() const {
return std::get<json::Path>(parsed_path_);
}
std::error_code ec;
static_resources<ValueType, Reference> static_resources(funcs);
Evaluator e;
inline const JsonExpression& WrappedJsonPath::AsJsonExpression() const {
return std::get<JsonExpression>(parsed_path_);
}
JsonSelector expr = e.compile(static_resources, path_.view(), ec);
if (ec) {
VLOG(1) << "Failed to mutate json with error: " << ec.message();
return OpStatus::SYNTAX_ERR;
}
inline std::string_view WrappedJsonPath::Path() const {
return path_.view();
}
dynamic_resources<ValueType, Reference> resources;
auto f = [&mutate_callback](const basic_path_node<char>& path, JsonType& val) {
mutate_callback(to_string(path), &val);
};
expr.evaluate(resources, *json_entry, JsonSelector::path_node_type{}, *json_entry,
std::move(f), result_options::nodups | result_options::path);
}
return mutate_result;
inline CallbackResultOptions WrappedJsonPath::InitializePathType(
CallbackResultOptions options) const {
if (!options.path_type) {
options.path_type = path_type_;
}
bool IsLegacyModePath() const {
return path_type_ == JsonPathType::kLegacy;
}
bool RefersToRootElement() const {
auto path = path_.view();
return path.empty() || path == kV1PathRootElement || path == kV2PathRootElement;
}
bool HoldsJsonPath() const {
return std::holds_alternative<json::Path>(parsed_path_);
}
const json::Path& AsJsonPath() const {
return std::get<json::Path>(parsed_path_);
}
const JsonExpression& AsJsonExpression() const {
return std::get<JsonExpression>(parsed_path_);
}
std::string_view Path() const {
return path_.view();
}
private:
CallbackResultOptions InitializePathType(CallbackResultOptions options) const {
if (!options.path_type) {
options.path_type = path_type_;
}
return options;
}
private:
std::variant<json::Path, JsonExpression> parsed_path_;
StringOrView path_;
JsonPathType path_type_ = kDefaultJsonPathType;
};
return options;
}
} // namespace dfly

View file

@ -404,17 +404,6 @@ string JsonTypeToName(const JsonType& val) {
return std::string{};
}
OpResult<JsonType*> GetJson(const OpArgs& op_args, string_view key) {
auto it_res = op_args.GetDbSlice().FindReadOnly(op_args.db_cntx, key, OBJ_JSON);
if (!it_res.ok())
return it_res.status();
JsonType* json_val = it_res.value()->second.GetJson();
DCHECK(json_val) << "should have a valid JSON object for key " << key;
return json_val;
}
// Returns the index of the next right bracket
OptSize GetNextIndex(string_view str) {
size_t current_idx = 0;
@ -593,25 +582,31 @@ size_t CountJsonFields(const JsonType& j) {
return res;
}
struct EvaluateOperationOptions {
struct ReadOnlyOperationOptions {
bool return_nil_if_key_not_found = false;
CallbackResultOptions cb_result_options = CallbackResultOptions::DefaultEvaluateOptions();
CallbackResultOptions cb_result_options = CallbackResultOptions::DefaultReadOnlyOptions();
};
template <typename T>
OpResult<JsonCallbackResult<T>> JsonEvaluateOperation(const OpArgs& op_args, std::string_view key,
OpResult<JsonCallbackResult<T>> JsonReadOnlyOperation(const OpArgs& op_args, std::string_view key,
const WrappedJsonPath& json_path,
JsonPathEvaluateCallback<T> cb,
EvaluateOperationOptions options = {}) {
OpResult<JsonType*> result = GetJson(op_args, key);
if (options.return_nil_if_key_not_found && result == OpStatus::KEY_NOTFOUND) {
return JsonCallbackResult<T>{
{JsonPathType::kLegacy, options.cb_result_options.saving_order,
CallbackResultOptions::OnEmpty::kSendNil}}; // set legacy mode to return nil
JsonPathReadOnlyCallback<T> cb,
ReadOnlyOperationOptions options = {}) {
auto it_res = op_args.GetDbSlice().FindReadOnly(op_args.db_cntx, key, OBJ_JSON);
if (!it_res) {
if (options.return_nil_if_key_not_found && it_res == OpStatus::KEY_NOTFOUND) {
return JsonCallbackResult<T>{{CallbackResultOptions::OnEmpty::kSendNil,
options.cb_result_options.saving_order,
JsonPathType::kLegacy}}; // set legacy mode to return nil
}
return it_res.status();
}
RETURN_ON_BAD_STATUS(result);
return json_path.Evaluate<T>(*result, cb, options.cb_result_options);
JsonType* json_val = it_res.value()->second.GetJson();
DCHECK(json_val) << "should have a valid JSON object for key " << key;
return json_path.ExecuteReadOnlyCallback<T>(json_val, cb, options.cb_result_options);
}
struct MutateOperationOptions {
@ -640,7 +635,7 @@ OpResult<JsonCallbackResult<optional<T>>> JsonMutateOperation(const OpArgs& op_a
op_args.shard->search_indices()->RemoveDoc(key, op_args.db_cntx, pv);
auto mutate_res = json_path.Mutate(json_val, cb, options.cb_result_options);
auto mutate_res = json_path.ExecuteMutateCallback(json_val, cb, options.cb_result_options);
// Call post mutate callback
if (mutate_res && options.post_mutate_cb) {
@ -719,11 +714,11 @@ OpResult<std::string> OpJsonGet(const OpArgs& op_args, string_view key,
auto cb = [](std::string_view, const JsonType& val) { return val; };
const bool legacy_mode_is_enabled = LegacyModeIsEnabled(paths);
CallbackResultOptions cb_options = CallbackResultOptions::DefaultEvaluateOptions();
CallbackResultOptions cb_options = CallbackResultOptions::DefaultReadOnlyOptions();
cb_options.path_type = legacy_mode_is_enabled ? JsonPathType::kLegacy : JsonPathType::kV2;
auto eval_wrapped = [&](const WrappedJsonPath& json_path) -> std::optional<JsonType> {
auto eval_result = json_path.Evaluate<JsonType>(&json_entry, cb, cb_options);
auto eval_result = json_path.ExecuteReadOnlyCallback<JsonType>(&json_entry, cb, cb_options);
DCHECK(legacy_mode_is_enabled == eval_result.IsV1());
@ -764,7 +759,7 @@ auto OpType(const OpArgs& op_args, string_view key, const WrappedJsonPath& json_
auto cb = [](const string_view&, const JsonType& val) -> std::string {
return JsonTypeToName(val);
};
return JsonEvaluateOperation<std::string>(op_args, key, json_path, std::move(cb), {true});
return JsonReadOnlyOperation<std::string>(op_args, key, json_path, std::move(cb), {true});
}
OpResult<JsonCallbackResult<OptSize>> OpStrLen(const OpArgs& op_args, string_view key,
@ -776,9 +771,9 @@ OpResult<JsonCallbackResult<OptSize>> OpStrLen(const OpArgs& op_args, string_vie
return nullopt;
}
};
return JsonEvaluateOperation<OptSize>(
return JsonReadOnlyOperation<OptSize>(
op_args, key, json_path, std::move(cb),
{true, CallbackResultOptions::DefaultEvaluateOptions(SavingOrder::kSaveFirst)});
{true, CallbackResultOptions::DefaultReadOnlyOptions(SavingOrder::kSaveFirst)});
}
OpResult<JsonCallbackResult<OptSize>> OpObjLen(const OpArgs& op_args, string_view key,
@ -790,10 +785,10 @@ OpResult<JsonCallbackResult<OptSize>> OpObjLen(const OpArgs& op_args, string_vie
return nullopt;
}
};
return JsonEvaluateOperation<OptSize>(
return JsonReadOnlyOperation<OptSize>(
op_args, key, json_path, std::move(cb),
{json_path.IsLegacyModePath(),
CallbackResultOptions::DefaultEvaluateOptions(SavingOrder::kSaveFirst)});
CallbackResultOptions::DefaultReadOnlyOptions(SavingOrder::kSaveFirst)});
}
OpResult<JsonCallbackResult<OptSize>> OpArrLen(const OpArgs& op_args, string_view key,
@ -805,9 +800,9 @@ OpResult<JsonCallbackResult<OptSize>> OpArrLen(const OpArgs& op_args, string_vie
return std::nullopt;
}
};
return JsonEvaluateOperation<OptSize>(
return JsonReadOnlyOperation<OptSize>(
op_args, key, json_path, std::move(cb),
{true, CallbackResultOptions::DefaultEvaluateOptions(SavingOrder::kSaveFirst)});
{true, CallbackResultOptions::DefaultReadOnlyOptions(SavingOrder::kSaveFirst)});
}
template <typename T>
@ -973,8 +968,8 @@ OpResult<long> OpDel(const OpArgs& op_args, string_view key, string_view path,
return {};
};
auto res = json_path.Mutate<Nothing>(json_val, std::move(cb),
CallbackResultOptions::DefaultMutateOptions());
auto res = json_path.ExecuteMutateCallback<Nothing>(
json_val, std::move(cb), CallbackResultOptions::DefaultMutateOptions());
RETURN_ON_BAD_STATUS(res);
if (deletion_items.empty()) {
@ -1017,10 +1012,10 @@ auto OpObjKeys(const OpArgs& op_args, string_view key, const WrappedJsonPath& js
}
return vec;
};
return JsonEvaluateOperation<StringVec>(
return JsonReadOnlyOperation<StringVec>(
op_args, key, json_path, std::move(cb),
{json_path.IsLegacyModePath(),
CallbackResultOptions::DefaultEvaluateOptions(SavingOrder::kSaveFirst)});
CallbackResultOptions::DefaultReadOnlyOptions(SavingOrder::kSaveFirst)});
}
OpResult<JsonCallbackResult<OptSize>> OpStrAppend(const OpArgs& op_args, string_view key,
@ -1243,7 +1238,7 @@ auto OpArrIndex(const OpArgs& op_args, string_view key, const WrappedJsonPath& j
return pos;
};
return JsonEvaluateOperation<std::optional<long>>(
return JsonReadOnlyOperation<std::optional<long>>(
op_args, key, json_path, std::move(cb),
{false, CallbackResultOptions{CallbackResultOptions::OnEmpty::kSendWrongType}});
}
@ -1270,8 +1265,8 @@ std::vector<std::optional<std::string>> OpJsonMGet(const WrappedJsonPath& json_p
auto eval_wrapped = [&json_val,
&cb](const WrappedJsonPath& json_path) -> std::optional<JsonType> {
auto eval_result = json_path.Evaluate<JsonType>(
json_val, std::move(cb), CallbackResultOptions::DefaultEvaluateOptions());
auto eval_result = json_path.ExecuteReadOnlyCallback<JsonType>(
json_val, std::move(cb), CallbackResultOptions::DefaultReadOnlyOptions());
if (eval_result.IsV1()) {
if (eval_result.Empty())
@ -1306,13 +1301,13 @@ auto OpFields(const OpArgs& op_args, string_view key, const WrappedJsonPath& jso
auto cb = [](const string_view&, const JsonType& val) -> std::optional<std::size_t> {
return CountJsonFields(val);
};
return JsonEvaluateOperation<std::optional<std::size_t>>(op_args, key, json_path, std::move(cb));
return JsonReadOnlyOperation<std::optional<std::size_t>>(op_args, key, json_path, std::move(cb));
}
// Returns json vector that represents the result of the json query.
auto OpResp(const OpArgs& op_args, string_view key, const WrappedJsonPath& json_path) {
auto cb = [](const string_view&, const JsonType& val) { return val; };
return JsonEvaluateOperation<JsonType>(op_args, key, json_path, std::move(cb));
return JsonReadOnlyOperation<JsonType>(op_args, key, json_path, std::move(cb));
}
// Returns boolean that represents the result of the operation.