PragmaTwice commented on code in PR #3549:
URL: https://github.com/apache/kvrocks/pull/3549#discussion_r3542715239
##########
src/server/server.cc:
##########
@@ -1548,25 +1548,64 @@ std::string Server::GetInfo(const std::string &ns,
const std::vector<std::string
};
std::string info_str;
+ jsoncons::ojson json_obj;
bool all = sections.empty() || util::FindICase(sections.begin(),
sections.end(), "all") != sections.end();
bool first = true;
for (const auto &[sec, fn] : info_funcs) {
if (all || util::FindICase(sections.begin(), sections.end(), sec) !=
sections.end()) {
- if (first)
- first = false;
- else
- info_str.append("\r\n");
-
- info_str.append("# " + sec + "\r\n");
-
- for (const auto &entry : fn(this)) {
- info_str.append(fmt::format("{}:{}\r\n", entry.name, entry.val));
+ auto entries = fn(this);
+ if (format == InfoFormat::Json) {
+ jsoncons::ojson sec_obj;
+ for (const auto &entry : entries) {
+ std::visit(
+ [&](const auto &v) {
+ using T = std::decay_t<decltype(v)>;
+ if constexpr (std::is_same_v<T, double>) {
+ // Serialize via the same %f text form used above so the
JSON number stays consistent
+ // with the text output (and free of float-to-double
widening noise).
+ sec_obj[entry.name] = std::stod(std::to_string(v));
+ } else {
+ // string -> JSON string, int64/uint64 -> JSON number, bool
-> JSON true/false.
+ sec_obj[entry.name] = v;
+ }
+ },
+ entry.val);
+ }
+ json_obj[sec] = std::move(sec_obj);
+ } else {
+ if (first)
+ first = false;
+ else
+ info_str.append("\r\n");
+
+ info_str.append("# " + sec + "\r\n");
+
+ for (const auto &entry : entries) {
+ // Render the typed value as Redis-compatible text: strings
verbatim, booleans as 0/1,
+ // numbers via std::to_string.
+ std::string value = std::visit(
+ [](const auto &v) -> std::string {
+ using T = std::decay_t<decltype(v)>;
+ if constexpr (std::is_same_v<T, std::string>) {
+ return v;
+ } else if constexpr (std::is_same_v<T, bool>) {
+ return v ? "1" : "0";
+ } else {
+ return std::to_string(v);
+ }
+ },
+ entry.val);
Review Comment:
This should be a method of `InfoEntry`.
##########
src/server/server.h:
##########
@@ -263,15 +264,30 @@ class Server {
int64_t GetLastBgsaveTime();
std::string GetRoleInfo();
+ // An INFO entry holds its value with its original type in a variant, so
each output format can
+ // render it appropriately: GetInfo emits the Redis-compatible text (e.g. a
bool as 0/1, numbers via
+ // std::to_string) while FORMAT JSON emits the native JSON type (a bool as
true/false, numbers
+ // unquoted). The type is captured here at construction, where it is
statically known.
struct InfoEntry {
+ using Value = std::variant<std::string, int64_t, uint64_t, double, bool>;
Review Comment:
Is `uint64_t` useful here?
##########
src/server/server.cc:
##########
@@ -1548,25 +1548,64 @@ std::string Server::GetInfo(const std::string &ns,
const std::vector<std::string
};
std::string info_str;
+ jsoncons::ojson json_obj;
bool all = sections.empty() || util::FindICase(sections.begin(),
sections.end(), "all") != sections.end();
bool first = true;
for (const auto &[sec, fn] : info_funcs) {
if (all || util::FindICase(sections.begin(), sections.end(), sec) !=
sections.end()) {
- if (first)
- first = false;
- else
- info_str.append("\r\n");
-
- info_str.append("# " + sec + "\r\n");
-
- for (const auto &entry : fn(this)) {
- info_str.append(fmt::format("{}:{}\r\n", entry.name, entry.val));
+ auto entries = fn(this);
+ if (format == InfoFormat::Json) {
+ jsoncons::ojson sec_obj;
+ for (const auto &entry : entries) {
+ std::visit(
+ [&](const auto &v) {
+ using T = std::decay_t<decltype(v)>;
+ if constexpr (std::is_same_v<T, double>) {
+ // Serialize via the same %f text form used above so the
JSON number stays consistent
+ // with the text output (and free of float-to-double
widening noise).
+ sec_obj[entry.name] = std::stod(std::to_string(v));
+ } else {
+ // string -> JSON string, int64/uint64 -> JSON number, bool
-> JSON true/false.
+ sec_obj[entry.name] = v;
+ }
+ },
+ entry.val);
Review Comment:
I don't think it's useful and it made the logic more complicated. Please
consider to remove it.
##########
src/server/server.cc:
##########
@@ -1548,25 +1548,64 @@ std::string Server::GetInfo(const std::string &ns,
const std::vector<std::string
};
std::string info_str;
+ jsoncons::ojson json_obj;
Review Comment:
Better to use `::json` instead.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]