Skip to main content

elph_agent/datastore/
mod.rs

1//! Turso local database helpers and migration runner.
2
3mod lazy;
4mod migrations;
5
6use std::path::Path;
7
8use anyhow::Result;
9use turso::Builder;
10
11pub use crate::migration::Migration;
12pub use lazy::ensure_databases_once;
13pub use migrations::run as run_migrations;
14
15/// A local database file and its pending migrations.
16pub struct DatabaseSpec<'a> {
17    pub path: &'a Path,
18    pub migrations: &'static [Migration],
19}
20
21/// Initialize one local Turso database and apply pending migrations.
22pub async fn ensure_database(path: &Path, migrations: &'static [Migration]) -> Result<()> {
23    ensure_parent_dir(path)?;
24    open_and_migrate(path, migrations).await
25}
26
27/// Initialize multiple local Turso databases.
28pub async fn ensure_databases(specs: &[DatabaseSpec<'_>]) -> Result<()> {
29    for spec in specs {
30        ensure_database(spec.path, spec.migrations).await?;
31    }
32    Ok(())
33}
34
35async fn open_and_migrate(path: &Path, migrations: &'static [Migration]) -> Result<()> {
36    let db = Builder::new_local(&path.to_string_lossy()).build().await?;
37    let conn = db.connect()?;
38    migrations::run(&conn, migrations).await?;
39    Ok(())
40}
41
42fn ensure_parent_dir(path: &Path) -> Result<()> {
43    if let Some(parent) = path.parent() {
44        std::fs::create_dir_all(parent)?;
45    }
46    Ok(())
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    static TEST_MIGRATIONS: [Migration; 1] = [Migration {
54        version: 1,
55        name: "create_notes",
56        up: "CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, body TEXT NOT NULL)",
57    }];
58
59    #[tokio::test]
60    async fn ensure_database_applies_migrations() {
61        let tmp = tempfile::tempdir().expect("tempdir");
62        let db_path = tmp.path().join("test.db");
63
64        ensure_database(&db_path, &TEST_MIGRATIONS)
65            .await
66            .expect("ensure database");
67
68        assert!(db_path.exists());
69    }
70}