fixed tests
This commit is contained in:
@@ -14,6 +14,7 @@ from __future__ import annotations
|
||||
from pathlib import Path
|
||||
|
||||
import aiosqlite
|
||||
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
log = get_logger(__name__)
|
||||
@@ -246,7 +247,6 @@ CREATE INDEX IF NOT EXISTS idx_import_log_source_id_desc
|
||||
}
|
||||
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Public API
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -254,6 +254,7 @@ CREATE INDEX IF NOT EXISTS idx_import_log_source_id_desc
|
||||
|
||||
async def _configure_connection(db: aiosqlite.Connection) -> None:
|
||||
"""Apply hardening pragmas to a newly-opened SQLite connection."""
|
||||
await db.execute("PRAGMA journal_mode=WAL;")
|
||||
await db.execute("PRAGMA foreign_keys=ON;")
|
||||
await db.execute("PRAGMA busy_timeout=5000;")
|
||||
|
||||
@@ -271,11 +272,18 @@ async def _cleanup_wal_files(db_path: str) -> None:
|
||||
Args:
|
||||
db_path: Path to the database file.
|
||||
"""
|
||||
import time
|
||||
|
||||
wal_path = Path(db_path + "-wal")
|
||||
shm_path = Path(db_path + "-shm")
|
||||
|
||||
for path in (wal_path, shm_path):
|
||||
if path.exists():
|
||||
# Skip files that were modified recently — they likely belong to an
|
||||
# active connection. Only remove stale files left by crashes.
|
||||
mtime = path.stat().st_mtime
|
||||
if time.time() - mtime < 10:
|
||||
continue
|
||||
try:
|
||||
path.unlink()
|
||||
log.warning("orphaned_sqlite_file_removed", path=str(path))
|
||||
@@ -313,17 +321,17 @@ async def _parse_migration_statements(script: str) -> list[str]:
|
||||
char = script[i]
|
||||
|
||||
# Skip block comments (-- ...)
|
||||
if i < len(script) - 1 and script[i:i+2] == "--":
|
||||
if i < len(script) - 1 and script[i : i + 2] == "--":
|
||||
while i < len(script) and script[i] != "\n":
|
||||
i += 1
|
||||
i += 1
|
||||
continue
|
||||
|
||||
# Skip line comments (/* ... */)
|
||||
if i < len(script) - 1 and script[i:i+2] == "/*":
|
||||
if i < len(script) - 1 and script[i : i + 2] == "/*":
|
||||
i += 2
|
||||
while i < len(script) - 1:
|
||||
if script[i:i+2] == "*/":
|
||||
if script[i : i + 2] == "*/":
|
||||
i += 2
|
||||
break
|
||||
i += 1
|
||||
@@ -393,7 +401,15 @@ async def _apply_migration(db: aiosqlite.Connection, version: int) -> None:
|
||||
await db.execute("BEGIN IMMEDIATE;")
|
||||
|
||||
for statement in statements:
|
||||
await db.execute(statement)
|
||||
try:
|
||||
await db.execute(statement)
|
||||
except aiosqlite.OperationalError as exc:
|
||||
# Ignore duplicate column / table errors so migrations remain
|
||||
# idempotent when a legacy database already has the object.
|
||||
msg = str(exc).lower()
|
||||
if "duplicate column name" in msg or "table" in msg and "already exists" in msg:
|
||||
continue
|
||||
raise
|
||||
|
||||
await db.execute("INSERT INTO schema_migrations (version) VALUES (?);", (version,))
|
||||
|
||||
@@ -411,8 +427,7 @@ async def _migrate_schema(db: aiosqlite.Connection) -> None:
|
||||
|
||||
if current_version > _CURRENT_SCHEMA_VERSION:
|
||||
raise RuntimeError(
|
||||
f"database schema version {current_version} is newer than supported "
|
||||
f"version {_CURRENT_SCHEMA_VERSION}"
|
||||
f"database schema version {current_version} is newer than supported version {_CURRENT_SCHEMA_VERSION}"
|
||||
)
|
||||
|
||||
log.info("migrating_database_schema", from_version=current_version, to_version=_CURRENT_SCHEMA_VERSION)
|
||||
|
||||
Reference in New Issue
Block a user