from contextlib import asynccontextmanager from typing import AsyncIterator from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.exc import IntegrityError from fooder.repository.user import UserRepository from fooder.repository.product import ProductRepository from fooder.repository.user_product_usage import UserProductUsageRepository from fooder.repository.user_settings import UserSettingsRepository from fooder.domain import User, Product, UserProductUsage, UserSettings from fooder.exc import Conflict class Repository: def __init__(self, session: AsyncSession): self.session = session self.user = UserRepository(User, session) self.product = ProductRepository(Product, session) self.user_product_usage = UserProductUsageRepository(UserProductUsage, session) self.user_settings = UserSettingsRepository(UserSettings, session) async def commit(self) -> None: try: await self.session.commit() except IntegrityError: raise Conflict() async def rollback(self) -> None: await self.session.rollback() @asynccontextmanager async def transaction(self) -> AsyncIterator["Repository"]: try: yield self await self.commit() except Exception: await self.rollback() raise