chat_back/app/users/chat/dao.py

193 lines
7.9 KiB
Python

from sqlalchemy import insert, select, update, and_, delete
from app.dao.base import BaseDAO
from app.database import async_session_maker
from app.exceptions import UserAlreadyInChatException
from app.users.models import Users
from app.users.chat.models import Chats, Messages, UsersXChats, PinnedChats, PinnedMessages
class ChatDAO(BaseDAO):
model = Chats
@staticmethod
async def create(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
@staticmethod
async def add_user_to_chat(user_id: int, chat_id: int):
query = select(UsersXChats.user_id).where(UsersXChats.chat_id == chat_id)
async with async_session_maker() as session:
result = await session.execute(query)
result = [res['user_id'] for res in result.mappings().all()]
if user_id in result:
raise UserAlreadyInChatException
query = insert(UsersXChats).values(user_id=user_id, chat_id=chat_id)
await session.execute(query)
await session.commit()
return True
@staticmethod
async def send_message(user_id, chat_id: int, message: str, image_url: str | None = None):
query = (insert(Messages).values(chat_id=chat_id, user_id=user_id, message=message, image_url=image_url)
.returning(Messages.id))
async with async_session_maker() as session:
result = await session.execute(query)
await session.commit()
return result.scalar()
@staticmethod
async def get_message_by_id(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]
@staticmethod
async def delete_message(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
@staticmethod
async def get_some_messages(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
@staticmethod
async def delete_chat(chat_id: int):
query = update(Chats).where(Chats.id == chat_id).values(visibility=False)
async with async_session_maker() as session:
await session.execute(query)
await session.commit()
return True
@staticmethod
async def delete_user(chat_id: int, user_id: int):
query = delete(UsersXChats).where(and_(
UsersXChats.chat_id == chat_id,
UsersXChats.user_id == user_id
))
async with async_session_maker() as session:
await session.execute(query)
await session.commit()
return True
@staticmethod
async def pinn_chat(chat_id: int, user_id: int):
query = insert(PinnedChats).values(chat_id=chat_id, user_id=user_id)
async with async_session_maker() as session:
await session.execute(query)
await session.commit()
return True
@staticmethod
async def unpinn_chat(chat_id: int, user_id: int):
query = delete(PinnedChats).where(PinnedChats.chat_id == chat_id, PinnedChats.user_id == user_id)
async with async_session_maker() as session:
await session.execute(query)
await session.commit()
return True
@staticmethod
async def get_pinned_chats(user_id: int):
query = (select(Chats.__table__.columns).select_from(PinnedChats)
.join(Chats, PinnedChats.chat_id == Chats.id, isouter=True)
.where(PinnedChats.user_id == user_id))
async with async_session_maker() as session:
result = await session.execute(query)
result = result.mappings().all()
return result
@staticmethod
async def pinn_message(chat_id: int, message_id: int, user_id: int):
query = insert(PinnedMessages).values(chat_id=chat_id, message_id=message_id, user_id=user_id)
async with async_session_maker() as session:
await session.execute(query)
await session.commit()
return True
@staticmethod
async def get_message_pinner(chat_id: int, message_id: int):
query = select(PinnedMessages.user_id).where(
PinnedMessages.chat_id == chat_id, PinnedMessages.message_id == message_id
)
async with async_session_maker() as session:
result = await session.execute(query)
result = result.scalar()
return result
@staticmethod
async def unpinn_message(chat_id: int, message_id: int):
query = delete(PinnedMessages).where(
PinnedMessages.chat_id == chat_id, PinnedMessages.message_id == message_id
)
async with async_session_maker() as session:
await session.execute(query)
await session.commit()
return True
@staticmethod
async def get_pinned_messages(chat_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(PinnedMessages)
.join(Messages, PinnedMessages.message_id == Messages.id, isouter=True)
.join(Users, PinnedMessages.user_id == Users.id, isouter=True)
.where(PinnedMessages.chat_id == chat_id)
.order_by(Messages.created_at.desc()))
async with async_session_maker() as session:
result = await session.execute(query)
result = result.mappings().all()
return result