mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-23 00:39:20 +08:00
Make Connection::close() return the connection on failure.
This commit is contained in:
parent
914023ce9c
commit
3af91b36bf
@ -1,3 +1,8 @@
|
|||||||
|
# Version UPCOMING (TBD)
|
||||||
|
|
||||||
|
* BREAKING CHANGE: `Connection::close()` now returns a `Result<(), (Connection, Error)>` instead
|
||||||
|
of a `Result<(), Error>` so callers get the still-open connection back on failure.
|
||||||
|
|
||||||
# Version 0.8.0 (2016-12-31)
|
# Version 0.8.0 (2016-12-31)
|
||||||
|
|
||||||
* BREAKING CHANGE: The `FromSql` trait has been redesigned. It now requires a single, safe
|
* BREAKING CHANGE: The `FromSql` trait has been redesigned. It now requires a single, safe
|
||||||
|
48
src/lib.rs
48
src/lib.rs
@ -398,15 +398,19 @@ impl Connection {
|
|||||||
/// Close the SQLite connection.
|
/// Close the SQLite connection.
|
||||||
///
|
///
|
||||||
/// This is functionally equivalent to the `Drop` implementation for `Connection` except
|
/// This is functionally equivalent to the `Drop` implementation for `Connection` except
|
||||||
/// that it returns any error encountered to the caller.
|
/// that on failure, it returns an error and the connection itself (presumably so closing
|
||||||
|
/// can be attempted again).
|
||||||
///
|
///
|
||||||
/// # Failure
|
/// # Failure
|
||||||
///
|
///
|
||||||
/// Will return `Err` if the underlying SQLite call fails.
|
/// Will return `Err` if the underlying SQLite call fails.
|
||||||
pub fn close(self) -> Result<()> {
|
pub fn close(self) -> std::result::Result<(), (Connection, Error)> {
|
||||||
self.flush_prepared_statement_cache();
|
self.flush_prepared_statement_cache();
|
||||||
let mut db = self.db.borrow_mut();
|
{
|
||||||
db.close()
|
let mut db = self.db.borrow_mut();
|
||||||
|
db.close()
|
||||||
|
}
|
||||||
|
.map_err(move |err| (self, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enable loading of SQLite extensions. Strongly consider using `LoadExtensionGuard`
|
/// Enable loading of SQLite extensions. Strongly consider using `LoadExtensionGuard`
|
||||||
@ -1242,6 +1246,42 @@ mod test {
|
|||||||
assert!(db.close().is_ok());
|
assert!(db.close().is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_close_retry() {
|
||||||
|
let db = checked_memory_handle();
|
||||||
|
|
||||||
|
// force the DB to be busy by preparing a statement; this must be done at the FFI
|
||||||
|
// level to allow us to call .close() without dropping the prepared statement first.
|
||||||
|
let raw_stmt = {
|
||||||
|
use std::mem;
|
||||||
|
use std::ptr;
|
||||||
|
use libc::c_int;
|
||||||
|
use super::str_to_cstring;
|
||||||
|
|
||||||
|
let raw_db = db.db.borrow_mut().db;
|
||||||
|
let sql = "SELECT 1";
|
||||||
|
let mut raw_stmt: *mut ffi::sqlite3_stmt = unsafe { mem::uninitialized() };
|
||||||
|
let rc = unsafe {
|
||||||
|
ffi::sqlite3_prepare_v2(raw_db,
|
||||||
|
str_to_cstring(sql).unwrap().as_ptr(),
|
||||||
|
(sql.len() + 1) as c_int,
|
||||||
|
&mut raw_stmt,
|
||||||
|
ptr::null_mut())
|
||||||
|
};
|
||||||
|
assert_eq!(rc, ffi::SQLITE_OK);
|
||||||
|
raw_stmt
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = db.close();
|
||||||
|
assert!(result.is_err());
|
||||||
|
|
||||||
|
// finalize the open statement so a second close will succeed
|
||||||
|
assert_eq!(ffi::SQLITE_OK, unsafe { ffi::sqlite3_finalize(raw_stmt) });
|
||||||
|
|
||||||
|
let (db, _) = result.unwrap_err();
|
||||||
|
db.close().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_open_with_flags() {
|
fn test_open_with_flags() {
|
||||||
for bad_flags in &[OpenFlags::empty(),
|
for bad_flags in &[OpenFlags::empty(),
|
||||||
|
Loading…
Reference in New Issue
Block a user