orchai/src-tauri/src/db.rs

97 lines
2.7 KiB
Rust

use rusqlite::{Connection, Result};
use std::path::Path;
const MIGRATION_001: &str = include_str!("../migrations/001_init.sql");
const MIGRATION_002: &str = include_str!("../migrations/002_add_last_polled.sql");
const MIGRATION_003: &str = include_str!("../migrations/003_add_agents.sql");
pub fn init(db_path: &Path) -> Result<Connection> {
let conn = Connection::open(db_path)?;
configure(&conn)?;
migrate(&conn)?;
Ok(conn)
}
#[cfg(test)]
pub fn init_in_memory() -> Result<Connection> {
let conn = Connection::open_in_memory()?;
configure(&conn)?;
migrate(&conn)?;
Ok(conn)
}
fn configure(conn: &Connection) -> Result<()> {
conn.pragma_update(None, "journal_mode", "wal")?;
conn.pragma_update(None, "foreign_keys", "ON")?;
Ok(())
}
fn migrate(conn: &Connection) -> Result<()> {
let version: i32 = conn.pragma_query_value(None, "user_version", |row| row.get(0))?;
if version < 1 {
conn.execute_batch(MIGRATION_001)?;
conn.pragma_update(None, "user_version", 1)?;
}
if version < 2 {
conn.execute_batch(MIGRATION_002)?;
conn.pragma_update(None, "user_version", 2)?;
}
if version < 3 {
conn.execute_batch(MIGRATION_003)?;
conn.pragma_update(None, "user_version", 3)?;
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_init_in_memory_creates_tables() {
let conn = init_in_memory().expect("should initialize");
// Verify all 7 tables exist
let tables: Vec<String> = conn
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name")
.unwrap()
.query_map([], |row| row.get(0))
.unwrap()
.collect::<Result<Vec<String>, _>>()
.unwrap();
assert_eq!(
tables,
vec![
"agents",
"notifications",
"processed_tickets",
"projects",
"tuleap_credentials",
"watched_trackers",
"worktrees",
]
);
}
#[test]
fn test_init_in_memory_enables_foreign_keys() {
let conn = init_in_memory().expect("should initialize");
let fk_enabled: i32 = conn
.query_row("PRAGMA foreign_keys", [], |row| row.get(0))
.unwrap();
assert_eq!(fk_enabled, 1);
}
#[test]
fn test_migration_is_idempotent() {
let conn = init_in_memory().expect("should initialize");
// Running init again on same connection should not fail
let version: i32 = conn
.pragma_query_value(None, "user_version", |row| row.get(0))
.unwrap();
assert_eq!(version, 3);
}
}