From ec53f19be121e4a96a13251c30c7e18aa02ffaf0 Mon Sep 17 00:00:00 2001 From: gwenn Date: Wed, 15 Aug 2018 18:00:58 +0200 Subject: [PATCH 1/3] Backup progress callback can be `Fn`. --- src/backup.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backup.rs b/src/backup.rs index be50cc0..2a4a8b0 100644 --- a/src/backup.rs +++ b/src/backup.rs @@ -95,11 +95,11 @@ impl Connection { /// /// Will return `Err` if the destination path cannot be opened /// or if the restore fails. - pub fn restore>( + pub fn restore, F: Fn(Progress)>( &mut self, name: DatabaseName, src_path: P, - progress: Option, + progress: Option, ) -> Result<()> { use self::StepResult::{Busy, Done, Locked, More}; let src = try!(Connection::open(src_path)); @@ -109,7 +109,7 @@ impl Connection { let mut busy_count = 0i32; 'restore_loop: while r == More || r == Busy { r = try!(restore.step(100)); - if let Some(f) = progress { + if let Some(ref f) = progress { f(restore.progress()); } if r == Busy { From 4770060396cc462b6df758ed8cfdca2b580d136e Mon Sep 17 00:00:00 2001 From: gwenn Date: Wed, 15 Aug 2018 18:30:18 +0200 Subject: [PATCH 2/3] Make sure scalar functions and hooks are `Send`able --- src/functions.rs | 4 ++-- src/hooks.rs | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/functions.rs b/src/functions.rs index a51e979..bbe1355 100644 --- a/src/functions.rs +++ b/src/functions.rs @@ -230,7 +230,7 @@ impl Connection { x_func: F, ) -> Result<()> where - F: FnMut(&Context) -> Result, + F: FnMut(&Context) -> Result + Send, T: ToSql, { self.db @@ -281,7 +281,7 @@ impl InnerConnection { x_func: F, ) -> Result<()> where - F: FnMut(&Context) -> Result, + F: FnMut(&Context) -> Result + Send, T: ToSql, { unsafe extern "C" fn call_boxed_closure( diff --git a/src/hooks.rs b/src/hooks.rs index 56a54e7..bf3f059 100644 --- a/src/hooks.rs +++ b/src/hooks.rs @@ -96,7 +96,7 @@ impl Connection { /// The callback returns `true` to rollback. pub fn commit_hook(&self, hook: Option) where - F: FnMut() -> bool, + F: FnMut() -> bool + Send, { self.db.borrow_mut().commit_hook(hook); } @@ -106,7 +106,7 @@ impl Connection { /// The callback returns `true` to rollback. pub fn rollback_hook(&self, hook: Option) where - F: FnMut(), + F: FnMut() + Send, { self.db.borrow_mut().rollback_hook(hook); } @@ -122,7 +122,7 @@ impl Connection { /// - the ROWID of the row that is updated. pub fn update_hook(&self, hook: Option) where - F: FnMut(Action, &str, &str, i64), + F: FnMut(Action, &str, &str, i64) + Send, { self.db.borrow_mut().update_hook(hook); } @@ -137,7 +137,7 @@ impl InnerConnection { fn commit_hook(&mut self, hook: Option) where - F: FnMut() -> bool, + F: FnMut() -> bool + Send, { unsafe extern "C" fn call_boxed_closure(p_arg: *mut c_void) -> c_int where @@ -182,7 +182,7 @@ impl InnerConnection { fn rollback_hook(&mut self, hook: Option) where - F: FnMut(), + F: FnMut() + Send, { unsafe extern "C" fn call_boxed_closure(p_arg: *mut c_void) where @@ -221,7 +221,7 @@ impl InnerConnection { fn update_hook(&mut self, hook: Option) where - F: FnMut(Action, &str, &str, i64), + F: FnMut(Action, &str, &str, i64) + Send, { unsafe extern "C" fn call_boxed_closure( p_arg: *mut c_void, From 8c6ce46c1793f446693c2e51ec0488f70bb0e6d8 Mon Sep 17 00:00:00 2001 From: gwenn Date: Wed, 15 Aug 2018 20:04:01 +0200 Subject: [PATCH 3/3] Make sure scalar functions and hooks outlive the connection --- src/functions.rs | 4 ++-- src/hooks.rs | 37 ++++++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/functions.rs b/src/functions.rs index bbe1355..c0064c3 100644 --- a/src/functions.rs +++ b/src/functions.rs @@ -230,7 +230,7 @@ impl Connection { x_func: F, ) -> Result<()> where - F: FnMut(&Context) -> Result + Send, + F: FnMut(&Context) -> Result + Send + 'static, T: ToSql, { self.db @@ -281,7 +281,7 @@ impl InnerConnection { x_func: F, ) -> Result<()> where - F: FnMut(&Context) -> Result + Send, + F: FnMut(&Context) -> Result + Send + 'static, T: ToSql, { unsafe extern "C" fn call_boxed_closure( diff --git a/src/hooks.rs b/src/hooks.rs index bf3f059..afc7ba0 100644 --- a/src/hooks.rs +++ b/src/hooks.rs @@ -96,7 +96,7 @@ impl Connection { /// The callback returns `true` to rollback. pub fn commit_hook(&self, hook: Option) where - F: FnMut() -> bool + Send, + F: FnMut() -> bool + Send + 'static, { self.db.borrow_mut().commit_hook(hook); } @@ -106,7 +106,7 @@ impl Connection { /// The callback returns `true` to rollback. pub fn rollback_hook(&self, hook: Option) where - F: FnMut() + Send, + F: FnMut() + Send + 'static, { self.db.borrow_mut().rollback_hook(hook); } @@ -122,7 +122,7 @@ impl Connection { /// - the ROWID of the row that is updated. pub fn update_hook(&self, hook: Option) where - F: FnMut(Action, &str, &str, i64) + Send, + F: FnMut(Action, &str, &str, i64) + Send + 'static, { self.db.borrow_mut().update_hook(hook); } @@ -137,7 +137,7 @@ impl InnerConnection { fn commit_hook(&mut self, hook: Option) where - F: FnMut() -> bool + Send, + F: FnMut() -> bool + Send + 'static, { unsafe extern "C" fn call_boxed_closure(p_arg: *mut c_void) -> c_int where @@ -182,7 +182,7 @@ impl InnerConnection { fn rollback_hook(&mut self, hook: Option) where - F: FnMut() + Send, + F: FnMut() + Send + 'static, { unsafe extern "C" fn call_boxed_closure(p_arg: *mut c_void) where @@ -221,7 +221,7 @@ impl InnerConnection { fn update_hook(&mut self, hook: Option) where - F: FnMut(Action, &str, &str, i64) + Send, + F: FnMut(Action, &str, &str, i64) + Send + 'static, { unsafe extern "C" fn call_boxed_closure( p_arg: *mut c_void, @@ -285,20 +285,23 @@ fn free_boxed_hook(p: *mut c_void) { #[cfg(test)] mod test { use super::Action; + use std::sync::atomic::{AtomicBool, Ordering}; use Connection; #[test] fn test_commit_hook() { let db = Connection::open_in_memory().unwrap(); - let mut called = false; + lazy_static! { + static ref called: AtomicBool = AtomicBool::new(false); + } db.commit_hook(Some(|| { - called = true; + called.store(true, Ordering::Relaxed); false })); db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); COMMIT;") .unwrap(); - assert!(called); + assert!(called.load(Ordering::Relaxed)); } #[test] @@ -318,29 +321,33 @@ mod test { fn test_rollback_hook() { let db = Connection::open_in_memory().unwrap(); - let mut called = false; + lazy_static! { + static ref called: AtomicBool = AtomicBool::new(false); + } db.rollback_hook(Some(|| { - called = true; + called.store(true, Ordering::Relaxed); })); db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); ROLLBACK;") .unwrap(); - assert!(called); + assert!(called.load(Ordering::Relaxed)); } #[test] fn test_update_hook() { let db = Connection::open_in_memory().unwrap(); - let mut called = false; + lazy_static! { + static ref called: AtomicBool = AtomicBool::new(false); + } db.update_hook(Some(|action, db: &str, tbl: &str, row_id| { assert_eq!(Action::SQLITE_INSERT, action); assert_eq!("main", db); assert_eq!("foo", tbl); assert_eq!(1, row_id); - called = true; + called.store(true, Ordering::Relaxed); })); db.execute_batch("CREATE TABLE foo (t TEXT)").unwrap(); db.execute_batch("INSERT INTO foo VALUES ('lisa')").unwrap(); - assert!(called); + assert!(called.load(Ordering::Relaxed)); } }