"""Sound repository for database operations.""" from sqlalchemy import func from sqlmodel import col, select from sqlmodel.ext.asyncio.session import AsyncSession from app.core.logging import get_logger from app.models.sound import Sound from app.repositories.base import BaseRepository logger = get_logger(__name__) class SoundRepository(BaseRepository[Sound]): """Repository for sound operations.""" def __init__(self, session: AsyncSession) -> None: """Initialize the sound repository.""" super().__init__(Sound, session) async def get_by_filename(self, filename: str) -> Sound | None: """Get a sound by filename.""" try: statement = select(Sound).where(Sound.filename == filename) result = await self.session.exec(statement) return result.first() except Exception: logger.exception("Failed to get sound by filename: %s", filename) raise async def get_by_hash(self, hash_value: str) -> Sound | None: """Get a sound by hash.""" try: statement = select(Sound).where(Sound.hash == hash_value) result = await self.session.exec(statement) return result.first() except Exception: logger.exception("Failed to get sound by hash") raise async def get_by_type(self, sound_type: str) -> list[Sound]: """Get all sounds by type.""" try: statement = select(Sound).where(Sound.type == sound_type) result = await self.session.exec(statement) return list(result.all()) except Exception: logger.exception("Failed to get sounds by type: %s", sound_type) raise async def search_by_name(self, query: str) -> list[Sound]: """Search sounds by name (case-insensitive).""" try: statement = select(Sound).where( func.lower(Sound.name).like(f"%{query.lower()}%"), ) result = await self.session.exec(statement) return list(result.all()) except Exception: logger.exception("Failed to search sounds by name: %s", query) raise async def get_popular_sounds(self, limit: int = 10) -> list[Sound]: """Get the most played sounds.""" try: statement = select(Sound).order_by(Sound.play_count.desc()).limit(limit) result = await self.session.exec(statement) return list(result.all()) except Exception: logger.exception("Failed to get popular sounds") raise async def get_unnormalized_sounds(self) -> list[Sound]: """Get all sounds that haven't been normalized yet.""" try: statement = select(Sound).where(Sound.is_normalized == False) # noqa: E712 result = await self.session.exec(statement) return list(result.all()) except Exception: logger.exception("Failed to get unnormalized sounds") raise async def get_unnormalized_sounds_by_type(self, sound_type: str) -> list[Sound]: """Get unnormalized sounds by type.""" try: statement = select(Sound).where( Sound.type == sound_type, Sound.is_normalized == False, # noqa: E712 ) result = await self.session.exec(statement) return list(result.all()) except Exception: logger.exception( "Failed to get unnormalized sounds by type: %s", sound_type, ) raise async def get_by_types(self, sound_types: list[str] | None = None) -> list[Sound]: """Get sounds by types. If types is None or empty, return all sounds.""" try: statement = select(Sound) if sound_types: statement = statement.where(col(Sound.type).in_(sound_types)) result = await self.session.exec(statement) return list(result.all()) except Exception: logger.exception("Failed to get sounds by types: %s", sound_types) raise