Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(4)

Delta Between Two Patch Sets: Modules/_sqlite/row.c

Issue 13583: sqlite3.Row doesn't support slice indexes
Left Patch Set: Created 5 years, 11 months ago
Right Patch Set: Created 5 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/sqlite3/test/factory.py ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* row.c - an enhanced tuple for database rows 1 /* row.c - an enhanced tuple for database rows
2 * 2 *
3 * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> 3 * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
4 * 4 *
5 * This file is part of pysqlite. 5 * This file is part of pysqlite.
6 * 6 *
7 * This software is provided 'as-is', without any express or implied 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 8 * warranty. In no event will the authors be held liable for any damages
9 * arising from the use of this software. 9 * arising from the use of this software.
10 * 10 *
(...skipping 14 matching lines...) Expand all
25 #include "cursor.h" 25 #include "cursor.h"
26 26
27 void pysqlite_row_dealloc(pysqlite_Row* self) 27 void pysqlite_row_dealloc(pysqlite_Row* self)
28 { 28 {
29 Py_XDECREF(self->data); 29 Py_XDECREF(self->data);
30 Py_XDECREF(self->description); 30 Py_XDECREF(self->description);
31 31
32 Py_TYPE(self)->tp_free((PyObject*)self); 32 Py_TYPE(self)->tp_free((PyObject*)self);
33 } 33 }
34 34
35 int pysqlite_row_init(pysqlite_Row* self, PyObject* args, PyObject* kwargs) 35 static PyObject *
36 { 36 pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
37 {
38 pysqlite_Row *self;
37 PyObject* data; 39 PyObject* data;
38 pysqlite_Cursor* cursor; 40 pysqlite_Cursor* cursor;
39 41
40 self->data = 0; 42 assert(type != NULL && type->tp_alloc != NULL);
41 self->description = 0; 43
42 44 if (!_PyArg_NoKeywords("Row()", kwargs))
43 if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) { 45 return NULL;
44 return -1; 46 if (!PyArg_ParseTuple(args, "OO", &cursor, &data))
45 } 47 return NULL;
46 48
47 if (!PyObject_IsInstance((PyObject*)cursor, (PyObject*)&pysqlite_CursorType) ) { 49 if (!PyObject_IsInstance((PyObject*)cursor, (PyObject*)&pysqlite_CursorType) ) {
48 PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument"); 50 PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument");
49 return -1; 51 return NULL;
50 } 52 }
51 53
52 if (!PyTuple_Check(data)) { 54 if (!PyTuple_Check(data)) {
53 PyErr_SetString(PyExc_TypeError, "tuple required for second argument"); 55 PyErr_SetString(PyExc_TypeError, "tuple required for second argument");
54 return -1; 56 return NULL;
55 } 57 }
58
59 self = (pysqlite_Row *) type->tp_alloc(type, 0);
60 if (self == NULL)
61 return NULL;
56 62
57 Py_INCREF(data); 63 Py_INCREF(data);
58 self->data = data; 64 self->data = data;
59 65
60 Py_INCREF(cursor->description); 66 Py_INCREF(cursor->description);
61 self->description = cursor->description; 67 self->description = cursor->description;
62 68
63 return 0; 69 return (PyObject *) self;
70 }
71
72 PyObject* pysqlite_row_item(pysqlite_Row* self, Py_ssize_t idx)
73 {
74 PyObject* item = PyTuple_GetItem(self->data, idx);
75 Py_XINCREF(item);
76 return item;
64 } 77 }
65 78
66 PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) 79 PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx)
67 { 80 {
68 long _idx; 81 Py_ssize_t _idx;
69 char* key; 82 char* key;
70 Py_ssize_t nitems, i; 83 Py_ssize_t nitems, i;
71 char* compare_key; 84 char* compare_key;
72 85
73 char* p1; 86 char* p1;
74 char* p2; 87 char* p2;
75 88
76 PyObject* item; 89 PyObject* item;
77 90
78 if (PyLong_Check(idx)) { 91 if (PyLong_Check(idx)) {
79 _idx = PyLong_AsLong(idx); 92 _idx = PyNumber_AsSsize_t(idx, PyExc_IndexError);
93 if (_idx == -1 && PyErr_Occurred())
94 return NULL;
95 if (_idx < 0)
96 _idx += PyTuple_GET_SIZE(self->data);
80 item = PyTuple_GetItem(self->data, _idx); 97 item = PyTuple_GetItem(self->data, _idx);
81 Py_XINCREF(item); 98 Py_XINCREF(item);
82 return item; 99 return item;
83 } else if (PyUnicode_Check(idx)) { 100 } else if (PyUnicode_Check(idx)) {
84 key = _PyUnicode_AsString(idx); 101 key = _PyUnicode_AsString(idx);
85 if (key == NULL) 102 if (key == NULL)
86 return NULL; 103 return NULL;
87 104
88 nitems = PyTuple_Size(self->description); 105 nitems = PyTuple_Size(self->description);
89 106
(...skipping 28 matching lines...) Expand all
118 Py_INCREF(item); 135 Py_INCREF(item);
119 return item; 136 return item;
120 } 137 }
121 138
122 } 139 }
123 140
124 PyErr_SetString(PyExc_IndexError, "No item with that key"); 141 PyErr_SetString(PyExc_IndexError, "No item with that key");
125 return NULL; 142 return NULL;
126 } 143 }
127 else if (PySlice_Check(idx)) { 144 else if (PySlice_Check(idx)) {
128 Py_ssize_t start, stop, step, slicelength, cur, i; 145 return PyObject_GetItem(self->data, idx);
129 PyObject* result;
130 PyObject* it;
131 PyObject **src, **dest;
132 if (PySlice_GetIndicesEx((PyObject *)idx,
133 PyTuple_GET_SIZE(self->data),
134 &start, &stop, &step, &slicelength) < 0) {
135 return NULL;
136 }
137
138 if (step == 1) {
139 return PyTuple_GetSlice(self->data, start, stop);
140 }
141 else {
142 result = PyTuple_New(slicelength);
143 if (!result) return NULL;
144
145 src = ((PyTupleObject *)self->data)->ob_item;
146 dest = ((PyTupleObject *)result)->ob_item;
147 for (cur = start, i = 0; i < slicelength;
148 cur += step, i++) {
149 it = src[cur];
AntoinePitrou 2014/04/28 13:26:54 Why not simply use PyTuple_SET_ITEM and PyTuple_GE
150 Py_INCREF(it);
151 dest[i] = it;
152 }
153
154 return result;
155 }
156 } 146 }
157 else { 147 else {
158 PyErr_SetString(PyExc_IndexError, "Index must be int or string"); 148 PyErr_SetString(PyExc_IndexError, "Index must be int or string");
159 return NULL; 149 return NULL;
160 } 150 }
161 } 151 }
162 152
163 Py_ssize_t pysqlite_row_length(pysqlite_Row* self, PyObject* args, PyObject* kwa rgs) 153 Py_ssize_t pysqlite_row_length(pysqlite_Row* self, PyObject* args, PyObject* kwa rgs)
164 { 154 {
165 return PyTuple_GET_SIZE(self->data); 155 return PyTuple_GET_SIZE(self->data);
166 } 156 }
167 157
168 PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject* args, PyObject* kwargs ) 158 PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject* args, PyObject* kwargs )
169 { 159 {
170 PyObject* list; 160 PyObject* list;
171 int nitems, i; 161 Py_ssize_t nitems, i;
172 162
173 list = PyList_New(0); 163 list = PyList_New(0);
174 if (!list) { 164 if (!list) {
175 return NULL; 165 return NULL;
176 } 166 }
177 nitems = PyTuple_Size(self->description); 167 nitems = PyTuple_Size(self->description);
178 168
179 for (i = 0; i < nitems; i++) { 169 for (i = 0; i < nitems; i++) {
180 if (PyList_Append(list, PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->descript ion, i), 0)) != 0) { 170 if (PyList_Append(list, PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->descript ion, i), 0)) != 0) {
181 Py_DECREF(list); 171 Py_DECREF(list);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 } 206 }
217 } 207 }
218 Py_RETURN_NOTIMPLEMENTED; 208 Py_RETURN_NOTIMPLEMENTED;
219 } 209 }
220 210
221 PyMappingMethods pysqlite_row_as_mapping = { 211 PyMappingMethods pysqlite_row_as_mapping = {
222 /* mp_length */ (lenfunc)pysqlite_row_length, 212 /* mp_length */ (lenfunc)pysqlite_row_length,
223 /* mp_subscript */ (binaryfunc)pysqlite_row_subscript, 213 /* mp_subscript */ (binaryfunc)pysqlite_row_subscript,
224 /* mp_ass_subscript */ (objobjargproc)0, 214 /* mp_ass_subscript */ (objobjargproc)0,
225 }; 215 };
216
217 static PySequenceMethods pysqlite_row_as_sequence = {
218 /* sq_length */ (lenfunc)pysqlite_row_length,
219 /* sq_concat */ 0,
220 /* sq_repeat */ 0,
221 /* sq_item */ (ssizeargfunc)pysqlite_row_item,
222 };
223
226 224
227 static PyMethodDef pysqlite_row_methods[] = { 225 static PyMethodDef pysqlite_row_methods[] = {
228 {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS, 226 {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS,
229 PyDoc_STR("Returns the keys of the row.")}, 227 PyDoc_STR("Returns the keys of the row.")},
230 {NULL, NULL} 228 {NULL, NULL}
231 }; 229 };
232 230
233 231
234 PyTypeObject pysqlite_RowType = { 232 PyTypeObject pysqlite_RowType = {
235 PyVarObject_HEAD_INIT(NULL, 0) 233 PyVarObject_HEAD_INIT(NULL, 0)
(...skipping 24 matching lines...) Expand all
260 (getiterfunc)pysqlite_iter, /* tp_iter */ 258 (getiterfunc)pysqlite_iter, /* tp_iter */
261 0, /* tp_iternext */ 259 0, /* tp_iternext */
262 pysqlite_row_methods, /* tp_methods */ 260 pysqlite_row_methods, /* tp_methods */
263 0, /* tp_members */ 261 0, /* tp_members */
264 0, /* tp_getset */ 262 0, /* tp_getset */
265 0, /* tp_base */ 263 0, /* tp_base */
266 0, /* tp_dict */ 264 0, /* tp_dict */
267 0, /* tp_descr_get */ 265 0, /* tp_descr_get */
268 0, /* tp_descr_set */ 266 0, /* tp_descr_set */
269 0, /* tp_dictoffset */ 267 0, /* tp_dictoffset */
270 (initproc)pysqlite_row_init, /* tp_init */ 268 0, /* tp_init */
271 0, /* tp_alloc */ 269 0, /* tp_alloc */
272 0, /* tp_new */ 270 0, /* tp_new */
273 0 /* tp_free */ 271 0 /* tp_free */
274 }; 272 };
275 273
276 extern int pysqlite_row_setup_types(void) 274 extern int pysqlite_row_setup_types(void)
277 { 275 {
278 pysqlite_RowType.tp_new = PyType_GenericNew; 276 pysqlite_RowType.tp_new = pysqlite_row_new;
279 pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping; 277 pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping;
278 pysqlite_RowType.tp_as_sequence = &pysqlite_row_as_sequence;
280 return PyType_Ready(&pysqlite_RowType); 279 return PyType_Ready(&pysqlite_RowType);
281 } 280 }
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+