from datetime import datetime import asyncpg _INSERT_CHAT_HISTORY = """ INSERT INTO chat_history (account_id, chat_id, message_id, event, title, photo_unique_id, actor_id, ts, raw) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::jsonb) ON CONFLICT DO NOTHING """ _INSERT_CHAT_META = """ INSERT INTO chat_history (account_id, chat_id, message_id, event, title, photo_unique_id, ts, raw) SELECT $1, $2, $3, 'meta', $4::text, $5::text, $6, $7::jsonb WHERE ($4::text, $5::text) IS DISTINCT FROM ( (SELECT title FROM chat_history WHERE account_id = $1 AND chat_id = $2 AND event IN ('meta', 'title') ORDER BY ts DESC LIMIT 1), (SELECT photo_unique_id FROM chat_history WHERE account_id = $1 AND chat_id = $2 AND event IN ('meta', 'photo', 'photo_deleted') ORDER BY ts DESC LIMIT 1) ) ON CONFLICT DO NOTHING """ _INSERT_MEMBERSHIP = """ INSERT INTO memberships (account_id, chat_id, message_id, user_id, event, actor_id, ts, raw) VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb) ON CONFLICT (account_id, chat_id, message_id, user_id) DO NOTHING """ _LATEST_TITLE = """ SELECT title FROM chat_history WHERE account_id = $1 AND chat_id = $2 AND event IN ('meta', 'title') ORDER BY ts DESC LIMIT 1 """ _LATEST_PHOTO = """ SELECT photo_unique_id FROM chat_history WHERE account_id = $1 AND chat_id = $2 AND event IN ('meta', 'photo', 'photo_deleted') ORDER BY ts DESC LIMIT 1 """ async def get_latest_chat_meta( pool: asyncpg.Pool, account_id: int, chat_id: int ) -> tuple[str | None, str | None]: title = await pool.fetchval(_LATEST_TITLE, account_id, chat_id) photo_unique_id = await pool.fetchval(_LATEST_PHOTO, account_id, chat_id) return title, photo_unique_id async def insert_chat_history( # noqa: PLR0913 pool: asyncpg.Pool, account_id: int, chat_id: int, message_id: int, event: str, title: str | None, photo_unique_id: str | None, actor_id: int | None, ts: datetime, raw: str, ) -> None: await pool.execute( _INSERT_CHAT_HISTORY, account_id, chat_id, message_id, event, title, photo_unique_id, actor_id, ts, raw, ) async def record_chat_meta( # noqa: PLR0913 pool: asyncpg.Pool, account_id: int, chat_id: int, message_id: int, title: str | None, photo_unique_id: str | None, ts: datetime, raw: str, ) -> bool: status = await pool.execute( _INSERT_CHAT_META, account_id, chat_id, message_id, title, photo_unique_id, ts, raw, ) return status == "INSERT 0 1" async def insert_membership( # noqa: PLR0913 pool: asyncpg.Pool, account_id: int, chat_id: int, message_id: int, user_id: int, event: str, actor_id: int | None, ts: datetime, raw: str, ) -> None: await pool.execute( _INSERT_MEMBERSHIP, account_id, chat_id, message_id, user_id, event, actor_id, ts, raw, )