185 lines
7.1 KiB
Python
185 lines
7.1 KiB
Python
"""
|
||
Репозитории для работы с моделями базы данных системы тестирования
|
||
"""
|
||
|
||
from typing import Optional, List
|
||
from sqlalchemy.orm import Session
|
||
from sqlalchemy import and_, or_
|
||
from database.models import (
|
||
User, Message, BotSettings, Test, TestCategory, Question,
|
||
AnswerOption, TestResult, UserAnswer, Image
|
||
)
|
||
import logging
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
class UserRepository:
|
||
"""Репозиторий для работы с пользователями"""
|
||
|
||
@staticmethod
|
||
def create_user(session: Session, telegram_id: int, username: str = None,
|
||
first_name: str = None, last_name: str = None) -> User:
|
||
"""Создание нового пользователя"""
|
||
user = User(
|
||
telegram_id=telegram_id,
|
||
username=username,
|
||
first_name=first_name,
|
||
last_name=last_name
|
||
)
|
||
session.add(user)
|
||
session.flush() # Получаем ID без коммита
|
||
return user
|
||
|
||
@staticmethod
|
||
def get_user_by_telegram_id(session: Session, telegram_id: int) -> Optional[User]:
|
||
"""Получение пользователя по Telegram ID"""
|
||
return session.query(User).filter(User.telegram_id == telegram_id).first()
|
||
|
||
@staticmethod
|
||
def get_user_by_id(session: Session, user_id: int) -> Optional[User]:
|
||
"""Получение пользователя по ID"""
|
||
return session.query(User).filter(User.id == user_id).first()
|
||
|
||
@staticmethod
|
||
def get_all_users(session: Session, active_only: bool = True) -> List[User]:
|
||
"""Получение всех пользователей"""
|
||
query = session.query(User)
|
||
if active_only:
|
||
query = query.filter(User.is_active == True)
|
||
return query.all()
|
||
|
||
@staticmethod
|
||
def update_user(session: Session, telegram_id: int, **kwargs) -> Optional[User]:
|
||
"""Обновление данных пользователя"""
|
||
user = UserRepository.get_user_by_telegram_id(session, telegram_id)
|
||
if user:
|
||
for key, value in kwargs.items():
|
||
if hasattr(user, key):
|
||
setattr(user, key, value)
|
||
session.flush()
|
||
return user
|
||
|
||
@staticmethod
|
||
def get_or_create_user(session: Session, telegram_id: int, **kwargs) -> tuple[User, bool]:
|
||
"""Получение или создание пользователя. Возвращает (user, created)"""
|
||
user = UserRepository.get_user_by_telegram_id(session, telegram_id)
|
||
if user:
|
||
return user, False
|
||
else:
|
||
user = UserRepository.create_user(session, telegram_id, **kwargs)
|
||
return user, True
|
||
|
||
class MessageRepository:
|
||
"""Репозиторий для работы с сообщениями"""
|
||
|
||
@staticmethod
|
||
def create_message(session: Session, telegram_message_id: int, user_id: int,
|
||
text: str = None, message_type: str = 'text') -> Message:
|
||
"""Создание нового сообщения"""
|
||
message = Message(
|
||
telegram_message_id=telegram_message_id,
|
||
user_id=user_id,
|
||
text=text,
|
||
message_type=message_type
|
||
)
|
||
session.add(message)
|
||
session.flush()
|
||
return message
|
||
|
||
@staticmethod
|
||
def get_messages_by_user(session: Session, user_id: int, limit: int = 100) -> List[Message]:
|
||
"""Получение сообщений пользователя"""
|
||
return (session.query(Message)
|
||
.filter(Message.user_id == user_id)
|
||
.order_by(Message.created_at.desc())
|
||
.limit(limit)
|
||
.all())
|
||
|
||
@staticmethod
|
||
def get_recent_messages(session: Session, limit: int = 100) -> List[Message]:
|
||
"""Получение последних сообщений"""
|
||
return (session.query(Message)
|
||
.order_by(Message.created_at.desc())
|
||
.limit(limit)
|
||
.all())
|
||
|
||
class SettingsRepository:
|
||
"""Репозиторий для работы с настройками бота"""
|
||
|
||
@staticmethod
|
||
def get_setting(session: Session, key: str) -> Optional[str]:
|
||
"""Получение значения настройки"""
|
||
setting = session.query(BotSettings).filter(BotSettings.key == key).first()
|
||
return setting.value if setting else None
|
||
|
||
@staticmethod
|
||
def set_setting(session: Session, key: str, value: str, description: str = None) -> BotSettings:
|
||
"""Установка значения настройки"""
|
||
setting = session.query(BotSettings).filter(BotSettings.key == key).first()
|
||
if setting:
|
||
setting.value = value
|
||
if description:
|
||
setting.description = description
|
||
else:
|
||
setting = BotSettings(key=key, value=value, description=description)
|
||
session.add(setting)
|
||
session.flush()
|
||
return setting
|
||
|
||
@staticmethod
|
||
def get_all_settings(session: Session) -> List[BotSettings]:
|
||
"""Получение всех настроек"""
|
||
return session.query(BotSettings).all()
|
||
|
||
@staticmethod
|
||
def delete_setting(session: Session, key: str) -> bool:
|
||
"""Удаление настройки"""
|
||
setting = session.query(BotSettings).filter(BotSettings.key == key).first()
|
||
if setting:
|
||
session.delete(setting)
|
||
session.flush()
|
||
return True
|
||
return False
|
||
|
||
|
||
class ImageRepository:
|
||
"""Репозиторий для работы с изображениями"""
|
||
|
||
@staticmethod
|
||
def create_image(session: Session, filename: str, content_type: str,
|
||
image_data: bytes, alt_text: str = None) -> Image:
|
||
"""Создание записи изображения"""
|
||
image = Image(
|
||
filename=filename,
|
||
content_type=content_type,
|
||
file_size=len(image_data),
|
||
image_data=image_data,
|
||
alt_text=alt_text
|
||
)
|
||
session.add(image)
|
||
session.flush()
|
||
return image
|
||
|
||
@staticmethod
|
||
def get_image_by_id(session: Session, image_id: int) -> Optional[Image]:
|
||
"""Получение изображения по ID"""
|
||
return session.query(Image).filter(Image.id == image_id).first()
|
||
|
||
@staticmethod
|
||
def get_image_by_filename(session: Session, filename: str) -> Optional[Image]:
|
||
"""Получение изображения по имени файла"""
|
||
return session.query(Image).filter(Image.filename == filename).first()
|
||
|
||
@staticmethod
|
||
def get_all_images(session: Session) -> List[Image]:
|
||
"""Получение всех изображений"""
|
||
return session.query(Image).all()
|
||
|
||
@staticmethod
|
||
def delete_image(session: Session, image_id: int) -> bool:
|
||
"""Удаление изображения"""
|
||
image = session.query(Image).filter(Image.id == image_id).first()
|
||
if image:
|
||
session.delete(image)
|
||
return True
|
||
return False |