From bffd91f1c09cee6a550635e479718b5d61fd527d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 14 Jan 2022 15:47:51 +0100 Subject: Merging upstream version 3.3.0. Signed-off-by: Daniel Baumann --- pgcli/__init__.py | 2 +- pgcli/main.py | 61 ++++++++++++++++++++++++++++++++++++++++-------------- pgcli/pgclirc | 6 ++++++ pgcli/pgexecute.py | 2 +- 4 files changed, 54 insertions(+), 17 deletions(-) (limited to 'pgcli') diff --git a/pgcli/__init__.py b/pgcli/__init__.py index 1173108..88c513e 100644 --- a/pgcli/__init__.py +++ b/pgcli/__init__.py @@ -1 +1 @@ -__version__ = "3.2.0" +__version__ = "3.3.0" diff --git a/pgcli/main.py b/pgcli/main.py index 5135f6f..5395f67 100644 --- a/pgcli/main.py +++ b/pgcli/main.py @@ -86,6 +86,7 @@ from textwrap import dedent # Ref: https://stackoverflow.com/questions/30425105/filter-special-chars-such-as-color-codes-from-shell-output COLOR_CODE_REGEX = re.compile(r"\x1b(\[.*?[@-~]|\].*?(\x07|\x1b\\))") +DEFAULT_MAX_FIELD_WIDTH = 500 # Query tuples are used for maintaining history MetaQuery = namedtuple( @@ -106,7 +107,7 @@ MetaQuery.__new__.__defaults__ = ("", False, 0, 0, False, False, False, False) OutputSettings = namedtuple( "OutputSettings", - "table_format dcmlfmt floatfmt missingval expanded max_width case_function style_output", + "table_format dcmlfmt floatfmt missingval expanded max_width case_function style_output max_field_width", ) OutputSettings.__new__.__defaults__ = ( None, @@ -117,6 +118,7 @@ OutputSettings.__new__.__defaults__ = ( None, lambda x: x, None, + DEFAULT_MAX_FIELD_WIDTH, ) @@ -201,6 +203,16 @@ class PGCli: else: self.row_limit = c["main"].as_int("row_limit") + # if not specified, set to DEFAULT_MAX_FIELD_WIDTH + # if specified but empty, set to None to disable truncation + # ellipsis will take at least 3 symbols, so this can't be less than 3 if specified and > 0 + max_field_width = c["main"].get("max_field_width", DEFAULT_MAX_FIELD_WIDTH) + if max_field_width and max_field_width.lower() != "none": + max_field_width = max(3, abs(int(max_field_width))) + else: + max_field_width = None + self.max_field_width = max_field_width + self.min_num_menu_lines = c["main"].as_int("min_num_menu_lines") self.multiline_continuation_char = c["main"]["multiline_continuation_char"] self.table_format = c["main"]["table_format"] @@ -760,18 +772,7 @@ class PGCli: click.secho(str(e), err=True, fg="red") continue - # Initialize default metaquery in case execution fails - self.watch_command, timing = special.get_watch_command(text) - if self.watch_command: - while self.watch_command: - try: - query = self.execute_command(self.watch_command) - click.echo(f"Waiting for {timing} seconds before repeating") - sleep(timing) - except KeyboardInterrupt: - self.watch_command = None - else: - query = self.execute_command(text) + self.handle_watch_command(text) self.now = dt.datetime.today() @@ -779,12 +780,40 @@ class PGCli: with self._completer_lock: self.completer.extend_query_history(text) - self.query_history.append(query) - except (PgCliQuitError, EOFError): if not self.less_chatty: print("Goodbye!") + def handle_watch_command(self, text): + # Initialize default metaquery in case execution fails + self.watch_command, timing = special.get_watch_command(text) + + # If we run \watch without a command, apply it to the last query run. + if self.watch_command is not None and not self.watch_command.strip(): + try: + self.watch_command = self.query_history[-1].query + except IndexError: + click.secho( + "\\watch cannot be used with an empty query", err=True, fg="red" + ) + self.watch_command = None + + # If there's a command to \watch, run it in a loop. + if self.watch_command: + while self.watch_command: + try: + query = self.execute_command(self.watch_command) + click.echo(f"Waiting for {timing} seconds before repeating") + sleep(timing) + except KeyboardInterrupt: + self.watch_command = None + + # Otherwise, execute it as a regular command. + else: + query = self.execute_command(text) + + self.query_history.append(query) + def _build_cli(self, history): key_bindings = pgcli_bindings(self) @@ -934,6 +963,7 @@ class PGCli: else lambda x: x ), style_output=self.style_output, + max_field_width=self.max_field_width, ) execution = time() - start formatted = format_output(title, cur, headers, status, settings) @@ -1444,6 +1474,7 @@ def format_output(title, cur, headers, status, settings): "disable_numparse": True, "preserve_whitespace": True, "style": settings.style_output, + "max_field_width": settings.max_field_width, } if not settings.floatfmt: output_kwargs["preprocessors"] = (align_decimals,) diff --git a/pgcli/pgclirc b/pgcli/pgclirc index 15c10f5..6654ce9 100644 --- a/pgcli/pgclirc +++ b/pgcli/pgclirc @@ -119,6 +119,12 @@ on_error = STOP # Set threshold for row limit. Use 0 to disable limiting. row_limit = 1000 +# Truncate long text fields to this value for tabular display (does not apply to csv). +# Leave unset to disable truncation. Example: "max_field_width = " +# Be aware that formatting might get slow with values larger than 500 and tables with +# lots of records. +max_field_width = 500 + # Skip intro on startup and goodbye on exit less_chatty = False diff --git a/pgcli/pgexecute.py b/pgcli/pgexecute.py index a013b55..22e9ea4 100644 --- a/pgcli/pgexecute.py +++ b/pgcli/pgexecute.py @@ -430,7 +430,7 @@ class PGExecute: for sql in sqlparse.split(statement): # Remove spaces, eol and semi-colons. sql = sql.rstrip(";") - sql = sqlparse.format(sql, strip_comments=True).strip() + sql = sqlparse.format(sql, strip_comments=False).strip() if not sql: continue try: -- cgit v1.2.3