from sqlalchemy import create_engine, event, text from sqlalchemy.orm import sessionmaker, DeclarativeBase from .config import settings engine = create_engine( settings.database_url, connect_args={"check_same_thread": False}, echo=False, ) @event.listens_for(engine, "connect") def set_sqlite_pragma(dbapi_conn, _): cursor = dbapi_conn.cursor() cursor.execute("PRAGMA journal_mode=WAL") cursor.execute("PRAGMA foreign_keys=ON") cursor.close() SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) class Base(DeclarativeBase): pass FTS_SETUP_SQL = """ CREATE VIRTUAL TABLE IF NOT EXISTS videos_fts USING fts5( title, description, content=videos, content_rowid=id ); CREATE VIRTUAL TABLE IF NOT EXISTS channels_fts USING fts5( name, description, content=channels, content_rowid=id ); CREATE TRIGGER IF NOT EXISTS videos_ai AFTER INSERT ON videos BEGIN INSERT INTO videos_fts(rowid, title, description) VALUES (new.id, new.title, COALESCE(new.description, '')); END; CREATE TRIGGER IF NOT EXISTS videos_ad AFTER DELETE ON videos BEGIN INSERT INTO videos_fts(videos_fts, rowid, title, description) VALUES ('delete', old.id, old.title, COALESCE(old.description, '')); END; CREATE TRIGGER IF NOT EXISTS videos_au AFTER UPDATE ON videos BEGIN INSERT INTO videos_fts(videos_fts, rowid, title, description) VALUES ('delete', old.id, old.title, COALESCE(old.description, '')); INSERT INTO videos_fts(rowid, title, description) VALUES (new.id, new.title, COALESCE(new.description, '')); END; CREATE TRIGGER IF NOT EXISTS channels_ai AFTER INSERT ON channels BEGIN INSERT INTO channels_fts(rowid, name, description) VALUES (new.id, new.name, COALESCE(new.description, '')); END; CREATE TRIGGER IF NOT EXISTS channels_ad AFTER DELETE ON channels BEGIN INSERT INTO channels_fts(channels_fts, rowid, name, description) VALUES ('delete', old.id, old.name, COALESCE(old.description, '')); END; CREATE TRIGGER IF NOT EXISTS channels_au AFTER UPDATE ON channels BEGIN INSERT INTO channels_fts(channels_fts, rowid, name, description) VALUES ('delete', old.id, old.name, COALESCE(old.description, '')); INSERT INTO channels_fts(rowid, name, description) VALUES (new.id, new.name, COALESCE(new.description, '')); END; """ def init_db(): from . import models # noqa: F401 Base.metadata.create_all(bind=engine) # executescript handles multi-statement SQL including trigger BEGIN...END blocks raw_conn = engine.raw_connection() try: raw_conn.executescript(FTS_SETUP_SQL) finally: raw_conn.close() def get_db(): db = SessionLocal() try: yield db finally: db.close()