1#include "duckdb/common/progress_bar/progress_bar.hpp"
2#include "duckdb/main/client_context.hpp"
3#include "duckdb/common/progress_bar/display/terminal_progress_bar_display.hpp"
4
5namespace duckdb {
6
7void ProgressBar::SystemOverrideCheck(ClientConfig &config) {
8 if (config.system_progress_bar_disable_reason != nullptr) {
9 throw InvalidInputException("Could not change the progress bar setting because: '%s'",
10 config.system_progress_bar_disable_reason);
11 }
12}
13
14unique_ptr<ProgressBarDisplay> ProgressBar::DefaultProgressBarDisplay() {
15 return make_uniq<TerminalProgressBarDisplay>();
16}
17
18ProgressBar::ProgressBar(Executor &executor, idx_t show_progress_after,
19 progress_bar_display_create_func_t create_display_func)
20 : executor(executor), show_progress_after(show_progress_after), current_percentage(-1) {
21 if (create_display_func) {
22 display = create_display_func();
23 }
24}
25
26double ProgressBar::GetCurrentPercentage() {
27 return current_percentage;
28}
29
30void ProgressBar::Start() {
31 profiler.Start();
32 current_percentage = 0;
33 supported = true;
34}
35
36bool ProgressBar::PrintEnabled() const {
37 return display != nullptr;
38}
39
40bool ProgressBar::ShouldPrint(bool final) const {
41 if (!PrintEnabled()) {
42 // Don't print progress at all
43 return false;
44 }
45 // FIXME - do we need to check supported before running `profiler.Elapsed()` ?
46 auto sufficient_time_elapsed = profiler.Elapsed() > show_progress_after / 1000.0;
47 if (!sufficient_time_elapsed) {
48 // Don't print yet
49 return false;
50 }
51 if (final) {
52 // Print the last completed bar
53 return true;
54 }
55 if (!supported) {
56 return false;
57 }
58 return current_percentage > -1;
59}
60
61void ProgressBar::Update(bool final) {
62 if (!final && !supported) {
63 return;
64 }
65 double new_percentage;
66 supported = executor.GetPipelinesProgress(current_progress&: new_percentage);
67 if (!final && !supported) {
68 return;
69 }
70 if (new_percentage > current_percentage) {
71 current_percentage = new_percentage;
72 }
73 if (ShouldPrint(final)) {
74#ifndef DUCKDB_DISABLE_PRINT
75 if (final) {
76 FinishProgressBarPrint();
77 } else {
78 PrintProgress(percentage: current_percentage);
79 }
80#endif
81 }
82}
83
84void ProgressBar::PrintProgress(int current_percentage) {
85 D_ASSERT(display);
86 display->Update(percentage: current_percentage);
87}
88
89void ProgressBar::FinishProgressBarPrint() {
90 if (finished) {
91 return;
92 }
93 D_ASSERT(display);
94 display->Finish();
95 finished = true;
96}
97
98} // namespace duckdb
99