from sqlalchemy import insert, select, update, and_ from app.dao.base import BaseDAO from app.database import async_session_maker from app.users.models import Users from app.users.chat.models import Chats, Messages, UsersXChats class ChatDAO(BaseDAO): model = Chats @classmethod async def create(cls, user_id: int, chat_name: str, created_by: int) -> int: query = insert(Chats).values(chat_for=user_id, chat_name=chat_name, created_by=created_by).returning(Chats.id) async with async_session_maker() as session: result = await session.execute(query) await session.commit() result = result.scalar() return result @classmethod async def add_user_to_chat(cls, user_id: int, chat_id: int): query = insert(UsersXChats).values(user_id=user_id, chat_id=chat_id) async with async_session_maker() as session: await session.execute(query) await session.commit() return True @classmethod async def send_message(cls, user_id, chat_id: int, message: str): query = (insert(Messages).values(chat_id=chat_id, user_id=user_id, message=message, image_url=None) .returning(Messages.id)) async with async_session_maker() as session: result = await session.execute(query) await session.commit() return result.scalar() @classmethod async def get_message_by_id(cls, message_id: int): query = (select(Messages.message, Messages.image_url, Messages.chat_id, Messages.user_id, Messages.created_at, Users.avatar_image, Users.username).select_from(Messages) .join(Users, Users.id == Messages.user_id) .where( and_( Messages.id == message_id, Messages.visibility == True ) )) async with async_session_maker() as session: result = await session.execute(query) result = result.mappings().all() if result: return result[0] @classmethod async def delete_message(cls, message_id: int): query = update(Messages).where(Messages.id == message_id).values(visibility=False) async with async_session_maker() as session: await session.execute(query) await session.commit() return True @classmethod async def delete_chat(cls, chat_id: int, user_id: int): pass @classmethod async def get_some_messages(cls, chat_id: int, message_number_from: int, messages_to_get: int): """ WITH messages_with_users AS ( SELECT * FROM messages LEFT JOIN users ON messages.user_id = users.id ) SELECT message, image_url, chat_id, user_id, created_at, avatar_image FROM messages_with_users WHERE visibility = true AND chat_id = 2 ORDER BY created_at DESC LIMIT 15 OFFSET 0; """ messages_with_users = ( select(Messages.__table__.columns, Users.__table__.columns) .select_from(Messages) .join(Users, Messages.user_id == Users.id)).cte('messages_with_users') messages = (select(messages_with_users.c.message, messages_with_users.c.image_url, messages_with_users.c.chat_id, messages_with_users.c.user_id, messages_with_users.c.created_at, messages_with_users.c.avatar_image, messages_with_users.c.username ) .where( and_( messages_with_users.c.chat_id == chat_id, messages_with_users.c.visibility == True ) ).order_by(messages_with_users.c.created_at.desc()).limit(messages_to_get).offset(message_number_from)) async with async_session_maker() as session: result = await session.execute(messages) result = result.mappings().all() if result: result = [dict(res) for res in result] return result