Check callbacks lifetime (#1052)

Check callbacks lifetime
This commit is contained in:
gwenn 2024-03-31 11:41:05 +02:00 committed by GitHub
parent 8421769032
commit d8bcd4d28a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 134 additions and 0 deletions

View File

@ -42,6 +42,28 @@ impl Connection {
}
impl InnerConnection {
/// ```compile_fail
/// use rusqlite::{Connection, Result};
/// fn main() -> Result<()> {
/// let db = Connection::open_in_memory()?;
/// {
/// let mut called = std::sync::atomic::AtomicBool::new(false);
/// db.create_collation("foo", |_, _| {
/// called.store(true, std::sync::atomic::Ordering::Relaxed);
/// std::cmp::Ordering::Equal
/// })?;
/// }
/// let value: String = db.query_row(
/// "WITH cte(bar) AS
/// (VALUES ('v1'),('v2'),('v3'),('v4'),('v5'))
/// SELECT DISTINCT bar COLLATE foo FROM cte;",
/// [],
/// |row| row.get(0),
/// )?;
/// assert_eq!(value, "v1");
/// Ok(())
/// }
/// ```
fn create_collation<C>(&mut self, collation_name: &str, x_compare: C) -> Result<()>
where
C: Fn(&str, &str) -> Ordering + Send + 'static,

View File

@ -518,6 +518,27 @@ impl Connection {
}
impl InnerConnection {
/// ```compile_fail
/// use rusqlite::{functions::FunctionFlags, Connection, Result};
/// fn main() -> Result<()> {
/// let db = Connection::open_in_memory()?;
/// {
/// let mut called = std::sync::atomic::AtomicBool::new(false);
/// db.create_scalar_function(
/// "test",
/// 0,
/// FunctionFlags::SQLITE_UTF8 | FunctionFlags::SQLITE_DETERMINISTIC,
/// |_| {
/// called.store(true, std::sync::atomic::Ordering::Relaxed);
/// Ok(true)
/// },
/// );
/// }
/// let result: Result<bool> = db.query_row("SELECT test()", [], |r| r.get(0));
/// assert!(result?);
/// Ok(())
/// }
/// ```
fn create_scalar_function<F, T>(
&mut self,
fn_name: &str,

View File

@ -414,6 +414,27 @@ impl InnerConnection {
self.authorizer(None::<fn(AuthContext<'_>) -> Authorization>);
}
/// ```compile_fail
/// use rusqlite::{Connection, Result};
/// fn main() -> Result<()> {
/// let db = Connection::open_in_memory()?;
/// {
/// let mut called = std::sync::atomic::AtomicBool::new(false);
/// db.commit_hook(Some(|| {
/// called.store(true, std::sync::atomic::Ordering::Relaxed);
/// true
/// }));
/// }
/// assert!(db
/// .execute_batch(
/// "BEGIN;
/// CREATE TABLE foo (t TEXT);
/// COMMIT;",
/// )
/// .is_err());
/// Ok(())
/// }
/// ```
fn commit_hook<F>(&mut self, hook: Option<F>)
where
F: FnMut() -> bool + Send + 'static,
@ -459,6 +480,26 @@ impl InnerConnection {
self.free_commit_hook = free_commit_hook;
}
/// ```compile_fail
/// use rusqlite::{Connection, Result};
/// fn main() -> Result<()> {
/// let db = Connection::open_in_memory()?;
/// {
/// let mut called = std::sync::atomic::AtomicBool::new(false);
/// db.rollback_hook(Some(|| {
/// called.store(true, std::sync::atomic::Ordering::Relaxed);
/// }));
/// }
/// assert!(db
/// .execute_batch(
/// "BEGIN;
/// CREATE TABLE foo (t TEXT);
/// ROLLBACK;",
/// )
/// .is_err());
/// Ok(())
/// }
/// ```
fn rollback_hook<F>(&mut self, hook: Option<F>)
where
F: FnMut() + Send + 'static,
@ -500,6 +541,19 @@ impl InnerConnection {
self.free_rollback_hook = free_rollback_hook;
}
/// ```compile_fail
/// use rusqlite::{Connection, Result};
/// fn main() -> Result<()> {
/// let db = Connection::open_in_memory()?;
/// {
/// let mut called = std::sync::atomic::AtomicBool::new(false);
/// db.update_hook(Some(|_, _: &str, _: &str, _| {
/// called.store(true, std::sync::atomic::Ordering::Relaxed);
/// }));
/// }
/// db.execute_batch("CREATE TABLE foo AS SELECT 1 AS bar;")
/// }
/// ```
fn update_hook<F>(&mut self, hook: Option<F>)
where
F: FnMut(Action, &str, &str, i64) + Send + 'static,
@ -552,6 +606,26 @@ impl InnerConnection {
self.free_update_hook = free_update_hook;
}
/// ```compile_fail
/// use rusqlite::{Connection, Result};
/// fn main() -> Result<()> {
/// let db = Connection::open_in_memory()?;
/// {
/// let mut called = std::sync::atomic::AtomicBool::new(false);
/// db.progress_handler(
/// 1,
/// Some(|| {
/// called.store(true, std::sync::atomic::Ordering::Relaxed);
/// true
/// }),
/// );
/// }
/// assert!(db
/// .execute_batch("BEGIN; CREATE TABLE foo (t TEXT); COMMIT;")
/// .is_err());
/// Ok(())
/// }
/// ```
fn progress_handler<F>(&mut self, num_ops: c_int, handler: Option<F>)
where
F: FnMut() -> bool + Send + 'static,
@ -584,6 +658,23 @@ impl InnerConnection {
};
}
/// ```compile_fail
/// use rusqlite::{Connection, Result};
/// fn main() -> Result<()> {
/// let db = Connection::open_in_memory()?;
/// {
/// let mut called = std::sync::atomic::AtomicBool::new(false);
/// db.authorizer(Some(|_: rusqlite::hooks::AuthContext<'_>| {
/// called.store(true, std::sync::atomic::Ordering::Relaxed);
/// rusqlite::hooks::Authorization::Deny
/// }));
/// }
/// assert!(db
/// .execute_batch("BEGIN; CREATE TABLE foo (t TEXT); COMMIT;")
/// .is_err());
/// Ok(())
/// }
/// ```
fn authorizer<'c, F>(&'c mut self, authorizer: Option<F>)
where
F: for<'r> FnMut(AuthContext<'r>) -> Authorization + Send + 'static,