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 Nothing = std::monostate;
using JsonExpression = jsoncons::jsonpath::jsonpath_expression<JsonType>; using JsonExpression = jsoncons::jsonpath::jsonpath_expression<JsonType>;
namespace details {
template <typename T> 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 { 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; bool should_be_deleted = false;
std::optional<T> value; std::optional<T> value;
}; };
@ -40,6 +40,101 @@ template <typename T>
using JsonPathMutateCallback = using JsonPathMutateCallback =
absl::FunctionRef<MutateCallbackResult<T>(std::optional<std::string_view>, JsonType*)>; 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 { namespace details {
template <typename T> template <typename T>
@ -57,234 +152,177 @@ template <typename T> void OptionalEmplace(bool keep_defined, T src, T* dest) {
} // namespace details } // namespace details
enum class JsonPathType { kV2, kLegacy /*Or V1*/ }; inline CallbackResultOptions CallbackResultOptions::DefaultReadOnlyOptions(
constexpr JsonPathType kDefaultJsonPathType = JsonPathType::kV2; SavingOrder saving_order) {
return CallbackResultOptions{OnEmpty::kSendNil, saving_order};
}
struct CallbackResultOptions { inline CallbackResultOptions CallbackResultOptions::DefaultMutateOptions() {
public: return CallbackResultOptions{OnEmpty::kSendWrongType};
enum class SavingOrder { kSaveFirst, kSaveLast }; }
enum class OnEmpty { kSendNil, kSendWrongType };
// Default options for WrappedJsonPath::Evaluate template <typename T>
static CallbackResultOptions DefaultEvaluateOptions() { JsonCallbackResult<T>::JsonCallbackResult(CallbackResultOptions options) : options_(options) {
return CallbackResultOptions{OnEmpty::kSendNil}; }
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) { details::OptionalEmplace(options_.saving_order == SavingOrder::kSaveFirst, std::move(value),
return {saving_order, OnEmpty::kSendNil}; &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 return read_result;
static CallbackResultOptions DefaultMutateOptions() { }
return CallbackResultOptions{OnEmpty::kSendWrongType};
}
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_) auto mutate_callback = [&cb, &mutate_result](std::optional<std::string_view> path,
: path_type(path_type_), saving_order(saving_order_), on_empty(on_empty_) { 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; if (HoldsJsonPath()) {
SavingOrder saving_order{SavingOrder::kSaveLast}; const auto& json_path = AsJsonPath();
OnEmpty on_empty; 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: custom_functions<JsonType> funcs = custom_functions<JsonType>();
CallbackResultOptions(SavingOrder saving_order_, OnEmpty on_empty_)
: saving_order(saving_order_), on_empty(on_empty_) {
}
};
template <typename T> class JsonCallbackResult { std::error_code ec;
template <typename V> struct is_optional : std::false_type {}; static_resources<ValueType, Reference> static_resources(funcs);
Evaluator e;
template <typename V> struct is_optional<std::optional<V>> : std::true_type {}; JsonSelector expr = e.compile(static_resources, path_.view(), ec);
if (ec) {
public: VLOG(1) << "Failed to mutate json with error: " << ec.message();
using SavingOrder = CallbackResultOptions::SavingOrder; return OpStatus::SYNTAX_ERR;
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;
} }
details::OptionalEmplace(options_.saving_order == SavingOrder::kSaveFirst, std::move(value), dynamic_resources<ValueType, Reference> resources;
&result_.front());
}
bool IsV1() const { auto f = [&mutate_callback](const basic_path_node<char>& path, JsonType& val) {
return options_.path_type == JsonPathType::kLegacy; mutate_callback(to_string(path), &val);
}
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));
}; };
if (HoldsJsonPath()) { expr.evaluate(resources, *json_entry, JsonSelector::path_node_type{}, *json_entry, std::move(f),
const auto& json_path = AsJsonPath(); result_options::nodups | result_options::path);
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;
} }
return mutate_result;
}
template <typename T> inline bool WrappedJsonPath::IsLegacyModePath() const {
OpResult<JsonCallbackResult<std::optional<T>>> Mutate(JsonType* json_entry, return path_type_ == JsonPathType::kLegacy;
JsonPathMutateCallback<T> cb, }
CallbackResultOptions options) const {
JsonCallbackResult<std::optional<T>> mutate_result{InitializePathType(options)};
auto mutate_callback = [&cb, &mutate_result](std::optional<std::string_view> path, inline bool WrappedJsonPath::RefersToRootElement() const {
JsonType* val) -> bool { auto path = path_.view();
auto res = cb(path, val); return path.empty() || path == kV1PathRootElement || path == kV2PathRootElement;
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;
};
if (HoldsJsonPath()) { inline bool WrappedJsonPath::HoldsJsonPath() const {
const auto& json_path = AsJsonPath(); return std::holds_alternative<json::Path>(parsed_path_);
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;
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; inline const JsonExpression& WrappedJsonPath::AsJsonExpression() const {
static_resources<ValueType, Reference> static_resources(funcs); return std::get<JsonExpression>(parsed_path_);
Evaluator e; }
JsonSelector expr = e.compile(static_resources, path_.view(), ec); inline std::string_view WrappedJsonPath::Path() const {
if (ec) { return path_.view();
VLOG(1) << "Failed to mutate json with error: " << ec.message(); }
return OpStatus::SYNTAX_ERR;
}
dynamic_resources<ValueType, Reference> resources; inline CallbackResultOptions WrappedJsonPath::InitializePathType(
CallbackResultOptions options) const {
auto f = [&mutate_callback](const basic_path_node<char>& path, JsonType& val) { if (!options.path_type) {
mutate_callback(to_string(path), &val); options.path_type = path_type_;
};
expr.evaluate(resources, *json_entry, JsonSelector::path_node_type{}, *json_entry,
std::move(f), result_options::nodups | result_options::path);
}
return mutate_result;
} }
return options;
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;
};
} // namespace dfly } // namespace dfly

View file

@ -404,17 +404,6 @@ string JsonTypeToName(const JsonType& val) {
return std::string{}; 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 // Returns the index of the next right bracket
OptSize GetNextIndex(string_view str) { OptSize GetNextIndex(string_view str) {
size_t current_idx = 0; size_t current_idx = 0;
@ -593,25 +582,31 @@ size_t CountJsonFields(const JsonType& j) {
return res; return res;
} }
struct EvaluateOperationOptions { struct ReadOnlyOperationOptions {
bool return_nil_if_key_not_found = false; bool return_nil_if_key_not_found = false;
CallbackResultOptions cb_result_options = CallbackResultOptions::DefaultEvaluateOptions(); CallbackResultOptions cb_result_options = CallbackResultOptions::DefaultReadOnlyOptions();
}; };
template <typename T> 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, const WrappedJsonPath& json_path,
JsonPathEvaluateCallback<T> cb, JsonPathReadOnlyCallback<T> cb,
EvaluateOperationOptions options = {}) { ReadOnlyOperationOptions options = {}) {
OpResult<JsonType*> result = GetJson(op_args, key); auto it_res = op_args.GetDbSlice().FindReadOnly(op_args.db_cntx, key, OBJ_JSON);
if (options.return_nil_if_key_not_found && result == OpStatus::KEY_NOTFOUND) {
return JsonCallbackResult<T>{ if (!it_res) {
{JsonPathType::kLegacy, options.cb_result_options.saving_order, if (options.return_nil_if_key_not_found && it_res == OpStatus::KEY_NOTFOUND) {
CallbackResultOptions::OnEmpty::kSendNil}}; // set legacy mode to return nil 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); JsonType* json_val = it_res.value()->second.GetJson();
return json_path.Evaluate<T>(*result, cb, options.cb_result_options); 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 { 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); 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 // Call post mutate callback
if (mutate_res && options.post_mutate_cb) { 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; }; auto cb = [](std::string_view, const JsonType& val) { return val; };
const bool legacy_mode_is_enabled = LegacyModeIsEnabled(paths); 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; cb_options.path_type = legacy_mode_is_enabled ? JsonPathType::kLegacy : JsonPathType::kV2;
auto eval_wrapped = [&](const WrappedJsonPath& json_path) -> std::optional<JsonType> { 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()); 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 { auto cb = [](const string_view&, const JsonType& val) -> std::string {
return JsonTypeToName(val); 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, 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 nullopt;
} }
}; };
return JsonEvaluateOperation<OptSize>( return JsonReadOnlyOperation<OptSize>(
op_args, key, json_path, std::move(cb), 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, 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 nullopt;
} }
}; };
return JsonEvaluateOperation<OptSize>( return JsonReadOnlyOperation<OptSize>(
op_args, key, json_path, std::move(cb), op_args, key, json_path, std::move(cb),
{json_path.IsLegacyModePath(), {json_path.IsLegacyModePath(),
CallbackResultOptions::DefaultEvaluateOptions(SavingOrder::kSaveFirst)}); CallbackResultOptions::DefaultReadOnlyOptions(SavingOrder::kSaveFirst)});
} }
OpResult<JsonCallbackResult<OptSize>> OpArrLen(const OpArgs& op_args, string_view key, 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 std::nullopt;
} }
}; };
return JsonEvaluateOperation<OptSize>( return JsonReadOnlyOperation<OptSize>(
op_args, key, json_path, std::move(cb), op_args, key, json_path, std::move(cb),
{true, CallbackResultOptions::DefaultEvaluateOptions(SavingOrder::kSaveFirst)}); {true, CallbackResultOptions::DefaultReadOnlyOptions(SavingOrder::kSaveFirst)});
} }
template <typename T> template <typename T>
@ -973,8 +968,8 @@ OpResult<long> OpDel(const OpArgs& op_args, string_view key, string_view path,
return {}; return {};
}; };
auto res = json_path.Mutate<Nothing>(json_val, std::move(cb), auto res = json_path.ExecuteMutateCallback<Nothing>(
CallbackResultOptions::DefaultMutateOptions()); json_val, std::move(cb), CallbackResultOptions::DefaultMutateOptions());
RETURN_ON_BAD_STATUS(res); RETURN_ON_BAD_STATUS(res);
if (deletion_items.empty()) { if (deletion_items.empty()) {
@ -1017,10 +1012,10 @@ auto OpObjKeys(const OpArgs& op_args, string_view key, const WrappedJsonPath& js
} }
return vec; return vec;
}; };
return JsonEvaluateOperation<StringVec>( return JsonReadOnlyOperation<StringVec>(
op_args, key, json_path, std::move(cb), op_args, key, json_path, std::move(cb),
{json_path.IsLegacyModePath(), {json_path.IsLegacyModePath(),
CallbackResultOptions::DefaultEvaluateOptions(SavingOrder::kSaveFirst)}); CallbackResultOptions::DefaultReadOnlyOptions(SavingOrder::kSaveFirst)});
} }
OpResult<JsonCallbackResult<OptSize>> OpStrAppend(const OpArgs& op_args, string_view key, 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 pos;
}; };
return JsonEvaluateOperation<std::optional<long>>( return JsonReadOnlyOperation<std::optional<long>>(
op_args, key, json_path, std::move(cb), op_args, key, json_path, std::move(cb),
{false, CallbackResultOptions{CallbackResultOptions::OnEmpty::kSendWrongType}}); {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, auto eval_wrapped = [&json_val,
&cb](const WrappedJsonPath& json_path) -> std::optional<JsonType> { &cb](const WrappedJsonPath& json_path) -> std::optional<JsonType> {
auto eval_result = json_path.Evaluate<JsonType>( auto eval_result = json_path.ExecuteReadOnlyCallback<JsonType>(
json_val, std::move(cb), CallbackResultOptions::DefaultEvaluateOptions()); json_val, std::move(cb), CallbackResultOptions::DefaultReadOnlyOptions());
if (eval_result.IsV1()) { if (eval_result.IsV1()) {
if (eval_result.Empty()) 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> { auto cb = [](const string_view&, const JsonType& val) -> std::optional<std::size_t> {
return CountJsonFields(val); 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. // 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 OpResp(const OpArgs& op_args, string_view key, const WrappedJsonPath& json_path) {
auto cb = [](const string_view&, const JsonType& val) { return val; }; 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. // Returns boolean that represents the result of the operation.