mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-15 05:26:37 +03:00
Report NotSupportedError for PGRES_COPY_BOTH and PGRES_SINGLE_TUPLE
Fixes #352.
This commit is contained in:
parent
3e31fb359e
commit
abf1f28c44
2
NEWS
2
NEWS
|
@ -5,6 +5,8 @@ What's new in psycopg 2.6.2
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
- Report the server response status on errors (such as :ticket:`#281`).
|
- Report the server response status on errors (such as :ticket:`#281`).
|
||||||
|
- Raise NotSupportedError on unhandled server response status
|
||||||
|
(:ticket:`#352`).
|
||||||
|
|
||||||
|
|
||||||
What's new in psycopg 2.6.1
|
What's new in psycopg 2.6.1
|
||||||
|
|
|
@ -1597,11 +1597,26 @@ pq_fetch(cursorObject *curs, int no_result)
|
||||||
ex = -1;
|
ex = -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case PGRES_BAD_RESPONSE:
|
||||||
Dprintf("pq_fetch: uh-oh, something FAILED: pgconn = %p", curs->conn);
|
case PGRES_NONFATAL_ERROR:
|
||||||
|
case PGRES_FATAL_ERROR:
|
||||||
|
Dprintf("pq_fetch: uh-oh, something FAILED: status = %d pgconn = %p",
|
||||||
|
status, curs->conn);
|
||||||
pq_raise(curs->conn, curs, NULL);
|
pq_raise(curs->conn, curs, NULL);
|
||||||
ex = -1;
|
ex = -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* PGRES_COPY_BOTH, PGRES_SINGLE_TUPLE, future statuses */
|
||||||
|
Dprintf("pq_fetch: got unsupported result: status = %d pgconn = %p",
|
||||||
|
status, curs->conn);
|
||||||
|
PyErr_Format(NotSupportedError,
|
||||||
|
"got server response with unsupported status %s",
|
||||||
|
PQresStatus(curs->pgres == NULL ?
|
||||||
|
PQstatus(curs->conn->pgconn) : PQresultStatus(curs->pgres)));
|
||||||
|
CLEARPGRES(curs->pgres);
|
||||||
|
ex = -1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* error checking, close the connection if necessary (some critical errors
|
/* error checking, close the connection if necessary (some critical errors
|
||||||
|
|
|
@ -26,6 +26,7 @@ import os
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
|
from StringIO import StringIO
|
||||||
|
|
||||||
import psycopg2
|
import psycopg2
|
||||||
import psycopg2.errorcodes
|
import psycopg2.errorcodes
|
||||||
|
@ -1067,6 +1068,17 @@ class AutocommitTests(ConnectingTestCase):
|
||||||
self.assertEqual(cur.fetchone()[0], 'on')
|
self.assertEqual(cur.fetchone()[0], 'on')
|
||||||
|
|
||||||
|
|
||||||
|
class ReplicationTest(ConnectingTestCase):
|
||||||
|
@skip_before_postgres(9, 0)
|
||||||
|
def test_replication_not_supported(self):
|
||||||
|
conn = self.repl_connect()
|
||||||
|
if conn is None: return
|
||||||
|
cur = conn.cursor()
|
||||||
|
f = StringIO()
|
||||||
|
self.assertRaises(psycopg2.NotSupportedError,
|
||||||
|
cur.copy_expert, "START_REPLICATION 0/0", f)
|
||||||
|
|
||||||
|
|
||||||
def test_suite():
|
def test_suite():
|
||||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@ dbhost = os.environ.get('PSYCOPG2_TESTDB_HOST', None)
|
||||||
dbport = os.environ.get('PSYCOPG2_TESTDB_PORT', None)
|
dbport = os.environ.get('PSYCOPG2_TESTDB_PORT', None)
|
||||||
dbuser = os.environ.get('PSYCOPG2_TESTDB_USER', None)
|
dbuser = os.environ.get('PSYCOPG2_TESTDB_USER', None)
|
||||||
dbpass = os.environ.get('PSYCOPG2_TESTDB_PASSWORD', None)
|
dbpass = os.environ.get('PSYCOPG2_TESTDB_PASSWORD', None)
|
||||||
|
repl_dsn = os.environ.get('PSYCOPG2_TEST_REPL_DSN',
|
||||||
|
"dbname=psycopg2_test replication=1")
|
||||||
|
|
||||||
# Check if we want to test psycopg's green path.
|
# Check if we want to test psycopg's green path.
|
||||||
green = os.environ.get('PSYCOPG2_TEST_GREEN', None)
|
green = os.environ.get('PSYCOPG2_TEST_GREEN', None)
|
||||||
|
|
|
@ -28,7 +28,7 @@ import os
|
||||||
import platform
|
import platform
|
||||||
import sys
|
import sys
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from testconfig import dsn
|
from testconfig import dsn, repl_dsn
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import unittest2
|
import unittest2
|
||||||
|
@ -103,11 +103,35 @@ class ConnectingTestCase(unittest.TestCase):
|
||||||
"%s (did you remember calling ConnectingTestCase.setUp()?)"
|
"%s (did you remember calling ConnectingTestCase.setUp()?)"
|
||||||
% e)
|
% e)
|
||||||
|
|
||||||
|
if 'dsn' in kwargs:
|
||||||
|
conninfo = kwargs.pop('dsn')
|
||||||
|
else:
|
||||||
|
conninfo = dsn
|
||||||
import psycopg2
|
import psycopg2
|
||||||
conn = psycopg2.connect(dsn, **kwargs)
|
conn = psycopg2.connect(conninfo, **kwargs)
|
||||||
self._conns.append(conn)
|
self._conns.append(conn)
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
|
def repl_connect(self, **kwargs):
|
||||||
|
"""Return a connection set up for replication
|
||||||
|
|
||||||
|
The connection is on "PSYCOPG2_TEST_REPL_DSN" unless overridden by
|
||||||
|
a *dsn* kwarg.
|
||||||
|
|
||||||
|
Should raise a skip test if not available, but guard for None on
|
||||||
|
old Python versions.
|
||||||
|
"""
|
||||||
|
if 'dsn' not in kwargs:
|
||||||
|
kwargs['dsn'] = repl_dsn
|
||||||
|
import psycopg2
|
||||||
|
try:
|
||||||
|
conn = self.connect(**kwargs)
|
||||||
|
except psycopg2.OperationalError, e:
|
||||||
|
return self.skipTest("replication db not configured: %s" % e)
|
||||||
|
|
||||||
|
conn.autocommit = True
|
||||||
|
return conn
|
||||||
|
|
||||||
def _get_conn(self):
|
def _get_conn(self):
|
||||||
if not hasattr(self, '_the_conn'):
|
if not hasattr(self, '_the_conn'):
|
||||||
self._the_conn = self.connect()
|
self._the_conn = self.connect()
|
||||||
|
@ -351,4 +375,3 @@ class py3_raises_typeerror(object):
|
||||||
if sys.version_info[0] >= 3:
|
if sys.version_info[0] >= 3:
|
||||||
assert type is TypeError
|
assert type is TypeError
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user