use rusqlite::Connection;
pub const CURRENT_VERSION: &str = "1.0.0";
pub fn init_schema(conn: &Connection) -> Result<(), rusqlite::Error> {
conn.execute_batch(
"PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA busy_timeout = 5000;
PRAGMA cache_size = -64000;
PRAGMA temp_store = MEMORY;",
)?;
conn.execute_batch(SCHEMA_SQL)?;
let count: i64 = conn.query_row("SELECT COUNT(*) FROM schema_version", [], |row| row.get(0))?;
if count == 0 {
conn.execute("INSERT INTO schema_version (version) VALUES (?1)", [CURRENT_VERSION])?;
}
Ok(())
}
const SCHEMA_SQL: &str = "
CREATE TABLE IF NOT EXISTS schema_version (
version TEXT NOT NULL,
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS experiments (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
config TEXT,
tags TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS runs (
id TEXT PRIMARY KEY,
experiment_id TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
start_time TEXT,
end_time TEXT,
tags TEXT,
FOREIGN KEY (experiment_id) REFERENCES experiments(id)
);
CREATE INDEX IF NOT EXISTS idx_runs_experiment ON runs(experiment_id);
CREATE INDEX IF NOT EXISTS idx_runs_status ON runs(status);
CREATE TABLE IF NOT EXISTS params (
run_id TEXT NOT NULL,
key TEXT NOT NULL,
value TEXT NOT NULL,
type TEXT NOT NULL,
PRIMARY KEY (run_id, key),
FOREIGN KEY (run_id) REFERENCES runs(id)
);
CREATE TABLE IF NOT EXISTS metrics (
run_id TEXT NOT NULL,
key TEXT NOT NULL,
step INTEGER NOT NULL,
value REAL NOT NULL,
timestamp TEXT NOT NULL DEFAULT (datetime('now')),
FOREIGN KEY (run_id) REFERENCES runs(id)
);
CREATE INDEX IF NOT EXISTS idx_metrics_run_key ON metrics(run_id, key);
CREATE TABLE IF NOT EXISTS artifacts (
id TEXT PRIMARY KEY,
run_id TEXT NOT NULL,
path TEXT NOT NULL,
size_bytes INTEGER,
sha256 TEXT NOT NULL,
data BLOB,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
FOREIGN KEY (run_id) REFERENCES runs(id)
);
CREATE INDEX IF NOT EXISTS idx_artifacts_run ON artifacts(run_id);
CREATE INDEX IF NOT EXISTS idx_artifacts_sha ON artifacts(sha256);
CREATE TABLE IF NOT EXISTS span_ids (
run_id TEXT PRIMARY KEY,
span_id TEXT NOT NULL,
FOREIGN KEY (run_id) REFERENCES runs(id)
);
";