14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* row.c - an enhanced tuple for database rows
24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *
34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Copyright (C) 2005-2010 Gerhard H�ring <gh@ghaering.de>
44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *
54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * This file is part of pysqlite.
64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *
74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * This software is provided 'as-is', without any express or implied
84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * warranty.  In no event will the authors be held liable for any damages
94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * arising from the use of this software.
104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *
114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Permission is granted to anyone to use this software for any purpose,
124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * including commercial applications, and to alter it and redistribute it
134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * freely, subject to the following restrictions:
144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *
154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * 1. The origin of this software must not be misrepresented; you must not
164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *    claim that you wrote the original software. If you use this software
174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *    in a product, an acknowledgment in the product documentation would be
184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *    appreciated but is not required.
194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * 2. Altered source versions must be plainly marked as such, and must not be
204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *    misrepresented as being the original software.
214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * 3. This notice may not be removed or altered from any source distribution.
224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "row.h"
254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "cursor.h"
264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "sqlitecompat.h"
274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmvoid pysqlite_row_dealloc(pysqlite_Row* self)
294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(self->data);
314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(self->description);
324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_TYPE(self)->tp_free((PyObject*)self);
344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint pysqlite_row_init(pysqlite_Row* self, PyObject* args, PyObject* kwargs)
374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject* data;
394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    pysqlite_Cursor* cursor;
404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    self->data = 0;
424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    self->description = 0;
434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) {
454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyObject_IsInstance((PyObject*)cursor, (PyObject*)&pysqlite_CursorType)) {
494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument");
504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyTuple_Check(data)) {
544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_TypeError, "tuple required for second argument");
554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_INCREF(data);
594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    self->data = data;
604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_INCREF(cursor->description);
624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    self->description = cursor->description;
634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx)
684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    long _idx;
704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char* key;
714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int nitems, i;
724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char* compare_key;
734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char* p1;
754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char* p2;
764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject* item;
784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyInt_Check(idx)) {
804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        _idx = PyInt_AsLong(idx);
814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        item = PyTuple_GetItem(self->data, _idx);
824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_XINCREF(item);
834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return item;
844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    } else if (PyLong_Check(idx)) {
854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        _idx = PyLong_AsLong(idx);
864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        item = PyTuple_GetItem(self->data, _idx);
874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_XINCREF(item);
884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return item;
894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    } else if (PyString_Check(idx)) {
904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        key = PyString_AsString(idx);
914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        nitems = PyTuple_Size(self->description);
934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for (i = 0; i < nitems; i++) {
954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            compare_key = PyString_AsString(PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0));
964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (!compare_key) {
974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return NULL;
984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            p1 = key;
1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            p2 = compare_key;
1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            while (1) {
1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if ((*p1 == (char)0) || (*p2 == (char)0)) {
1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    break;
1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if ((*p1 | 0x20) != (*p2 | 0x20)) {
1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    break;
1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                p1++;
1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                p2++;
1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if ((*p1 == (char)0) && (*p2 == (char)0)) {
1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                /* found item */
1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                item = PyTuple_GetItem(self->data, i);
1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_INCREF(item);
1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return item;
1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_IndexError, "No item with that key");
1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    } else if (PySlice_Check(idx)) {
1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_ValueError, "slices not implemented, yet");
1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    } else {
1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_IndexError, "Index must be int or string");
1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPy_ssize_t pysqlite_row_length(pysqlite_Row* self, PyObject* args, PyObject* kwargs)
1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyTuple_GET_SIZE(self->data);
1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject* args, PyObject* kwargs)
1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject* list;
1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int nitems, i;
1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    list = PyList_New(0);
1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!list) {
1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    nitems = PyTuple_Size(self->description);
1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (i = 0; i < nitems; i++) {
1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyList_Append(list, PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0)) != 0) {
1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(list);
1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return list;
1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int pysqlite_row_print(pysqlite_Row* self, FILE *fp, int flags)
1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return (&PyTuple_Type)->tp_print(self->data, fp, flags);
1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject* pysqlite_iter(pysqlite_Row* self)
1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyObject_GetIter(self->data);
1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic long pysqlite_row_hash(pysqlite_Row *self)
1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyObject_Hash(self->description) ^ PyObject_Hash(self->data);
1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, int opid)
1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (opid != Py_EQ && opid != Py_NE) {
1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(Py_NotImplemented);
1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return Py_NotImplemented;
1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyType_IsSubtype(Py_TYPE(_other), &pysqlite_RowType)) {
1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        pysqlite_Row *other = (pysqlite_Row *)_other;
1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *res = PyObject_RichCompare(self->description, other->description, opid);
1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if ((opid == Py_EQ && res == Py_True)
1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            || (opid == Py_NE && res == Py_False)) {
1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(res);
1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return PyObject_RichCompare(self->data, other->data, opid);
1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_INCREF(Py_NotImplemented);
1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return Py_NotImplemented;
1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyMappingMethods pysqlite_row_as_mapping = {
1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* mp_length        */ (lenfunc)pysqlite_row_length,
1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* mp_subscript     */ (binaryfunc)pysqlite_row_subscript,
1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* mp_ass_subscript */ (objobjargproc)0,
2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyMethodDef pysqlite_row_methods[] = {
2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS,
2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyDoc_STR("Returns the keys of the row.")},
2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {NULL, NULL}
2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyTypeObject pysqlite_RowType = {
2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyVarObject_HEAD_INIT(NULL, 0)
2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        MODULE_NAME ".Row",                             /* tp_name */
2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        sizeof(pysqlite_Row),                           /* tp_basicsize */
2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_itemsize */
2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (destructor)pysqlite_row_dealloc,               /* tp_dealloc */
2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (printfunc)pysqlite_row_print,                  /* tp_print */
2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_getattr */
2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_setattr */
2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_compare */
2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_repr */
2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_as_number */
2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_as_sequence */
2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_as_mapping */
2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (hashfunc)pysqlite_row_hash,                    /* tp_hash */
2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_call */
2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_str */
2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_getattro */
2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_setattro */
2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_as_buffer */
2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,         /* tp_flags */
2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_doc */
2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (traverseproc)0,                                /* tp_traverse */
2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_clear */
2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (richcmpfunc)pysqlite_row_richcompare,          /* tp_richcompare */
2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_weaklistoffset */
2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (getiterfunc)pysqlite_iter,                     /* tp_iter */
2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_iternext */
2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        pysqlite_row_methods,                           /* tp_methods */
2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_members */
2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_getset */
2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_base */
2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_dict */
2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_descr_get */
2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_descr_set */
2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_dictoffset */
2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (initproc)pysqlite_row_init,                    /* tp_init */
2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_alloc */
2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0,                                              /* tp_new */
2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0                                               /* tp_free */
2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmextern int pysqlite_row_setup_types(void)
2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    pysqlite_RowType.tp_new = PyType_GenericNew;
2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping;
2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyType_Ready(&pysqlite_RowType);
2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
257