aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Processors/Formats/Impl/PrettyBlockOutputFormat.h
blob: dfb23ac63f92850460820c0ba02a9c94a8b3961e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#pragma once

#include <Core/Block.h>
#include <Processors/Formats/IOutputFormat.h>
#include <Formats/FormatSettings.h>
#include <Formats/FormatFactory.h>


namespace DB
{

class WriteBuffer;
class Context;


/** Prints the result in the form of beautiful tables.
  */
class PrettyBlockOutputFormat : public IOutputFormat
{
public:
    /// no_escapes - do not use ANSI escape sequences - to display in the browser, not in the console.
    PrettyBlockOutputFormat(WriteBuffer & out_, const Block & header_, const FormatSettings & format_settings_, bool mono_block_);

    String getName() const override { return "PrettyBlockOutputFormat"; }

protected:
    void consume(Chunk) override;
    void consumeTotals(Chunk) override;
    void consumeExtremes(Chunk) override;

    size_t total_rows = 0;
    size_t row_number_width = 7; // "10000. "

    const FormatSettings format_settings;
    Serializations serializations;

    using Widths = PODArray<size_t>;
    using WidthsPerColumn = std::vector<Widths>;

    void write(Chunk chunk, PortKind port_kind);
    virtual void writeChunk(const Chunk & chunk, PortKind port_kind);
    void writeMonoChunkIfNeeded();
    void writeSuffix() override;

    void onRowsReadBeforeUpdate() override { total_rows = getRowsReadBefore(); }

    void calculateWidths(
        const Block & header, const Chunk & chunk,
        WidthsPerColumn & widths, Widths & max_padded_widths, Widths & name_widths);

    void writeValueWithPadding(
        const IColumn & column, const ISerialization & serialization, size_t row_num,
        size_t value_width, size_t pad_to_width, bool align_right);

    void resetFormatterImpl() override
    {
        total_rows = 0;
    }

private:
    bool mono_block;
    /// For mono_block == true only
    Chunk mono_chunk;
};

template <class OutputFormat>
void registerPrettyFormatWithNoEscapesAndMonoBlock(FormatFactory & factory, const String & base_name)
{
    auto creator = [&](FormatFactory & fact, const String & name, bool no_escapes, bool mono_block)
    {
        fact.registerOutputFormat(name, [no_escapes, mono_block](
            WriteBuffer & buf,
            const Block & sample,
            const FormatSettings & format_settings)
        {
            if (no_escapes)
            {
                FormatSettings changed_settings = format_settings;
                changed_settings.pretty.color = false;
                return std::make_shared<OutputFormat>(buf, sample, changed_settings, mono_block);
            }
            return std::make_shared<OutputFormat>(buf, sample, format_settings, mono_block);
        });
        if (!mono_block)
            factory.markOutputFormatSupportsParallelFormatting(name);
    };
    creator(factory, base_name, false, false);
    creator(factory, base_name + "NoEscapes", true, false);
    creator(factory, base_name + "MonoBlock", false, true);
    creator(factory, base_name + "NoEscapesMonoBlock", true, true);
}

}