rightkit-db 0.3.2

Correct-by-default SQLite and SQLCipher connection bootstrap for Right Suite apps.
Documentation

rightkit-db

Correct-by-default SQLite and SQLCipher connection bootstrap for Right Suite desktop apps. It owns connection pragmas, SQLCipher key ordering, a bounded read pool, checkpointing, optimization, optional integrity checks, online backup and restore, and versioned migrations. It does not own app schemas or queries.

Catalog capability: sqlite-storage. Published to crates.io (see INDEX.md).

When to use it

  • Use it to open a SQLite or SQLCipher database with the suite's journal, busy-timeout and durability rules.
  • Use write_txn() for any transaction that may write. It starts BEGIN IMMEDIATE, so read-then-write work cannot fail with an unretryable stale snapshot.

Do not use it to define app tables or queries. Keep those in the app.

Default behaviour

The default writer and legacy reader open select WAL with rollback fallback, a bounded busy wait and journal, memory-backed temporary storage, and the selected durability profile.

  • DurabilityProfile::Full: for user mutations that cannot be reconstructed.
  • DurabilityProfile::Normal: for rebuildable indexes or telemetry.
  • CacheProfile::LargeWorkingSet: opt-in. It is currently intended for MailRight.

Cargo features

Feature Default Pulls in Enables
bundled yes rusqlite/bundled Bundled plain SQLite.
sqlcipher no cipher, rusqlite/bundled-sqlcipher-vendored-openssl SQLCipher with vendored OpenSSL, the same crypto provider on every OS.
sqlcipher-system no cipher, rusqlite/bundled-sqlcipher SQLCipher with the system crypto provider: CommonCrypto on Apple, libcrypto elsewhere. Use it where existing encrypted databases were created with system crypto. Switching providers is not a silent refactor.
cipher no none Internal gate for keyed open and rekey. Enabled by either SQLCipher feature. Do not name it directly.
hooks no rusqlite/hooks progress_handler() for cancellation through returned connections, and the rightkit_db::rusqlite re-export.

SQLCipher consumers must turn off default features and choose exactly one provider feature. Both providers expose the same keyed-open and rekey APIs. Enabling both is a compile error. Keep the provider compatible with existing encrypted databases:

rightkit-db = { version = "<exact published version from INDEX.md>", default-features = false, features = ["sqlcipher"] }

rusqlite is a caret requirement (0.40.1), so consumers that resolve 0.40.2 stay compatible.

Usage

Taken from tests/contract.rs and the crate's read-only and migration API. Illustrative as a snippet:

use std::time::Duration;
use rightkit_db::{DbOptions, MigrateOptions, VersionStorage};

let mut db = DbOptions::new("file:context.db?mode=ro");
db.busy_timeout = Duration::from_millis(250);
let reader = db.open_read_only()?;

let migrations = MigrateOptions {
    version_storage: VersionStorage::Table {
        table: "meta".into(),
        key: "schema_version".into(),
    },
    ..Default::default()
};

Other APIs

  • open_read_only(path) opens with SQLITE_OPEN_READ_ONLY. open_existing_writer(path) opens read-write without CREATE. Both accept paths or file: URIs with query parameters, and refuse missing files. The matching DbOptions methods use the path, key, timeout and optional integrity check. They skip journal selection, per-host routing, permission changes, init, optimization and migrations. Read-only main databases still allow SQLite TEMP tables unless callers set query_only.
  • open_reader() is unchanged: read-write or create bootstrap, then query_only.
  • DbOptions::busy_timeout: Duration defaults to five seconds. It is installed before any bootstrap SQL, including key verification and init.
  • open_in_memory() returns a private ephemeral connection. The matching DbOptions::open_in_memory() keeps key, timeout, initializer, cache, foreign-key, durability, optimization and integrity options. Path, filesystem permissions, journal selection and mmap do not apply. The journal mode stays memory, including with WalStrict. Run migrate with db_path: None to skip filesystem backup and marker handling.
  • MigrateOptions::version_storage defaults to VersionStorage::UserVersion. VersionStorage::Table { table, key } uses key and value columns compatible with Blueprint's meta table. Values are decimal text. Identifiers accept ASCII letters, digits and underscores. Keys are bound parameters. A missing table or key reads as zero. Table creation and version writes share each migration transaction. migration_version reads the chosen storage, and rollback_to_with_storage reverses it. user_version and rollback_to keep the default storage.
  • DbOptions::restore_from(backup_path) checks every PRAGMA integrity_check row, including CHECK constraints, before it restores an existing live database through SQLite's backup API. A read transaction holds the validated source snapshot until the copy finishes. A missing or corrupt backup leaves the live database untouched. A missing live database is refused. The backup must use the options' SQLCipher key. The free function restore_from(options, destination, backup_path) restores into an existing mutable connection, including in-memory stores. The destination must be writable and outside any transaction. Busy and locked retries are bounded by the options' timeout.

Platform support

  • Unix: descriptor-relative file handling through rightkit-fs.
  • Windows: the same database API. SQLCipher provider choice is the main per-OS difference (see Cargo features).
  • Apple: sqlcipher-system uses CommonCrypto.

Verification

Tests: tests/contract.rs, tests/e2e.rs, tests/journal_fallback.rs, tests/membrane.rs.

Version and changes

Published version: see INDEX.md. No CHANGELOG.md in this crate.

Publish only through the RightKit release command:

right-release publish cargo --crate rightkit-db