summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmjith Ramanujam <amjith.r@gmail.com>2019-03-18 09:47:12 -0700
committerGitHub <noreply@github.com>2019-03-18 09:47:12 -0700
commitd8df2cc03b8b83061786027c1def3a0edd02f05c (patch)
tree1a8035f4040f4e0fe1a4e83fe9b8b51cc4f57692
parent72f6b6a5611c08ae22ee72d320995a35b6e45998 (diff)
parenta8739c8c1566347d5455f8b703c76ec17aaf5ddf (diff)
Merge pull request #1017 from dbcli/j-bennet/bugfix-should-exit-even-with-connection-closed
Fix for https://github.com/dbcli/pgcli/issues/1014.
-rw-r--r--changelog.rst1
-rw-r--r--pgcli/pgexecute.py8
-rw-r--r--tests/test_pgexecute.py35
3 files changed, 39 insertions, 5 deletions
diff --git a/changelog.rst b/changelog.rst
index 069d782e..7db254c5 100644
--- a/changelog.rst
+++ b/changelog.rst
@@ -13,6 +13,7 @@ Bug fixes:
* All pexpect submodules have been moved into the pexpect package as of version 3.0. Use pexpect.TIMEOUT (Thanks: `Marcin Cieślak`_)
* Resizing pgcli terminal kills the connection to postgres in python 2.7 (Thanks: `Amjith Ramanujam`_)
* Fix crash retrieving server version with ``--single-connection``. (Thanks: `Irina Truong`_)
+* Cannot quit application without reconnecting to database (#1014). (Thanks: `Irina Truong`_)
Internal:
---------
diff --git a/pgcli/pgexecute.py b/pgcli/pgexecute.py
index 4deaf279..8c3bfa82 100644
--- a/pgcli/pgexecute.py
+++ b/pgcli/pgexecute.py
@@ -354,7 +354,13 @@ class PGExecute(object):
if pgspecial:
# First try to run each query as special
_logger.debug('Trying a pgspecial command. sql: %r', sql)
- cur = self.conn.cursor()
+ try:
+ cur = self.conn.cursor()
+ except psycopg2.InterfaceError:
+ # edge case when connection is already closed, but we
+ # don't need cursor for special_cmd.arg_type == NO_QUERY.
+ # See https://github.com/dbcli/pgcli/issues/1014.
+ cur = None
try:
for result in pgspecial.execute(cur, sql):
# e.g. execute_from_file already appends these
diff --git a/tests/test_pgexecute.py b/tests/test_pgexecute.py
index 39788950..f49cb6bc 100644
--- a/tests/test_pgexecute.py
+++ b/tests/test_pgexecute.py
@@ -1,13 +1,16 @@
# coding=UTF-8
from __future__ import print_function
-import pytest
-import psycopg2
-from mock import patch
-from pgcli.packages.parseutils.meta import FunctionMetadata
from textwrap import dedent
+
+import psycopg2
+import pytest
+from mock import patch, MagicMock
+from pgspecial.main import PGSpecial, NO_QUERY
from utils import run, dbtest, requires_json, requires_jsonb
+
from pgcli.main import PGCli
+from pgcli.packages.parseutils.meta import FunctionMetadata
def function_meta_data(
@@ -425,3 +428,27 @@ def test_short_host(executor):
assert executor.short_host == 'localhost'
with patch.object(executor, 'host', 'localhost1.example.org,localhost2.example.org'):
assert executor.short_host == 'localhost1'
+
+
+class BrokenConnection(object):
+ """Mock a connection that failed."""
+
+ def cursor(self):
+ raise psycopg2.InterfaceError("I'm broken!")
+
+
+@dbtest
+def test_exit_without_active_connection(executor):
+ quit_handler = MagicMock()
+ pgspecial = PGSpecial()
+ pgspecial.register(quit_handler, '\\q', '\\q', 'Quit pgcli.',
+ arg_type=NO_QUERY, case_sensitive=True, aliases=(':q',))
+
+ with patch.object(executor, "conn", BrokenConnection()):
+ # we should be able to quit the app, even without active connection
+ run(executor, "\\q", pgspecial=pgspecial)
+ quit_handler.assert_called_once()
+
+ # an exception should be raised when running a query without active connection
+ with pytest.raises(psycopg2.InterfaceError):
+ run(executor, "select 1", pgspecial=pgspecial)