use convergio_types::extension::Migration;
pub fn migrations() -> Vec<Migration> {
vec![Migration {
version: 1,
description: "backup tables",
up: "\
CREATE TABLE IF NOT EXISTS backup_snapshots (
id TEXT PRIMARY KEY,
path TEXT NOT NULL,
size_bytes INTEGER NOT NULL DEFAULT 0,
checksum TEXT NOT NULL,
node TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_backup_snap_date
ON backup_snapshots(created_at);
CREATE TABLE IF NOT EXISTS backup_retention_rules (
id INTEGER PRIMARY KEY AUTOINCREMENT,
table_name TEXT NOT NULL,
timestamp_column TEXT NOT NULL DEFAULT 'created_at',
max_age_days INTEGER NOT NULL,
org_id TEXT NOT NULL DEFAULT '__global__',
created_at TEXT NOT NULL DEFAULT (datetime('now')),
UNIQUE(table_name, org_id)
);
CREATE TABLE IF NOT EXISTS backup_purge_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
table_name TEXT NOT NULL,
rows_deleted INTEGER NOT NULL,
cutoff_date TEXT NOT NULL,
executed_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_purge_log_date
ON backup_purge_log(executed_at);",
}]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn migrations_have_sequential_versions() {
let migs = migrations();
assert_eq!(migs.len(), 1);
assert_eq!(migs[0].version, 1);
}
#[test]
fn migrations_apply_to_sqlite() {
let conn = rusqlite::Connection::open_in_memory().unwrap();
for m in migrations() {
conn.execute_batch(m.up).unwrap();
}
let count: i64 = conn
.query_row(
"SELECT COUNT(*) FROM sqlite_master WHERE type='table' \
AND name LIKE 'backup_%'",
[],
|r| r.get(0),
)
.unwrap();
assert_eq!(count, 3);
}
#[test]
fn retention_rules_table_has_unique_constraint() {
let conn = rusqlite::Connection::open_in_memory().unwrap();
for m in migrations() {
conn.execute_batch(m.up).unwrap();
}
conn.execute(
"INSERT INTO backup_retention_rules \
(table_name, max_age_days, org_id) \
VALUES ('audit_log', 365, '__global__')",
[],
)
.unwrap();
let result = conn.execute(
"INSERT INTO backup_retention_rules \
(table_name, max_age_days, org_id) \
VALUES ('audit_log', 30, '__global__')",
[],
);
assert!(result.is_err());
}
}