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