Skip to content

Commit f370af2

Browse files
committed
Don't panic when reseting a SQLite statement fails
As per SQLite's docs, resetting a prepared statement isn't actually an operation that can fail, but it will return the appropriate error code if the last call to `sqlite3_step` was an error. The statement object isn't inherently corrupted, so we can continue to reuse it.
1 parent 3074acf commit f370af2

4 files changed

Lines changed: 38 additions & 16 deletions

File tree

diesel/src/sqlite/connection/stmt.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@ impl Statement {
128128
}
129129
}
130130

131-
fn reset(&mut self) -> QueryResult<()> {
131+
fn reset(&mut self) {
132132
self.bind_index = 0;
133-
ensure_sqlite_ok(unsafe { ffi::sqlite3_reset(self.inner_statement) }, &self.raw_connection)
133+
unsafe { ffi::sqlite3_reset(self.inner_statement) };
134134
}
135135
}
136136

@@ -189,15 +189,6 @@ impl Deref for StatementUse {
189189

190190
impl Drop for StatementUse {
191191
fn drop(&mut self) {
192-
use std::thread::panicking;
193-
194-
let reset_result = self.statement.borrow_mut().reset();
195-
if let Err(e) = reset_result {
196-
if panicking() {
197-
write!(stderr(), "Error resetting SQLite prepared statement: {:?}", e).unwrap();
198-
} else {
199-
panic!("Error resetting SQLite prepared statement: {:?}", e);
200-
}
201-
}
192+
self.statement.borrow_mut().reset();
202193
}
203194
}

diesel_tests/Cargo.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@ diesel = { path = "../diesel", default-features = false }
1313
dotenv = { git = "https://github.com/slapresta/rust-dotenv.git" }
1414

1515
[dependencies]
16+
assert_matches = "1.0.1"
17+
chrono = { version = "^0.2.17" }
1618
diesel = { path = "../diesel", default-features = false, features = ["quickcheck", "chrono", "uuid"] }
1719
diesel_codegen = { path = "../diesel_codegen", default-features = false }
1820
dotenv_macros = { git = "https://github.com/slapresta/rust-dotenv.git", optional = true }
19-
chrono = { version = "^0.2.17" }
20-
uuid = { version = "^0.2.0" }
21-
22-
[dev-dependencies]
2321
quickcheck = "0.2.25"
22+
uuid = { version = "^0.2.0" }
2423

2524
[features]
2625
default = ["with-syntex"]

diesel_tests/tests/errors.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use diesel;
2+
use diesel::prelude::*;
3+
use diesel::result::Error::DatabaseError;
4+
use schema::*;
5+
6+
macro_rules! try_no_coerce {
7+
($e:expr) => ({
8+
match $e {
9+
Ok(e) => e,
10+
Err(e) => return Err(e),
11+
}
12+
})
13+
}
14+
15+
#[test]
16+
fn cached_prepared_statements_can_be_reused_after_error() {
17+
let connection = connection_without_transaction();
18+
let user = User::new(1, "Sean");
19+
let query = diesel::insert(&user).into(users::table);
20+
21+
connection.test_transaction(|| {
22+
try_no_coerce!(query.execute(&connection));
23+
24+
let failure = query.execute(&connection);
25+
assert_matches!(failure, Err(DatabaseError(_)));
26+
Ok(())
27+
});
28+
29+
connection.test_transaction(|| query.execute(&connection));
30+
}

diesel_tests/tests/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#![cfg_attr(feature = "unstable", plugin(diesel_codegen, dotenv_macros))]
33

44
extern crate quickcheck;
5+
#[macro_use] extern crate assert_matches;
56
#[macro_use] extern crate diesel;
67

78
#[cfg(feature = "unstable")]
@@ -14,6 +15,7 @@ mod associations;
1415
mod boxed_queries;
1516
mod connection;
1617
mod debug;
18+
mod errors;
1719
mod expressions;
1820
mod filter;
1921
mod filter_operators;

0 commit comments

Comments
 (0)