mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-22 17:06:33 +03:00
Merge branch 'connection-closed'
NEWS for released 2.5.3 reordered.
This commit is contained in:
commit
03b8b1e97a
17
NEWS
17
NEWS
|
@ -15,18 +15,23 @@ What's new in psycopg 2.5.3
|
||||||
|
|
||||||
- Work around `pip issue #1630 <https://github.com/pypa/pip/issues/1630>`__
|
- Work around `pip issue #1630 <https://github.com/pypa/pip/issues/1630>`__
|
||||||
making installation via ``pip -e git+url`` impossible (:ticket:`#18`).
|
making installation via ``pip -e git+url`` impossible (:ticket:`#18`).
|
||||||
|
- It is now possible to call `get_transaction_status()` on closed connections.
|
||||||
|
- Fixed unsafe access to object names causing assertion failures in
|
||||||
|
Python 3 debug builds (:ticket:`#188`).
|
||||||
|
- Mark the connection closed if found broken on `poll()` (from :ticket:`#192`
|
||||||
|
discussion)
|
||||||
|
- Fixed handling of dsn and closed attributes in connection subclasses
|
||||||
|
failing to connect (from :ticket:`#192` discussion).
|
||||||
- Added arbitrary but stable order to `Range` objects, thanks to
|
- Added arbitrary but stable order to `Range` objects, thanks to
|
||||||
Chris Withers (:ticket:`#193`).
|
Chris Withers (:ticket:`#193`).
|
||||||
- Avoid blocking async connections on connect (:ticket:`#194`). Thanks to
|
- Avoid blocking async connections on connect (:ticket:`#194`). Thanks to
|
||||||
Adam Petrovich for the bug report and diagnosis.
|
Adam Petrovich for the bug report and diagnosis.
|
||||||
- Fixed unsafe access to object names causing assertion failures in
|
|
||||||
Python 3 debug builds (:ticket:`#188`).
|
|
||||||
- Fixed handling of dsn and closed attributes in connection subclasses
|
|
||||||
failing to connect (from :ticket:`#192` discussion).
|
|
||||||
- Fixed overflow opening a lobject with an oid not fitting in a signed int
|
|
||||||
(:ticket:`#203`).
|
|
||||||
- Don't segfault using poorly defined cursor subclasses which forgot to call
|
- Don't segfault using poorly defined cursor subclasses which forgot to call
|
||||||
the superclass init (:ticket:`#195`).
|
the superclass init (:ticket:`#195`).
|
||||||
|
- Mark the connection closed when a Socket connection is broken, as it
|
||||||
|
happens for TCP connections instead (:ticket:`#196`).
|
||||||
|
- Fixed overflow opening a lobject with an oid not fitting in a signed int
|
||||||
|
(:ticket:`#203`).
|
||||||
- Fixed possible segfault in named cursors creation.
|
- Fixed possible segfault in named cursors creation.
|
||||||
- Fixed debug build on Windows, thanks to James Emerton.
|
- Fixed debug build on Windows, thanks to James Emerton.
|
||||||
|
|
||||||
|
|
|
@ -295,8 +295,8 @@ The ``connection`` class
|
||||||
|
|
||||||
.. attribute:: closed
|
.. attribute:: closed
|
||||||
|
|
||||||
Read-only attribute reporting whether the database connection is open
|
Read-only integer attribute: 0 if the connection is open, nonzero if
|
||||||
(0) or closed (1).
|
it is closed or broken.
|
||||||
|
|
||||||
|
|
||||||
.. method:: cancel
|
.. method:: cancel
|
||||||
|
|
|
@ -700,8 +700,6 @@ psyco_conn_set_client_encoding(connectionObject *self, PyObject *args)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_get_transaction_status(connectionObject *self)
|
psyco_conn_get_transaction_status(connectionObject *self)
|
||||||
{
|
{
|
||||||
EXC_IF_CONN_CLOSED(self);
|
|
||||||
|
|
||||||
return PyInt_FromLong((long)PQtransactionStatus(self->pgconn));
|
return PyInt_FromLong((long)PQtransactionStatus(self->pgconn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -253,7 +253,7 @@ lobject_close_locked(lobjectObject *self, char **error)
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PyErr_SetString(OperationalError, "the connection is broken");
|
*error = strdup("the connection is broken");
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -355,7 +355,7 @@ lobject_dealloc(PyObject* obj)
|
||||||
{
|
{
|
||||||
lobjectObject *self = (lobjectObject *)obj;
|
lobjectObject *self = (lobjectObject *)obj;
|
||||||
|
|
||||||
if (self->conn) { /* if not, init failed */
|
if (self->conn && self->fd != -1) {
|
||||||
if (lobject_close(self) < 0)
|
if (lobject_close(self) < 0)
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
Py_XDECREF((PyObject*)self->conn);
|
Py_XDECREF((PyObject*)self->conn);
|
||||||
|
|
|
@ -417,10 +417,20 @@ pq_complete_error(connectionObject *conn, PGresult **pgres, char **error)
|
||||||
pq_raise(conn, NULL, pgres);
|
pq_raise(conn, NULL, pgres);
|
||||||
/* now *pgres is null */
|
/* now *pgres is null */
|
||||||
}
|
}
|
||||||
else if (*error != NULL) {
|
else {
|
||||||
PyErr_SetString(OperationalError, *error);
|
if (*error != NULL) {
|
||||||
} else {
|
PyErr_SetString(OperationalError, *error);
|
||||||
PyErr_SetString(OperationalError, "unknown error");
|
} else {
|
||||||
|
PyErr_SetString(OperationalError, "unknown error");
|
||||||
|
}
|
||||||
|
/* Trivia: with a broken socket connection PQexec returns NULL, so we
|
||||||
|
* end up here. With a TCP connection we get a pgres with an error
|
||||||
|
* instead, and the connection gets closed in the pq_raise call above
|
||||||
|
* (see ticket #196)
|
||||||
|
*/
|
||||||
|
if (CONNECTION_BAD == PQstatus(conn->pgconn)) {
|
||||||
|
conn->closed = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*error) {
|
if (*error) {
|
||||||
|
@ -797,6 +807,12 @@ pq_is_busy(connectionObject *conn)
|
||||||
Dprintf("pq_is_busy: PQconsumeInput() failed");
|
Dprintf("pq_is_busy: PQconsumeInput() failed");
|
||||||
pthread_mutex_unlock(&(conn->lock));
|
pthread_mutex_unlock(&(conn->lock));
|
||||||
Py_BLOCK_THREADS;
|
Py_BLOCK_THREADS;
|
||||||
|
|
||||||
|
/* if the libpq says pgconn is lost, close the py conn */
|
||||||
|
if (CONNECTION_BAD == PQstatus(conn->pgconn)) {
|
||||||
|
conn->closed = 2;
|
||||||
|
}
|
||||||
|
|
||||||
PyErr_SetString(OperationalError, PQerrorMessage(conn->pgconn));
|
PyErr_SetString(OperationalError, PQerrorMessage(conn->pgconn));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -826,6 +842,12 @@ pq_is_busy_locked(connectionObject *conn)
|
||||||
|
|
||||||
if (PQconsumeInput(conn->pgconn) == 0) {
|
if (PQconsumeInput(conn->pgconn) == 0) {
|
||||||
Dprintf("pq_is_busy_locked: PQconsumeInput() failed");
|
Dprintf("pq_is_busy_locked: PQconsumeInput() failed");
|
||||||
|
|
||||||
|
/* if the libpq says pgconn is lost, close the py conn */
|
||||||
|
if (CONNECTION_BAD == PQstatus(conn->pgconn)) {
|
||||||
|
conn->closed = 2;
|
||||||
|
}
|
||||||
|
|
||||||
PyErr_SetString(OperationalError, PQerrorMessage(conn->pgconn));
|
PyErr_SetString(OperationalError, PQerrorMessage(conn->pgconn));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,6 +130,7 @@ class LargeObjectTests(LargeObjectTestCase):
|
||||||
|
|
||||||
self.assertRaises(psycopg2.OperationalError,
|
self.assertRaises(psycopg2.OperationalError,
|
||||||
self.conn.lobject, 0, "w", lo.oid)
|
self.conn.lobject, 0, "w", lo.oid)
|
||||||
|
self.assert_(not self.conn.closed)
|
||||||
|
|
||||||
def test_import(self):
|
def test_import(self):
|
||||||
self.tmpdir = tempfile.mkdtemp()
|
self.tmpdir = tempfile.mkdtemp()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user