//----------------------------------------------------------------------------- // Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // cxoSodaDocCursor.c // Defines the routines for handling SODA document cursors. These cursors // permit iterating over the documents that match the criteria that was // specified by the user. //----------------------------------------------------------------------------- #include "cxoModule.h" //----------------------------------------------------------------------------- // Declaration of functions //----------------------------------------------------------------------------- static void cxoSodaDocCursor_free(cxoSodaDocCursor*); static PyObject *cxoSodaDocCursor_repr(cxoSodaDocCursor*); static PyObject *cxoSodaDocCursor_getIter(cxoSodaDocCursor*); static PyObject *cxoSodaDocCursor_getNext(cxoSodaDocCursor*); static PyObject *cxoSodaDocCursor_close(cxoSodaDocCursor*, PyObject*); //----------------------------------------------------------------------------- // declaration of methods //----------------------------------------------------------------------------- static PyMethodDef cxoMethods[] = { { "close", (PyCFunction) cxoSodaDocCursor_close, METH_NOARGS }, { NULL } }; //----------------------------------------------------------------------------- // Python type declarations //----------------------------------------------------------------------------- PyTypeObject cxoPyTypeSodaDocCursor = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "cx_Oracle.SodaDocCursor", .tp_basicsize = sizeof(cxoSodaDocCursor), .tp_dealloc = (destructor) cxoSodaDocCursor_free, .tp_repr = (reprfunc) cxoSodaDocCursor_repr, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_iter = (getiterfunc) cxoSodaDocCursor_getIter, .tp_iternext = (iternextfunc) cxoSodaDocCursor_getNext, .tp_methods = cxoMethods }; //----------------------------------------------------------------------------- // cxoSodaDocCursor_new() // Create a new SODA document cursor. //----------------------------------------------------------------------------- cxoSodaDocCursor *cxoSodaDocCursor_new(cxoSodaDatabase *db, dpiSodaDocCursor *handle) { cxoSodaDocCursor *cursor; cursor = (cxoSodaDocCursor*) cxoPyTypeSodaDocCursor.tp_alloc(&cxoPyTypeSodaDocCursor, 0); if (!cursor) { dpiSodaDocCursor_release(handle); return NULL; } Py_INCREF(db); cursor->db = db; cursor->handle = handle; return cursor; } //----------------------------------------------------------------------------- // cxoSodaDocCursor_free() // Free the memory associated with a SODA document cursor. //----------------------------------------------------------------------------- static void cxoSodaDocCursor_free(cxoSodaDocCursor *cursor) { if (cursor->handle) { dpiSodaDocCursor_release(cursor->handle); cursor->handle = NULL; } Py_CLEAR(cursor->db); Py_TYPE(cursor)->tp_free((PyObject*) cursor); } //----------------------------------------------------------------------------- // cxoSodaDocCursor_repr() // Return a string representation of a SODA document cursor. //----------------------------------------------------------------------------- static PyObject *cxoSodaDocCursor_repr(cxoSodaDocCursor *cursor) { PyObject *module, *name, *result; if (cxoUtils_getModuleAndName(Py_TYPE(cursor), &module, &name) < 0) return NULL; result = cxoUtils_formatString("<%s.%s>", PyTuple_Pack(2, module, name)); Py_DECREF(module); Py_DECREF(name); return result; } //----------------------------------------------------------------------------- // cxoSodaDocCursor_close() // Create a SODA collection and return it. //----------------------------------------------------------------------------- static PyObject *cxoSodaDocCursor_close(cxoSodaDocCursor *cursor, PyObject *args) { if (dpiSodaDocCursor_close(cursor->handle) < 0) return cxoError_raiseAndReturnNull(); Py_RETURN_NONE; } //----------------------------------------------------------------------------- // cxoSodaDocCursor_getIter() // Return a reference to the cursor which supports the iterator protocol. //----------------------------------------------------------------------------- static PyObject *cxoSodaDocCursor_getIter(cxoSodaDocCursor *cursor) { Py_INCREF(cursor); return (PyObject*) cursor; } //----------------------------------------------------------------------------- // cxoSodaDocCursor_getNext() // Return the next document from the cursor. //----------------------------------------------------------------------------- static PyObject *cxoSodaDocCursor_getNext(cxoSodaDocCursor *cursor) { dpiSodaDoc *handle; cxoSodaDoc *doc; uint32_t flags; int status; if (cxoConnection_getSodaFlags(cursor->db->connection, &flags) < 0) return NULL; Py_BEGIN_ALLOW_THREADS status = dpiSodaDocCursor_getNext(cursor->handle, flags, &handle); Py_END_ALLOW_THREADS if (status < 0) return cxoError_raiseAndReturnNull(); if (!handle) return NULL; doc = cxoSodaDoc_new(cursor->db, handle); if (!doc) return NULL; return (PyObject*) doc; }