libsqlcipher_sys/
error.rs

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