|
35 | 35 | import clickdc |
36 | 36 | from configobj import ConfigObj |
37 | 37 | import keyring |
| 38 | +import prompt_toolkit |
38 | 39 | from prompt_toolkit import print_formatted_text |
39 | 40 | from prompt_toolkit.application.current import get_app |
40 | 41 | from prompt_toolkit.auto_suggest import AutoSuggestFromHistory, ThreadedAutoSuggest |
|
55 | 56 | from prompt_toolkit.layout.processors import ConditionalProcessor, HighlightMatchingBracketProcessor |
56 | 57 | from prompt_toolkit.lexers import PygmentsLexer |
57 | 58 | from prompt_toolkit.output import ColorDepth |
58 | | -from prompt_toolkit.shortcuts import CompleteStyle, PromptSession |
| 59 | +from prompt_toolkit.shortcuts import CompleteStyle, ProgressBar, PromptSession |
| 60 | +from prompt_toolkit.shortcuts.progress_bar import formatters as progress_bar_formatters |
59 | 61 | import pymysql |
60 | 62 | from pymysql.constants.CR import CR_SERVER_LOST |
61 | 63 | from pymysql.constants.ER import ACCESS_DENIED_ERROR, HANDSHAKE_ERROR |
@@ -2165,6 +2167,10 @@ class CliArgs: |
2165 | 2167 | default=0.0, |
2166 | 2168 | help='Pause in seconds between queries in batch mode.', |
2167 | 2169 | ) |
| 2170 | + progress: bool = clickdc.option( |
| 2171 | + is_flag=True, |
| 2172 | + help='Show progress with --batch.', |
| 2173 | + ) |
2168 | 2174 | use_keyring: str | None = clickdc.option( |
2169 | 2175 | type=click.Choice(['true', 'false', 'reset']), |
2170 | 2176 | default=None, |
@@ -2709,17 +2715,70 @@ def dispatch_batch_statements(statements: str, batch_counter: int) -> None: |
2709 | 2715 | click.secho(str(e), err=True, fg="red") |
2710 | 2716 | sys.exit(1) |
2711 | 2717 |
|
2712 | | - if cli_args.batch or not sys.stdin.isatty(): |
2713 | | - if cli_args.batch: |
2714 | | - if not sys.stdin.isatty() and cli_args.batch != '-': |
2715 | | - click.secho('Ignoring STDIN since --batch was also given.', err=True, fg='red') |
2716 | | - try: |
2717 | | - batch_h = click.open_file(cli_args.batch) |
2718 | | - except (OSError, FileNotFoundError): |
2719 | | - click.secho(f'Failed to open --batch file: {cli_args.batch}', err=True, fg='red') |
2720 | | - sys.exit(1) |
2721 | | - else: |
2722 | | - batch_h = click.get_text_stream('stdin') |
| 2718 | + if cli_args.batch and cli_args.batch != '-' and cli_args.progress and sys.stderr.isatty(): |
| 2719 | + # The actual number of SQL statements can be greater, if there is more than |
| 2720 | + # one statement per line, but this is how the progress bar will count. |
| 2721 | + goal_statements = 0 |
| 2722 | + if not sys.stdin.isatty() and cli_args.batch != '-': |
| 2723 | + click.secho('Ignoring STDIN since --batch was also given.', err=True, fg='yellow') |
| 2724 | + if os.path.exists(cli_args.batch) and not os.path.isfile(cli_args.batch): |
| 2725 | + click.secho('--progress is only compatible with a plain file.', err=True, fg='red') |
| 2726 | + sys.exit(1) |
| 2727 | + try: |
| 2728 | + batch_count_h = click.open_file(cli_args.batch) |
| 2729 | + for _statement, _counter in statements_from_filehandle(batch_count_h): |
| 2730 | + goal_statements += 1 |
| 2731 | + batch_count_h.close() |
| 2732 | + batch_h = click.open_file(cli_args.batch) |
| 2733 | + except (OSError, FileNotFoundError): |
| 2734 | + click.secho(f'Failed to open --batch file: {cli_args.batch}', err=True, fg='red') |
| 2735 | + sys.exit(1) |
| 2736 | + except ValueError as e: |
| 2737 | + click.secho(f'Error reading --batch file: {cli_args.batch}: {e}', err=True, fg='red') |
| 2738 | + sys.exit(1) |
| 2739 | + try: |
| 2740 | + if goal_statements: |
| 2741 | + pb_style = prompt_toolkit.styles.Style.from_dict({'bar-a': 'reverse'}) |
| 2742 | + custom_formatters = [ |
| 2743 | + progress_bar_formatters.Bar(start='[', end=']', sym_a=' ', sym_b=' ', sym_c=' '), |
| 2744 | + progress_bar_formatters.Text(' '), |
| 2745 | + progress_bar_formatters.Progress(), |
| 2746 | + progress_bar_formatters.Text(' '), |
| 2747 | + progress_bar_formatters.Text('eta ', style='class:time-left'), |
| 2748 | + progress_bar_formatters.TimeLeft(), |
| 2749 | + progress_bar_formatters.Text(' ', style='class:time-left'), |
| 2750 | + ] |
| 2751 | + err_output = prompt_toolkit.output.create_output(stdout=sys.stderr, always_prefer_tty=True) |
| 2752 | + with ProgressBar(style=pb_style, formatters=custom_formatters, output=err_output) as pb: |
| 2753 | + for pb_counter in pb(range(goal_statements)): |
| 2754 | + statement, _untrusted_counter = next(statements_from_filehandle(batch_h)) |
| 2755 | + dispatch_batch_statements(statement, pb_counter) |
| 2756 | + except (ValueError, StopIteration) as e: |
| 2757 | + click.secho(str(e), err=True, fg='red') |
| 2758 | + sys.exit(1) |
| 2759 | + finally: |
| 2760 | + batch_h.close() |
| 2761 | + sys.exit(0) |
| 2762 | + |
| 2763 | + if cli_args.batch: |
| 2764 | + if not sys.stdin.isatty() and cli_args.batch != '-': |
| 2765 | + click.secho('Ignoring STDIN since --batch was also given.', err=True, fg='red') |
| 2766 | + try: |
| 2767 | + batch_h = click.open_file(cli_args.batch) |
| 2768 | + except (OSError, FileNotFoundError): |
| 2769 | + click.secho(f'Failed to open --batch file: {cli_args.batch}', err=True, fg='red') |
| 2770 | + sys.exit(1) |
| 2771 | + try: |
| 2772 | + for statement, counter in statements_from_filehandle(batch_h): |
| 2773 | + dispatch_batch_statements(statement, counter) |
| 2774 | + batch_h.close() |
| 2775 | + except ValueError as e: |
| 2776 | + click.secho(str(e), err=True, fg='red') |
| 2777 | + sys.exit(1) |
| 2778 | + sys.exit(0) |
| 2779 | + |
| 2780 | + if not sys.stdin.isatty(): |
| 2781 | + batch_h = click.get_text_stream('stdin') |
2723 | 2782 | try: |
2724 | 2783 | for statement, counter in statements_from_filehandle(batch_h): |
2725 | 2784 | dispatch_batch_statements(statement, counter) |
|
0 commit comments