from typing import Optional, List from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from sqlalchemy.orm import selectinload from src.interfaces.base import IUserRepository, ILotteryRepository, IParticipationRepository, IWinnerRepository from src.core.models import User, Lottery, Participation, Winner class UserRepository(IUserRepository): """Репозиторий для работы с пользователями""" def __init__(self, session: AsyncSession): self.session = session async def get_by_telegram_id(self, telegram_id: int) -> Optional[User]: """Получить пользователя по Telegram ID""" result = await self.session.execute( select(User).where(User.telegram_id == telegram_id) ) return result.scalars().first() async def create(self, **kwargs) -> User: """Создать нового пользователя""" user = User(**kwargs) self.session.add(user) await self.session.commit() await self.session.refresh(user) return user async def update(self, user: User) -> User: """Обновить пользователя""" await self.session.commit() await self.session.refresh(user) return user async def get_all(self) -> List[User]: """Получить всех пользователей""" result = await self.session.execute(select(User)) return list(result.scalars().all()) class LotteryRepository(ILotteryRepository): """Репозиторий для работы с розыгрышами""" def __init__(self, session: AsyncSession): self.session = session async def get_by_id(self, lottery_id: int) -> Optional[Lottery]: """Получить розыгрыш по ID""" result = await self.session.execute( select(Lottery).where(Lottery.id == lottery_id) ) return result.scalars().first() async def create(self, **kwargs) -> Lottery: """Создать новый розыгрыш""" lottery = Lottery(**kwargs) self.session.add(lottery) await self.session.commit() await self.session.refresh(lottery) return lottery async def get_active(self) -> List[Lottery]: """Получить активные розыгрыши""" result = await self.session.execute( select(Lottery).where( Lottery.is_active == True, Lottery.is_completed == False ).order_by(Lottery.created_at.desc()) ) return list(result.scalars().all()) async def get_all(self) -> List[Lottery]: """Получить все розыгрыши""" result = await self.session.execute( select(Lottery).order_by(Lottery.created_at.desc()) ) return list(result.scalars().all()) async def update(self, lottery: Lottery) -> Lottery: """Обновить розыгрыш""" await self.session.commit() await self.session.refresh(lottery) return lottery class ParticipationRepository(IParticipationRepository): """Репозиторий для работы с участиями""" def __init__(self, session: AsyncSession): self.session = session async def create(self, **kwargs) -> Participation: """Создать новое участие""" participation = Participation(**kwargs) self.session.add(participation) await self.session.commit() await self.session.refresh(participation) return participation async def get_by_lottery(self, lottery_id: int) -> List[Participation]: """Получить участия по розыгрышу""" result = await self.session.execute( select(Participation) .options(selectinload(Participation.user)) .where(Participation.lottery_id == lottery_id) ) return list(result.scalars().all()) async def get_count_by_lottery(self, lottery_id: int) -> int: """Получить количество участников в розыгрыше""" result = await self.session.execute( select(Participation).where(Participation.lottery_id == lottery_id) ) return len(list(result.scalars().all())) class WinnerRepository(IWinnerRepository): """Репозиторий для работы с победителями""" def __init__(self, session: AsyncSession): self.session = session async def create(self, **kwargs) -> Winner: """Создать запись о победителе""" winner = Winner(**kwargs) self.session.add(winner) await self.session.commit() await self.session.refresh(winner) return winner async def get_by_lottery(self, lottery_id: int) -> List[Winner]: """Получить победителей розыгрыша""" result = await self.session.execute( select(Winner) .options(selectinload(Winner.user)) .where(Winner.lottery_id == lottery_id) .order_by(Winner.place) ) return list(result.scalars().all())