slave-framework 0.7.0

Runtime for slave apps (a Laravel-inspired Rust framework for MCP-first apps): server lifecycle, config, logging, Turso Cloud database and migrations, and OpenID Connect sign-in
Documentation
//! Connections to a real libSQL server (see `slave_framework::testing`).

use slave_framework::migration::drop_all_tables;
use slave_framework::testing::TestDatabase;

#[tokio::test]
async fn connections_enforce_foreign_keys_and_share_data() {
    let db = TestDatabase::start();
    let database = db.database().await;
    let conn = database.connect().await.unwrap();
    conn.execute("CREATE TABLE a (id INTEGER PRIMARY KEY)", ())
        .await
        .unwrap();
    conn.execute(
        "CREATE TABLE b (a_id INTEGER NOT NULL REFERENCES a(id))",
        (),
    )
    .await
    .unwrap();
    let err = conn.execute("INSERT INTO b (a_id) VALUES (1)", ()).await;
    assert!(err.is_err(), "insert with a dangling reference must fail");

    conn.execute("INSERT INTO a (id) VALUES (7)", ())
        .await
        .unwrap();
    let other = database.connect().await.unwrap();
    let mut rows = other.query("SELECT id FROM a", ()).await.unwrap();
    let id: i64 = rows.next().await.unwrap().unwrap().get(0).unwrap();
    assert_eq!(id, 7);
}

#[tokio::test]
async fn concurrent_writers_all_succeed() {
    let db = TestDatabase::start();
    let database = db.database().await;
    let conn = database.connect().await.unwrap();
    conn.execute("CREATE TABLE t (id INTEGER PRIMARY KEY, n INTEGER)", ())
        .await
        .unwrap();
    let tasks: Vec<_> = (0..20i64)
        .map(|n| {
            let database = database.clone();
            tokio::spawn(async move {
                let conn = database.connect().await?;
                conn.execute("INSERT INTO t (n) VALUES (?1)", [n]).await
            })
        })
        .collect();
    for task in tasks {
        task.await.unwrap().unwrap();
    }
    let mut rows = conn.query("SELECT count(*) FROM t", ()).await.unwrap();
    let count: i64 = rows.next().await.unwrap().unwrap().get(0).unwrap();
    assert_eq!(count, 20);
}

#[tokio::test]
async fn drop_all_tables_empties_the_schema() {
    let db = TestDatabase::start();
    let conn = db.database().await.connect().await.unwrap();
    conn.execute("CREATE TABLE parent (id INTEGER PRIMARY KEY)", ())
        .await
        .unwrap();
    conn.execute("CREATE TABLE child (p INTEGER REFERENCES parent(id))", ())
        .await
        .unwrap();
    conn.execute("CREATE VIEW v AS SELECT * FROM parent", ())
        .await
        .unwrap();
    assert_eq!(drop_all_tables(&conn).await.unwrap(), 2);
    let mut rows = conn
        .query(
            "SELECT count(*) FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%' AND name NOT LIKE 'libsql_%'",
            (),
        )
        .await
        .unwrap();
    let left: i64 = rows.next().await.unwrap().unwrap().get(0).unwrap();
    assert_eq!(left, 0);
}