Skip to content

Commit b611246

Browse files
Add support for getting the contents of a collection as a dictionary where the
keys are the indexes of the collection and the values are elements of the collection.
1 parent 7946142 commit b611246

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

doc/src/objecttype.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ Object Objects
6666
collection.
6767

6868

69+
.. method:: Object.asdict()
70+
71+
Return a dictionary where the collection's indexes are the keys and the
72+
elements are its values.
73+
74+
6975
.. method:: Object.aslist()
7076

7177
Return a list of each of the collection's elements in index order.

src/cxoObject.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ static PyObject *cxoObject_getAttr(cxoObject*, PyObject*);
2222
static PyObject *cxoObject_repr(cxoObject*);
2323
static int cxoObject_setAttr(cxoObject*, PyObject*, PyObject*);
2424
static PyObject *cxoObject_append(cxoObject*, PyObject*);
25+
static PyObject *cxoObject_asDict(cxoObject*, PyObject*);
2526
static PyObject *cxoObject_asList(cxoObject*, PyObject*);
2627
static PyObject *cxoObject_copy(cxoObject*, PyObject*);
2728
static PyObject *cxoObject_delete(cxoObject*, PyObject*);
@@ -42,6 +43,7 @@ static PyObject *cxoObject_trim(cxoObject*, PyObject*);
4243
//-----------------------------------------------------------------------------
4344
static PyMethodDef cxoObjectMethods[] = {
4445
{ "append", (PyCFunction) cxoObject_append, METH_O },
46+
{ "asdict", (PyCFunction) cxoObject_asDict, METH_NOARGS },
4547
{ "aslist", (PyCFunction) cxoObject_asList, METH_NOARGS },
4648
{ "copy", (PyCFunction) cxoObject_copy, METH_NOARGS },
4749
{ "delete", (PyCFunction) cxoObject_delete, METH_VARARGS },
@@ -384,6 +386,59 @@ static PyObject *cxoObject_internalGetElementByIndex(cxoObject *obj,
384386
}
385387

386388

389+
//-----------------------------------------------------------------------------
390+
// cxoObject_asDict()
391+
// Returns a collection as a dictionary. If the object is not a collection,
392+
// an error is returned.
393+
//-----------------------------------------------------------------------------
394+
static PyObject *cxoObject_asDict(cxoObject *obj, PyObject *args)
395+
{
396+
PyObject *dict, *key, *value;
397+
int32_t index, nextIndex;
398+
int exists;
399+
400+
// create the result dictionary
401+
dict = PyDict_New();
402+
if (!dict)
403+
return NULL;
404+
405+
// populate it with each of the elements in the collection
406+
if (dpiObject_getFirstIndex(obj->handle, &index, &exists) < 0) {
407+
Py_DECREF(dict);
408+
return cxoError_raiseAndReturnNull();
409+
}
410+
while (exists) {
411+
value = cxoObject_internalGetElementByIndex(obj, index);
412+
if (!value) {
413+
Py_DECREF(dict);
414+
return NULL;
415+
}
416+
key = PyInt_FromLong(index);
417+
if (!key) {
418+
Py_DECREF(value);
419+
Py_DECREF(dict);
420+
return NULL;
421+
}
422+
if (PyDict_SetItem(dict, key, value) < 0) {
423+
Py_DECREF(key);
424+
Py_DECREF(value);
425+
Py_DECREF(dict);
426+
return NULL;
427+
}
428+
Py_DECREF(key);
429+
Py_DECREF(value);
430+
if (dpiObject_getNextIndex(obj->handle, index, &nextIndex,
431+
&exists) < 0) {
432+
Py_DECREF(dict);
433+
return cxoError_raiseAndReturnNull();
434+
}
435+
index = nextIndex;
436+
}
437+
438+
return dict;
439+
}
440+
441+
387442
//-----------------------------------------------------------------------------
388443
// cxoObject_asList()
389444
// Returns a collection as a list of elements. If the object is not a

test/Features12_1.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,17 @@ def testBindPLSQLStringCollectionOutWithHoles(self):
243243
self.assertEqual(obj.aslist(),
244244
["First element", "Second element", "Third element",
245245
"Fourth element"])
246+
self.assertEqual(obj.asdict(),
247+
{ -1048576 : 'First element',
248+
-576 : 'Second element',
249+
284 : 'Third element',
250+
8388608: 'Fourth element' })
246251
obj.delete(-576)
247252
obj.delete(284)
248253
self.assertEqual(obj.aslist(), ["First element", "Fourth element"])
254+
self.assertEqual(obj.asdict(),
255+
{ -1048576 : 'First element',
256+
8388608: 'Fourth element' })
249257

250258
def testExceptionInIteration(self):
251259
"test executing with arraydmlrowcounts with exception"

0 commit comments

Comments
 (0)