"""PostgreSQL DB-API bridge for legacy '?' SQL (optional, requires psycopg[binary]). No automatic conversion of existing SQLite files is attempted. Production migration requires a tested one-time data migration and reconciliation. """ from __future__ import annotations import re from contextlib import contextmanager def placeholders(sql: str) -> str: """Translate SQLite positional placeholders outside SQL quoted strings.""" out=[];quote=None;i=0 while i str: sql=sql.strip() if re.match(r'^INSERT\s+OR\s+IGNORE\s+INTO\b',sql,re.I): sql=re.sub(r'^INSERT\s+OR\s+IGNORE\s+INTO\b','INSERT INTO',sql,flags=re.I) sql=sql.rstrip(';')+' ON CONFLICT DO NOTHING' return placeholders(sql) class PGConnection: def __init__(self,dsn): import psycopg from psycopg.rows import dict_row self.connection=psycopg.connect(dsn,row_factory=dict_row,connect_timeout=5) self.total_changes=0 def execute(self,sql,params=()): stripped=sql.strip() if stripped.upper().startswith('PRAGMA TABLE_INFO('): table=stripped.split('(',1)[1].split(')',1)[0].strip().strip('"\'') if not re.fullmatch(r'[A-Za-z_][A-Za-z0-9_]*',table):raise ValueError('Invalid table name') return self.connection.execute('SELECT column_name AS name FROM information_schema.columns WHERE table_schema=current_schema() AND table_name=%s',(table,)) if stripped.upper()=='BEGIN IMMEDIATE': # Conservative transaction-wide lock while porting SQLite queue semantics. # Replace with per-site advisory locks before large multi-worker scale. return self.connection.execute('SELECT pg_advisory_xact_lock(823947231)') if stripped.upper().startswith('PRAGMA '): return _EmptyResult() cursor=self.connection.execute(normalize(sql),params) if cursor.rowcount and cursor.rowcount>0 and stripped.split(None,1)[0].upper() in ('UPDATE','INSERT','DELETE'): self.total_changes+=cursor.rowcount return cursor def executescript(self,script): # Schema migrations contain only simple DDL and SQLite PRAGMA statements. for statement in script.split(';'): if statement.strip():self.execute(statement) def __enter__(self):return self def __exit__(self,typ,val,tb): try: if typ:self.connection.rollback() else:self.connection.commit() finally:self.connection.close() return False class _EmptyResult: rowcount=0 def fetchone(self):return None def fetchall(self):return [] def connect(dsn):return PGConnection(dsn)