/Users/erlendaasland/src/cpython.git/Modules/_sqlite/util.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* util.c - various utility functions |
2 | | * |
3 | | * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> |
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 | 112 | { |
31 | 112 | switch (errorcode) { |
32 | 13 | case SQLITE_OK: |
33 | 13 | PyErr_Clear(); |
34 | 13 | return NULL; |
35 | 0 | case SQLITE_INTERNAL: |
36 | 0 | case SQLITE_NOTFOUND: |
37 | 0 | return state->InternalError; |
38 | 2 | case SQLITE_NOMEM: |
39 | 2 | return PyErr_NoMemory(); |
40 | 50 | case SQLITE_ERROR: |
41 | 50 | case SQLITE_PERM: |
42 | 53 | case SQLITE_ABORT: |
43 | 56 | case SQLITE_BUSY: |
44 | 56 | case SQLITE_LOCKED: |
45 | 58 | case SQLITE_READONLY: |
46 | 63 | case SQLITE_INTERRUPT: |
47 | 63 | case SQLITE_IOERR: |
48 | 63 | case SQLITE_FULL: |
49 | 67 | case SQLITE_CANTOPEN: |
50 | 67 | case SQLITE_PROTOCOL: |
51 | 67 | case SQLITE_EMPTY: |
52 | 67 | case SQLITE_SCHEMA: |
53 | 67 | return state->OperationalError; |
54 | 0 | case SQLITE_CORRUPT: |
55 | 0 | return state->DatabaseError; |
56 | 9 | case SQLITE_TOOBIG: |
57 | 9 | return state->DataError; |
58 | 10 | case SQLITE_CONSTRAINT: |
59 | 10 | case SQLITE_MISMATCH: |
60 | 10 | return state->IntegrityError; |
61 | 0 | case SQLITE_MISUSE: |
62 | 0 | case SQLITE_RANGE: |
63 | 0 | return state->InterfaceError; |
64 | 11 | default: |
65 | 11 | return state->DatabaseError; |
66 | 112 | } |
67 | 112 | } |
68 | | |
69 | | static void |
70 | | raise_exception(PyObject *type, int errcode, const char *errmsg) |
71 | 97 | { |
72 | 97 | PyObject *exc = NULL; |
73 | 97 | PyObject *args[] = { PyUnicode_FromString(errmsg), }; |
74 | 97 | if (args[0] == NULL) { |
75 | 0 | goto exit; |
76 | 0 | } |
77 | 97 | exc = PyObject_Vectorcall(type, args, 1, NULL); |
78 | 97 | Py_DECREF(args[0]); |
79 | 97 | if (exc == NULL) { |
80 | 0 | goto exit; |
81 | 0 | } |
82 | | |
83 | 97 | PyObject *code = PyLong_FromLong(errcode); |
84 | 97 | if (code == NULL) { |
85 | 0 | goto exit; |
86 | 0 | } |
87 | 97 | int rc = PyObject_SetAttrString(exc, "sqlite_errorcode", code); |
88 | 97 | Py_DECREF(code); |
89 | 97 | if (rc < 0) { |
90 | 0 | goto exit; |
91 | 0 | } |
92 | | |
93 | 97 | const char *error_name = pysqlite_error_name(errcode); |
94 | 97 | PyObject *name; |
95 | 97 | if (error_name) { |
96 | 97 | name = PyUnicode_FromString(error_name); |
97 | 97 | } |
98 | 0 | else { |
99 | 0 | name = PyUnicode_InternFromString("unknown"); |
100 | 0 | } |
101 | 97 | if (name == NULL) { |
102 | 0 | goto exit; |
103 | 0 | } |
104 | 97 | rc = PyObject_SetAttrString(exc, "sqlite_errorname", name); |
105 | 97 | Py_DECREF(name); |
106 | 97 | if (rc < 0) { |
107 | 0 | goto exit; |
108 | 0 | } |
109 | | |
110 | 97 | PyErr_SetObject(type, exc); |
111 | | |
112 | 97 | exit: |
113 | 97 | Py_XDECREF(exc); |
114 | 97 | } |
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 | 112 | { |
123 | 112 | int errorcode = sqlite3_errcode(db); |
124 | 112 | PyObject *exc_class = get_exception_class(state, errorcode); |
125 | 112 | if (exc_class == NULL) { |
126 | | // No new exception need be raised; just pass the error code |
127 | 15 | return errorcode; |
128 | 15 | } |
129 | | |
130 | | /* Create and set the exception. */ |
131 | 97 | int extended_errcode = sqlite3_extended_errcode(db); |
132 | 97 | const char *errmsg = sqlite3_errmsg(db); |
133 | 97 | raise_exception(exc_class, extended_errcode, errmsg); |
134 | 97 | return extended_errcode; |
135 | 112 | } |
136 | | |
137 | | #ifdef WORDS_BIGENDIAN |
138 | | # define IS_LITTLE_ENDIAN 0 |
139 | | #else |
140 | 0 | # define IS_LITTLE_ENDIAN 1 |
141 | | #endif |
142 | | |
143 | | sqlite_int64 |
144 | | _pysqlite_long_as_int64(PyObject * py_val) |
145 | 367 | { |
146 | 367 | int overflow; |
147 | 367 | long long value = PyLong_AsLongLongAndOverflow(py_val, &overflow); |
148 | 367 | if (value == -1 && PyErr_Occurred()) |
149 | 0 | return -1; |
150 | 367 | if (!overflow) { |
151 | | # if SIZEOF_LONG_LONG > 8 |
152 | | if (-0x8000000000000000LL <= value && value <= 0x7FFFFFFFFFFFFFFFLL) |
153 | | # endif |
154 | 356 | return value; |
155 | 356 | } |
156 | 11 | else if (sizeof(value) < sizeof(sqlite_int64)) { |
157 | 0 | sqlite_int64 int64val; |
158 | 0 | if (_PyLong_AsByteArray((PyLongObject *)py_val, |
159 | 0 | (unsigned char *)&int64val, sizeof(int64val), |
160 | 0 | IS_LITTLE_ENDIAN, 1 /* signed */) >= 0) { |
161 | 0 | return int64val; |
162 | 0 | } |
163 | 0 | } |
164 | 11 | PyErr_SetString(PyExc_OverflowError, |
165 | 11 | "Python int too large to convert to SQLite INTEGER"); |
166 | 11 | return -1; |
167 | 367 | } |