mirror of
				https://github.com/psycopg/psycopg2.git
				synced 2025-10-31 07:47:30 +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 *factory = (PyObject *)&cursorType; | ||||
|     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, | ||||
|                                      &name, &factory, &withhold)) { | ||||
|     if (!PyArg_ParseTupleAndKeywords( | ||||
|             args, kwargs, "|OOOO", kwlist, | ||||
|             &name, &factory, &withhold, &scrollable)) { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|  | @ -70,6 +73,12 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *kwargs) | |||
|         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); | ||||
| 
 | ||||
|     if (self->status != CONN_STATUS_READY && | ||||
|  | @ -104,6 +113,9 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *kwargs) | |||
|     if (PyObject_IsTrue(withhold)) | ||||
|         ((cursorObject*)obj)->withhold = 1; | ||||
| 
 | ||||
|     if (PyObject_IsTrue(scrollable)) | ||||
|         ((cursorObject*)obj)->scrollable = 1; | ||||
| 
 | ||||
|     Dprintf("psyco_conn_cursor: new cursor at %p: refcnt = " | ||||
|         FORMAT_CODE_PY_SSIZE_T, | ||||
|         obj, Py_REFCNT(obj) | ||||
|  |  | |||
|  | @ -43,6 +43,7 @@ struct cursorObject { | |||
|     int closed:1;            /* 1 if the cursor is closed */ | ||||
|     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 scrollable:1;        /* 1 if the cursor is named as SCROLLABLE */ | ||||
| 
 | ||||
|     long int rowcount;       /* number of rows affected by last execute */ | ||||
|     long int columns;        /* number of columns fetched from the db */ | ||||
|  |  | |||
|  | @ -403,8 +403,9 @@ _psyco_curs_execute(cursorObject *self, | |||
| 
 | ||||
|         if (self->name != NULL) { | ||||
|             self->query = Bytes_FromFormat( | ||||
|                 "DECLARE \"%s\" CURSOR %s HOLD FOR %s", | ||||
|                 "DECLARE \"%s\" %sSCROLL CURSOR %s HOLD FOR %s", | ||||
|                 self->name, | ||||
|                 self->scrollable ? "":"NO ", | ||||
|                 self->withhold ? "WITH" : "WITHOUT", | ||||
|                 Bytes_AS_STRING(fquery)); | ||||
|             Py_DECREF(fquery); | ||||
|  | @ -416,8 +417,9 @@ _psyco_curs_execute(cursorObject *self, | |||
|     else { | ||||
|         if (self->name != NULL) { | ||||
|             self->query = Bytes_FromFormat( | ||||
|                 "DECLARE \"%s\" CURSOR %s HOLD FOR %s", | ||||
|                 "DECLARE \"%s\" %sSCROLL CURSOR %s HOLD FOR %s", | ||||
|                 self->name, | ||||
|                 self->scrollable ? "":"NO ", | ||||
|                 self->withhold ? "WITH" : "WITHOUT", | ||||
|                 Bytes_AS_STRING(operation)); | ||||
|         } | ||||
|  | @ -1584,6 +1586,37 @@ psyco_curs_withhold_set(cursorObject *self, PyObject *pyvalue) | |||
|     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 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -1710,6 +1743,10 @@ static struct PyGetSetDef cursorObject_getsets[] = { | |||
|       (getter)psyco_curs_withhold_get, | ||||
|       (setter)psyco_curs_withhold_set, | ||||
|       psyco_curs_withhold_doc, NULL }, | ||||
|     { "scrollable", | ||||
|       (getter)psyco_curs_scrollable_get, | ||||
|       (setter)psyco_curs_scrollable_set, | ||||
|       psyco_curs_scrollable_doc, NULL }, | ||||
| #endif | ||||
|     {NULL} | ||||
| }; | ||||
|  | @ -1740,6 +1777,7 @@ cursor_setup(cursorObject *self, connectionObject *conn, const char *name) | |||
| 
 | ||||
|     self->closed = 0; | ||||
|     self->withhold = 0; | ||||
|     self->scrollable = 0; | ||||
|     self->mark = conn->mark; | ||||
|     self->pgres = NULL; | ||||
|     self->notuples = 1; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user