Joedb 9.5.0
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
Readable_Command_Processor.cpp
Go to the documentation of this file.
2#include "joedb/ui/type_io.h"
5#include "joedb/ui/json.h"
6#include "joedb/ui/dump.h"
7#include "joedb/Readable.h"
8
9#include <vector>
10#include <sstream>
11#include <iomanip>
12
13namespace joedb
14{
15 ////////////////////////////////////////////////////////////////////////////
17 ////////////////////////////////////////////////////////////////////////////
18 (
19 std::istream &in,
20 const Readable &readable
21 )
22 {
23 std::string table_name;
24 in >> table_name;
25 const Table_Id table_id = readable.find_table(table_name);
26 if (table_id == Table_Id(0))
27 throw Exception("No such table: " + table_name);
28 return table_id;
29 }
30
31 ////////////////////////////////////////////////////////////////////////////
33 ////////////////////////////////////////////////////////////////////////////
34 (
35 const std::string &command,
36 std::istream &parameters,
37 std::istream &in,
38 std::ostream &out
39 )
40 {
41 if (command == "table") ///////////////////////////////////////////////////
42 {
43 const Table_Id table_id = parse_table(parameters, readable);
44
45 size_t max_column_width = 25;
46 {
47 size_t w;
48 if (parameters >> w)
49 max_column_width = w;
50 }
51
52 Record_Id start = Record_Id(0);
53 size_t length = 0;
54
55 parameters >> start >> length;
56
57 if (table_id != Table_Id(0))
58 {
59 const auto &fields = readable.get_fields(table_id);
60 std::map<Field_Id, size_t> column_width;
61
62 for (const auto &[fid, fname]: fields)
63 {
64 const size_t width = fname.size();
65 column_width[fid] = width;
66 }
67
68 //
69 // Store values in strings to determine column widths
70 //
71 std::map<Field_Id, std::vector<std::string>> columns;
72 std::vector<Record_Id> id_column;
73
74 size_t rows = 0;
75 const Record_Id last_record_id = readable.get_last_record_id(table_id);
76 for (Record_Id record_id = Record_Id(1); record_id <= last_record_id; ++record_id)
77 {
78 if
79 (
80 readable.is_used(table_id, record_id) &&
81 (length == 0 || (record_id >= start && record_id < start + length))
82 )
83 {
84 rows++;
85 id_column.emplace_back(record_id);
86
87 for (const auto &[fid, fname]: fields)
88 {
89 std::ostringstream ss;
90 write_value(ss, table_id, record_id, fid);
91 ss.flush();
92 const std::string &s = ss.str();
93 const size_t width = utf8_display_size(s);
94 if (column_width[fid] < width)
95 column_width[fid] = width;
96 columns[fid].emplace_back(s);
97 }
98 }
99 }
100
101 //
102 // Determine table width
103 //
104 size_t id_width = 0;
105 {
106 std::ostringstream ss;
107 ss << last_record_id;
108 ss.flush();
109 id_width = ss.str().size();
110 }
111 size_t table_width = id_width;
112 for (const auto &[fid, fname]: fields)
113 {
114 if (max_column_width && column_width[fid] > max_column_width)
115 column_width[fid] = max_column_width;
116 table_width += column_width[fid] + 1;
117 }
118
119 //
120 // Table header
121 //
122 out << std::string(table_width, '-') << '\n';
123 out << std::string(id_width, ' ');
124 for (const auto &[fid, fname]: fields)
125 {
126 const Type::Type_Id type_id = readable.get_field_type
127 (
128 table_id,
129 fid
130 ).get_type_id();
131 out << ' ';
133 (
134 out,
135 fname,
136 column_width[fid],
137 type_id == Type::Type_Id::string
138 );
139 }
140 out << '\n';
141 out << std::string(table_width, '-') << '\n';
142
143 //
144 // Table data
145 //
146 for (size_t i = 0; i < rows; i++)
147 {
148 out << std::setw(int(id_width)) << id_column[i];
149
150 for (const auto &[fid, fname]: fields)
151 {
152 const Type::Type_Id type_id = readable.get_field_type
153 (
154 table_id,
155 fid
156 ).get_type_id();
157
158 out << ' ';
160 (
161 out,
162 columns[fid][i],
163 column_width[fid],
164 type_id == Type::Type_Id::string
165 );
166 }
167 out << '\n';
168 }
169 }
170 }
171 else if (command == "record") /////////////////////////////////////////////
172 {
173 const Table_Id table_id = parse_table(parameters, readable);
174 Record_Id record_id;
175 if (!(parameters >> record_id))
176 record_id = Record_Id{1};
177 if (!readable.is_used(table_id, record_id))
178 throw Exception("no such record");
179
180 const auto &fields = readable.get_fields(table_id);
181 size_t max_field_size = 0;
182 for (const auto &[fid, fname]: fields)
183 if (fname.size() > max_field_size)
184 max_field_size = fname.size();
185
186 for (const auto &[fid, fname]: fields)
187 {
188 out << std::setw(int(max_field_size)) << fname << ": ";
189 write_value(out, table_id, record_id, fid);
190 out << '\n';
191 }
192 }
193 else if (command == "table_size") /////////////////////////////////////////
194 {
195 const Table_Id table_id = parse_table(parameters, readable);
196 const auto &freedom = readable.get_freedom(table_id);
197 out << freedom.get_used_count() << '\n';
198 }
199 else if (command == "schema") /////////////////////////////////////////////
200 {
201 Interpreter_Dump_Writable dump_writable(out);
202 dump(readable, dump_writable, true);
203 }
204 else if (command == "dump") ///////////////////////////////////////////////
205 {
206 Interpreter_Dump_Writable dump_writable(out);
207 dump(readable, dump_writable);
208 }
209 else if (command == "sql") ////////////////////////////////////////////////
210 {
211 SQL_Dump_Writable dump_writable(out);
212 dump(readable, dump_writable);
213 }
214 else if (command == "json") ///////////////////////////////////////////////
215 {
216 bool use_base64 = false;
217 parameters >> use_base64;
218 write_json(out, readable, use_base64);
219 }
220 else if (command == "help") ///////////////////////////////////////////////
221 {
222 out << R"RRR(Displaying data
223~~~~~~~~~~~~~~~
224 table <table_name> [<max_column_width>] [start] [length]
225 record <table_name> [<record_id>]
226 table_size <table_name>
227 schema
228 dump
229 sql
230 json [<base64>]
231
232)RRR";
233
234 return Status::ok;
235 }
236 else
237 return Status::not_found;
238
239 return Status::done;
240 }
241}
static Table_Id parse_table(std::istream &in, const Readable &readable)
Status process_command(const std::string &command, std::istream &parameters, std::istream &in, std::ostream &out) override
void write_justified(std::ostream &out, const std::string &s, size_t width, bool flush_left)
Definition type_io.cpp:161
size_t utf8_display_size(const std::string &s)
Definition type_io.cpp:104
int write_json(std::ostream &out, const Readable &db, bool base64)
Definition json.cpp:16
void dump(const Readable &db, Writable &writable, bool schema_only)
Definition dump.cpp:12
void write_value(std::ostream &out, const Readable &readable, Table_Id table_id, Record_Id record_id, Field_Id field_id)
Definition Blob.h:7