Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ Features:
* You can specify multiple times.
* Runs one statement at a time, like `-f`, and can be combined with `-f`:
both run, the same way psql does.
* Add ``--no-timings`` and ``--no-status`` to suppress the timing line and the
status footer independently. ``-t``/``--tuples-only`` already turns off both,
along with the headers and the title, but there was no way to keep the table
formatting and drop only one of the two, which scripts that post-process the
output often want.
* Add support for forcing destructive commands without confirmation.
* Command line option `-y` or `--yes`.
* Skips the destructive command confirmation prompt when enabled.
Expand Down
34 changes: 31 additions & 3 deletions pgcli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@
OutputSettings = namedtuple(
"OutputSettings",
"table_format dcmlfmt floatfmt column_date_formats missingval expanded max_width case_function style_output "
"max_field_width tuples_only",
"max_field_width tuples_only show_status",
)
OutputSettings.__new__.__defaults__ = (
None,
Expand All @@ -134,6 +134,7 @@
None,
DEFAULT_MAX_FIELD_WIDTH,
False,
True,
)


Expand Down Expand Up @@ -224,6 +225,8 @@ def __init__(
single_connection=False,
less_chatty=None,
tuples_only=None,
no_timings=False,
no_status=False,
prompt=None,
prompt_dsn=None,
auto_vertical_output=False,
Expand Down Expand Up @@ -290,8 +293,14 @@ def __init__(
# alone here and switched to an unadorned one at output time, so \T
# still reports (and can change) the configured format.
self.tuples_only = bool(tuples_only)
if self.tuples_only:
# --no-timings and --no-status turn off one thing each, for scripts that
# want the rows plus one of the two. -t is the psql-compatible shorthand
# that turns off both, along with the headers and the title.
self.show_status = not no_status
if no_timings or self.tuples_only:
self.pgspecial.timing_enabled = False
if self.tuples_only:
self.show_status = False
self.syntax_style = c["main"]["syntax_style"]
self.cli_style = c["colors"]
self.wider_completion_menu = c["main"].as_bool("wider_completion_menu")
Expand Down Expand Up @@ -1370,6 +1379,7 @@ def _evaluate_command(self, text):
style_output=self.style_output,
max_field_width=self.max_field_width,
tuples_only=self.tuples_only,
show_status=self.show_status,
)

# Hide query text for named queries in quiet mode
Expand Down Expand Up @@ -1650,6 +1660,20 @@ def echo_via_pager(self, text, color=None):
default=False,
help="Print rows only: no column headers, no status footer and no timing, like psql.",
)
@click.option(
"--no-timings",
"no_timings",
is_flag=True,
default=False,
help="Do not print the timing line after each query.",
)
@click.option(
"--no-status",
"no_status",
is_flag=True,
default=False,
help="Do not print the status footer (SELECT 3, UPDATE 1, ...) after each query.",
)
@click.option("--prompt", help='Prompt format (Default: "\\u@\\h:\\d> ").')
@click.option(
"--prompt-dsn",
Expand Down Expand Up @@ -1737,6 +1761,8 @@ def cli(
application_name,
less_chatty,
tuples_only,
no_timings: bool,
no_status: bool,
prompt,
prompt_dsn,
list_databases,
Expand Down Expand Up @@ -1809,6 +1835,8 @@ def cli(
single_connection=single_connection,
less_chatty=less_chatty,
tuples_only=tuples_only,
no_timings=no_timings,
no_status=no_status,
prompt=prompt,
prompt_dsn=prompt_dsn,
auto_vertical_output=auto_vertical_output,
Expand Down Expand Up @@ -2229,7 +2257,7 @@ def format_status(cur, status):
output = itertools.chain(output, formatted)

# Likewise the status footer.
if status and not settings.tuples_only:
if status and settings.show_status and not settings.tuples_only:
output = itertools.chain(output, [format_status(cur, status)])

return output
Expand Down
67 changes: 67 additions & 0 deletions tests/test_no_timings_no_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from unittest.mock import patch

from click.testing import CliRunner

from pgcli.main import cli, format_output, OutputSettings, PGCli


def test_no_timings_flag_passed_to_pgcli():
runner = CliRunner()
with patch.object(PGCli, "__init__", autospec=True, return_value=None) as mock_pgcli:
runner.invoke(cli, ["--no-timings", "mydb"])
assert mock_pgcli.call_args[1]["no_timings"] is True


def test_no_status_flag_passed_to_pgcli():
runner = CliRunner()
with patch.object(PGCli, "__init__", autospec=True, return_value=None) as mock_pgcli:
runner.invoke(cli, ["--no-status", "mydb"])
assert mock_pgcli.call_args[1]["no_status"] is True


def test_both_default_to_false():
runner = CliRunner()
with patch.object(PGCli, "__init__", autospec=True, return_value=None) as mock_pgcli:
runner.invoke(cli, ["mydb"])
assert mock_pgcli.call_args[1]["no_timings"] is False
assert mock_pgcli.call_args[1]["no_status"] is False


def test_no_timings_turns_off_timing_only():
"""The point of having two flags: each one leaves the other alone."""
cli_obj = PGCli(no_timings=True)

assert cli_obj.pgspecial.timing_enabled is False
assert cli_obj.show_status is True


def test_no_status_turns_off_status_only():
cli_obj = PGCli(no_status=True)

assert cli_obj.show_status is False
assert cli_obj.pgspecial.timing_enabled is True


def test_tuples_only_still_turns_off_both():
"""-t stays the psql-compatible shorthand for both."""
cli_obj = PGCli(tuples_only=True)

assert cli_obj.show_status is False
assert cli_obj.pgspecial.timing_enabled is False


def test_no_status_suppresses_only_the_footer():
settings = OutputSettings(table_format="psql", show_status=False)
output = "\n".join(format_output("Title", [(1,)], ["a"], "SELECT 1", settings))

assert "SELECT 1" not in output
# Rows, headers and title are untouched.
assert "Title" in output
assert "a" in output and "1" in output


def test_status_footer_is_printed_by_default():
settings = OutputSettings(table_format="psql")
output = "\n".join(format_output("Title", [(1,)], ["a"], "SELECT 1", settings))

assert "SELECT 1" in output
Loading