44 lines
2.0 KiB
Rust
44 lines
2.0 KiB
Rust
//! Shared SQLite open policy, expanded against the plugin's own rusqlite version.
|
|
|
|
/// Open SQLite under an already-held Sausage host lock. The caller must depend
|
|
/// on `rusqlite` (bundled) and hold the SAME host lock for EVERY connection's
|
|
/// entire lifetime, including reads and old/new plugin versions. This macro does
|
|
/// not acquire the lock. Do not use it for the host journal or databases accessed
|
|
/// outside Sausage. Native builds retain OS locks; WASI selects `unix-none`, so
|
|
/// crash-leftover dotfile lock directories cannot block recovery.
|
|
///
|
|
/// Temporary tables/sorts stay in memory before any schema access. Writable opens
|
|
/// use DELETE journals; SQLite rolls back hot journals itself. Never delete a
|
|
/// leftover journal. Read-only opens cannot recover a hot journal: recover with
|
|
/// a writable open first.
|
|
///
|
|
/// The flags form preserves the caller's open flags. A macro avoids coupling the
|
|
/// SDK to a particular rusqlite/libsqlite3-sys version (the host and plugins use
|
|
/// different versions, which cannot coexist as dependencies due to `links`).
|
|
///
|
|
/// ```ignore
|
|
/// let _guard = sausage_plugin::lock("/state/example/db.lock").await?;
|
|
/// let c = sausage_plugin::sqlite_open!("/state/example/db.sqlite")?;
|
|
/// // Query here; c must drop before _guard.
|
|
/// ```
|
|
#[macro_export]
|
|
macro_rules! sqlite_open {
|
|
($path:expr) => {
|
|
$crate::sqlite_open!($path, ::rusqlite::OpenFlags::default())
|
|
};
|
|
($path:expr, $flags:expr) => {{
|
|
(|| -> ::rusqlite::Result<::rusqlite::Connection> {
|
|
let flags = $flags;
|
|
#[cfg(target_os = "wasi")]
|
|
let c = ::rusqlite::Connection::open_with_flags_and_vfs($path, flags, "unix-none")?;
|
|
#[cfg(not(target_os = "wasi"))]
|
|
let c = ::rusqlite::Connection::open_with_flags($path, flags)?;
|
|
c.pragma_update(None, "temp_store", "MEMORY")?;
|
|
if !flags.contains(::rusqlite::OpenFlags::SQLITE_OPEN_READ_ONLY) {
|
|
c.pragma_update(None, "journal_mode", "DELETE")?;
|
|
}
|
|
Ok(c)
|
|
})()
|
|
}};
|
|
}
|