mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-23 01:16:34 +03:00
Make some methods raise an exception in asynchronous mode
The methods changed are connection.commit(), rollback(), reset(), set_isolation_level(), set_client_encoding(), lobject(), cursor(str) as well as cursor.execute() and cursor.callproc() if another query is in progress and cursor.executemany(), cursor.copy_{from,to,expert)().
This commit is contained in:
parent
01799e9137
commit
727670c269
|
@ -137,6 +137,11 @@ HIDDEN PyObject *conn_poll_fetch(connectionObject *self);
|
|||
PyErr_SetString(InterfaceError, "connection already closed"); \
|
||||
return NULL; }
|
||||
|
||||
#define EXC_IF_CONN_ASYNC(self, cmd) if ((self)->async == 1) { \
|
||||
PyErr_SetString(ProgrammingError, #cmd " cannot be used " \
|
||||
"in asynchronous mode"); \
|
||||
return NULL; }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -134,6 +134,7 @@ static PyObject *
|
|||
psyco_conn_commit(connectionObject *self, PyObject *args)
|
||||
{
|
||||
EXC_IF_CONN_CLOSED(self);
|
||||
EXC_IF_CONN_ASYNC(self, commit);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "")) return NULL;
|
||||
|
||||
|
@ -154,6 +155,7 @@ static PyObject *
|
|||
psyco_conn_rollback(connectionObject *self, PyObject *args)
|
||||
{
|
||||
EXC_IF_CONN_CLOSED(self);
|
||||
EXC_IF_CONN_ASYNC(self, rollback);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "")) return NULL;
|
||||
|
||||
|
@ -178,6 +180,7 @@ psyco_conn_set_isolation_level(connectionObject *self, PyObject *args)
|
|||
int level = 1;
|
||||
|
||||
EXC_IF_CONN_CLOSED(self);
|
||||
EXC_IF_CONN_ASYNC(self, set_isolation_level);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i", &level)) return NULL;
|
||||
|
||||
|
@ -211,6 +214,7 @@ psyco_conn_set_client_encoding(connectionObject *self, PyObject *args)
|
|||
size_t i, j;
|
||||
|
||||
EXC_IF_CONN_CLOSED(self);
|
||||
EXC_IF_CONN_ASYNC(self, set_client_encoding);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s", &enc)) return NULL;
|
||||
|
||||
|
@ -309,6 +313,7 @@ psyco_conn_lobject(connectionObject *self, PyObject *args, PyObject *keywds)
|
|||
}
|
||||
|
||||
EXC_IF_CONN_CLOSED(self);
|
||||
EXC_IF_CONN_ASYNC(self, lobject);
|
||||
|
||||
Dprintf("psyco_conn_lobject: new lobject for connection at %p", self);
|
||||
Dprintf("psyco_conn_lobject: parameters: oid = %d, mode = %s",
|
||||
|
@ -381,6 +386,7 @@ psyco_conn_reset(connectionObject *self)
|
|||
int res;
|
||||
|
||||
EXC_IF_CONN_CLOSED(self);
|
||||
EXC_IF_CONN_ASYNC(self, reset);
|
||||
|
||||
if (pq_reset(self) < 0)
|
||||
return NULL;
|
||||
|
|
|
@ -106,6 +106,17 @@ if ((self)->mark != (self)->conn->mark) { \
|
|||
PyErr_SetString(ProgrammingError, "named cursor isn't valid anymore"); \
|
||||
return NULL; }
|
||||
|
||||
#define EXC_IF_CURS_ASYNC(self, cmd) if ((self)->conn->async == 1) { \
|
||||
PyErr_SetString(ProgrammingError, #cmd " cannot be used " \
|
||||
"in asynchronous mode"); \
|
||||
return NULL; }
|
||||
|
||||
#define EXC_IF_ASYNC_IN_PROGRESS(self, cmd) \
|
||||
if ((self)->conn->async_cursor != NULL) { \
|
||||
PyErr_SetString(ProgrammingError, #cmd " cannot be used " \
|
||||
"while an asynchronous query is underway"); \
|
||||
return NULL; }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -57,6 +57,7 @@ psyco_curs_close(cursorObject *self, PyObject *args)
|
|||
if (!PyArg_ParseTuple(args, "")) return NULL;
|
||||
|
||||
EXC_IF_CURS_CLOSED(self);
|
||||
EXC_IF_ASYNC_IN_PROGRESS(self, close);
|
||||
|
||||
if (self->name != NULL) {
|
||||
char buffer[128];
|
||||
|
@ -67,7 +68,6 @@ psyco_curs_close(cursorObject *self, PyObject *args)
|
|||
}
|
||||
|
||||
self->closed = 1;
|
||||
pq_clear_async(self->conn);
|
||||
Dprintf("psyco_curs_close: cursor at %p closed", self);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
|
@ -471,6 +471,7 @@ psyco_curs_execute(cursorObject *self, PyObject *args, PyObject *kwargs)
|
|||
}
|
||||
|
||||
EXC_IF_CURS_CLOSED(self);
|
||||
EXC_IF_ASYNC_IN_PROGRESS(self, execute);
|
||||
|
||||
if (_psyco_curs_execute(self, operation, vars, self->conn->async)) {
|
||||
Py_INCREF(Py_None);
|
||||
|
@ -502,6 +503,7 @@ psyco_curs_executemany(cursorObject *self, PyObject *args, PyObject *kwargs)
|
|||
}
|
||||
|
||||
EXC_IF_CURS_CLOSED(self);
|
||||
EXC_IF_CURS_ASYNC(self, executemany);
|
||||
|
||||
if (self->name != NULL) {
|
||||
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||
|
@ -509,12 +511,6 @@ psyco_curs_executemany(cursorObject *self, PyObject *args, PyObject *kwargs)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (self->conn->async == 1) {
|
||||
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||
"can't call .executemany() on async cursors", NULL, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyIter_Check(vars)) {
|
||||
vars = iter = PyObject_GetIter(vars);
|
||||
if (iter == NULL) return NULL;
|
||||
|
@ -528,7 +524,7 @@ psyco_curs_executemany(cursorObject *self, PyObject *args, PyObject *kwargs)
|
|||
}
|
||||
else {
|
||||
if (self->rowcount == -1)
|
||||
rowcount = -1;
|
||||
rowcount = -1;
|
||||
else if (rowcount >= 0)
|
||||
rowcount += self->rowcount;
|
||||
Py_DECREF(v);
|
||||
|
@ -649,20 +645,6 @@ _psyco_curs_prefetch(cursorObject *self)
|
|||
{
|
||||
int i = 0;
|
||||
|
||||
/* check if there is an asynchronous query in progess and block until data
|
||||
is read from it */
|
||||
if (self->conn->async_cursor != NULL) {
|
||||
/* first check if it's the right cursor */
|
||||
if (self->conn->async_cursor != (PyObject*)self) {
|
||||
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||
"asynchronous fetch by wrong cursor", NULL, NULL);
|
||||
return -2;
|
||||
}
|
||||
/* now get the result */
|
||||
Dprintf("_psyco_curs_prefetch: blocking until all data is read");
|
||||
curs_get_last_result(self);
|
||||
}
|
||||
|
||||
if (self->pgres == NULL || self->needsfetch) {
|
||||
self->needsfetch = 0;
|
||||
Dprintf("_psyco_curs_prefetch: trying to fetch data");
|
||||
|
@ -759,7 +741,8 @@ psyco_curs_fetchone(cursorObject *self, PyObject *args)
|
|||
|
||||
if (args && !PyArg_ParseTuple(args, "")) return NULL;
|
||||
|
||||
EXC_IF_CURS_CLOSED(self)
|
||||
EXC_IF_CURS_CLOSED(self);
|
||||
EXC_IF_ASYNC_IN_PROGRESS(self, fetchone);
|
||||
if (_psyco_curs_prefetch(self) < 0) return NULL;
|
||||
EXC_IF_NO_TUPLES(self);
|
||||
|
||||
|
@ -820,6 +803,7 @@ psyco_curs_fetchmany(cursorObject *self, PyObject *args, PyObject *kwords)
|
|||
}
|
||||
|
||||
EXC_IF_CURS_CLOSED(self);
|
||||
EXC_IF_ASYNC_IN_PROGRESS(self, fetchmany);
|
||||
if (_psyco_curs_prefetch(self) < 0) return NULL;
|
||||
EXC_IF_NO_TUPLES(self);
|
||||
|
||||
|
@ -892,6 +876,7 @@ psyco_curs_fetchall(cursorObject *self, PyObject *args)
|
|||
}
|
||||
|
||||
EXC_IF_CURS_CLOSED(self);
|
||||
EXC_IF_ASYNC_IN_PROGRESS(self, fetchall);
|
||||
if (_psyco_curs_prefetch(self) < 0) return NULL;
|
||||
EXC_IF_NO_TUPLES(self);
|
||||
|
||||
|
@ -959,6 +944,7 @@ psyco_curs_callproc(cursorObject *self, PyObject *args, PyObject *kwargs)
|
|||
{ return NULL; }
|
||||
|
||||
EXC_IF_CURS_CLOSED(self);
|
||||
EXC_IF_ASYNC_IN_PROGRESS(self, callproc);
|
||||
|
||||
if (self->name != NULL) {
|
||||
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||
|
@ -1223,6 +1209,7 @@ psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs)
|
|||
return NULL;
|
||||
|
||||
EXC_IF_CURS_CLOSED(self);
|
||||
EXC_IF_CURS_ASYNC(self, copy_from);
|
||||
|
||||
quoted_delimiter = psycopg_escape_string((PyObject*)self->conn, sep, 0, NULL, NULL);
|
||||
if (quoted_delimiter == NULL) {
|
||||
|
@ -1327,6 +1314,7 @@ psyco_curs_copy_to(cursorObject *self, PyObject *args, PyObject *kwargs)
|
|||
return NULL;
|
||||
|
||||
EXC_IF_CURS_CLOSED(self);
|
||||
EXC_IF_CURS_ASYNC(self, copy_to);
|
||||
quoted_delimiter = psycopg_escape_string((PyObject*)self->conn, sep, 0, NULL, NULL);
|
||||
if (quoted_delimiter == NULL) {
|
||||
PyErr_NoMemory();
|
||||
|
@ -1410,6 +1398,7 @@ psyco_curs_copy_expert(cursorObject *self, PyObject *args, PyObject *kwargs)
|
|||
{ return NULL; }
|
||||
|
||||
EXC_IF_CURS_CLOSED(self);
|
||||
EXC_IF_CURS_ASYNC(self, copy_expert);
|
||||
|
||||
sql = _psyco_curs_validate_sql_basic(self, sql);
|
||||
|
||||
|
|
|
@ -398,7 +398,6 @@ pq_begin_locked(connectionObject *conn, PGresult **pgres, char **error)
|
|||
return 0;
|
||||
}
|
||||
|
||||
pq_clear_async(conn);
|
||||
result = pq_execute_command_locked(conn, query[conn->isolation_level],
|
||||
pgres, error);
|
||||
if (result == 0)
|
||||
|
@ -432,7 +431,6 @@ pq_commit(connectionObject *conn)
|
|||
pthread_mutex_lock(&conn->lock);
|
||||
conn->mark += 1;
|
||||
|
||||
pq_clear_async(conn);
|
||||
retvalue = pq_execute_command_locked(conn, "COMMIT", &pgres, &error);
|
||||
|
||||
pthread_mutex_unlock(&conn->lock);
|
||||
|
@ -464,7 +462,6 @@ pq_abort_locked(connectionObject *conn, PGresult **pgres, char **error)
|
|||
}
|
||||
|
||||
conn->mark += 1;
|
||||
pq_clear_async(conn);
|
||||
retvalue = pq_execute_command_locked(conn, "ROLLBACK", pgres, error);
|
||||
if (retvalue == 0)
|
||||
conn->status = CONN_STATUS_READY;
|
||||
|
@ -526,7 +523,6 @@ pq_reset_locked(connectionObject *conn, PGresult **pgres, char **error)
|
|||
conn->pgconn, conn->isolation_level, conn->status);
|
||||
|
||||
conn->mark += 1;
|
||||
pq_clear_async(conn);
|
||||
|
||||
if (conn->isolation_level > 0 && conn->status == CONN_STATUS_BEGIN) {
|
||||
retvalue = pq_execute_command_locked(conn, "ABORT", pgres, error);
|
||||
|
@ -682,10 +678,6 @@ pq_execute(cursorObject *curs, const char *query, int async)
|
|||
Py_BEGIN_ALLOW_THREADS;
|
||||
pthread_mutex_lock(&(curs->conn->lock));
|
||||
|
||||
/* FIXME: we should first try to cancel the query, otherwise we will block
|
||||
until it completes AND until we get the result back */
|
||||
pq_clear_async(curs->conn);
|
||||
|
||||
if (pq_begin_locked(curs->conn, &pgres, &error) < 0) {
|
||||
pthread_mutex_unlock(&(curs->conn->lock));
|
||||
Py_BLOCK_THREADS;
|
||||
|
|
Loading…
Reference in New Issue
Block a user