sqlint/connector/sqlite/
error.rs1use crate::error::*;
2use libsqlite3_sys as ffi;
3use rusqlite::types::FromSqlError;
4
5impl From<rusqlite::Error> for Error {
6 fn from(e: rusqlite::Error) -> Error {
7 match e {
8 rusqlite::Error::ToSqlConversionFailure(error) => match error.downcast::<Error>() {
9 Ok(error) => *error,
10 Err(error) => {
11 let mut builder = Error::builder(ErrorKind::QueryError(error));
12
13 builder.set_original_message("Could not interpret parameters in an SQLite query.");
14
15 builder.build()
16 }
17 },
18 rusqlite::Error::InvalidQuery => {
19 let mut builder = Error::builder(ErrorKind::QueryError(e.into()));
20
21 builder.set_original_message(
22 "Could not interpret the query or its parameters. Check the syntax and parameter types.",
23 );
24
25 builder.build()
26 }
27 rusqlite::Error::ExecuteReturnedResults => {
28 let mut builder = Error::builder(ErrorKind::QueryError(e.into()));
29 builder.set_original_message("Execute returned results, which is not allowed in SQLite.");
30
31 builder.build()
32 }
33
34 rusqlite::Error::QueryReturnedNoRows => Error::builder(ErrorKind::NotFound).build(),
35
36 rusqlite::Error::SqliteFailure(
37 ffi::Error { code: ffi::ErrorCode::ConstraintViolation, extended_code: 2067 },
38 Some(description),
39 ) => {
40 let constraint = description
41 .split(": ")
42 .nth(1)
43 .map(|s| s.split(", "))
44 .map(|i| i.flat_map(|s| s.split('.').last()))
45 .map(DatabaseConstraint::fields)
46 .unwrap_or(DatabaseConstraint::CannotParse);
47
48 let kind = ErrorKind::UniqueConstraintViolation { constraint };
49 let mut builder = Error::builder(kind);
50
51 builder.set_original_code("2067");
52 builder.set_original_message(description);
53
54 builder.build()
55 }
56
57 rusqlite::Error::SqliteFailure(
58 ffi::Error { code: ffi::ErrorCode::ConstraintViolation, extended_code: 1555 },
59 Some(description),
60 ) => {
61 let constraint = description
62 .split(": ")
63 .nth(1)
64 .map(|s| s.split(", "))
65 .map(|i| i.flat_map(|s| s.split('.').last()))
66 .map(DatabaseConstraint::fields)
67 .unwrap_or(DatabaseConstraint::CannotParse);
68
69 let kind = ErrorKind::UniqueConstraintViolation { constraint };
70 let mut builder = Error::builder(kind);
71
72 builder.set_original_code("1555");
73 builder.set_original_message(description);
74
75 builder.build()
76 }
77
78 rusqlite::Error::SqliteFailure(
79 ffi::Error { code: ffi::ErrorCode::ConstraintViolation, extended_code: 1299 },
80 Some(description),
81 ) => {
82 let constraint = description
83 .split(": ")
84 .nth(1)
85 .map(|s| s.split(", "))
86 .map(|i| i.flat_map(|s| s.split('.').last()))
87 .map(DatabaseConstraint::fields)
88 .unwrap_or(DatabaseConstraint::CannotParse);
89
90 let kind = ErrorKind::NullConstraintViolation { constraint };
91 let mut builder = Error::builder(kind);
92
93 builder.set_original_code("1299");
94 builder.set_original_message(description);
95
96 builder.build()
97 }
98
99 rusqlite::Error::SqliteFailure(
100 ffi::Error { code: ffi::ErrorCode::ConstraintViolation, extended_code: 787 },
101 Some(description),
102 ) => {
103 let mut builder = Error::builder(ErrorKind::ForeignKeyConstraintViolation {
104 constraint: DatabaseConstraint::ForeignKey,
105 });
106
107 builder.set_original_code("787");
108 builder.set_original_message(description);
109
110 builder.build()
111 }
112
113 rusqlite::Error::SqliteFailure(
114 ffi::Error { code: ffi::ErrorCode::ConstraintViolation, extended_code: 1811 },
115 Some(description),
116 ) => {
117 let mut builder = Error::builder(ErrorKind::ForeignKeyConstraintViolation {
118 constraint: DatabaseConstraint::ForeignKey,
119 });
120
121 builder.set_original_code("1811");
122 builder.set_original_message(description);
123
124 builder.build()
125 }
126
127 rusqlite::Error::SqliteFailure(
128 ffi::Error { code: ffi::ErrorCode::DatabaseBusy, extended_code },
129 description,
130 ) => {
131 let mut builder = Error::builder(ErrorKind::SocketTimeout);
132 builder.set_original_code(format!("{extended_code}"));
133
134 if let Some(description) = description {
135 builder.set_original_message(description);
136 }
137
138 builder.build()
139 }
140
141 rusqlite::Error::SqliteFailure(ffi::Error { extended_code, .. }, ref description) => match description {
142 Some(d) if d.starts_with("no such table") => {
143 let table = d.split(": ").last().into();
144 let kind = ErrorKind::TableDoesNotExist { table };
145
146 let mut builder = Error::builder(kind);
147 builder.set_original_code(format!("{extended_code}"));
148 builder.set_original_message(d);
149
150 builder.build()
151 }
152 Some(d) if d.contains("has no column named") => {
153 let column = d.split(" has no column named ").last().into();
154 let kind = ErrorKind::ColumnNotFound { column };
155
156 let mut builder = Error::builder(kind);
157 builder.set_original_code(format!("{extended_code}"));
158 builder.set_original_message(d);
159
160 builder.build()
161 }
162 Some(d) if d.starts_with("no such column: ") => {
163 let column = d.split("no such column: ").last().into();
164 let kind = ErrorKind::ColumnNotFound { column };
165
166 let mut builder = Error::builder(kind);
167 builder.set_original_code(format!("{extended_code}"));
168 builder.set_original_message(d);
169
170 builder.build()
171 }
172 _ => {
173 let description = description.as_ref().map(|d| d.to_string());
174 let mut builder = Error::builder(ErrorKind::QueryError(e.into()));
175 builder.set_original_code(format!("{extended_code}"));
176
177 if let Some(description) = description {
178 builder.set_original_message(description);
179 }
180
181 builder.build()
182 }
183 },
184 e => Error::builder(ErrorKind::QueryError(e.into())).build(),
185 }
186 }
187}
188
189impl From<FromSqlError> for Error {
190 fn from(e: FromSqlError) -> Error {
191 Error::builder(ErrorKind::ColumnReadFailure(e.into())).build()
192 }
193}