"""Lazy async engine + session-factory singletons. The factories read ``IX_POSTGRES_URL`` from the environment on first call. In Task 3.2 this switches to ``get_config()``; for now we go through ``os.environ`` directly so the store module doesn't depend on config that doesn't exist yet. Both factories are idempotent on success — repeat calls return the same engine / sessionmaker. ``reset_engine`` nukes the cache and should only be used in tests (where we teardown-recreate the DB between sessions). """ from __future__ import annotations import os from sqlalchemy.ext.asyncio import ( AsyncEngine, AsyncSession, async_sessionmaker, create_async_engine, ) _engine: AsyncEngine | None = None _session_factory: async_sessionmaker[AsyncSession] | None = None def _resolve_url() -> str: """Grab the Postgres URL from the environment. Task 3.2 refactors this to go through ``ix.config.get_config()``; this version keeps the store module usable during the bootstrap window where ``ix.config`` doesn't exist yet. Behaviour after refactor is identical — both paths ultimately read ``IX_POSTGRES_URL``. """ try: from ix.config import get_config except ImportError: url = os.environ.get("IX_POSTGRES_URL") if not url: raise RuntimeError( "IX_POSTGRES_URL is not set and ix.config is unavailable" ) from None return url return get_config().postgres_url def get_engine() -> AsyncEngine: """Return the process-wide async engine; create on first call.""" global _engine if _engine is None: _engine = create_async_engine(_resolve_url(), pool_pre_ping=True) return _engine def get_session_factory() -> async_sessionmaker[AsyncSession]: """Return the process-wide session factory; create on first call. ``expire_on_commit=False`` so ORM instances stay usable after ``commit()`` — we frequently commit inside a repo method and then ``model_validate`` the row outside the session. """ global _session_factory if _session_factory is None: _session_factory = async_sessionmaker(get_engine(), expire_on_commit=False) return _session_factory def reset_engine() -> None: """Drop the cached engine + session factory. Test-only.""" global _engine, _session_factory _engine = None _session_factory = None