"""Peewee SQLite database instance and initialization.""" from peewee import SqliteDatabase from imptune.config import DB_PATH # Deferred init — path is set at runtime via init_db() so tests can override DB_PATH db = SqliteDatabase(None) def init_db() -> None: """Initialize the SQLite database with WAL mode and foreign keys. Idempotent — safe to call on every application startup. Creates all ORM tables if they do not already exist. Closes any existing connection before re-initializing so that test fixtures can monkeypatch DB_PATH between test runs. """ from imptune.db.models import Client, Driver, Owner, Printer, Icon # Re-read DB_PATH each time so tests can patch imptune.config.DB_PATH import imptune.config as cfg # Close any lingering connection from a previous run (important for tests) if not db.is_closed(): db.close() db.init( cfg.DB_PATH, pragmas={ "journal_mode": "wal", "foreign_keys": 1, }, ) db.connect(reuse_if_open=True) db.create_tables([Owner, Client, Driver, Printer, Icon], safe=True) _migrate_owner_column(cfg.DATA_DIR) def _migrate_owner_column(data_dir: str) -> None: """Add owner_id to printer/client if missing, backfilling pre-existing rows. Runs against a DB created before per-owner scoping existed. Idempotent: a no-op once the column exists and no rows are left with a NULL owner_id. """ from pathlib import Path from imptune.db.models import Client, Owner, Printer from imptune.services.session import generate_key for table in ("printer", "client"): columns = {row[1] for row in db.execute_sql(f"PRAGMA table_info({table})")} if "owner_id" not in columns: db.execute_sql( f"ALTER TABLE {table} ADD COLUMN owner_id INTEGER REFERENCES owner (id)" ) orphaned = Printer.select().where(Printer.owner.is_null()).count() or Client.select().where( Client.owner.is_null() ).count() if not orphaned: return legacy_owner = Owner.create(key=generate_key(), is_permanent=True) Printer.update(owner=legacy_owner.id).where(Printer.owner.is_null()).execute() Client.update(owner=legacy_owner.id).where(Client.owner.is_null()).execute() key_path = Path(data_dir) / "legacy_owner_key.txt" key_path.write_text(legacy_owner.key, encoding="utf-8") print(f"[imptune] Pre-existing printers/clients migrated to a legacy owner. " f"Restore key written to {key_path} — paste it into /session/restore to reclaim them.")