19std::string
fit(std::string_view text, std::size_t width,
char filler)
21 std::string result(text.substr(0, width));
22 result.resize(width, filler);
32 for (std::size_t i = 0; i < table.
headers.size(); ++i) {
46 std::string out =
"\"";
47 for (
const unsigned char c : text) {
49 case '"': out +=
"\\\"";
break;
50 case '\\': out +=
"\\\\";
break;
51 case '\n': out +=
"\\n";
break;
52 case '\r': out +=
"\\r";
break;
53 case '\t': out +=
"\\t";
break;
56 out += std::format(
"\\u{:04x}", c);
58 out +=
static_cast<char>(c);
72 std::string out = std::format(
"> {}\n", result.
sql);
74 return out + std::format(
"ERROR: {}\n\n", result.
message);
76 if (
const auto& table = result.
table) {
77 out += std::string(
trimRight(headerLine(*table))) +
'\n';
78 for (
const auto& row : table->rows) {
80 for (std::size_t i = 0; i < row.size(); ++i) {
84 line += fit(row[i], table->widths[i],
' ');
86 out += std::string(
trimRight(line)) +
'\n';
88 out += std::format(
"({})\n\n", result.
message);
95std::string
renderJson(
const std::vector<StatementResult>& results)
97 std::string out =
"{\"results\":[";
103 out += first ?
"" :
",";
105 out += std::format(
"{{\"sql\":{},\"ok\":{},\"message\":{},\"table\":{}", jsonString(result.sql),
106 result.failed ?
"false" :
"true", jsonString(result.message), jsonString(result.tableName));
108 if (
const auto& table = result.table) {
109 out +=
",\"columns\":[";
110 for (std::size_t i = 0; i < table->headers.size(); ++i) {
112 const bool editable = table->idColumn && i != *table->idColumn && !table->literal[i];
113 out += std::format(
"{}{{\"name\":{},\"width\":{},\"editable\":{}}}", i > 0 ?
"," :
"",
114 jsonString(table->headers[i]), table->storageWidths[i], editable ?
"true" :
"false");
116 out +=
"],\"rows\":[";
117 for (std::size_t r = 0; r < table->rows.size(); ++r) {
118 out += r > 0 ?
",[" :
"[";
119 for (std::size_t i = 0; i < table->rows[r].size(); ++i) {
120 out += (i > 0 ?
"," :
"") + jsonString(table->rows[r][i]);
124 out +=
"],\"idColumn\":" + (table->idColumn ? std::to_string(*table->idColumn) : std::string(
"null"));
133 std::string out =
"{\"tables\":[";
134 for (std::size_t t = 0; t < tables.size(); ++t) {
136 out += std::format(
"{}{{\"name\":{},\"readOnly\":{},\"autoId\":{},\"columns\":[", t > 0 ?
"," :
"",
139 for (std::size_t i = 0; i < table.
columns.size(); ++i) {
140 out += std::format(
"{}{{\"name\":{},\"width\":{}}}", i > 0 ?
"," :
"",
constexpr std::string_view kCatalogTable
Name of the catalogue table: it describes every table, itself included, and is its own data file.
Turning statement results into console text or JSON for the browser page.
std::string renderText(const StatementResult &result)
Formats one result for the console.
std::string renderTablesJson(const std::vector< TableSchema > &tables)
Builds the JSON answer of GET /api/tables: every table with its columns.
std::string renderJson(const std::vector< StatementResult > &results)
Builds the JSON answer of POST /api/sql: one object per statement that has something to show.
The SqlError exception and small string helpers used everywhere.
std::string_view trimRight(std::string_view text)
Removes trailing spaces, tabs and line ends.
bool equalsIgnoreCase(std::string_view a, std::string_view b)
Compares two strings, ignoring the case of ASCII letters.
std::string jsonString(std::string_view text)
Writes text as a JSON string: in double quotes, with quotes, backslashes and control characters escap...
std::string fit(std::string_view text, std::size_t width, char filler)
Cuts or pads text to an exact width.
std::string headerLine(const ResultSet &table)
Builds the dashed header line of a console table, e.g. ID-------- NOME----.
The rows produced by a SELECT or DESCRIBE. All per-column vectors have the same length.
std::vector< std::size_t > widths
Display width of each column in console output.
std::vector< std::string > headers
Column titles.
What running one statement produced: a table, a message, or an error.
std::string sql
The statement as it was run.
bool failed
True if the statement failed; message holds the error.
std::string message
E.g. "1 row inserted ...", or the error text.
std::optional< ResultSet > table
The rows, for SELECT and DESCRIBE.
bool silent
True for COLUMN and comments: nothing to show.
The definition of one table: its name, its columns, and the length of a row.
std::string name
Table name, e.g. EMPLOY.
bool hasAutoId() const
Tells whether rows are numbered automatically.
std::vector< Column > columns
Columns in file order.