| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  | /* row.c - an enhanced tuple for database rows
 | 
					
						
							|  |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2006-04-04 06:29:05 +00:00
										 |  |  |  |  * Copyright (C) 2005-2006 Gerhard H<EFBFBD>ring <gh@ghaering.de> | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  |  * This file is part of pysqlite. | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * This software is provided 'as-is', without any express or implied | 
					
						
							|  |  |  |  |  * warranty.  In no event will the authors be held liable for any damages | 
					
						
							|  |  |  |  |  * arising from the use of this software. | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * Permission is granted to anyone to use this software for any purpose, | 
					
						
							|  |  |  |  |  * including commercial applications, and to alter it and redistribute it | 
					
						
							|  |  |  |  |  * freely, subject to the following restrictions: | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * 1. The origin of this software must not be misrepresented; you must not | 
					
						
							|  |  |  |  |  *    claim that you wrote the original software. If you use this software | 
					
						
							|  |  |  |  |  *    in a product, an acknowledgment in the product documentation would be | 
					
						
							|  |  |  |  |  *    appreciated but is not required. | 
					
						
							|  |  |  |  |  * 2. Altered source versions must be plainly marked as such, and must not be | 
					
						
							|  |  |  |  |  *    misrepresented as being the original software. | 
					
						
							|  |  |  |  |  * 3. This notice may not be removed or altered from any source distribution. | 
					
						
							|  |  |  |  |  */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #include "row.h"
 | 
					
						
							|  |  |  |  | #include "cursor.h"
 | 
					
						
							| 
									
										
										
										
											2006-04-04 06:29:05 +00:00
										 |  |  |  | #include "sqlitecompat.h"
 | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  | void pysqlite_row_dealloc(pysqlite_Row* self) | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     Py_XDECREF(self->data); | 
					
						
							|  |  |  |  |     Py_XDECREF(self->description); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-19 02:37:44 +00:00
										 |  |  |  |     Py_TYPE(self)->tp_free((PyObject*)self); | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  | int pysqlite_row_init(pysqlite_Row* self, PyObject* args, PyObject* kwargs) | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     PyObject* data; | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  |     pysqlite_Cursor* cursor; | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     self->data = 0; | 
					
						
							|  |  |  |  |     self->description = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) { | 
					
						
							|  |  |  |  |         return -1; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  |     if (!PyObject_IsInstance((PyObject*)cursor, (PyObject*)&pysqlite_CursorType)) { | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  |         PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument"); | 
					
						
							|  |  |  |  |         return -1; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (!PyTuple_Check(data)) { | 
					
						
							|  |  |  |  |         PyErr_SetString(PyExc_TypeError, "tuple required for second argument"); | 
					
						
							|  |  |  |  |         return -1; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     Py_INCREF(data); | 
					
						
							|  |  |  |  |     self->data = data; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     Py_INCREF(cursor->description); | 
					
						
							|  |  |  |  |     self->description = cursor->description; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return 0; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  | PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     long _idx; | 
					
						
							|  |  |  |  |     char* key; | 
					
						
							|  |  |  |  |     int nitems, i; | 
					
						
							|  |  |  |  |     char* compare_key; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     char* p1; | 
					
						
							|  |  |  |  |     char* p2; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     PyObject* item; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (PyInt_Check(idx)) { | 
					
						
							|  |  |  |  |         _idx = PyInt_AsLong(idx); | 
					
						
							|  |  |  |  |         item = PyTuple_GetItem(self->data, _idx); | 
					
						
							| 
									
										
										
										
											2006-04-04 06:29:05 +00:00
										 |  |  |  |         Py_XINCREF(item); | 
					
						
							|  |  |  |  |         return item; | 
					
						
							|  |  |  |  |     } else if (PyLong_Check(idx)) { | 
					
						
							|  |  |  |  |         _idx = PyLong_AsLong(idx); | 
					
						
							|  |  |  |  |         item = PyTuple_GetItem(self->data, _idx); | 
					
						
							|  |  |  |  |         Py_XINCREF(item); | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  |         return item; | 
					
						
							|  |  |  |  |     } else if (PyString_Check(idx)) { | 
					
						
							|  |  |  |  |         key = PyString_AsString(idx); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         nitems = PyTuple_Size(self->description); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         for (i = 0; i < nitems; i++) { | 
					
						
							|  |  |  |  |             compare_key = PyString_AsString(PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0)); | 
					
						
							| 
									
										
										
										
											2006-04-04 06:29:05 +00:00
										 |  |  |  |             if (!compare_key) { | 
					
						
							|  |  |  |  |                 return NULL; | 
					
						
							|  |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |             p1 = key; | 
					
						
							|  |  |  |  |             p2 = compare_key; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             while (1) { | 
					
						
							|  |  |  |  |                 if ((*p1 == (char)0) || (*p2 == (char)0)) { | 
					
						
							|  |  |  |  |                     break; | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 if ((*p1 | 0x20) != (*p2 | 0x20)) { | 
					
						
							|  |  |  |  |                     break; | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 p1++; | 
					
						
							|  |  |  |  |                 p2++; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if ((*p1 == (char)0) && (*p2 == (char)0)) { | 
					
						
							|  |  |  |  |                 /* found item */ | 
					
						
							|  |  |  |  |                 item = PyTuple_GetItem(self->data, i); | 
					
						
							|  |  |  |  |                 Py_INCREF(item); | 
					
						
							|  |  |  |  |                 return item; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         PyErr_SetString(PyExc_IndexError, "No item with that key"); | 
					
						
							|  |  |  |  |         return NULL; | 
					
						
							|  |  |  |  |     } else if (PySlice_Check(idx)) { | 
					
						
							|  |  |  |  |         PyErr_SetString(PyExc_ValueError, "slices not implemented, yet"); | 
					
						
							|  |  |  |  |         return NULL; | 
					
						
							|  |  |  |  |     } else { | 
					
						
							|  |  |  |  |         PyErr_SetString(PyExc_IndexError, "Index must be int or string"); | 
					
						
							|  |  |  |  |         return NULL; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  | Py_ssize_t pysqlite_row_length(pysqlite_Row* self, PyObject* args, PyObject* kwargs) | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     return PyTuple_GET_SIZE(self->data); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  | PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject* args, PyObject* kwargs) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     PyObject* list; | 
					
						
							|  |  |  |  |     int nitems, i; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     list = PyList_New(0); | 
					
						
							|  |  |  |  |     if (!list) { | 
					
						
							|  |  |  |  |         return NULL; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     nitems = PyTuple_Size(self->description); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     for (i = 0; i < nitems; i++) { | 
					
						
							|  |  |  |  |         if (PyList_Append(list, PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0)) != 0) { | 
					
						
							|  |  |  |  |             Py_DECREF(list); | 
					
						
							|  |  |  |  |             return NULL; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return list; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static int pysqlite_row_print(pysqlite_Row* self, FILE *fp, int flags) | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     return (&PyTuple_Type)->tp_print(self->data, fp, flags); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  | static PyObject* pysqlite_iter(pysqlite_Row* self) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     return PyObject_GetIter(self->data); | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  | PyMappingMethods pysqlite_row_as_mapping = { | 
					
						
							|  |  |  |  |     /* mp_length        */ (lenfunc)pysqlite_row_length, | 
					
						
							|  |  |  |  |     /* mp_subscript     */ (binaryfunc)pysqlite_row_subscript, | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  |     /* mp_ass_subscript */ (objobjargproc)0, | 
					
						
							|  |  |  |  | }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  | static PyMethodDef pysqlite_row_methods[] = { | 
					
						
							|  |  |  |  |     {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS, | 
					
						
							|  |  |  |  |         PyDoc_STR("Returns the keys of the row.")}, | 
					
						
							|  |  |  |  |     {NULL, NULL} | 
					
						
							|  |  |  |  | }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  | PyTypeObject pysqlite_RowType = { | 
					
						
							| 
									
										
										
										
											2007-07-21 06:55:02 +00:00
										 |  |  |  |         PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							| 
									
										
										
										
											2006-04-05 18:25:33 +00:00
										 |  |  |  |         MODULE_NAME ".Row",                             /* tp_name */ | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  |         sizeof(pysqlite_Row),                           /* tp_basicsize */ | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  |         0,                                              /* tp_itemsize */ | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  |         (destructor)pysqlite_row_dealloc,               /* tp_dealloc */ | 
					
						
							|  |  |  |  |         (printfunc)pysqlite_row_print,                  /* tp_print */ | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  |         0,                                              /* tp_getattr */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_setattr */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_compare */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_repr */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_as_number */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_as_sequence */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_as_mapping */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_hash */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_call */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_str */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_getattro */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_setattro */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_as_buffer */ | 
					
						
							|  |  |  |  |         Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,         /* tp_flags */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_doc */ | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  |         (traverseproc)0,                                /* tp_traverse */ | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  |         0,                                              /* tp_clear */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_richcompare */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_weaklistoffset */ | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  |         (getiterfunc)pysqlite_iter,                     /* tp_iter */ | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  |         0,                                              /* tp_iternext */ | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  |         pysqlite_row_methods,                           /* tp_methods */ | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  |         0,                                              /* tp_members */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_getset */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_base */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_dict */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_descr_get */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_descr_set */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_dictoffset */ | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  |         (initproc)pysqlite_row_init,                    /* tp_init */ | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  |         0,                                              /* tp_alloc */ | 
					
						
							|  |  |  |  |         0,                                              /* tp_new */ | 
					
						
							|  |  |  |  |         0                                               /* tp_free */ | 
					
						
							|  |  |  |  | }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  | extern int pysqlite_row_setup_types(void) | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-01-14 01:43:50 +00:00
										 |  |  |  |     pysqlite_RowType.tp_new = PyType_GenericNew; | 
					
						
							|  |  |  |  |     pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping; | 
					
						
							|  |  |  |  |     return PyType_Ready(&pysqlite_RowType); | 
					
						
							| 
									
										
										
										
											2006-04-01 00:57:31 +00:00
										 |  |  |  | } |