launchbadge / sqlx

🧰 The Rust SQL Toolkit. An async, pure Rust SQL crate featuring compile-time checked queries without a DSL. Supports PostgreSQL, MySQL, and SQLite.
Apache License 2.0
12.9k stars 1.23k forks source link

Expose `sqlite3_create_function_v2` similar to rusqlite #2732

Open nyurik opened 1 year ago

nyurik commented 1 year ago

Is your feature request related to a problem? Please describe. I need to register and use custom SQLite functions, such as hashing functions like md5(...) similar to how sqlite-hashes crate implements them.

Describe the solution you'd like Add create_scalar_function and create_aggregate_function, as done here. Some other functions like the window and removal might also be useful.

Describe alternatives you've considered

Additional context See also #2656 and the comment by @abonander

abonander commented 11 months ago

The best place for this would be in SqliteConnectOptions, similar to collations: https://docs.rs/sqlx-sqlite/0.7.1/sqlx_sqlite/struct.SqliteConnectOptions.html#method.collation

Making this work with the macros at compile time would require some shenanigans, though.

JumpyLionnn commented 7 months ago

are there any updates on this? i think this feature can have a lot of uses

nyurik commented 7 months ago

For now, I ended up using this approach - lock and get the raw handle, use rusqlite to register , unlock, and rely on sqlite's cleanup to free the registration.

pub async fn attach_hash_fn(conn: &mut SqliteConnection) -> MbtResult<()> {
    let mut handle_lock = conn.lock_handle().await?;
    let handle = handle_lock.as_raw_handle().as_ptr();
    // Safety: we know that the handle is a SQLite connection is locked and is not used anywhere else.
    // The registered functions will be dropped when SQLX drops DB connection.
    let rc = unsafe { sqlite_hashes::rusqlite::Connection::from_handle(handle) }?;
    register_md5_function(&rc)?;    // this calls rc.create_scalar_function(...)
    Ok(())
}