»Core Development>Code coverage>Modules/_sqlite/row.c

Python code coverage for Modules/_sqlite/row.c

#countcontent
1n/a/* row.c - an enhanced tuple for database rows
2n/a *
3n/a * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
4n/a *
5n/a * This file is part of pysqlite.
6n/a *
7n/a * This software is provided 'as-is', without any express or implied
8n/a * warranty. In no event will the authors be held liable for any damages
9n/a * arising from the use of this software.
10n/a *
11n/a * Permission is granted to anyone to use this software for any purpose,
12n/a * including commercial applications, and to alter it and redistribute it
13n/a * freely, subject to the following restrictions:
14n/a *
15n/a * 1. The origin of this software must not be misrepresented; you must not
16n/a * claim that you wrote the original software. If you use this software
17n/a * in a product, an acknowledgment in the product documentation would be
18n/a * appreciated but is not required.
19n/a * 2. Altered source versions must be plainly marked as such, and must not be
20n/a * misrepresented as being the original software.
21n/a * 3. This notice may not be removed or altered from any source distribution.
22n/a */
23n/a
24n/a#include "row.h"
25n/a#include "cursor.h"
26n/a
27n/avoid pysqlite_row_dealloc(pysqlite_Row* self)
28n/a{
29n/a Py_XDECREF(self->data);
30n/a Py_XDECREF(self->description);
31n/a
32n/a Py_TYPE(self)->tp_free((PyObject*)self);
33n/a}
34n/a
35n/astatic PyObject *
36n/apysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
37n/a{
38n/a pysqlite_Row *self;
39n/a PyObject* data;
40n/a pysqlite_Cursor* cursor;
41n/a
42n/a assert(type != NULL && type->tp_alloc != NULL);
43n/a
44n/a if (!_PyArg_NoKeywords("Row()", kwargs))
45n/a return NULL;
46n/a if (!PyArg_ParseTuple(args, "OO", &cursor, &data))
47n/a return NULL;
48n/a
49n/a if (!PyObject_TypeCheck((PyObject*)cursor, &pysqlite_CursorType)) {
50n/a PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument");
51n/a return NULL;
52n/a }
53n/a
54n/a if (!PyTuple_Check(data)) {
55n/a PyErr_SetString(PyExc_TypeError, "tuple required for second argument");
56n/a return NULL;
57n/a }
58n/a
59n/a self = (pysqlite_Row *) type->tp_alloc(type, 0);
60n/a if (self == NULL)
61n/a return NULL;
62n/a
63n/a Py_INCREF(data);
64n/a self->data = data;
65n/a
66n/a Py_INCREF(cursor->description);
67n/a self->description = cursor->description;
68n/a
69n/a return (PyObject *) self;
70n/a}
71n/a
72n/aPyObject* pysqlite_row_item(pysqlite_Row* self, Py_ssize_t idx)
73n/a{
74n/a PyObject* item = PyTuple_GetItem(self->data, idx);
75n/a Py_XINCREF(item);
76n/a return item;
77n/a}
78n/a
79n/aPyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx)
80n/a{
81n/a Py_ssize_t _idx;
82n/a const char *key;
83n/a Py_ssize_t nitems, i;
84n/a const char *compare_key;
85n/a
86n/a const char *p1;
87n/a const char *p2;
88n/a
89n/a PyObject* item;
90n/a
91n/a if (PyLong_Check(idx)) {
92n/a _idx = PyNumber_AsSsize_t(idx, PyExc_IndexError);
93n/a if (_idx == -1 && PyErr_Occurred())
94n/a return NULL;
95n/a if (_idx < 0)
96n/a _idx += PyTuple_GET_SIZE(self->data);
97n/a item = PyTuple_GetItem(self->data, _idx);
98n/a Py_XINCREF(item);
99n/a return item;
100n/a } else if (PyUnicode_Check(idx)) {
101n/a key = PyUnicode_AsUTF8(idx);
102n/a if (key == NULL)
103n/a return NULL;
104n/a
105n/a nitems = PyTuple_Size(self->description);
106n/a
107n/a for (i = 0; i < nitems; i++) {
108n/a PyObject *obj;
109n/a obj = PyTuple_GET_ITEM(self->description, i);
110n/a obj = PyTuple_GET_ITEM(obj, 0);
111n/a compare_key = PyUnicode_AsUTF8(obj);
112n/a if (!compare_key) {
113n/a return NULL;
114n/a }
115n/a
116n/a p1 = key;
117n/a p2 = compare_key;
118n/a
119n/a while (1) {
120n/a if ((*p1 == (char)0) || (*p2 == (char)0)) {
121n/a break;
122n/a }
123n/a
124n/a if ((*p1 | 0x20) != (*p2 | 0x20)) {
125n/a break;
126n/a }
127n/a
128n/a p1++;
129n/a p2++;
130n/a }
131n/a
132n/a if ((*p1 == (char)0) && (*p2 == (char)0)) {
133n/a /* found item */
134n/a item = PyTuple_GetItem(self->data, i);
135n/a Py_INCREF(item);
136n/a return item;
137n/a }
138n/a
139n/a }
140n/a
141n/a PyErr_SetString(PyExc_IndexError, "No item with that key");
142n/a return NULL;
143n/a }
144n/a else if (PySlice_Check(idx)) {
145n/a return PyObject_GetItem(self->data, idx);
146n/a }
147n/a else {
148n/a PyErr_SetString(PyExc_IndexError, "Index must be int or string");
149n/a return NULL;
150n/a }
151n/a}
152n/a
153n/aPy_ssize_t pysqlite_row_length(pysqlite_Row* self, PyObject* args, PyObject* kwargs)
154n/a{
155n/a return PyTuple_GET_SIZE(self->data);
156n/a}
157n/a
158n/aPyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject* args, PyObject* kwargs)
159n/a{
160n/a PyObject* list;
161n/a Py_ssize_t nitems, i;
162n/a
163n/a list = PyList_New(0);
164n/a if (!list) {
165n/a return NULL;
166n/a }
167n/a nitems = PyTuple_Size(self->description);
168n/a
169n/a for (i = 0; i < nitems; i++) {
170n/a if (PyList_Append(list, PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0)) != 0) {
171n/a Py_DECREF(list);
172n/a return NULL;
173n/a }
174n/a }
175n/a
176n/a return list;
177n/a}
178n/a
179n/astatic int pysqlite_row_print(pysqlite_Row* self, FILE *fp, int flags)
180n/a{
181n/a return (&PyTuple_Type)->tp_print(self->data, fp, flags);
182n/a}
183n/a
184n/astatic PyObject* pysqlite_iter(pysqlite_Row* self)
185n/a{
186n/a return PyObject_GetIter(self->data);
187n/a}
188n/a
189n/astatic Py_hash_t pysqlite_row_hash(pysqlite_Row *self)
190n/a{
191n/a return PyObject_Hash(self->description) ^ PyObject_Hash(self->data);
192n/a}
193n/a
194n/astatic PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, int opid)
195n/a{
196n/a if (opid != Py_EQ && opid != Py_NE)
197n/a Py_RETURN_NOTIMPLEMENTED;
198n/a
199n/a if (PyType_IsSubtype(Py_TYPE(_other), &pysqlite_RowType)) {
200n/a pysqlite_Row *other = (pysqlite_Row *)_other;
201n/a PyObject *res = PyObject_RichCompare(self->description, other->description, opid);
202n/a if ((opid == Py_EQ && res == Py_True)
203n/a || (opid == Py_NE && res == Py_False)) {
204n/a Py_DECREF(res);
205n/a return PyObject_RichCompare(self->data, other->data, opid);
206n/a }
207n/a }
208n/a Py_RETURN_NOTIMPLEMENTED;
209n/a}
210n/a
211n/aPyMappingMethods pysqlite_row_as_mapping = {
212n/a /* mp_length */ (lenfunc)pysqlite_row_length,
213n/a /* mp_subscript */ (binaryfunc)pysqlite_row_subscript,
214n/a /* mp_ass_subscript */ (objobjargproc)0,
215n/a};
216n/a
217n/astatic PySequenceMethods pysqlite_row_as_sequence = {
218n/a /* sq_length */ (lenfunc)pysqlite_row_length,
219n/a /* sq_concat */ 0,
220n/a /* sq_repeat */ 0,
221n/a /* sq_item */ (ssizeargfunc)pysqlite_row_item,
222n/a};
223n/a
224n/a
225n/astatic PyMethodDef pysqlite_row_methods[] = {
226n/a {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS,
227n/a PyDoc_STR("Returns the keys of the row.")},
228n/a {NULL, NULL}
229n/a};
230n/a
231n/a
232n/aPyTypeObject pysqlite_RowType = {
233n/a PyVarObject_HEAD_INIT(NULL, 0)
234n/a MODULE_NAME ".Row", /* tp_name */
235n/a sizeof(pysqlite_Row), /* tp_basicsize */
236n/a 0, /* tp_itemsize */
237n/a (destructor)pysqlite_row_dealloc, /* tp_dealloc */
238n/a (printfunc)pysqlite_row_print, /* tp_print */
239n/a 0, /* tp_getattr */
240n/a 0, /* tp_setattr */
241n/a 0, /* tp_reserved */
242n/a 0, /* tp_repr */
243n/a 0, /* tp_as_number */
244n/a 0, /* tp_as_sequence */
245n/a 0, /* tp_as_mapping */
246n/a (hashfunc)pysqlite_row_hash, /* tp_hash */
247n/a 0, /* tp_call */
248n/a 0, /* tp_str */
249n/a 0, /* tp_getattro */
250n/a 0, /* tp_setattro */
251n/a 0, /* tp_as_buffer */
252n/a Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
253n/a 0, /* tp_doc */
254n/a (traverseproc)0, /* tp_traverse */
255n/a 0, /* tp_clear */
256n/a (richcmpfunc)pysqlite_row_richcompare, /* tp_richcompare */
257n/a 0, /* tp_weaklistoffset */
258n/a (getiterfunc)pysqlite_iter, /* tp_iter */
259n/a 0, /* tp_iternext */
260n/a pysqlite_row_methods, /* tp_methods */
261n/a 0, /* tp_members */
262n/a 0, /* tp_getset */
263n/a 0, /* tp_base */
264n/a 0, /* tp_dict */
265n/a 0, /* tp_descr_get */
266n/a 0, /* tp_descr_set */
267n/a 0, /* tp_dictoffset */
268n/a 0, /* tp_init */
269n/a 0, /* tp_alloc */
270n/a 0, /* tp_new */
271n/a 0 /* tp_free */
272n/a};
273n/a
274n/aextern int pysqlite_row_setup_types(void)
275n/a{
276n/a pysqlite_RowType.tp_new = pysqlite_row_new;
277n/a pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping;
278n/a pysqlite_RowType.tp_as_sequence = &pysqlite_row_as_sequence;
279n/a return PyType_Ready(&pysqlite_RowType);
280n/a}