from typing import Annotated, Literal from uuid import UUID from fastapi import Depends from sqlalchemy.ext.asyncio.session import AsyncSession from sqlmodel import asc, desc, select from ..models.house import House from ..providers.db_provider import get_session class HouseRepository: def __init__(self, session: Annotated[AsyncSession, Depends(get_session)]) -> None: self.session = session async def get_all( self, limit: int = 100, offset: int = 0, order_by: Literal["PRICE"] = "PRICE", sort_order: Literal["ASC", "DESC"] = "DESC", ) -> list[House]: sorter = desc if sort_order == "DESC" else asc statement = ( select(House).offset(offset).limit(limit).order_by(sorter(House.price)) ) result = await self.session.execute(statement) return result.scalars().all() async def get_by_id(self, house_id: UUID): statement = select(House).where(House.id == house_id) result = await self.session.execute(statement) return result.scalar_one_or_none() async def save(self, house: House) -> None: """ Save a house to the database. If a house with that ID already exists, do an upsert. """ existing_house = await self.get_by_id(house.id) if not existing_house: existing_house = house for key, value in house.model_dump(exclude_unset=True).items(): setattr(house, key, value) try: self.session.add(house) await self.session.commit() await self.session.refresh(house) except Exception as e: await self.session.rollback() raise e