1 | #include <Common/PODArray.h> |
2 | #include <IO/WriteBuffer.h> |
3 | #include <IO/WriteHelpers.h> |
4 | ///#include <DataStreams/SquashingBlockOutputStream.h> |
5 | #include <Formats/FormatFactory.h> |
6 | #include <Processors/Formats/Impl/PrettyCompactBlockOutputFormat.h> |
7 | |
8 | |
9 | namespace DB |
10 | { |
11 | |
12 | namespace ErrorCodes |
13 | { |
14 | |
15 | extern const int ILLEGAL_COLUMN; |
16 | |
17 | } |
18 | |
19 | void PrettyCompactBlockOutputFormat::( |
20 | const Block & block, |
21 | const Widths & max_widths, |
22 | const Widths & name_widths) |
23 | { |
24 | /// Names |
25 | writeCString("┌─" , out); |
26 | for (size_t i = 0; i < max_widths.size(); ++i) |
27 | { |
28 | if (i != 0) |
29 | writeCString("─┬─" , out); |
30 | |
31 | const ColumnWithTypeAndName & col = block.getByPosition(i); |
32 | |
33 | if (col.type->shouldAlignRightInPrettyFormats()) |
34 | { |
35 | for (size_t k = 0; k < max_widths[i] - name_widths[i]; ++k) |
36 | writeCString("─" , out); |
37 | |
38 | if (format_settings.pretty.color) |
39 | writeCString("\033[1m" , out); |
40 | writeString(col.name, out); |
41 | if (format_settings.pretty.color) |
42 | writeCString("\033[0m" , out); |
43 | } |
44 | else |
45 | { |
46 | if (format_settings.pretty.color) |
47 | writeCString("\033[1m" , out); |
48 | writeString(col.name, out); |
49 | if (format_settings.pretty.color) |
50 | writeCString("\033[0m" , out); |
51 | |
52 | for (size_t k = 0; k < max_widths[i] - name_widths[i]; ++k) |
53 | writeCString("─" , out); |
54 | } |
55 | } |
56 | writeCString("─┐\n" , out); |
57 | } |
58 | |
59 | void PrettyCompactBlockOutputFormat::writeBottom(const Widths & max_widths) |
60 | { |
61 | /// Create delimiters |
62 | std::stringstream bottom_separator; |
63 | |
64 | bottom_separator << "└" ; |
65 | for (size_t i = 0; i < max_widths.size(); ++i) |
66 | { |
67 | if (i != 0) |
68 | bottom_separator << "┴" ; |
69 | |
70 | for (size_t j = 0; j < max_widths[i] + 2; ++j) |
71 | bottom_separator << "─" ; |
72 | } |
73 | bottom_separator << "┘\n" ; |
74 | |
75 | writeString(bottom_separator.str(), out); |
76 | } |
77 | |
78 | void PrettyCompactBlockOutputFormat::writeRow( |
79 | size_t row_num, |
80 | const Block & , |
81 | const Columns & columns, |
82 | const WidthsPerColumn & widths, |
83 | const Widths & max_widths) |
84 | { |
85 | size_t num_columns = max_widths.size(); |
86 | |
87 | writeCString("│ " , out); |
88 | |
89 | for (size_t j = 0; j < num_columns; ++j) |
90 | { |
91 | if (j != 0) |
92 | writeCString(" │ " , out); |
93 | |
94 | auto & type = *header.getByPosition(j).type; |
95 | auto & cur_widths = widths[j].empty() ? max_widths[j] : widths[j][row_num]; |
96 | writeValueWithPadding(*columns[j], type, row_num, cur_widths, max_widths[j]); |
97 | } |
98 | |
99 | writeCString(" │\n" , out); |
100 | } |
101 | |
102 | void PrettyCompactBlockOutputFormat::write(const Chunk & chunk, PortKind port_kind) |
103 | { |
104 | UInt64 max_rows = format_settings.pretty.max_rows; |
105 | |
106 | if (total_rows >= max_rows) |
107 | { |
108 | total_rows += chunk.getNumRows(); |
109 | return; |
110 | } |
111 | |
112 | size_t num_rows = chunk.getNumRows(); |
113 | auto & = getPort(port_kind).getHeader(); |
114 | auto & columns = chunk.getColumns(); |
115 | |
116 | WidthsPerColumn widths; |
117 | Widths max_widths; |
118 | Widths name_widths; |
119 | calculateWidths(header, chunk, widths, max_widths, name_widths); |
120 | |
121 | writeHeader(header, max_widths, name_widths); |
122 | |
123 | for (size_t i = 0; i < num_rows && total_rows + i < max_rows; ++i) |
124 | writeRow(i, header, columns, widths, max_widths); |
125 | |
126 | writeBottom(max_widths); |
127 | |
128 | total_rows += num_rows; |
129 | } |
130 | |
131 | |
132 | void registerOutputFormatProcessorPrettyCompact(FormatFactory & factory) |
133 | { |
134 | factory.registerOutputFormatProcessor("PrettyCompact" , []( |
135 | WriteBuffer & buf, |
136 | const Block & sample, |
137 | FormatFactory::WriteCallback, |
138 | const FormatSettings & format_settings) |
139 | { |
140 | return std::make_shared<PrettyCompactBlockOutputFormat>(buf, sample, format_settings); |
141 | }); |
142 | |
143 | factory.registerOutputFormatProcessor("PrettyCompactNoEscapes" , []( |
144 | WriteBuffer & buf, |
145 | const Block & sample, |
146 | FormatFactory::WriteCallback, |
147 | const FormatSettings & format_settings) |
148 | { |
149 | FormatSettings changed_settings = format_settings; |
150 | changed_settings.pretty.color = false; |
151 | return std::make_shared<PrettyCompactBlockOutputFormat>(buf, sample, changed_settings); |
152 | }); |
153 | |
154 | /// TODO |
155 | // factory.registerOutputFormat("PrettyCompactMonoBlock", []( |
156 | // WriteBuffer & buf, |
157 | // const Block & sample, |
158 | // const FormatSettings & format_settings) |
159 | // { |
160 | // BlockOutputStreamPtr impl = std::make_shared<PrettyCompactBlockOutputFormat>(buf, sample, format_settings); |
161 | // auto res = std::make_shared<SquashingBlockOutputStream>(impl, impl->getHeader(), format_settings.pretty.max_rows, 0); |
162 | // res->disableFlush(); |
163 | // return res; |
164 | // }); |
165 | } |
166 | |
167 | } |
168 | |