Skip to main content

register_auto_extension

Function register_auto_extension 

Source
pub fn register_auto_extension<F>(extension: F) -> QueryResult<()>
where F: Fn(&mut BorrowedSqliteConnection) -> QueryResult<()> + Sync + 'static,
Available on crate feature __sqlite-shared only.
Expand description

Registers an auto-extension that runs for every SQLite connection opened in this process, including non-Diesel ones.

This is a safe wrapper around sqlite3_auto_extension. The callback receives the SqliteConnection being opened and returns Ok(()) to continue or an error to fail the open. Use it to register SQL functions, collations, or aggregates through the usual connection API, or to initialize a statically linked C extension such as Spatialite or sqlite-vec via SqliteConnection::with_raw_connection.

Call this before opening any connection. Extensions run in registration order, and the first error aborts the open. The callback must be a fn item or a closure that captures only zero-sized values (enforced at compile time), and registering the same fn twice is a no-op. It may run on several threads at once and must not open another connection (which would re-enter the auto-extensions and recurse) or call register_auto_extension, cancel_auto_extension, or reset_auto_extension. Panics are caught and turned into a failed open.

ยงExample

use diesel::dsl::sql;
use diesel::prelude::*;
use diesel::sql_types::Integer;
use diesel::sqlite::{register_auto_extension, reset_auto_extension, SqliteConnection, BorrowedSqliteConnection};
use std::pin::Pin;

// Registers a case-insensitive collation on every new connection.
fn my_ext(conn: &mut BorrowedSqliteConnection) -> QueryResult<()> {
    unsafe {
        // SAFETY: This is safe as long as we don't move or replace out the
        // inner SqliteConnection. None of the functions defined on SqliteConnection
        // do that
        conn.inner_mut().register_collation("RUSTNOCASE", |a, b| a.to_lowercase().cmp(&b.to_lowercase()))
    }
}

register_auto_extension(my_ext).unwrap();

// Every future connection now has the collation.
let mut conn = SqliteConnection::establish(":memory:").unwrap();
let equal: i32 = sql::<Integer>("SELECT 'a' = 'A' COLLATE RUSTNOCASE")
    .get_result(&mut conn)
    .unwrap();
assert_eq!(equal, 1);