1#include "duckdb/common/progress_bar/display/terminal_progress_bar_display.hpp"
2#include "duckdb/common/printer.hpp"
3#include "duckdb/common/to_string.hpp"
4
5namespace duckdb {
6
7void TerminalProgressBarDisplay::PrintProgressInternal(int percentage) {
8 if (percentage > 100) {
9 percentage = 100;
10 }
11 if (percentage < 0) {
12 percentage = 0;
13 }
14 string result;
15 // we divide the number of blocks by the percentage
16 // 0% = 0
17 // 100% = PROGRESS_BAR_WIDTH
18 // the percentage determines how many blocks we need to draw
19 double blocks_to_draw = PROGRESS_BAR_WIDTH * (percentage / 100.0);
20 // because of the power of unicode, we can also draw partial blocks
21
22 // render the percentage with some padding to ensure everything stays nicely aligned
23 result = "\r";
24 if (percentage < 100) {
25 result += " ";
26 }
27 if (percentage < 10) {
28 result += " ";
29 }
30 result += to_string(val: percentage) + "%";
31 result += " ";
32 result += PROGRESS_START;
33 idx_t i;
34 for (i = 0; i < idx_t(blocks_to_draw); i++) {
35 result += PROGRESS_BLOCK;
36 }
37 if (i < PROGRESS_BAR_WIDTH) {
38 // print a partial block based on the percentage of the progress bar remaining
39 idx_t index = idx_t((blocks_to_draw - idx_t(blocks_to_draw)) * PARTIAL_BLOCK_COUNT);
40 if (index >= PARTIAL_BLOCK_COUNT) {
41 index = PARTIAL_BLOCK_COUNT - 1;
42 }
43 result += PROGRESS_PARTIAL[index];
44 i++;
45 }
46 for (; i < PROGRESS_BAR_WIDTH; i++) {
47 result += PROGRESS_EMPTY;
48 }
49 result += PROGRESS_END;
50 result += " ";
51
52 Printer::RawPrint(stream: OutputStream::STREAM_STDOUT, str: result);
53}
54
55void TerminalProgressBarDisplay::Update(double percentage) {
56 PrintProgressInternal(percentage);
57 Printer::Flush(stream: OutputStream::STREAM_STDOUT);
58}
59
60void TerminalProgressBarDisplay::Finish() {
61 PrintProgressInternal(percentage: 100);
62 Printer::RawPrint(stream: OutputStream::STREAM_STDOUT, str: "\n");
63 Printer::Flush(stream: OutputStream::STREAM_STDOUT);
64}
65
66} // namespace duckdb
67