diff options
author | Erlend Egeberg Aasland <erlend.aasland@innova.no> | 2021-08-30 20:32:21 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-30 19:32:21 +0100 |
commit | 86d8b465231473f850cc5e906013ba8581ddb503 (patch) | |
tree | 38821067898cf1fb5fec7b0102e08776ce9df3fe /Modules/_sqlite/module.c | |
parent | f62763d26755260c31c717fb396550e00eb6b2a0 (diff) | |
download | cpython-86d8b465231473f850cc5e906013ba8581ddb503.tar.gz cpython-86d8b465231473f850cc5e906013ba8581ddb503.zip |
bpo-16379: expose SQLite error codes and error names in `sqlite3` (GH-27786)
Diffstat (limited to 'Modules/_sqlite/module.c')
-rw-r--r-- | Modules/_sqlite/module.c | 75 |
1 files changed, 73 insertions, 2 deletions
diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 993e572c5cd..47b1f7a9d07 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -282,12 +282,79 @@ static PyMethodDef module_methods[] = { {NULL, NULL} }; +/* SQLite API error codes */ +static const struct { + const char *name; + long value; +} error_codes[] = { +#define DECLARE_ERROR_CODE(code) {#code, code} + // Primary result code list + DECLARE_ERROR_CODE(SQLITE_ABORT), + DECLARE_ERROR_CODE(SQLITE_AUTH), + DECLARE_ERROR_CODE(SQLITE_BUSY), + DECLARE_ERROR_CODE(SQLITE_CANTOPEN), + DECLARE_ERROR_CODE(SQLITE_CONSTRAINT), + DECLARE_ERROR_CODE(SQLITE_CORRUPT), + DECLARE_ERROR_CODE(SQLITE_DONE), + DECLARE_ERROR_CODE(SQLITE_EMPTY), + DECLARE_ERROR_CODE(SQLITE_ERROR), + DECLARE_ERROR_CODE(SQLITE_FORMAT), + DECLARE_ERROR_CODE(SQLITE_FULL), + DECLARE_ERROR_CODE(SQLITE_INTERNAL), + DECLARE_ERROR_CODE(SQLITE_INTERRUPT), + DECLARE_ERROR_CODE(SQLITE_IOERR), + DECLARE_ERROR_CODE(SQLITE_LOCKED), + DECLARE_ERROR_CODE(SQLITE_MISMATCH), + DECLARE_ERROR_CODE(SQLITE_MISUSE), + DECLARE_ERROR_CODE(SQLITE_NOLFS), + DECLARE_ERROR_CODE(SQLITE_NOMEM), + DECLARE_ERROR_CODE(SQLITE_NOTADB), + DECLARE_ERROR_CODE(SQLITE_NOTFOUND), + DECLARE_ERROR_CODE(SQLITE_OK), + DECLARE_ERROR_CODE(SQLITE_PERM), + DECLARE_ERROR_CODE(SQLITE_PROTOCOL), + DECLARE_ERROR_CODE(SQLITE_READONLY), + DECLARE_ERROR_CODE(SQLITE_ROW), + DECLARE_ERROR_CODE(SQLITE_SCHEMA), + DECLARE_ERROR_CODE(SQLITE_TOOBIG), +#if SQLITE_VERSION_NUMBER >= 3007017 + DECLARE_ERROR_CODE(SQLITE_NOTICE), + DECLARE_ERROR_CODE(SQLITE_WARNING), +#endif +#undef DECLARE_ERROR_CODE + {NULL, 0}, +}; + +static int +add_error_constants(PyObject *module) +{ + for (int i = 0; error_codes[i].name != NULL; i++) { + const char *name = error_codes[i].name; + const long value = error_codes[i].value; + if (PyModule_AddIntConstant(module, name, value) < 0) { + return -1; + } + } + return 0; +} + +const char * +pysqlite_error_name(int rc) +{ + for (int i = 0; error_codes[i].name != NULL; i++) { + if (error_codes[i].value == rc) { + return error_codes[i].name; + } + } + // No error code matched. + return NULL; +} + static int add_integer_constants(PyObject *module) { int ret = 0; ret += PyModule_AddIntMacro(module, PARSE_DECLTYPES); ret += PyModule_AddIntMacro(module, PARSE_COLNAMES); - ret += PyModule_AddIntMacro(module, SQLITE_OK); ret += PyModule_AddIntMacro(module, SQLITE_DENY); ret += PyModule_AddIntMacro(module, SQLITE_IGNORE); ret += PyModule_AddIntMacro(module, SQLITE_CREATE_INDEX); @@ -325,7 +392,6 @@ static int add_integer_constants(PyObject *module) { #if SQLITE_VERSION_NUMBER >= 3008003 ret += PyModule_AddIntMacro(module, SQLITE_RECURSIVE); #endif - ret += PyModule_AddIntMacro(module, SQLITE_DONE); return ret; } @@ -406,6 +472,11 @@ PyMODINIT_FUNC PyInit__sqlite3(void) ADD_EXCEPTION(module, state, DataError, state->DatabaseError); ADD_EXCEPTION(module, state, NotSupportedError, state->DatabaseError); + /* Set error constants */ + if (add_error_constants(module) < 0) { + goto error; + } + /* Set integer constants */ if (add_integer_constants(module) < 0) { goto error; |