Added in-memory database support to storage and switched tests to use it.
CI / Formatting (push) Failing after 32s
CI / Linting (push) Successful in 34s
CI / Tests (Python 3.12) (push) Successful in 39s
CI / Tests (Python 3.13) (push) Successful in 26s
CI / Tests (Python 3.14) (push) Successful in 16s
CI / Type Checking (push) Successful in 21s
CI / Spelling (push) Successful in 18s

This commit is contained in:
2026-04-04 18:48:27 -04:00
parent 15e9cd6131
commit 7957ceabfa
3 changed files with 20 additions and 18 deletions
+14 -5
View File
@@ -21,13 +21,13 @@ import contextlib
import contextvars
import logging
from contextlib import asynccontextmanager
from pathlib import Path
from typing import TYPE_CHECKING, Any
import aiosqlite
if TYPE_CHECKING:
from collections.abc import AsyncIterator
from pathlib import Path
class StorageError(Exception):
@@ -41,6 +41,9 @@ class ModuleStorage:
created lazily on the first storage operation and reused for all
subsequent calls. WAL mode is enabled for crash resilience.
Pass ``None`` as ``storage_dir`` to use an in-memory database
instead of a file, which is useful for testing.
Each storage operation (execute, fetch_one, etc.) auto-commits on
success and rolls back on failure. No transaction state is held
between calls.
@@ -50,13 +53,18 @@ class ModuleStorage:
unit.
"""
def __init__(self, storage_dir: Path, module_name: str):
def __init__(self, storage_dir: Path | None, module_name: str):
"""Initialize the storage API.
:param storage_dir: Directory where module databases are stored.
Pass ``None`` to use an in-memory database (useful for tests).
:param module_name: Name of the module this storage belongs to.
"""
self._db_path = storage_dir / f"{module_name}.db"
self._db_path: Path | str = (
storage_dir / f"{module_name}.db"
if storage_dir is not None
else ":memory:"
)
self._module_name = module_name
self._conn: aiosqlite.Connection | None = None
self._closed = False
@@ -242,7 +250,8 @@ class ModuleStorage:
raise StorageError("Storage is closed")
if self._conn is not None:
return self._conn
self._db_path.parent.mkdir(parents=True, exist_ok=True)
if isinstance(self._db_path, Path):
self._db_path.parent.mkdir(parents=True, exist_ok=True)
conn = await aiosqlite.connect(self._db_path)
try:
conn.row_factory = aiosqlite.Row
@@ -257,7 +266,7 @@ class ModuleStorage:
await asyncio.shield(conn.close())
raise
self._conn = conn
self._logger.info(f"Database opened at: {self._db_path.absolute()}")
self._logger.info(f"Database opened at: {self._db_path}")
return conn
@asynccontextmanager