diff --git a/dbms/programs/client/Client.cpp b/dbms/programs/client/Client.cpp index 24336822f88988dd6d65df8bfb9ee5776fd62675..1568f1cc5449fb6d454b7774cdda817122a3943b 100644 --- a/dbms/programs/client/Client.cpp +++ b/dbms/programs/client/Client.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -1314,6 +1315,9 @@ private: /// Received data block is immediately displayed to the user. block_out_stream->flush(); + + /// Restore progress bar after data block. + writeProgress(); } @@ -1353,8 +1357,8 @@ private: void clearProgress() { - std::cerr << RESTORE_CURSOR_POSITION CLEAR_TO_END_OF_LINE; written_progress_chars = 0; + std::cerr << RESTORE_CURSOR_POSITION CLEAR_TO_END_OF_LINE; } @@ -1363,6 +1367,9 @@ private: if (!need_render_progress) return; + /// Output all progress bar commands to stderr at once to avoid flicker. + WriteBufferFromFileDescriptor message(STDERR_FILENO, 1024); + static size_t increment = 0; static const char * indicators[8] = { @@ -1377,13 +1384,15 @@ private: }; if (written_progress_chars) - clearProgress(); + message << RESTORE_CURSOR_POSITION CLEAR_TO_END_OF_LINE; else - std::cerr << SAVE_CURSOR_POSITION; + message << SAVE_CURSOR_POSITION; + + message << DISABLE_LINE_WRAPPING; + + size_t prefix_size = message.count(); - std::stringstream message; message << indicators[increment % 8] - << std::fixed << std::setprecision(3) << " Progress: "; message @@ -1398,8 +1407,7 @@ private: else message << ". "; - written_progress_chars = message.str().size() - (increment % 8 == 7 ? 10 : 13); - std::cerr << DISABLE_LINE_WRAPPING << message.rdbuf(); + written_progress_chars = message.count() - prefix_size - (increment % 8 == 7 ? 10 : 13); /// Don't count invisible output (escape sequences). /// If the approximate number of rows to process is known, we can display a progress bar and percentage. if (progress.total_rows > 0) @@ -1421,19 +1429,21 @@ private: if (width_of_progress_bar > 0) { std::string bar = UnicodeBar::render(UnicodeBar::getWidth(progress.rows, 0, total_rows_corrected, width_of_progress_bar)); - std::cerr << "\033[0;32m" << bar << "\033[0m"; + message << "\033[0;32m" << bar << "\033[0m"; if (width_of_progress_bar > static_cast(bar.size() / UNICODE_BAR_CHAR_SIZE)) - std::cerr << std::string(width_of_progress_bar - bar.size() / UNICODE_BAR_CHAR_SIZE, ' '); + message << std::string(width_of_progress_bar - bar.size() / UNICODE_BAR_CHAR_SIZE, ' '); } } } /// Underestimate percentage a bit to avoid displaying 100%. - std::cerr << ' ' << (99 * progress.rows / total_rows_corrected) << '%'; + message << ' ' << (99 * progress.rows / total_rows_corrected) << '%'; } - std::cerr << ENABLE_LINE_WRAPPING; + message << ENABLE_LINE_WRAPPING; ++increment; + + message.next(); }