"""SQLite persistence for encrypted enrollment templates.""" import os from pathlib import Path from sqlalchemy import LargeBinary, String, create_engine from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, sessionmaker DATABASE_URL = os.environ.get( "SIGVERIFY_DATABASE_URL", f"sqlite:///{(Path(__file__).resolve().parents[1] / 'data' / 'signatures.sqlite3').as_posix()}", ) engine = create_engine( DATABASE_URL, connect_args={"check_same_thread": False} if DATABASE_URL.startswith("sqlite") else {}, ) SessionLocal = sessionmaker(bind=engine, expire_on_commit=False) class Base(DeclarativeBase): """Declarative base for API database tables.""" class SignatureTemplate(Base): """An encrypted sample belonging to one claimed user identity.""" __tablename__ = "signature_templates" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) user_id: Mapped[str] = mapped_column(String(200), index=True) encrypted_payload: Mapped[bytes] = mapped_column(LargeBinary) def initialize_database() -> None: """Create missing tables and ensure the SQLite data directory exists.""" if DATABASE_URL.startswith("sqlite:///"): Path(DATABASE_URL.removeprefix("sqlite:///")).parent.mkdir(parents=True, exist_ok=True) Base.metadata.create_all(engine)