"""chat stats Revision ID: d4a7e2b91f38 Revises: c1f6b3d84a92 Create Date: 2026-08-06 12:30:00.000000 """ from collections.abc import Sequence from alembic import op revision: str = "d4a7e2b91f38" down_revision: str | None = "c1f6b3d84a92" branch_labels: str | Sequence[str] | None = None depends_on: str | Sequence[str] | None = None _APPLY = """ CREATE FUNCTION chat_stats_apply() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN IF TG_OP = 'INSERT' THEN INSERT INTO chat_stats AS cs (account_id, chat_id, message_count, last_date, last_message_id, last_text, last_sender_id) VALUES (NEW.account_id, NEW.chat_id, 1, CASE WHEN NEW.date <= now() + interval '1 day' THEN NEW.date END, CASE WHEN NEW.date <= now() + interval '1 day' THEN NEW.message_id END, NEW.text, NEW.sender_id) ON CONFLICT (account_id, chat_id) DO UPDATE SET message_count = cs.message_count + 1, last_date = CASE WHEN chat_stats_newer(cs, EXCLUDED) THEN EXCLUDED.last_date ELSE cs.last_date END, last_message_id = CASE WHEN chat_stats_newer(cs, EXCLUDED) THEN EXCLUDED.last_message_id ELSE cs.last_message_id END, last_text = CASE WHEN chat_stats_newer(cs, EXCLUDED) THEN EXCLUDED.last_text ELSE cs.last_text END, last_sender_id = CASE WHEN chat_stats_newer(cs, EXCLUDED) THEN EXCLUDED.last_sender_id ELSE cs.last_sender_id END; ELSE UPDATE chat_stats SET last_text = NEW.text, last_sender_id = NEW.sender_id WHERE account_id = NEW.account_id AND chat_id = NEW.chat_id AND last_message_id = NEW.message_id; END IF; RETURN NULL; END; $$ """ _NEWER = """ CREATE FUNCTION chat_stats_newer(current chat_stats, incoming chat_stats) RETURNS boolean LANGUAGE sql IMMUTABLE AS $$ SELECT incoming.last_date IS NOT NULL AND (current.last_date IS NULL OR (incoming.last_date, incoming.last_message_id) > (current.last_date, current.last_message_id)) $$ """ _BACKFILL = """ INSERT INTO chat_stats (account_id, chat_id, message_count, last_date, last_message_id, last_text, last_sender_id) SELECT agg.account_id, agg.chat_id, agg.message_count, last.date, last.message_id, last.text, last.sender_id FROM ( SELECT account_id, chat_id, count(*) AS message_count FROM messages GROUP BY account_id, chat_id ) agg LEFT JOIN LATERAL ( SELECT date, message_id, text, sender_id FROM messages m WHERE m.account_id = agg.account_id AND m.chat_id = agg.chat_id AND m.date <= now() + interval '1 day' ORDER BY m.date DESC, m.message_id DESC LIMIT 1 ) last ON true """ def upgrade() -> None: op.execute( "CREATE TABLE chat_stats (" "account_id integer NOT NULL, " "chat_id bigint NOT NULL, " "message_count bigint NOT NULL DEFAULT 0, " "last_date timestamptz, " "last_message_id bigint, " "last_text text, " "last_sender_id bigint, " "PRIMARY KEY (account_id, chat_id))" ) op.execute(_BACKFILL) op.execute( "CREATE INDEX ix_chat_stats_recent ON chat_stats " "(account_id, last_date DESC, chat_id DESC)" ) op.execute(_NEWER) op.execute(_APPLY) op.execute( "CREATE TRIGGER messages_chat_stats_insert AFTER INSERT ON messages " "FOR EACH ROW EXECUTE FUNCTION chat_stats_apply()" ) op.execute( "CREATE TRIGGER messages_chat_stats_update AFTER UPDATE ON messages " "FOR EACH ROW WHEN (OLD.text IS DISTINCT FROM NEW.text " "OR OLD.sender_id IS DISTINCT FROM NEW.sender_id) " "EXECUTE FUNCTION chat_stats_apply()" ) def downgrade() -> None: op.execute("DROP TRIGGER IF EXISTS messages_chat_stats_update ON messages") op.execute("DROP TRIGGER IF EXISTS messages_chat_stats_insert ON messages") op.execute("DROP FUNCTION IF EXISTS chat_stats_apply()") op.execute("DROP FUNCTION IF EXISTS chat_stats_newer(chat_stats, chat_stats)") op.execute("DROP TABLE IF EXISTS chat_stats")