|
43 | 43 |
|
44 | 44 | _Py_IDENTIFIER(cursor); |
45 | 45 |
|
| 46 | +static const char * const begin_statements[] = { |
| 47 | + "BEGIN ", |
| 48 | + "BEGIN DEFERRED", |
| 49 | + "BEGIN IMMEDIATE", |
| 50 | + "BEGIN EXCLUSIVE", |
| 51 | + NULL |
| 52 | +}; |
| 53 | + |
46 | 54 | static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level); |
47 | 55 | static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self); |
48 | 56 |
|
@@ -258,9 +266,6 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self) |
258 | 266 | Py_END_ALLOW_THREADS |
259 | 267 | } |
260 | 268 |
|
261 | | - if (self->begin_statement) { |
262 | | - PyMem_Free(self->begin_statement); |
263 | | - } |
264 | 269 | Py_XDECREF(self->isolation_level); |
265 | 270 | Py_XDECREF(self->function_pinboard); |
266 | 271 | Py_XDECREF(self->row_factory); |
@@ -1175,59 +1180,48 @@ static PyObject* pysqlite_connection_get_total_changes(pysqlite_Connection* self |
1175 | 1180 |
|
1176 | 1181 | static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level) |
1177 | 1182 | { |
1178 | | - PyObject* res; |
1179 | | - PyObject* begin_statement; |
1180 | | - static PyObject* begin_word; |
1181 | | - |
1182 | | - Py_XDECREF(self->isolation_level); |
1183 | | - |
1184 | | - if (self->begin_statement) { |
1185 | | - PyMem_Free(self->begin_statement); |
1186 | | - self->begin_statement = NULL; |
1187 | | - } |
1188 | | - |
1189 | 1183 | if (isolation_level == Py_None) { |
1190 | | - Py_INCREF(Py_None); |
1191 | | - self->isolation_level = Py_None; |
1192 | | - |
1193 | | - res = pysqlite_connection_commit(self, NULL); |
| 1184 | + PyObject *res = pysqlite_connection_commit(self, NULL); |
1194 | 1185 | if (!res) { |
1195 | 1186 | return -1; |
1196 | 1187 | } |
1197 | 1188 | Py_DECREF(res); |
1198 | 1189 |
|
| 1190 | + self->begin_statement = NULL; |
1199 | 1191 | self->inTransaction = 0; |
1200 | 1192 | } else { |
1201 | | - const char *statement; |
1202 | | - Py_ssize_t size; |
1203 | | - |
1204 | | - Py_INCREF(isolation_level); |
1205 | | - self->isolation_level = isolation_level; |
1206 | | - |
1207 | | - if (!begin_word) { |
1208 | | - begin_word = PyUnicode_FromString("BEGIN "); |
1209 | | - if (!begin_word) return -1; |
1210 | | - } |
1211 | | - begin_statement = PyUnicode_Concat(begin_word, isolation_level); |
1212 | | - if (!begin_statement) { |
| 1193 | + const char * const *candidate; |
| 1194 | + PyObject *uppercase_level; |
| 1195 | + _Py_IDENTIFIER(upper); |
| 1196 | + |
| 1197 | + if (!PyUnicode_Check(isolation_level)) { |
| 1198 | + PyErr_Format(PyExc_TypeError, |
| 1199 | + "isolation_level must be a string or None, not %.100s", |
| 1200 | + Py_TYPE(isolation_level)->tp_name); |
1213 | 1201 | return -1; |
1214 | 1202 | } |
1215 | 1203 |
|
1216 | | - statement = _PyUnicode_AsStringAndSize(begin_statement, &size); |
1217 | | - if (!statement) { |
1218 | | - Py_DECREF(begin_statement); |
| 1204 | + uppercase_level = _PyObject_CallMethodIdObjArgs( |
| 1205 | + (PyObject *)&PyUnicode_Type, &PyId_upper, |
| 1206 | + isolation_level, NULL); |
| 1207 | + if (!uppercase_level) { |
1219 | 1208 | return -1; |
1220 | 1209 | } |
1221 | | - self->begin_statement = PyMem_Malloc(size + 2); |
1222 | | - if (!self->begin_statement) { |
1223 | | - Py_DECREF(begin_statement); |
| 1210 | + for (candidate = begin_statements; *candidate; candidate++) { |
| 1211 | + if (!PyUnicode_CompareWithASCIIString(uppercase_level, *candidate + 6)) |
| 1212 | + break; |
| 1213 | + } |
| 1214 | + Py_DECREF(uppercase_level); |
| 1215 | + if (!*candidate) { |
| 1216 | + PyErr_SetString(PyExc_ValueError, |
| 1217 | + "invalid value for isolation_level"); |
1224 | 1218 | return -1; |
1225 | 1219 | } |
1226 | | - |
1227 | | - strcpy(self->begin_statement, statement); |
1228 | | - Py_DECREF(begin_statement); |
| 1220 | + self->begin_statement = *candidate; |
1229 | 1221 | } |
1230 | 1222 |
|
| 1223 | + Py_INCREF(isolation_level); |
| 1224 | + Py_XSETREF(self->isolation_level, isolation_level); |
1231 | 1225 | return 0; |
1232 | 1226 | } |
1233 | 1227 |
|
|
0 commit comments