Add shared SQLite open macro with WASI crash recovery and in-memory temp storage
ci / check (push) Failing after 3m53s
ci / check (push) Failing after 3m53s
Card: SAU-249
This commit is contained in:
@@ -392,6 +392,7 @@ mod error;
|
||||
mod helpers;
|
||||
mod imports;
|
||||
mod lines;
|
||||
mod sqlite;
|
||||
mod transport;
|
||||
pub use discovery::*;
|
||||
pub use endpoints::*;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
//! 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)
|
||||
})()
|
||||
}};
|
||||
}
|
||||
Reference in New Issue
Block a user