libsqlite3_sys_le/
error.rs

1use std::error;
2use std::fmt;
3use std::os::raw::c_int;
4
5/// Error Codes
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7#[non_exhaustive]
8pub enum ErrorCode {
9    /// Internal logic error in SQLite
10    InternalMalfunction,
11    /// Access permission denied
12    PermissionDenied,
13    /// Callback routine requested an abort
14    OperationAborted,
15    /// The database file is locked
16    DatabaseBusy,
17    /// A table in the database is locked
18    DatabaseLocked,
19    /// A malloc() failed
20    OutOfMemory,
21    /// Attempt to write a readonly database
22    ReadOnly,
23    /// Operation terminated by sqlite3_interrupt()
24    OperationInterrupted,
25    /// Some kind of disk I/O error occurred
26    SystemIOFailure,
27    /// The database disk image is malformed
28    DatabaseCorrupt,
29    /// Unknown opcode in sqlite3_file_control()
30    NotFound,
31    /// Insertion failed because database is full
32    DiskFull,
33    /// Unable to open the database file
34    CannotOpen,
35    /// Database lock protocol error
36    FileLockingProtocolFailed,
37    /// The database schema changed
38    SchemaChanged,
39    /// String or BLOB exceeds size limit
40    TooBig,
41    /// Abort due to constraint violation
42    ConstraintViolation,
43    /// Data type mismatch
44    TypeMismatch,
45    /// Library used incorrectly
46    APIMisuse,
47    /// Uses OS features not supported on host
48    NoLargeFileSupport,
49    /// Authorization denied
50    AuthorizationForStatementDenied,
51    /// 2nd parameter to sqlite3_bind out of range
52    ParameterOutOfRange,
53    /// File opened that is not a database file
54    NotADatabase,
55    /// SQL error or missing database
56    Unknown,
57}
58
59#[derive(Clone, Copy, Debug, PartialEq, Eq)]
60pub struct Error {
61    pub code: ErrorCode,
62    pub extended_code: c_int,
63}
64
65impl Error {
66    pub fn new(result_code: c_int) -> Error {
67        let code = match result_code & 0xff {
68            super::SQLITE_INTERNAL => ErrorCode::InternalMalfunction,
69            super::SQLITE_PERM => ErrorCode::PermissionDenied,
70            super::SQLITE_ABORT => ErrorCode::OperationAborted,
71            super::SQLITE_BUSY => ErrorCode::DatabaseBusy,
72            super::SQLITE_LOCKED => ErrorCode::DatabaseLocked,
73            super::SQLITE_NOMEM => ErrorCode::OutOfMemory,
74            super::SQLITE_READONLY => ErrorCode::ReadOnly,
75            super::SQLITE_INTERRUPT => ErrorCode::OperationInterrupted,
76            super::SQLITE_IOERR => ErrorCode::SystemIOFailure,
77            super::SQLITE_CORRUPT => ErrorCode::DatabaseCorrupt,
78            super::SQLITE_NOTFOUND => ErrorCode::NotFound,
79            super::SQLITE_FULL => ErrorCode::DiskFull,
80            super::SQLITE_CANTOPEN => ErrorCode::CannotOpen,
81            super::SQLITE_PROTOCOL => ErrorCode::FileLockingProtocolFailed,
82            super::SQLITE_SCHEMA => ErrorCode::SchemaChanged,
83            super::SQLITE_TOOBIG => ErrorCode::TooBig,
84            super::SQLITE_CONSTRAINT => ErrorCode::ConstraintViolation,
85            super::SQLITE_MISMATCH => ErrorCode::TypeMismatch,
86            super::SQLITE_MISUSE => ErrorCode::APIMisuse,
87            super::SQLITE_NOLFS => ErrorCode::NoLargeFileSupport,
88            super::SQLITE_AUTH => ErrorCode::AuthorizationForStatementDenied,
89            super::SQLITE_RANGE => ErrorCode::ParameterOutOfRange,
90            super::SQLITE_NOTADB => ErrorCode::NotADatabase,
91            _ => ErrorCode::Unknown,
92        };
93
94        Error {
95            code,
96            extended_code: result_code,
97        }
98    }
99}
100
101impl fmt::Display for Error {
102    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103        write!(
104            f,
105            "Error code {}: {}",
106            self.extended_code,
107            code_to_str(self.extended_code)
108        )
109    }
110}
111
112impl error::Error for Error {
113    fn description(&self) -> &str {
114        code_to_str(self.extended_code)
115    }
116}
117
118// Result codes.
119// Note: These are not public because our bindgen bindings export whichever
120// constants are present in the current version of SQLite. We repeat them here
121// so we don't have to worry about which version of SQLite added which
122// constants, and we only use them to implement code_to_str below.
123
124const SQLITE_NOTICE: c_int = 27;
125const SQLITE_WARNING: c_int = 28;
126
127// Extended result codes.
128
129const SQLITE_ERROR_MISSING_COLLSEQ: c_int = super::SQLITE_ERROR | (1 << 8);
130const SQLITE_ERROR_RETRY: c_int = super::SQLITE_ERROR | (2 << 8);
131const SQLITE_ERROR_SNAPSHOT: c_int = super::SQLITE_ERROR | (3 << 8);
132
133const SQLITE_IOERR_SHMOPEN: c_int = super::SQLITE_IOERR | (18 << 8);
134const SQLITE_IOERR_SHMSIZE: c_int = super::SQLITE_IOERR | (19 << 8);
135const SQLITE_IOERR_SHMLOCK: c_int = super::SQLITE_IOERR | (20 << 8);
136const SQLITE_IOERR_SHMMAP: c_int = super::SQLITE_IOERR | (21 << 8);
137const SQLITE_IOERR_SEEK: c_int = super::SQLITE_IOERR | (22 << 8);
138const SQLITE_IOERR_DELETE_NOENT: c_int = super::SQLITE_IOERR | (23 << 8);
139const SQLITE_IOERR_MMAP: c_int = super::SQLITE_IOERR | (24 << 8);
140const SQLITE_IOERR_GETTEMPPATH: c_int = super::SQLITE_IOERR | (25 << 8);
141const SQLITE_IOERR_CONVPATH: c_int = super::SQLITE_IOERR | (26 << 8);
142const SQLITE_IOERR_VNODE: c_int = super::SQLITE_IOERR | (27 << 8);
143const SQLITE_IOERR_AUTH: c_int = super::SQLITE_IOERR | (28 << 8);
144const SQLITE_IOERR_BEGIN_ATOMIC: c_int = super::SQLITE_IOERR | (29 << 8);
145const SQLITE_IOERR_COMMIT_ATOMIC: c_int = super::SQLITE_IOERR | (30 << 8);
146const SQLITE_IOERR_ROLLBACK_ATOMIC: c_int = super::SQLITE_IOERR | (31 << 8);
147const SQLITE_IOERR_DATA: c_int = super::SQLITE_IOERR | (32 << 8);
148
149const SQLITE_LOCKED_SHAREDCACHE: c_int = super::SQLITE_LOCKED | (1 << 8);
150const SQLITE_LOCKED_VTAB: c_int = super::SQLITE_LOCKED | (2 << 8);
151
152const SQLITE_BUSY_RECOVERY: c_int = super::SQLITE_BUSY | (1 << 8);
153const SQLITE_BUSY_SNAPSHOT: c_int = super::SQLITE_BUSY | (2 << 8);
154const SQLITE_BUSY_TIMEOUT: c_int = super::SQLITE_BUSY | (3 << 8);
155
156const SQLITE_CANTOPEN_NOTEMPDIR: c_int = super::SQLITE_CANTOPEN | (1 << 8);
157const SQLITE_CANTOPEN_ISDIR: c_int = super::SQLITE_CANTOPEN | (2 << 8);
158const SQLITE_CANTOPEN_FULLPATH: c_int = super::SQLITE_CANTOPEN | (3 << 8);
159const SQLITE_CANTOPEN_CONVPATH: c_int = super::SQLITE_CANTOPEN | (4 << 8);
160const SQLITE_CANTOPEN_SYMLINK: c_int = super::SQLITE_CANTOPEN | (6 << 8);
161
162const SQLITE_CORRUPT_VTAB: c_int = super::SQLITE_CORRUPT | (1 << 8);
163const SQLITE_CORRUPT_SEQUENCE: c_int = super::SQLITE_CORRUPT | (2 << 8);
164const SQLITE_CORRUPT_INDEX: c_int = super::SQLITE_CORRUPT | (3 << 8);
165
166const SQLITE_READONLY_RECOVERY: c_int = super::SQLITE_READONLY | (1 << 8);
167const SQLITE_READONLY_CANTLOCK: c_int = super::SQLITE_READONLY | (2 << 8);
168const SQLITE_READONLY_ROLLBACK: c_int = super::SQLITE_READONLY | (3 << 8);
169const SQLITE_READONLY_DBMOVED: c_int = super::SQLITE_READONLY | (4 << 8);
170const SQLITE_READONLY_CANTINIT: c_int = super::SQLITE_READONLY | (5 << 8);
171const SQLITE_READONLY_DIRECTORY: c_int = super::SQLITE_READONLY | (6 << 8);
172
173const SQLITE_ABORT_ROLLBACK: c_int = super::SQLITE_ABORT | (2 << 8);
174
175const SQLITE_CONSTRAINT_CHECK: c_int = super::SQLITE_CONSTRAINT | (1 << 8);
176const SQLITE_CONSTRAINT_COMMITHOOK: c_int = super::SQLITE_CONSTRAINT | (2 << 8);
177const SQLITE_CONSTRAINT_FOREIGNKEY: c_int = super::SQLITE_CONSTRAINT | (3 << 8);
178const SQLITE_CONSTRAINT_FUNCTION: c_int = super::SQLITE_CONSTRAINT | (4 << 8);
179const SQLITE_CONSTRAINT_NOTNULL: c_int = super::SQLITE_CONSTRAINT | (5 << 8);
180const SQLITE_CONSTRAINT_PRIMARYKEY: c_int = super::SQLITE_CONSTRAINT | (6 << 8);
181const SQLITE_CONSTRAINT_TRIGGER: c_int = super::SQLITE_CONSTRAINT | (7 << 8);
182const SQLITE_CONSTRAINT_UNIQUE: c_int = super::SQLITE_CONSTRAINT | (8 << 8);
183const SQLITE_CONSTRAINT_VTAB: c_int = super::SQLITE_CONSTRAINT | (9 << 8);
184const SQLITE_CONSTRAINT_ROWID: c_int = super::SQLITE_CONSTRAINT | (10 << 8);
185const SQLITE_CONSTRAINT_PINNED: c_int = super::SQLITE_CONSTRAINT | (11 << 8);
186
187const SQLITE_NOTICE_RECOVER_WAL: c_int = SQLITE_NOTICE | (1 << 8);
188const SQLITE_NOTICE_RECOVER_ROLLBACK: c_int = SQLITE_NOTICE | (2 << 8);
189
190const SQLITE_WARNING_AUTOINDEX: c_int = SQLITE_WARNING | (1 << 8);
191
192const SQLITE_AUTH_USER: c_int = super::SQLITE_AUTH | (1 << 8);
193
194pub fn code_to_str(code: c_int) -> &'static str {
195    match code {
196        super::SQLITE_OK        => "Successful result",
197        super::SQLITE_ERROR     => "SQL error or missing database",
198        super::SQLITE_INTERNAL  => "Internal logic error in SQLite",
199        super::SQLITE_PERM      => "Access permission denied",
200        super::SQLITE_ABORT     => "Callback routine requested an abort",
201        super::SQLITE_BUSY      => "The database file is locked",
202        super::SQLITE_LOCKED    => "A table in the database is locked",
203        super::SQLITE_NOMEM     => "A malloc() failed",
204        super::SQLITE_READONLY  => "Attempt to write a readonly database",
205        super::SQLITE_INTERRUPT => "Operation terminated by sqlite3_interrupt()",
206        super::SQLITE_IOERR     => "Some kind of disk I/O error occurred",
207        super::SQLITE_CORRUPT   => "The database disk image is malformed",
208        super::SQLITE_NOTFOUND  => "Unknown opcode in sqlite3_file_control()",
209        super::SQLITE_FULL      => "Insertion failed because database is full",
210        super::SQLITE_CANTOPEN  => "Unable to open the database file",
211        super::SQLITE_PROTOCOL  => "Database lock protocol error",
212        super::SQLITE_EMPTY     => "Database is empty",
213        super::SQLITE_SCHEMA    => "The database schema changed",
214        super::SQLITE_TOOBIG    => "String or BLOB exceeds size limit",
215        super::SQLITE_CONSTRAINT=> "Abort due to constraint violation",
216        super::SQLITE_MISMATCH  => "Data type mismatch",
217        super::SQLITE_MISUSE    => "Library used incorrectly",
218        super::SQLITE_NOLFS     => "Uses OS features not supported on host",
219        super::SQLITE_AUTH      => "Authorization denied",
220        super::SQLITE_FORMAT    => "Auxiliary database format error",
221        super::SQLITE_RANGE     => "2nd parameter to sqlite3_bind out of range",
222        super::SQLITE_NOTADB    => "File opened that is not a database file",
223        SQLITE_NOTICE    => "Notifications from sqlite3_log()",
224        SQLITE_WARNING   => "Warnings from sqlite3_log()",
225        super::SQLITE_ROW       => "sqlite3_step() has another row ready",
226        super::SQLITE_DONE      => "sqlite3_step() has finished executing",
227
228        SQLITE_ERROR_MISSING_COLLSEQ   => "SQLITE_ERROR_MISSING_COLLSEQ",
229        SQLITE_ERROR_RETRY   => "SQLITE_ERROR_RETRY",
230        SQLITE_ERROR_SNAPSHOT   => "SQLITE_ERROR_SNAPSHOT",
231
232        super::SQLITE_IOERR_READ              => "Error reading from disk",
233        super::SQLITE_IOERR_SHORT_READ        => "Unable to obtain number of requested bytes (file truncated?)",
234        super::SQLITE_IOERR_WRITE             => "Error writing to disk",
235        super::SQLITE_IOERR_FSYNC             => "Error flushing data to persistent storage (fsync)",
236        super::SQLITE_IOERR_DIR_FSYNC         => "Error calling fsync on a directory",
237        super::SQLITE_IOERR_TRUNCATE          => "Error attempting to truncate file",
238        super::SQLITE_IOERR_FSTAT             => "Error invoking fstat to get file metadata",
239        super::SQLITE_IOERR_UNLOCK            => "I/O error within xUnlock of a VFS object",
240        super::SQLITE_IOERR_RDLOCK            => "I/O error within xLock of a VFS object (trying to obtain a read lock)",
241        super::SQLITE_IOERR_DELETE            => "I/O error within xDelete of a VFS object",
242        super::SQLITE_IOERR_BLOCKED           => "SQLITE_IOERR_BLOCKED", // no longer used
243        super::SQLITE_IOERR_NOMEM             => "Out of memory in I/O layer",
244        super::SQLITE_IOERR_ACCESS            => "I/O error within xAccess of a VFS object",
245        super::SQLITE_IOERR_CHECKRESERVEDLOCK => "I/O error within then xCheckReservedLock method",
246        super::SQLITE_IOERR_LOCK              => "I/O error in the advisory file locking layer",
247        super::SQLITE_IOERR_CLOSE             => "I/O error within the xClose method",
248        super::SQLITE_IOERR_DIR_CLOSE         => "SQLITE_IOERR_DIR_CLOSE", // no longer used
249        SQLITE_IOERR_SHMOPEN           => "I/O error within the xShmMap method (trying to open a new shared-memory segment)",
250        SQLITE_IOERR_SHMSIZE           => "I/O error within the xShmMap method (trying to resize an existing shared-memory segment)",
251        SQLITE_IOERR_SHMLOCK           => "SQLITE_IOERR_SHMLOCK", // no longer used
252        SQLITE_IOERR_SHMMAP            => "I/O error within the xShmMap method (trying to map a shared-memory segment into process address space)",
253        SQLITE_IOERR_SEEK              => "I/O error within the xRead or xWrite (trying to seek within a file)",
254        SQLITE_IOERR_DELETE_NOENT      => "File being deleted does not exist",
255        SQLITE_IOERR_MMAP              => "I/O error while trying to map or unmap part of the database file into process address space",
256        SQLITE_IOERR_GETTEMPPATH       => "VFS is unable to determine a suitable directory for temporary files",
257        SQLITE_IOERR_CONVPATH          => "cygwin_conv_path() system call failed",
258        SQLITE_IOERR_VNODE             => "SQLITE_IOERR_VNODE", // not documented?
259        SQLITE_IOERR_AUTH              => "SQLITE_IOERR_AUTH",
260        SQLITE_IOERR_BEGIN_ATOMIC      => "SQLITE_IOERR_BEGIN_ATOMIC",
261        SQLITE_IOERR_COMMIT_ATOMIC     => "SQLITE_IOERR_COMMIT_ATOMIC",
262        SQLITE_IOERR_ROLLBACK_ATOMIC   => "SQLITE_IOERR_ROLLBACK_ATOMIC",
263        SQLITE_IOERR_DATA   => "SQLITE_IOERR_DATA",
264
265        SQLITE_LOCKED_SHAREDCACHE      => "Locking conflict due to another connection with a shared cache",
266        SQLITE_LOCKED_VTAB             => "SQLITE_LOCKED_VTAB",
267
268        SQLITE_BUSY_RECOVERY           => "Another process is recovering a WAL mode database file",
269        SQLITE_BUSY_SNAPSHOT           => "Cannot promote read transaction to write transaction because of writes by another connection",
270        SQLITE_BUSY_TIMEOUT           => "SQLITE_BUSY_TIMEOUT",
271
272        SQLITE_CANTOPEN_NOTEMPDIR      => "SQLITE_CANTOPEN_NOTEMPDIR", // no longer used
273        SQLITE_CANTOPEN_ISDIR          => "Attempted to open directory as file",
274        SQLITE_CANTOPEN_FULLPATH       => "Unable to convert filename into full pathname",
275        SQLITE_CANTOPEN_CONVPATH       => "cygwin_conv_path() system call failed",
276        SQLITE_CANTOPEN_SYMLINK       => "SQLITE_CANTOPEN_SYMLINK",
277
278        SQLITE_CORRUPT_VTAB            => "Content in the virtual table is corrupt",
279        SQLITE_CORRUPT_SEQUENCE        => "SQLITE_CORRUPT_SEQUENCE",
280        SQLITE_CORRUPT_INDEX        => "SQLITE_CORRUPT_INDEX",
281
282        SQLITE_READONLY_RECOVERY       => "WAL mode database file needs recovery (requires write access)",
283        SQLITE_READONLY_CANTLOCK       => "Shared-memory file associated with WAL mode database is read-only",
284        SQLITE_READONLY_ROLLBACK       => "Database has hot journal that must be rolled back (requires write access)",
285        SQLITE_READONLY_DBMOVED        => "Database cannot be modified because database file has moved",
286        SQLITE_READONLY_CANTINIT       => "SQLITE_READONLY_CANTINIT",
287        SQLITE_READONLY_DIRECTORY      => "SQLITE_READONLY_DIRECTORY",
288
289        SQLITE_ABORT_ROLLBACK          => "Transaction was rolled back",
290
291        SQLITE_CONSTRAINT_CHECK        => "A CHECK constraint failed",
292        SQLITE_CONSTRAINT_COMMITHOOK   => "Commit hook caused rollback",
293        SQLITE_CONSTRAINT_FOREIGNKEY   => "Foreign key constraint failed",
294        SQLITE_CONSTRAINT_FUNCTION     => "Error returned from extension function",
295        SQLITE_CONSTRAINT_NOTNULL      => "A NOT NULL constraint failed",
296        SQLITE_CONSTRAINT_PRIMARYKEY   => "A PRIMARY KEY constraint failed",
297        SQLITE_CONSTRAINT_TRIGGER      => "A RAISE function within a trigger fired",
298        SQLITE_CONSTRAINT_UNIQUE       => "A UNIQUE constraint failed",
299        SQLITE_CONSTRAINT_VTAB         => "An application-defined virtual table error occurred",
300        SQLITE_CONSTRAINT_ROWID        => "A non-unique rowid occurred",
301        SQLITE_CONSTRAINT_PINNED        => "SQLITE_CONSTRAINT_PINNED",
302
303        SQLITE_NOTICE_RECOVER_WAL      => "A WAL mode database file was recovered",
304        SQLITE_NOTICE_RECOVER_ROLLBACK => "Hot journal was rolled back",
305
306        SQLITE_WARNING_AUTOINDEX       => "Automatic indexing used - database might benefit from additional indexes",
307
308        SQLITE_AUTH_USER               => "SQLITE_AUTH_USER", // not documented?
309
310        _ => "Unknown error code",
311    }
312}