Skip to content

Commit 753cf72

Browse files
Ensure that multiple fetches of nested cursors allow the nested cursors to be
closed (#12).
1 parent 243f81f commit 753cf72

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

src/CursorVar.c

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ typedef struct {
2020
OCIStmt **data;
2121
udt_Connection *connection;
2222
PyObject *cursors;
23+
int createCursors;
2324
} udt_CursorVar;
2425

2526

@@ -30,6 +31,7 @@ static int CursorVar_Initialize(udt_CursorVar*, udt_Cursor*);
3031
static void CursorVar_Finalize(udt_CursorVar*);
3132
static int CursorVar_SetValue(udt_CursorVar*, unsigned, PyObject*);
3233
static PyObject *CursorVar_GetValue(udt_CursorVar*, unsigned);
34+
static int CursorVar_PreFetch(udt_CursorVar*);
3335

3436

3537
//-----------------------------------------------------------------------------
@@ -69,7 +71,7 @@ static udt_VariableType vt_Cursor = {
6971
(PreDefineProc) NULL,
7072
(PostDefineProc) NULL,
7173
(PostBindProc) NULL,
72-
(PreFetchProc) NULL,
74+
(PreFetchProc) CursorVar_PreFetch,
7375
(IsNullProc) NULL,
7476
(SetValueProc) CursorVar_SetValue,
7577
(GetValueProc) CursorVar_GetValue,
@@ -99,6 +101,7 @@ static int CursorVar_Initialize(
99101
Py_INCREF(cursor->connection);
100102
var->connection = cursor->connection;
101103
var->cursors = PyList_New(var->allocatedElements);
104+
var->createCursors = 0;
102105
if (!var->cursors)
103106
return -1;
104107
for (i = 0; i < var->allocatedElements; i++) {
@@ -127,8 +130,8 @@ static int CursorVar_Initialize(
127130
static void CursorVar_Finalize(
128131
udt_CursorVar *var) // variable to free
129132
{
130-
Py_DECREF(var->connection);
131-
Py_XDECREF(var->cursors);
133+
Py_CLEAR(var->connection);
134+
Py_CLEAR(var->cursors);
132135
}
133136

134137

@@ -181,3 +184,41 @@ static PyObject *CursorVar_GetValue(
181184
return cursor;
182185
}
183186

187+
188+
//-----------------------------------------------------------------------------
189+
// CursorVar_PreFetch()
190+
// Clear cursors and create new ones in preparation for next fetch.
191+
//-----------------------------------------------------------------------------
192+
static int CursorVar_PreFetch(
193+
udt_CursorVar *var) // variable to free
194+
{
195+
udt_Cursor *tempCursor;
196+
ub4 i;
197+
198+
// do not clear cursors the first time (already created by initialize)
199+
if (!var->createCursors) {
200+
var->createCursors = 1;
201+
return 0;
202+
}
203+
204+
// clear original cursors and create new ones
205+
for (i = 0; i < var->allocatedElements; i++) {
206+
207+
// clear original cursor, if applicable
208+
Py_CLEAR(PyList_GET_ITEM(var->cursors, i));
209+
var->data[i] = NULL;
210+
211+
// create new cursor
212+
tempCursor = (udt_Cursor*) Connection_NewCursor(var->connection, NULL,
213+
NULL);
214+
if (!tempCursor)
215+
return -1;
216+
PyList_SET_ITEM(var->cursors, i, (PyObject*) tempCursor);
217+
if (Cursor_AllocateHandle(tempCursor) < 0)
218+
return -1;
219+
var->data[i] = tempCursor->handle;
220+
}
221+
222+
return 0;
223+
}
224+

0 commit comments

Comments
 (0)