Skip to content
This repository has been archived by the owner on Jun 23, 2022. It is now read-only.

utility: table_printer support output in json mode. #223

Merged
merged 9 commits into from
Mar 4, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions include/dsn/cpp/json_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <cctype>

#include <rapidjson/ostreamwrapper.h>
#include <rapidjson/prettywriter.h>
#include <rapidjson/writer.h>
#include <rapidjson/document.h>

Expand Down Expand Up @@ -200,14 +201,16 @@ namespace json {

typedef rapidjson::GenericValue<rapidjson::UTF8<>> JsonObject;
typedef rapidjson::Writer<rapidjson::OStreamWrapper> JsonWriter;
typedef rapidjson::PrettyWriter<rapidjson::OStreamWrapper> PrettyJsonWriter;

template <typename>
class json_forwarder;

// json serialization for string types.
// please notice when we call rapidjson::Writer::String, with 3rd parameter with "true",
// which means that we will COPY string to writer
inline void json_encode(JsonWriter &out, const std::string &str)
template <typename Writer>
void json_encode(Writer &out, const std::string &str)
{
out.String(str.c_str(), str.length(), true);
}
Expand Down Expand Up @@ -599,5 +602,5 @@ NON_MEMBER_JSON_SERIALIZATION(dsn::app_info,
expire_second,
create_second,
drop_second)
}
}
} // namespace json
} // namespace dsn
1 change: 1 addition & 0 deletions include/dsn/dist/replication/replication_ddl_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class replication_ddl_client
dsn::error_code list_apps(const dsn::app_status::type status,
bool show_all,
bool detailed,
bool json,
const std::string &file_name);

dsn::error_code list_apps(const dsn::app_status::type status,
Expand Down
96 changes: 79 additions & 17 deletions include/dsn/utility/output_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,22 @@
#include <string>
#include <vector>

#include <dsn/cpp/json_helper.h>

namespace dsn {
namespace utils {

class table_printer;
class multi_table_printer;

// Keep the same code style with dsn/cpp/json_helper.h
template <typename Writer>
void json_encode(Writer &out, const table_printer &tp);

/// A tool used to print data in a table form.
///
/// Example usage 1:
/// table_printer tp;
/// table_printer tp("sample_data");
/// tp.add_title("table_title");
/// tp.add_column("column_name1");
/// tp.add_column("column_name2");
Expand All @@ -50,22 +59,24 @@ namespace utils {
/// }
///
/// std::ostream out(...);
/// tp.output(out);
/// tp.output(out, output_format::kTabular);
///
/// Output looks like:
/// sample_data
/// table_title column_name1 column_name2
/// row_name_1 123 45.67
/// row_name_2 456 45.68
///
/// Example usage 2:
/// table_printer tp;
/// table_printer tp("sample_data_2");
/// tp.add_row_name_and_data("row_name_1", int_value);
/// tp.add_row_name_and_data("row_name_2", string_value);
///
/// std::ostream out(...);
/// tp.output(out, ": ");
/// tp.output(out);
///
/// Output looks like:
/// sample_data_2
/// row_name_1 : 4567
/// row_name_2 : hello
///
Expand All @@ -86,19 +97,29 @@ class table_printer
kRight = 1,
};

table_printer(int space_width = 2, int precision = 2)
: mode_(data_mode::kUninitialized), space_width_(space_width), precision_(precision)
enum class output_format
{
kTabular = 0,
kJsonCompact = 1,
kJsonPretty = 2,
};

explicit table_printer(std::string name = "", int tabular_width = 2, int precision = 2)
: _name(std::move(name)),
_mode(data_mode::kUninitialized),
_tabular_width(tabular_width),
_precision(precision)
{
}

// KMultiColumns
// KMultiColumns mode.
void add_title(const std::string &title, alignment align = alignment::kLeft);
void add_column(const std::string &col_name, alignment align = alignment::kLeft);
template <typename T>
void add_row(const T &row_name)
{
check_mode(data_mode::KMultiColumns);
matrix_data_.emplace_back(std::vector<std::string>());
_matrix_data.emplace_back(std::vector<std::string>());
append_data(row_name);
}
template <typename T>
Expand All @@ -108,15 +129,16 @@ class table_printer
append_string_data(to_string(data));
}

// KSingleColumn
// KSingleColumn mode.
template <typename T>
void add_row_name_and_data(const std::string &row_name, const T &data)
{
check_mode(data_mode::KSingleColumn);
add_row_name_and_string_data(row_name, to_string(data));
}

void output(std::ostream &out, const std::string &separator = "") const;
// Output result.
void output(std::ostream &out, output_format format = output_format::kTabular) const;

private:
template <typename T>
Expand All @@ -126,16 +148,31 @@ class table_printer
}

void check_mode(data_mode mode);

void append_string_data(const std::string &data);
void add_row_name_and_string_data(const std::string &row_name, const std::string &data);

void output_in_tabular(std::ostream &out) const;
template <typename Writer>
void output_in_json(std::ostream &out) const
{
rapidjson::OStreamWrapper wrapper(out);
Writer writer(wrapper);
json_encode(writer, *this);
}

private:
data_mode mode_;
int space_width_;
int precision_;
std::vector<bool> align_left_;
std::vector<int> max_col_width_;
std::vector<std::vector<std::string>> matrix_data_;
friend class multi_table_printer;
template <typename Writer>
friend void json_encode(Writer &out, const table_printer &tp);

std::string _name;
data_mode _mode;
int _tabular_width;
int _precision;
std::vector<bool> _align_left;
std::vector<int> _max_col_width;
std::vector<std::vector<std::string>> _matrix_data;
};

template <>
Expand All @@ -151,7 +188,7 @@ inline std::string table_printer::to_string<double>(double data)
return "0.00";
} else {
std::stringstream s;
s << std::fixed << std::setprecision(precision_) << data;
s << std::fixed << std::setprecision(_precision) << data;
return s.str();
}
}
Expand All @@ -168,5 +205,30 @@ inline std::string table_printer::to_string<const char *>(const char *data)
return std::string(data);
}

// Helper to output multiple tables into one large table.
class multi_table_printer
{
public:
void add(table_printer &&tp);
void output(std::ostream &out, table_printer::output_format format) const;

private:
void output_in_tabular(std::ostream &out) const;
template <typename Writer>
void output_in_json(std::ostream &out) const
{
rapidjson::OStreamWrapper wrapper(out);
Writer writer(wrapper);
writer.StartObject();
for (const auto &tp : _tps) {
json_encode(writer, tp);
}
writer.EndObject();
out << std::endl;
}

private:
std::vector<table_printer> _tps;
};
} // namespace utils
} // namespace dsn
Loading