sos_database/
lib.rs

1#![deny(missing_docs)]
2#![forbid(unsafe_code)]
3#![cfg_attr(all(doc, CHANNEL_NIGHTLY), feature(doc_auto_cfg))]
4//! Database storage layer for the [Save Our Secrets](https://saveoursecrets.com) SDK.
5#[cfg(feature = "archive")]
6pub mod archive;
7#[cfg(feature = "audit")]
8pub mod audit_provider;
9pub mod entity;
10pub mod event_log;
11pub mod migrations;
12#[cfg(feature = "preferences")]
13mod preferences;
14mod server_origins;
15#[cfg(feature = "system-messages")]
16mod system_messages;
17mod vault_writer;
18
19pub use event_log::{
20    AccountEventLog, DatabaseEventLog, DeviceEventLog, EventLogOwner,
21    FolderEventLog,
22};
23
24#[cfg(feature = "preferences")]
25pub use preferences::PreferenceProvider;
26
27#[cfg(feature = "system-messages")]
28pub use system_messages::SystemMessagesProvider;
29
30pub use server_origins::ServerOrigins;
31pub use vault_writer::VaultDatabaseWriter;
32
33#[cfg(feature = "files")]
34pub use event_log::FileEventLog;
35
36mod error;
37pub use async_sqlite;
38pub use error::Error;
39
40/// Result type for the library.
41pub(crate) type Result<T> = std::result::Result<T, Error>;
42
43use async_sqlite::{Client, ClientBuilder, JournalMode};
44use std::path::Path;
45
46/// Open a database file from a path with WAL journal mode enabled.
47pub async fn open_file(path: impl AsRef<Path>) -> Result<Client> {
48    tracing::debug!(
49        path = %path.as_ref().display(),
50        "database::open_file",
51    );
52    Ok(ClientBuilder::new()
53        .path(path.as_ref())
54        .journal_mode(JournalMode::Wal)
55        .open()
56        .await?)
57}
58
59/// Open a database file from a specific journal mode.
60pub async fn open_file_with_journal_mode(
61    path: impl AsRef<Path>,
62    mode: JournalMode,
63) -> Result<Client> {
64    Ok(ClientBuilder::new()
65        .path(path.as_ref())
66        .journal_mode(mode)
67        .open()
68        .await?)
69}
70
71/// Open an in-memory database and run migrations.
72pub async fn open_memory() -> Result<Client> {
73    let mut client = ClientBuilder::new().open().await?;
74    crate::migrations::migrate_client(&mut client).await?;
75    Ok(client)
76}
77
78#[cfg(debug_assertions)]
79#[allow(dead_code)]
80pub(crate) fn dump_rows<C>(
81    conn: C,
82    table: &str,
83) -> std::result::Result<(), async_sqlite::rusqlite::Error>
84where
85    C: std::ops::Deref<Target = async_sqlite::rusqlite::Connection>,
86{
87    println!("--- BEGIN DUMP ---");
88    let mut stmt = conn.prepare(&format!(
89        r#"
90            SELECT * FROM {}
91        "#,
92        table
93    ))?;
94    let mut rows = stmt.query([])?;
95    while let Ok(Some(row)) = rows.next() {
96        println!("{:#?}", row);
97    }
98    println!("--- END DUMP ---");
99    Ok(())
100}