1use std::os::raw::c_int;
2use std::error;
3use std::fmt;
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub enum ErrorCode {
8 InternalMalfunction,
10 PermissionDenied,
12 OperationAborted,
14 DatabaseBusy,
16 DatabaseLocked,
18 OutOfMemory,
20 ReadOnly,
22 OperationInterrupted,
24 SystemIOFailure,
26 DatabaseCorrupt,
28 NotFound,
30 DiskFull,
32 CannotOpen,
34 FileLockingProtocolFailed,
36 SchemaChanged,
38 TooBig,
40 ConstraintViolation,
42 TypeMismatch,
44 APIMisuse,
46 NoLargeFileSupport,
48 AuthorizationForStatementDenied,
50 ParameterOutOfRange,
52 NotADatabase,
54 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
112const SQLITE_NOTICE : c_int = 27;
118const SQLITE_WARNING : c_int = 28;
119
120const 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", 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", 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", 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", 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", 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", _ => "Unknown error code",
250 }
251}