Files
vm-core/ledger/migrate.py
2025-12-27 00:10:32 +00:00

53 lines
1.4 KiB
Python

from __future__ import annotations
import sqlite3
from pathlib import Path
THIS_FILE = Path(__file__).resolve()
PKG_DIR = THIS_FILE.parent
SCHEMA_DIR = PKG_DIR / "schema"
def _ensure_migrations_table(conn: sqlite3.Connection) -> None:
conn.execute(
"""
CREATE TABLE IF NOT EXISTS migrations (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
);
"""
)
def _applied_migrations(conn: sqlite3.Connection) -> set[str]:
_ensure_migrations_table(conn)
rows = conn.execute("SELECT name FROM migrations;").fetchall()
names: set[str] = set()
for row in rows:
try:
names.add(row["name"])
except Exception:
names.add(row[0])
return names
def _migration_files() -> list[Path]:
if not SCHEMA_DIR.exists():
return []
files = [p for p in SCHEMA_DIR.iterdir() if p.is_file() and p.suffix == ".sql"]
files.sort(key=lambda p: p.name)
return files
def migrate(conn: sqlite3.Connection) -> None:
applied = _applied_migrations(conn)
for path in _migration_files():
name = path.name
if name in applied:
continue
sql = path.read_text(encoding="utf-8")
conn.executescript(sql)
conn.execute("INSERT INTO migrations (name) VALUES (?);", (name,))