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
9namespace DB
10{
11
12namespace ErrorCodes
13{
14
15extern const int ILLEGAL_COLUMN;
16
17}
18
19void PrettyCompactBlockOutputFormat::writeHeader(
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
59void 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
78void PrettyCompactBlockOutputFormat::writeRow(
79 size_t row_num,
80 const Block & header,
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
102void 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 & header = 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
132void 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