mirror of
				https://github.com/isar/rusqlite.git
				synced 2025-10-31 05:48:56 +08:00 
			
		
		
		
	Fix callbacks lifetime
This commit is contained in:
		| @@ -179,9 +179,11 @@ mod build_bundled { | ||||
|  | ||||
|             if cfg!(feature = "bundled-sqlcipher-vendored-openssl") { | ||||
|                 cfg.include(std::env::var("DEP_OPENSSL_INCLUDE").unwrap()); | ||||
|                 // cargo will resolve downstream to the static lib in openssl-sys | ||||
|                 // cargo will resolve downstream to the static lib in | ||||
|                 // openssl-sys | ||||
|             } else if is_windows { | ||||
|                 // Windows without `-vendored-openssl` takes this to link against a prebuilt OpenSSL lib | ||||
|                 // Windows without `-vendored-openssl` takes this to link against a prebuilt | ||||
|                 // OpenSSL lib | ||||
|                 cfg.include(inc_dir.to_string_lossy().as_ref()); | ||||
|                 let lib = lib_dir.join("libcrypto.lib"); | ||||
|                 cfg.flag(lib.to_string_lossy().as_ref()); | ||||
|   | ||||
| @@ -16,9 +16,9 @@ unsafe extern "C" fn free_boxed_value<T>(p: *mut c_void) { | ||||
| impl Connection { | ||||
|     /// Add or modify a collation. | ||||
|     #[inline] | ||||
|     pub fn create_collation<'c, C>(&'c self, collation_name: &str, x_compare: C) -> Result<()> | ||||
|     pub fn create_collation<C>(&self, collation_name: &str, x_compare: C) -> Result<()> | ||||
|     where | ||||
|         C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'c, | ||||
|         C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'static, | ||||
|     { | ||||
|         self.db | ||||
|             .borrow_mut() | ||||
| @@ -42,9 +42,9 @@ impl Connection { | ||||
| } | ||||
|  | ||||
| impl InnerConnection { | ||||
|     fn create_collation<'c, C>(&'c mut self, collation_name: &str, x_compare: C) -> Result<()> | ||||
|     fn create_collation<C>(&mut self, collation_name: &str, x_compare: C) -> Result<()> | ||||
|     where | ||||
|         C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'c, | ||||
|         C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'static, | ||||
|     { | ||||
|         unsafe extern "C" fn call_boxed_closure<C>( | ||||
|             arg1: *mut c_void, | ||||
|   | ||||
| @@ -380,15 +380,15 @@ impl Connection { | ||||
|     /// | ||||
|     /// Will return Err if the function could not be attached to the connection. | ||||
|     #[inline] | ||||
|     pub fn create_scalar_function<'c, F, T>( | ||||
|         &'c self, | ||||
|     pub fn create_scalar_function<F, T>( | ||||
|         &self, | ||||
|         fn_name: &str, | ||||
|         n_arg: c_int, | ||||
|         flags: FunctionFlags, | ||||
|         x_func: F, | ||||
|     ) -> Result<()> | ||||
|     where | ||||
|         F: FnMut(&Context<'_>) -> Result<T> + Send + UnwindSafe + 'c, | ||||
|         F: FnMut(&Context<'_>) -> Result<T> + Send + UnwindSafe + 'static, | ||||
|         T: ToSql, | ||||
|     { | ||||
|         self.db | ||||
| @@ -462,15 +462,15 @@ impl Connection { | ||||
| } | ||||
|  | ||||
| impl InnerConnection { | ||||
|     fn create_scalar_function<'c, F, T>( | ||||
|         &'c mut self, | ||||
|     fn create_scalar_function<F, T>( | ||||
|         &mut self, | ||||
|         fn_name: &str, | ||||
|         n_arg: c_int, | ||||
|         flags: FunctionFlags, | ||||
|         x_func: F, | ||||
|     ) -> Result<()> | ||||
|     where | ||||
|         F: FnMut(&Context<'_>) -> Result<T> + Send + UnwindSafe + 'c, | ||||
|         F: FnMut(&Context<'_>) -> Result<T> + Send + UnwindSafe + 'static, | ||||
|         T: ToSql, | ||||
|     { | ||||
|         unsafe extern "C" fn call_boxed_closure<F, T>( | ||||
|   | ||||
							
								
								
									
										42
									
								
								src/hooks.rs
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								src/hooks.rs
									
									
									
									
									
								
							| @@ -345,9 +345,9 @@ impl Connection { | ||||
|     /// | ||||
|     /// The callback returns `true` to rollback. | ||||
|     #[inline] | ||||
|     pub fn commit_hook<'c, F>(&'c self, hook: Option<F>) | ||||
|     pub fn commit_hook<F>(&self, hook: Option<F>) | ||||
|     where | ||||
|         F: FnMut() -> bool + Send + 'c, | ||||
|         F: FnMut() -> bool + Send + 'static, | ||||
|     { | ||||
|         self.db.borrow_mut().commit_hook(hook); | ||||
|     } | ||||
| @@ -357,9 +357,9 @@ impl Connection { | ||||
|     /// | ||||
|     /// The callback returns `true` to rollback. | ||||
|     #[inline] | ||||
|     pub fn rollback_hook<'c, F>(&'c self, hook: Option<F>) | ||||
|     pub fn rollback_hook<F>(&self, hook: Option<F>) | ||||
|     where | ||||
|         F: FnMut() + Send + 'c, | ||||
|         F: FnMut() + Send + 'static, | ||||
|     { | ||||
|         self.db.borrow_mut().rollback_hook(hook); | ||||
|     } | ||||
| @@ -375,9 +375,9 @@ impl Connection { | ||||
|     /// - the name of the table that is updated, | ||||
|     /// - the ROWID of the row that is updated. | ||||
|     #[inline] | ||||
|     pub fn update_hook<'c, F>(&'c self, hook: Option<F>) | ||||
|     pub fn update_hook<F>(&self, hook: Option<F>) | ||||
|     where | ||||
|         F: FnMut(Action, &str, &str, i64) + Send + 'c, | ||||
|         F: FnMut(Action, &str, &str, i64) + Send + 'static, | ||||
|     { | ||||
|         self.db.borrow_mut().update_hook(hook); | ||||
|     } | ||||
| @@ -418,9 +418,9 @@ impl InnerConnection { | ||||
|         self.authorizer(None::<fn(AuthContext<'_>) -> Authorization>); | ||||
|     } | ||||
|  | ||||
|     fn commit_hook<'c, F>(&'c mut self, hook: Option<F>) | ||||
|     fn commit_hook<F>(&mut self, hook: Option<F>) | ||||
|     where | ||||
|         F: FnMut() -> bool + Send + 'c, | ||||
|         F: FnMut() -> bool + Send + 'static, | ||||
|     { | ||||
|         unsafe extern "C" fn call_boxed_closure<F>(p_arg: *mut c_void) -> c_int | ||||
|         where | ||||
| @@ -467,9 +467,9 @@ impl InnerConnection { | ||||
|         self.free_commit_hook = free_commit_hook; | ||||
|     } | ||||
|  | ||||
|     fn rollback_hook<'c, F>(&'c mut self, hook: Option<F>) | ||||
|     fn rollback_hook<F>(&mut self, hook: Option<F>) | ||||
|     where | ||||
|         F: FnMut() + Send + 'c, | ||||
|         F: FnMut() + Send + 'static, | ||||
|     { | ||||
|         unsafe extern "C" fn call_boxed_closure<F>(p_arg: *mut c_void) | ||||
|         where | ||||
| @@ -508,9 +508,9 @@ impl InnerConnection { | ||||
|         self.free_rollback_hook = free_rollback_hook; | ||||
|     } | ||||
|  | ||||
|     fn update_hook<'c, F>(&'c mut self, hook: Option<F>) | ||||
|     fn update_hook<F>(&mut self, hook: Option<F>) | ||||
|     where | ||||
|         F: FnMut(Action, &str, &str, i64) + Send + 'c, | ||||
|         F: FnMut(Action, &str, &str, i64) + Send + 'static, | ||||
|     { | ||||
|         unsafe extern "C" fn call_boxed_closure<F>( | ||||
|             p_arg: *mut c_void, | ||||
| @@ -698,13 +698,13 @@ mod test { | ||||
|     fn test_commit_hook() -> Result<()> { | ||||
|         let db = Connection::open_in_memory()?; | ||||
|  | ||||
|         let mut called = false; | ||||
|         static 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;")?; | ||||
|         assert!(called); | ||||
|         assert!(CALLED.load(Ordering::Relaxed)); | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
| @@ -726,12 +726,12 @@ mod test { | ||||
|     fn test_rollback_hook() -> Result<()> { | ||||
|         let db = Connection::open_in_memory()?; | ||||
|  | ||||
|         let mut called = false; | ||||
|         static 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;")?; | ||||
|         assert!(called); | ||||
|         assert!(CALLED.load(Ordering::Relaxed)); | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
| @@ -739,17 +739,17 @@ mod test { | ||||
|     fn test_update_hook() -> Result<()> { | ||||
|         let db = Connection::open_in_memory()?; | ||||
|  | ||||
|         let mut called = false; | ||||
|         static 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)")?; | ||||
|         db.execute_batch("INSERT INTO foo VALUES ('lisa')")?; | ||||
|         assert!(called); | ||||
|         assert!(CALLED.load(Ordering::Relaxed)); | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|   | ||||
							
								
								
									
										16
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/lib.rs
									
									
									
									
									
								
							| @@ -159,9 +159,11 @@ pub const NO_PARAMS: &[&dyn ToSql] = &[]; | ||||
| /// } | ||||
| /// | ||||
| /// fn add_person(conn: &Connection, person: &Person) -> Result<()> { | ||||
| ///     conn.execute("INSERT INTO person (name, age_in_years, data) | ||||
| ///     conn.execute( | ||||
| ///         "INSERT INTO person (name, age_in_years, data) | ||||
| ///                   VALUES (?1, ?2, ?3)", | ||||
| ///                  params![person.name, person.age_in_years, person.data])?; | ||||
| ///         params![person.name, person.age_in_years, person.data], | ||||
| ///     )?; | ||||
| ///     Ok(()) | ||||
| /// } | ||||
| /// ``` | ||||
| @@ -197,7 +199,7 @@ macro_rules! params { | ||||
| ///             ":name": person.name, | ||||
| ///             ":age": person.age_in_years, | ||||
| ///             ":data": person.data, | ||||
| ///         } | ||||
| ///         }, | ||||
| ///     )?; | ||||
| ///     Ok(()) | ||||
| /// } | ||||
| @@ -462,7 +464,8 @@ impl Connection { | ||||
|     /// ```rust,no_run | ||||
|     /// # use rusqlite::{Connection, Result}; | ||||
|     /// fn create_tables(conn: &Connection) -> Result<()> { | ||||
|     ///     conn.execute_batch("BEGIN; | ||||
|     ///     conn.execute_batch( | ||||
|     ///         "BEGIN; | ||||
|     ///          CREATE TABLE foo(x INTEGER); | ||||
|     ///          CREATE TABLE bar(y TEXT); | ||||
|     ///          COMMIT;", | ||||
| @@ -515,7 +518,10 @@ impl Connection { | ||||
|     /// ```rust,no_run | ||||
|     /// # use rusqlite::{params, Connection}; | ||||
|     /// fn update_rows(conn: &Connection) { | ||||
|     ///     match conn.execute("UPDATE foo SET bar = 'baz' WHERE qux = ?1 AND quux = ?2", params![1i32, 1.5f64]) { | ||||
|     ///     match conn.execute( | ||||
|     ///         "UPDATE foo SET bar = 'baz' WHERE qux = ?1 AND quux = ?2", | ||||
|     ///         params![1i32, 1.5f64], | ||||
|     ///     ) { | ||||
|     ///         Ok(updated) => println!("{} rows were updated", updated), | ||||
|     ///         Err(err) => println!("update failed: {}", err), | ||||
|     ///     } | ||||
|   | ||||
| @@ -251,7 +251,7 @@ impl_for_array_ref!( | ||||
| /// ## Basic usage | ||||
| /// | ||||
| /// ```rust,no_run | ||||
| /// use rusqlite::{Connection, Result, params_from_iter}; | ||||
| /// use rusqlite::{params_from_iter, Connection, Result}; | ||||
| /// use std::collections::BTreeSet; | ||||
| /// | ||||
| /// fn query(conn: &Connection, ids: &BTreeSet<String>) -> Result<()> { | ||||
|   | ||||
| @@ -346,13 +346,12 @@ impl Statement<'_> { | ||||
|     /// | ||||
|     /// fn name_to_person(name: String) -> Result<Person> { | ||||
|     ///     // ... check for valid name | ||||
|     ///     Ok(Person { name: name }) | ||||
|     ///     Ok(Person { name }) | ||||
|     /// } | ||||
|     /// | ||||
|     /// fn get_names(conn: &Connection) -> Result<Vec<Person>> { | ||||
|     ///     let mut stmt = conn.prepare("SELECT name FROM people WHERE id = :id")?; | ||||
|     ///     let rows = | ||||
|     ///         stmt.query_and_then(&[(":id", "one")], |row| name_to_person(row.get(0)?))?; | ||||
|     ///     let rows = stmt.query_and_then(&[(":id", "one")], |row| name_to_person(row.get(0)?))?; | ||||
|     /// | ||||
|     ///     let mut persons = Vec::new(); | ||||
|     ///     for person_result in rows { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user