Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
allendowney
GitHub Repository: allendowney/cpython
Path: blob/main/Modules/_sqlite/util.c
12 views
1
/* util.c - various utility functions
2
*
3
* Copyright (C) 2005-2010 Gerhard Häring <[email protected]>
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 "module.h"
25
#include "connection.h"
26
27
// Returns non-NULL if a new exception should be raised
28
static PyObject *
29
get_exception_class(pysqlite_state *state, int errorcode)
30
{
31
switch (errorcode) {
32
case SQLITE_OK:
33
PyErr_Clear();
34
return NULL;
35
case SQLITE_INTERNAL:
36
case SQLITE_NOTFOUND:
37
return state->InternalError;
38
case SQLITE_NOMEM:
39
return PyErr_NoMemory();
40
case SQLITE_ERROR:
41
case SQLITE_PERM:
42
case SQLITE_ABORT:
43
case SQLITE_BUSY:
44
case SQLITE_LOCKED:
45
case SQLITE_READONLY:
46
case SQLITE_INTERRUPT:
47
case SQLITE_IOERR:
48
case SQLITE_FULL:
49
case SQLITE_CANTOPEN:
50
case SQLITE_PROTOCOL:
51
case SQLITE_EMPTY:
52
case SQLITE_SCHEMA:
53
return state->OperationalError;
54
case SQLITE_CORRUPT:
55
return state->DatabaseError;
56
case SQLITE_TOOBIG:
57
return state->DataError;
58
case SQLITE_CONSTRAINT:
59
case SQLITE_MISMATCH:
60
return state->IntegrityError;
61
case SQLITE_MISUSE:
62
case SQLITE_RANGE:
63
return state->InterfaceError;
64
default:
65
return state->DatabaseError;
66
}
67
}
68
69
static void
70
raise_exception(PyObject *type, int errcode, const char *errmsg)
71
{
72
PyObject *exc = NULL;
73
PyObject *args[] = { PyUnicode_FromString(errmsg), };
74
if (args[0] == NULL) {
75
goto exit;
76
}
77
exc = PyObject_Vectorcall(type, args, 1, NULL);
78
Py_DECREF(args[0]);
79
if (exc == NULL) {
80
goto exit;
81
}
82
83
PyObject *code = PyLong_FromLong(errcode);
84
if (code == NULL) {
85
goto exit;
86
}
87
int rc = PyObject_SetAttrString(exc, "sqlite_errorcode", code);
88
Py_DECREF(code);
89
if (rc < 0) {
90
goto exit;
91
}
92
93
const char *error_name = pysqlite_error_name(errcode);
94
PyObject *name;
95
if (error_name) {
96
name = PyUnicode_FromString(error_name);
97
}
98
else {
99
name = PyUnicode_InternFromString("unknown");
100
}
101
if (name == NULL) {
102
goto exit;
103
}
104
rc = PyObject_SetAttrString(exc, "sqlite_errorname", name);
105
Py_DECREF(name);
106
if (rc < 0) {
107
goto exit;
108
}
109
110
PyErr_SetObject(type, exc);
111
112
exit:
113
Py_XDECREF(exc);
114
}
115
116
/**
117
* Checks the SQLite error code and sets the appropriate DB-API exception.
118
* Returns the error code (0 means no error occurred).
119
*/
120
int
121
_pysqlite_seterror(pysqlite_state *state, sqlite3 *db)
122
{
123
int errorcode = sqlite3_errcode(db);
124
PyObject *exc_class = get_exception_class(state, errorcode);
125
if (exc_class == NULL) {
126
// No new exception need be raised; just pass the error code
127
return errorcode;
128
}
129
130
/* Create and set the exception. */
131
int extended_errcode = sqlite3_extended_errcode(db);
132
const char *errmsg = sqlite3_errmsg(db);
133
raise_exception(exc_class, extended_errcode, errmsg);
134
return extended_errcode;
135
}
136
137
#ifdef WORDS_BIGENDIAN
138
# define IS_LITTLE_ENDIAN 0
139
#else
140
# define IS_LITTLE_ENDIAN 1
141
#endif
142
143
sqlite_int64
144
_pysqlite_long_as_int64(PyObject * py_val)
145
{
146
int overflow;
147
long long value = PyLong_AsLongLongAndOverflow(py_val, &overflow);
148
if (value == -1 && PyErr_Occurred())
149
return -1;
150
if (!overflow) {
151
# if SIZEOF_LONG_LONG > 8
152
if (-0x8000000000000000LL <= value && value <= 0x7FFFFFFFFFFFFFFFLL)
153
# endif
154
return value;
155
}
156
else if (sizeof(value) < sizeof(sqlite_int64)) {
157
sqlite_int64 int64val;
158
if (_PyLong_AsByteArray((PyLongObject *)py_val,
159
(unsigned char *)&int64val, sizeof(int64val),
160
IS_LITTLE_ENDIAN, 1 /* signed */) >= 0) {
161
return int64val;
162
}
163
}
164
PyErr_SetString(PyExc_OverflowError,
165
"Python int too large to convert to SQLite INTEGER");
166
return -1;
167
}
168
169