from __future__ import annotations from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.models.entities import Backend from app.models.entities import BlobReplica class BlobReplicaRepository: def __init__(self, session: AsyncSession) -> None: self.session = session async def get_by_blob_and_backend(self, blob_id: str, backend_id: str) -> BlobReplica | None: result = await self.session.execute( select(BlobReplica).where( BlobReplica.blob_id == blob_id, BlobReplica.backend_id == backend_id, ) ) return result.scalar_one_or_none() async def create(self, replica: BlobReplica) -> BlobReplica: self.session.add(replica) await self.session.flush() await self.session.refresh(replica) return replica async def get_ready_replica_for_blob(self, blob_id: str) -> BlobReplica | None: result = await self.session.execute( select(BlobReplica) .where( BlobReplica.blob_id == blob_id, BlobReplica.status == "ready", ) .order_by(BlobReplica.created_at.asc()) ) return result.scalar_one_or_none() async def list_ready_replicas_with_backends(self, blob_id: str) -> list[tuple[BlobReplica, Backend]]: result = await self.session.execute( select(BlobReplica, Backend) .join(Backend, BlobReplica.backend_id == Backend.id) .where( BlobReplica.blob_id == blob_id, BlobReplica.status == "ready", Backend.is_enabled.is_(True), ) .order_by(Backend.read_priority.desc(), BlobReplica.created_at.asc()) ) return list(result.all()) async def list_by_blob(self, blob_id: str) -> list[BlobReplica]: result = await self.session.execute(select(BlobReplica).where(BlobReplica.blob_id == blob_id)) return list(result.scalars().all()) async def save(self, replica: BlobReplica) -> BlobReplica: await self.session.flush() await self.session.refresh(replica) return replica