Skip to content

Commit cc37fd1

Browse files
wulczerfogzot
authored andcommitted
Add curs_get_last_result, a function to get the last result from a connection
1 parent 75a0299 commit cc37fd1

File tree

3 files changed

+38
-13
lines changed

3 files changed

+38
-13
lines changed

psycopg/cursor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ typedef struct {
8686

8787
/* C-callable functions in cursor_int.c and cursor_ext.c */
8888
HIDDEN void curs_reset(cursorObject *self);
89+
HIDDEN void curs_get_last_result(cursorObject *self);
8990

9091
/* exception-raising macros */
9192
#define EXC_IF_CURS_CLOSED(self) \

psycopg/cursor_int.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,28 @@ curs_reset(cursorObject *self)
5454
self->casts = NULL;
5555
Py_XDECREF(tmp);
5656
}
57+
58+
/*
59+
* curs_get_last_result
60+
*
61+
* read all results from the connection, save the last one
62+
*/
63+
64+
void
65+
curs_get_last_result(cursorObject *self) {
66+
PGresult *pgres;
67+
68+
IFCLEARPGRES(self->pgres);
69+
Py_BEGIN_ALLOW_THREADS;
70+
pthread_mutex_lock(&(self->conn->lock));
71+
/* read all results: there can be multiple if the client sent multiple
72+
statements */
73+
while ((pgres = PQgetResult(self->conn->pgconn)) != NULL) {
74+
IFCLEARPGRES(self->pgres);
75+
self->pgres = pgres;
76+
}
77+
self->conn->async_cursor = NULL;
78+
pthread_mutex_unlock(&(self->conn->lock));
79+
Py_END_ALLOW_THREADS;
80+
self->needsfetch = 1;
81+
}

psycopg/cursor_type.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -656,20 +656,19 @@ _psyco_curs_prefetch(cursorObject *self)
656656
{
657657
int i = 0;
658658

659-
/* check if the fetching cursor is the one that did the asynchronous query
660-
and raise an exception if not */
661-
Py_BEGIN_ALLOW_THREADS;
662-
pthread_mutex_lock(&(self->conn->lock));
663-
if (self->conn->async_cursor != NULL
664-
&& self->conn->async_cursor != (PyObject*)self) {
665-
pthread_mutex_unlock(&(self->conn->lock));
666-
Py_BLOCK_THREADS;
667-
psyco_set_error(ProgrammingError, (PyObject*)self,
668-
"asynchronous fetch by wrong cursor", NULL, NULL);
669-
return -2;
659+
/* check if there is an asynchronous query in progess and block until data
660+
is read from it */
661+
if (self->conn->async_cursor) {
662+
/* first check if it's the right cursor */
663+
if (self->conn->async_cursor != (PyObject*)self) {
664+
psyco_set_error(ProgrammingError, (PyObject*)self,
665+
"asynchronous fetch by wrong cursor", NULL, NULL);
666+
return -2;
667+
}
668+
/* now get the result */
669+
Dprintf("_psyco_curs_prefetch: blocking until all data is read");
670+
curs_get_last_result(self);
670671
}
671-
pthread_mutex_unlock(&(self->conn->lock));
672-
Py_END_ALLOW_THREADS;
673672

674673
if (self->pgres == NULL || self->needsfetch) {
675674
self->needsfetch = 0;

0 commit comments

Comments
 (0)