mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-02-12 07:10:33 +03:00
Added scrollable cursor implementation
Patch provided by Jon Nelson (ticket #108).
This commit is contained in:
parent
91c2ff9296
commit
fa4994e471
|
@ -56,11 +56,14 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *kwargs)
|
||||||
PyObject *name = Py_None;
|
PyObject *name = Py_None;
|
||||||
PyObject *factory = (PyObject *)&cursorType;
|
PyObject *factory = (PyObject *)&cursorType;
|
||||||
PyObject *withhold = Py_False;
|
PyObject *withhold = Py_False;
|
||||||
|
PyObject *scrollable = Py_False;
|
||||||
|
|
||||||
static char *kwlist[] = {"name", "cursor_factory", "withhold", NULL};
|
static char *kwlist[] = {
|
||||||
|
"name", "cursor_factory", "withhold", "scrollable", NULL};
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOO", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(
|
||||||
&name, &factory, &withhold)) {
|
args, kwargs, "|OOOO", kwlist,
|
||||||
|
&name, &factory, &withhold, &scrollable)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +73,12 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *kwargs)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PyObject_IsTrue(scrollable) && (name == Py_None)) {
|
||||||
|
PyErr_SetString(ProgrammingError,
|
||||||
|
"'scrollable=True can be specified only for named cursors");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
EXC_IF_CONN_CLOSED(self);
|
EXC_IF_CONN_CLOSED(self);
|
||||||
|
|
||||||
if (self->status != CONN_STATUS_READY &&
|
if (self->status != CONN_STATUS_READY &&
|
||||||
|
@ -104,6 +113,9 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *kwargs)
|
||||||
if (PyObject_IsTrue(withhold))
|
if (PyObject_IsTrue(withhold))
|
||||||
((cursorObject*)obj)->withhold = 1;
|
((cursorObject*)obj)->withhold = 1;
|
||||||
|
|
||||||
|
if (PyObject_IsTrue(scrollable))
|
||||||
|
((cursorObject*)obj)->scrollable = 1;
|
||||||
|
|
||||||
Dprintf("psyco_conn_cursor: new cursor at %p: refcnt = "
|
Dprintf("psyco_conn_cursor: new cursor at %p: refcnt = "
|
||||||
FORMAT_CODE_PY_SSIZE_T,
|
FORMAT_CODE_PY_SSIZE_T,
|
||||||
obj, Py_REFCNT(obj)
|
obj, Py_REFCNT(obj)
|
||||||
|
|
|
@ -43,6 +43,7 @@ struct cursorObject {
|
||||||
int closed:1; /* 1 if the cursor is closed */
|
int closed:1; /* 1 if the cursor is closed */
|
||||||
int notuples:1; /* 1 if the command was not a SELECT query */
|
int notuples:1; /* 1 if the command was not a SELECT query */
|
||||||
int withhold:1; /* 1 if the cursor is named and uses WITH HOLD */
|
int withhold:1; /* 1 if the cursor is named and uses WITH HOLD */
|
||||||
|
int scrollable:1; /* 1 if the cursor is named as SCROLLABLE */
|
||||||
|
|
||||||
long int rowcount; /* number of rows affected by last execute */
|
long int rowcount; /* number of rows affected by last execute */
|
||||||
long int columns; /* number of columns fetched from the db */
|
long int columns; /* number of columns fetched from the db */
|
||||||
|
|
|
@ -403,8 +403,9 @@ _psyco_curs_execute(cursorObject *self,
|
||||||
|
|
||||||
if (self->name != NULL) {
|
if (self->name != NULL) {
|
||||||
self->query = Bytes_FromFormat(
|
self->query = Bytes_FromFormat(
|
||||||
"DECLARE \"%s\" CURSOR %s HOLD FOR %s",
|
"DECLARE \"%s\" %sSCROLL CURSOR %s HOLD FOR %s",
|
||||||
self->name,
|
self->name,
|
||||||
|
self->scrollable ? "":"NO ",
|
||||||
self->withhold ? "WITH" : "WITHOUT",
|
self->withhold ? "WITH" : "WITHOUT",
|
||||||
Bytes_AS_STRING(fquery));
|
Bytes_AS_STRING(fquery));
|
||||||
Py_DECREF(fquery);
|
Py_DECREF(fquery);
|
||||||
|
@ -416,8 +417,9 @@ _psyco_curs_execute(cursorObject *self,
|
||||||
else {
|
else {
|
||||||
if (self->name != NULL) {
|
if (self->name != NULL) {
|
||||||
self->query = Bytes_FromFormat(
|
self->query = Bytes_FromFormat(
|
||||||
"DECLARE \"%s\" CURSOR %s HOLD FOR %s",
|
"DECLARE \"%s\" %sSCROLL CURSOR %s HOLD FOR %s",
|
||||||
self->name,
|
self->name,
|
||||||
|
self->scrollable ? "":"NO ",
|
||||||
self->withhold ? "WITH" : "WITHOUT",
|
self->withhold ? "WITH" : "WITHOUT",
|
||||||
Bytes_AS_STRING(operation));
|
Bytes_AS_STRING(operation));
|
||||||
}
|
}
|
||||||
|
@ -1584,6 +1586,37 @@ psyco_curs_withhold_set(cursorObject *self, PyObject *pyvalue)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define psyco_curs_scrollable_doc \
|
||||||
|
"Set or return cursor use of SCROLL"
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
psyco_curs_scrollable_get(cursorObject *self)
|
||||||
|
{
|
||||||
|
PyObject *ret;
|
||||||
|
ret = self->scrollable ? Py_True : Py_False;
|
||||||
|
Py_INCREF(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
psyco_curs_scrollable_set(cursorObject *self, PyObject *pyvalue)
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
|
||||||
|
if (self->name == NULL) {
|
||||||
|
PyErr_SetString(ProgrammingError,
|
||||||
|
"trying to set .scrollable on unnamed cursor");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((value = PyObject_IsTrue(pyvalue)) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
self->scrollable = value;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -1710,6 +1743,10 @@ static struct PyGetSetDef cursorObject_getsets[] = {
|
||||||
(getter)psyco_curs_withhold_get,
|
(getter)psyco_curs_withhold_get,
|
||||||
(setter)psyco_curs_withhold_set,
|
(setter)psyco_curs_withhold_set,
|
||||||
psyco_curs_withhold_doc, NULL },
|
psyco_curs_withhold_doc, NULL },
|
||||||
|
{ "scrollable",
|
||||||
|
(getter)psyco_curs_scrollable_get,
|
||||||
|
(setter)psyco_curs_scrollable_set,
|
||||||
|
psyco_curs_scrollable_doc, NULL },
|
||||||
#endif
|
#endif
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
@ -1740,6 +1777,7 @@ cursor_setup(cursorObject *self, connectionObject *conn, const char *name)
|
||||||
|
|
||||||
self->closed = 0;
|
self->closed = 0;
|
||||||
self->withhold = 0;
|
self->withhold = 0;
|
||||||
|
self->scrollable = 0;
|
||||||
self->mark = conn->mark;
|
self->mark = conn->mark;
|
||||||
self->pgres = NULL;
|
self->pgres = NULL;
|
||||||
self->notuples = 1;
|
self->notuples = 1;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user