core: mentions in history, unread mentions in stats (#5594)

* core: mentions in history, unread mentions in stats

* fix

* update plans
This commit is contained in:
Evgeny 2025-01-30 17:59:21 +00:00 committed by GitHub
parent 4ed67f094f
commit 3bc822a1e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 131 additions and 62 deletions

View file

@ -894,16 +894,16 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
in Just (fInv, fileDescrText) in Just (fInv, fileDescrText)
| otherwise = Nothing | otherwise = Nothing
processContentItem :: GroupMember -> ChatItem 'CTGroup d -> MsgContent -> Maybe (FileInvitation, RcvFileDescrText) -> CM [ChatMsgEvent 'Json] processContentItem :: GroupMember -> ChatItem 'CTGroup d -> MsgContent -> Maybe (FileInvitation, RcvFileDescrText) -> CM [ChatMsgEvent 'Json]
processContentItem sender ChatItem {meta, quotedItem} mc fInvDescr_ = processContentItem sender ChatItem {formattedText, meta, quotedItem, mentions} mc fInvDescr_ =
if isNothing fInvDescr_ && not (msgContentHasText mc) if isNothing fInvDescr_ && not (msgContentHasText mc)
then pure [] then pure []
else do else do
let CIMeta {itemTs, itemSharedMsgId, itemTimed} = meta let CIMeta {itemTs, itemSharedMsgId, itemTimed} = meta
quotedItemId_ = quoteItemId =<< quotedItem quotedItemId_ = quoteItemId =<< quotedItem
fInv_ = fst <$> fInvDescr_ fInv_ = fst <$> fInvDescr_
-- TODO [mentions] history? (mc', _, mentions') = updatedMentionNames mc formattedText mentions
-- let (_t, ft_) = msgContentTexts mc mentions'' = M.map (\CIMention {memberId} -> MsgMention {memberId}) mentions'
(chatMsgEvent, _) <- withStore $ \db -> prepareGroupMsg db user gInfo mc M.empty quotedItemId_ Nothing fInv_ itemTimed False (chatMsgEvent, _) <- withStore $ \db -> prepareGroupMsg db user gInfo mc' mentions'' quotedItemId_ Nothing fInv_ itemTimed False
let senderVRange = memberChatVRange' sender let senderVRange = memberChatVRange' sender
xMsgNewChatMsg = ChatMessage {chatVRange = senderVRange, msgId = itemSharedMsgId, chatMsgEvent} xMsgNewChatMsg = ChatMessage {chatVRange = senderVRange, msgId = itemSharedMsgId, chatMsgEvent}
fileDescrEvents <- case (snd <$> fInvDescr_, itemSharedMsgId) of fileDescrEvents <- case (snd <$> fInvDescr_, itemSharedMsgId) of

View file

@ -320,6 +320,7 @@ deriving instance Show AChat
data ChatStats = ChatStats data ChatStats = ChatStats
{ unreadCount :: Int, -- returned both in /_get chat initial API and in /_get chats API { unreadCount :: Int, -- returned both in /_get chat initial API and in /_get chats API
unreadMentions :: Int, -- returned both in /_get chat initial API and in /_get chats API
reportsCount :: Int, -- returned both in /_get chat initial API and in /_get chats API reportsCount :: Int, -- returned both in /_get chat initial API and in /_get chats API
minUnreadItemId :: ChatItemId, minUnreadItemId :: ChatItemId,
unreadChat :: Bool unreadChat :: Bool
@ -327,7 +328,7 @@ data ChatStats = ChatStats
deriving (Show) deriving (Show)
emptyChatStats :: ChatStats emptyChatStats :: ChatStats
emptyChatStats = ChatStats 0 0 0 False emptyChatStats = ChatStats 0 0 0 0 False
data NavigationInfo = NavigationInfo data NavigationInfo = NavigationInfo
{ afterUnread :: Int, { afterUnread :: Int,

View file

@ -570,7 +570,12 @@ data AChatPreviewData = forall c. ChatTypeI c => ACPD (SChatType c) (ChatPreview
type ChatStatsRow = (Int, Int, ChatItemId, BoolInt) type ChatStatsRow = (Int, Int, ChatItemId, BoolInt)
toChatStats :: ChatStatsRow -> ChatStats toChatStats :: ChatStatsRow -> ChatStats
toChatStats (unreadCount, reportsCount, minUnreadItemId, BI unreadChat) = ChatStats {unreadCount, reportsCount, minUnreadItemId, unreadChat} toChatStats (unreadCount, reportsCount, minUnreadItemId, BI unreadChat) = ChatStats {unreadCount, unreadMentions = 0, reportsCount, minUnreadItemId, unreadChat}
type GroupStatsRow = (Int, Int, Int, ChatItemId, BoolInt)
toGroupStats :: GroupStatsRow -> ChatStats
toGroupStats (unreadCount, unreadMentions, reportsCount, minUnreadItemId, BI unreadChat) = ChatStats {unreadCount, unreadMentions, reportsCount, minUnreadItemId, unreadChat}
findDirectChatPreviews_ :: DB.Connection -> User -> PaginationByTime -> ChatListQuery -> IO [AChatPreviewData] findDirectChatPreviews_ :: DB.Connection -> User -> PaginationByTime -> ChatListQuery -> IO [AChatPreviewData]
findDirectChatPreviews_ db User {userId} pagination clq = findDirectChatPreviews_ db User {userId} pagination clq =
@ -674,9 +679,9 @@ findGroupChatPreviews_ :: DB.Connection -> User -> PaginationByTime -> ChatListQ
findGroupChatPreviews_ db User {userId} pagination clq = findGroupChatPreviews_ db User {userId} pagination clq =
map toPreview <$> getPreviews map toPreview <$> getPreviews
where where
toPreview :: (GroupId, UTCTime, Maybe ChatItemId) :. ChatStatsRow -> AChatPreviewData toPreview :: (GroupId, UTCTime, Maybe ChatItemId) :. GroupStatsRow -> AChatPreviewData
toPreview ((groupId, ts, lastItemId_) :. statsRow) = toPreview ((groupId, ts, lastItemId_) :. statsRow) =
ACPD SCTGroup $ GroupChatPD ts groupId lastItemId_ (toChatStats statsRow) ACPD SCTGroup $ GroupChatPD ts groupId lastItemId_ (toGroupStats statsRow)
baseQuery = baseQuery =
[sql| [sql|
SELECT SELECT
@ -690,12 +695,13 @@ findGroupChatPreviews_ db User {userId} pagination clq =
LIMIT 1 LIMIT 1
) AS chat_item_id, ) AS chat_item_id,
COALESCE(ChatStats.UnreadCount, 0), COALESCE(ChatStats.UnreadCount, 0),
COALESCE(ChatStats.UnreadMentions, 0),
COALESCE(ReportCount.Count, 0), COALESCE(ReportCount.Count, 0),
COALESCE(ChatStats.MinUnread, 0), COALESCE(ChatStats.MinUnread, 0),
g.unread_chat g.unread_chat
FROM groups g FROM groups g
LEFT JOIN ( LEFT JOIN (
SELECT group_id, COUNT(1) AS UnreadCount, MIN(chat_item_id) AS MinUnread SELECT group_id, COUNT(1) AS UnreadCount, SUM(user_mention) as UnreadMentions, MIN(chat_item_id) AS MinUnread
FROM chat_items FROM chat_items
WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ? WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ?
GROUP BY group_id GROUP BY group_id
@ -761,7 +767,7 @@ findGroupChatPreviews_ db User {userId} pagination clq =
|] |]
p = baseParams :. (userId, search, search, search, search) p = baseParams :. (userId, search, search, search, search)
queryWithPagination q p queryWithPagination q p
queryWithPagination :: ToRow p => Query -> p -> IO [(GroupId, UTCTime, Maybe ChatItemId) :. ChatStatsRow] queryWithPagination :: ToRow p => Query -> p -> IO [(GroupId, UTCTime, Maybe ChatItemId) :. GroupStatsRow]
queryWithPagination query params = case pagination of queryWithPagination query params = case pagination of
PTLast count -> DB.query db (query <> " ORDER BY g.chat_ts DESC LIMIT ?") (params :. Only count) PTLast count -> DB.query db (query <> " ORDER BY g.chat_ts DESC LIMIT ?") (params :. Only count)
PTAfter ts count -> DB.query db (query <> " AND g.chat_ts > ? ORDER BY g.chat_ts ASC LIMIT ?") (params :. (ts, count)) PTAfter ts count -> DB.query db (query <> " AND g.chat_ts > ? ORDER BY g.chat_ts ASC LIMIT ?") (params :. (ts, count))
@ -1353,19 +1359,19 @@ getGroupChatInitial_ db user g contentFilter count = do
stats <- liftIO $ getStats minUnreadItemId =<< getGroupUnreadCount_ db user g Nothing stats <- liftIO $ getStats minUnreadItemId =<< getGroupUnreadCount_ db user g Nothing
getGroupChatAround' db user g contentFilter minUnreadItemId count "" stats getGroupChatAround' db user g contentFilter minUnreadItemId count "" stats
Nothing -> liftIO $ do Nothing -> liftIO $ do
stats <- getStats 0 0 stats <- getStats 0 (0, 0)
(,Just $ NavigationInfo 0 0) <$> getGroupChatLast_ db user g contentFilter count "" stats (,Just $ NavigationInfo 0 0) <$> getGroupChatLast_ db user g contentFilter count "" stats
where where
getStats minUnreadItemId unreadCount = do getStats minUnreadItemId (unreadCount, unreadMentions) = do
reportsCount <- getGroupReportsCount_ db user g False reportsCount <- getGroupReportsCount_ db user g False
pure ChatStats {unreadCount, reportsCount, minUnreadItemId, unreadChat = False} pure ChatStats {unreadCount, unreadMentions, reportsCount, minUnreadItemId, unreadChat = False}
getGroupStats_ :: DB.Connection -> User -> GroupInfo -> IO ChatStats getGroupStats_ :: DB.Connection -> User -> GroupInfo -> IO ChatStats
getGroupStats_ db user g = do getGroupStats_ db user g = do
minUnreadItemId <- fromMaybe 0 <$> getGroupMinUnreadId_ db user g Nothing minUnreadItemId <- fromMaybe 0 <$> getGroupMinUnreadId_ db user g Nothing
unreadCount <- getGroupUnreadCount_ db user g Nothing (unreadCount, unreadMentions) <- getGroupUnreadCount_ db user g Nothing
reportsCount <- getGroupReportsCount_ db user g False reportsCount <- getGroupReportsCount_ db user g False
pure ChatStats {unreadCount, reportsCount, minUnreadItemId, unreadChat = False} pure ChatStats {unreadCount, unreadMentions, reportsCount, minUnreadItemId, unreadChat = False}
getGroupMinUnreadId_ :: DB.Connection -> User -> GroupInfo -> Maybe MsgContentTag -> IO (Maybe ChatItemId) getGroupMinUnreadId_ :: DB.Connection -> User -> GroupInfo -> Maybe MsgContentTag -> IO (Maybe ChatItemId)
getGroupMinUnreadId_ db user g contentFilter = getGroupMinUnreadId_ db user g contentFilter =
@ -1375,11 +1381,11 @@ getGroupMinUnreadId_ db user g contentFilter =
baseQuery = "SELECT chat_item_id FROM chat_items WHERE user_id = ? AND group_id = ? " baseQuery = "SELECT chat_item_id FROM chat_items WHERE user_id = ? AND group_id = ? "
orderLimit = " ORDER BY item_ts ASC, chat_item_id ASC LIMIT 1" orderLimit = " ORDER BY item_ts ASC, chat_item_id ASC LIMIT 1"
getGroupUnreadCount_ :: DB.Connection -> User -> GroupInfo -> Maybe MsgContentTag -> IO Int getGroupUnreadCount_ :: DB.Connection -> User -> GroupInfo -> Maybe MsgContentTag -> IO (Int, Int)
getGroupUnreadCount_ db user g contentFilter = getGroupUnreadCount_ db user g contentFilter =
fromOnly . head <$> queryUnreadGroupItems db user g contentFilter baseQuery "" head <$> queryUnreadGroupItems db user g contentFilter baseQuery ""
where where
baseQuery = "SELECT COUNT(1) FROM chat_items WHERE user_id = ? AND group_id = ? " baseQuery = "SELECT COUNT(1), COALESCE(SUM(user_mention), 0) FROM chat_items WHERE user_id = ? AND group_id = ? "
getGroupReportsCount_ :: DB.Connection -> User -> GroupInfo -> Bool -> IO Int getGroupReportsCount_ :: DB.Connection -> User -> GroupInfo -> Bool -> IO Int
getGroupReportsCount_ db User {userId} GroupInfo {groupId} archived = getGroupReportsCount_ db User {userId} GroupInfo {groupId} archived =
@ -3111,10 +3117,9 @@ getGroupSndStatusCounts db itemId =
(Only itemId) (Only itemId)
getGroupHistoryItems :: DB.Connection -> User -> GroupInfo -> GroupMember -> Int -> IO [Either StoreError (CChatItem 'CTGroup)] getGroupHistoryItems :: DB.Connection -> User -> GroupInfo -> GroupMember -> Int -> IO [Either StoreError (CChatItem 'CTGroup)]
getGroupHistoryItems db user@User {userId} GroupInfo {groupId} m count = do getGroupHistoryItems db user@User {userId} g@GroupInfo {groupId} m count = do
ciIds <- getLastItemIds_ ciIds <- getLastItemIds_
-- use getGroupCIWithReactions to read reactions data reverse <$> mapM (runExceptT . getGroupCIWithReactions db user g) ciIds
reverse <$> mapM (runExceptT . getGroupChatItem db user groupId) ciIds
where where
getLastItemIds_ :: IO [ChatItemId] getLastItemIds_ :: IO [ChatItemId]
getLastItemIds_ = getLastItemIds_ =

View file

@ -22,11 +22,15 @@ CREATE INDEX idx_chat_item_mentions_group_id ON chat_item_mentions(group_id);
CREATE INDEX idx_chat_item_mentions_chat_item_id ON chat_item_mentions(chat_item_id); CREATE INDEX idx_chat_item_mentions_chat_item_id ON chat_item_mentions(chat_item_id);
CREATE UNIQUE INDEX idx_chat_item_mentions_display_name ON chat_item_mentions(chat_item_id, display_name); CREATE UNIQUE INDEX idx_chat_item_mentions_display_name ON chat_item_mentions(chat_item_id, display_name);
CREATE UNIQUE INDEX idx_chat_item_mentions_member_id ON chat_item_mentions(chat_item_id, member_id); CREATE UNIQUE INDEX idx_chat_item_mentions_member_id ON chat_item_mentions(chat_item_id, member_id);
CREATE INDEX idx_chat_items_groups_user_mention ON chat_items(user_id, group_id, item_status, user_mention);
|] |]
down_m20250126_mentions :: Query down_m20250126_mentions :: Query
down_m20250126_mentions = down_m20250126_mentions =
[sql| [sql|
DROP INDEX idx_chat_items_groups_user_mention;
DROP INDEX idx_chat_item_mentions_group_id; DROP INDEX idx_chat_item_mentions_group_id;
DROP INDEX idx_chat_item_mentions_chat_item_id; DROP INDEX idx_chat_item_mentions_chat_item_id;
DROP INDEX idx_chat_item_mentions_display_name; DROP INDEX idx_chat_item_mentions_display_name;

View file

@ -157,7 +157,7 @@ Query:
WHERE i.user_id = ? AND i.item_status = ? AND (g.enable_ntfs = 1 OR g.enable_ntfs IS NULL) WHERE i.user_id = ? AND i.item_status = ? AND (g.enable_ntfs = 1 OR g.enable_ntfs IS NULL)
Plan: Plan:
SEARCH i USING COVERING INDEX idx_chat_items_groups (user_id=?) SEARCH i USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=?)
SEARCH g USING INTEGER PRIMARY KEY (rowid=?) SEARCH g USING INTEGER PRIMARY KEY (rowid=?)
Query: Query:
@ -480,7 +480,7 @@ Query:
LIMIT ? LIMIT ?
Plan: Plan:
SEARCH chat_items USING INDEX idx_chat_items_groups_history (user_id=?) SEARCH chat_items USING INDEX idx_chat_items_groups_user_mention (user_id=?)
USE TEMP B-TREE FOR ORDER BY USE TEMP B-TREE FOR ORDER BY
Query: Query:
@ -491,7 +491,7 @@ Query:
LIMIT ? LIMIT ?
Plan: Plan:
SEARCH chat_items USING INDEX idx_chat_items_groups_history (user_id=?) SEARCH chat_items USING INDEX idx_chat_items_groups_user_mention (user_id=?)
USE TEMP B-TREE FOR ORDER BY USE TEMP B-TREE FOR ORDER BY
Query: Query:
@ -985,7 +985,7 @@ Query:
LIMIT 1 LIMIT 1
Plan: Plan:
SEARCH chat_items USING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?) SEARCH chat_items USING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id=?)
USE TEMP B-TREE FOR ORDER BY USE TEMP B-TREE FOR ORDER BY
Query: Query:
@ -1005,7 +1005,7 @@ Query:
LIMIT ? LIMIT ?
Plan: Plan:
SEARCH chat_items USING INDEX idx_chat_items_groups_history (user_id=?) SEARCH chat_items USING INDEX idx_chat_items_groups_user_mention (user_id=?)
USE TEMP B-TREE FOR ORDER BY USE TEMP B-TREE FOR ORDER BY
Query: Query:
@ -1151,7 +1151,7 @@ Query:
LIMIT 1 LIMIT 1
Plan: Plan:
SEARCH i USING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?) SEARCH i USING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id=?)
SEARCH m USING INTEGER PRIMARY KEY (rowid=?) SEARCH m USING INTEGER PRIMARY KEY (rowid=?)
SEARCH c USING INTEGER PRIMARY KEY (rowid=?) SEARCH c USING INTEGER PRIMARY KEY (rowid=?)
USE TEMP B-TREE FOR ORDER BY USE TEMP B-TREE FOR ORDER BY
@ -1920,12 +1920,13 @@ Query:
LIMIT 1 LIMIT 1
) AS chat_item_id, ) AS chat_item_id,
COALESCE(ChatStats.UnreadCount, 0), COALESCE(ChatStats.UnreadCount, 0),
COALESCE(ChatStats.UnreadMentions, 0),
COALESCE(ReportCount.Count, 0), COALESCE(ReportCount.Count, 0),
COALESCE(ChatStats.MinUnread, 0), COALESCE(ChatStats.MinUnread, 0),
g.unread_chat g.unread_chat
FROM groups g FROM groups g
LEFT JOIN ( LEFT JOIN (
SELECT group_id, COUNT(1) AS UnreadCount, MIN(chat_item_id) AS MinUnread SELECT group_id, COUNT(1) AS UnreadCount, SUM(user_mention) as UnreadMentions, MIN(chat_item_id) AS MinUnread
FROM chat_items FROM chat_items
WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ? WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ?
GROUP BY group_id GROUP BY group_id
@ -1949,7 +1950,7 @@ Query:
ORDER BY g.chat_ts DESC LIMIT ? ORDER BY g.chat_ts DESC LIMIT ?
Plan: Plan:
MATERIALIZE ChatStats MATERIALIZE ChatStats
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id>?)
MATERIALIZE ReportCount MATERIALIZE ReportCount
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?)
SEARCH g USING INDEX idx_groups_chat_ts (user_id=?) SEARCH g USING INDEX idx_groups_chat_ts (user_id=?)
@ -1971,12 +1972,13 @@ Query:
LIMIT 1 LIMIT 1
) AS chat_item_id, ) AS chat_item_id,
COALESCE(ChatStats.UnreadCount, 0), COALESCE(ChatStats.UnreadCount, 0),
COALESCE(ChatStats.UnreadMentions, 0),
COALESCE(ReportCount.Count, 0), COALESCE(ReportCount.Count, 0),
COALESCE(ChatStats.MinUnread, 0), COALESCE(ChatStats.MinUnread, 0),
g.unread_chat g.unread_chat
FROM groups g FROM groups g
LEFT JOIN ( LEFT JOIN (
SELECT group_id, COUNT(1) AS UnreadCount, MIN(chat_item_id) AS MinUnread SELECT group_id, COUNT(1) AS UnreadCount, SUM(user_mention) as UnreadMentions, MIN(chat_item_id) AS MinUnread
FROM chat_items FROM chat_items
WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ? WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ?
GROUP BY group_id GROUP BY group_id
@ -1995,7 +1997,7 @@ Query:
ORDER BY g.chat_ts DESC LIMIT ? ORDER BY g.chat_ts DESC LIMIT ?
Plan: Plan:
MATERIALIZE ChatStats MATERIALIZE ChatStats
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id>?)
MATERIALIZE ReportCount MATERIALIZE ReportCount
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?)
SEARCH g USING INDEX idx_groups_chat_ts (user_id=?) SEARCH g USING INDEX idx_groups_chat_ts (user_id=?)
@ -2016,12 +2018,13 @@ Query:
LIMIT 1 LIMIT 1
) AS chat_item_id, ) AS chat_item_id,
COALESCE(ChatStats.UnreadCount, 0), COALESCE(ChatStats.UnreadCount, 0),
COALESCE(ChatStats.UnreadMentions, 0),
COALESCE(ReportCount.Count, 0), COALESCE(ReportCount.Count, 0),
COALESCE(ChatStats.MinUnread, 0), COALESCE(ChatStats.MinUnread, 0),
g.unread_chat g.unread_chat
FROM groups g FROM groups g
LEFT JOIN ( LEFT JOIN (
SELECT group_id, COUNT(1) AS UnreadCount, MIN(chat_item_id) AS MinUnread SELECT group_id, COUNT(1) AS UnreadCount, SUM(user_mention) as UnreadMentions, MIN(chat_item_id) AS MinUnread
FROM chat_items FROM chat_items
WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ? WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ?
GROUP BY group_id GROUP BY group_id
@ -2039,7 +2042,7 @@ Query:
AND g.chat_ts < ? ORDER BY g.chat_ts DESC LIMIT ? AND g.chat_ts < ? ORDER BY g.chat_ts DESC LIMIT ?
Plan: Plan:
MATERIALIZE ChatStats MATERIALIZE ChatStats
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id>?)
MATERIALIZE ReportCount MATERIALIZE ReportCount
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?)
SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts<?) SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts<?)
@ -2060,12 +2063,13 @@ Query:
LIMIT 1 LIMIT 1
) AS chat_item_id, ) AS chat_item_id,
COALESCE(ChatStats.UnreadCount, 0), COALESCE(ChatStats.UnreadCount, 0),
COALESCE(ChatStats.UnreadMentions, 0),
COALESCE(ReportCount.Count, 0), COALESCE(ReportCount.Count, 0),
COALESCE(ChatStats.MinUnread, 0), COALESCE(ChatStats.MinUnread, 0),
g.unread_chat g.unread_chat
FROM groups g FROM groups g
LEFT JOIN ( LEFT JOIN (
SELECT group_id, COUNT(1) AS UnreadCount, MIN(chat_item_id) AS MinUnread SELECT group_id, COUNT(1) AS UnreadCount, SUM(user_mention) as UnreadMentions, MIN(chat_item_id) AS MinUnread
FROM chat_items FROM chat_items
WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ? WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ?
GROUP BY group_id GROUP BY group_id
@ -2083,7 +2087,7 @@ Query:
AND g.chat_ts > ? ORDER BY g.chat_ts ASC LIMIT ? AND g.chat_ts > ? ORDER BY g.chat_ts ASC LIMIT ?
Plan: Plan:
MATERIALIZE ChatStats MATERIALIZE ChatStats
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id>?)
MATERIALIZE ReportCount MATERIALIZE ReportCount
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?)
SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts>?) SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts>?)
@ -2104,12 +2108,13 @@ Query:
LIMIT 1 LIMIT 1
) AS chat_item_id, ) AS chat_item_id,
COALESCE(ChatStats.UnreadCount, 0), COALESCE(ChatStats.UnreadCount, 0),
COALESCE(ChatStats.UnreadMentions, 0),
COALESCE(ReportCount.Count, 0), COALESCE(ReportCount.Count, 0),
COALESCE(ChatStats.MinUnread, 0), COALESCE(ChatStats.MinUnread, 0),
g.unread_chat g.unread_chat
FROM groups g FROM groups g
LEFT JOIN ( LEFT JOIN (
SELECT group_id, COUNT(1) AS UnreadCount, MIN(chat_item_id) AS MinUnread SELECT group_id, COUNT(1) AS UnreadCount, SUM(user_mention) as UnreadMentions, MIN(chat_item_id) AS MinUnread
FROM chat_items FROM chat_items
WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ? WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ?
GROUP BY group_id GROUP BY group_id
@ -2127,7 +2132,7 @@ Query:
ORDER BY g.chat_ts DESC LIMIT ? ORDER BY g.chat_ts DESC LIMIT ?
Plan: Plan:
MATERIALIZE ChatStats MATERIALIZE ChatStats
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id>?)
MATERIALIZE ReportCount MATERIALIZE ReportCount
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?)
SEARCH g USING INDEX idx_groups_chat_ts (user_id=?) SEARCH g USING INDEX idx_groups_chat_ts (user_id=?)
@ -2148,12 +2153,13 @@ Query:
LIMIT 1 LIMIT 1
) AS chat_item_id, ) AS chat_item_id,
COALESCE(ChatStats.UnreadCount, 0), COALESCE(ChatStats.UnreadCount, 0),
COALESCE(ChatStats.UnreadMentions, 0),
COALESCE(ReportCount.Count, 0), COALESCE(ReportCount.Count, 0),
COALESCE(ChatStats.MinUnread, 0), COALESCE(ChatStats.MinUnread, 0),
g.unread_chat g.unread_chat
FROM groups g FROM groups g
LEFT JOIN ( LEFT JOIN (
SELECT group_id, COUNT(1) AS UnreadCount, MIN(chat_item_id) AS MinUnread SELECT group_id, COUNT(1) AS UnreadCount, SUM(user_mention) as UnreadMentions, MIN(chat_item_id) AS MinUnread
FROM chat_items FROM chat_items
WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ? WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ?
GROUP BY group_id GROUP BY group_id
@ -2171,7 +2177,7 @@ Query:
AND g.chat_ts < ? ORDER BY g.chat_ts DESC LIMIT ? AND g.chat_ts < ? ORDER BY g.chat_ts DESC LIMIT ?
Plan: Plan:
MATERIALIZE ChatStats MATERIALIZE ChatStats
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id>?)
MATERIALIZE ReportCount MATERIALIZE ReportCount
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?)
SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts<?) SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts<?)
@ -2192,12 +2198,13 @@ Query:
LIMIT 1 LIMIT 1
) AS chat_item_id, ) AS chat_item_id,
COALESCE(ChatStats.UnreadCount, 0), COALESCE(ChatStats.UnreadCount, 0),
COALESCE(ChatStats.UnreadMentions, 0),
COALESCE(ReportCount.Count, 0), COALESCE(ReportCount.Count, 0),
COALESCE(ChatStats.MinUnread, 0), COALESCE(ChatStats.MinUnread, 0),
g.unread_chat g.unread_chat
FROM groups g FROM groups g
LEFT JOIN ( LEFT JOIN (
SELECT group_id, COUNT(1) AS UnreadCount, MIN(chat_item_id) AS MinUnread SELECT group_id, COUNT(1) AS UnreadCount, SUM(user_mention) as UnreadMentions, MIN(chat_item_id) AS MinUnread
FROM chat_items FROM chat_items
WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ? WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ?
GROUP BY group_id GROUP BY group_id
@ -2215,7 +2222,7 @@ Query:
AND g.chat_ts > ? ORDER BY g.chat_ts ASC LIMIT ? AND g.chat_ts > ? ORDER BY g.chat_ts ASC LIMIT ?
Plan: Plan:
MATERIALIZE ChatStats MATERIALIZE ChatStats
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id>?)
MATERIALIZE ReportCount MATERIALIZE ReportCount
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?)
SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts>?) SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts>?)
@ -2236,12 +2243,13 @@ Query:
LIMIT 1 LIMIT 1
) AS chat_item_id, ) AS chat_item_id,
COALESCE(ChatStats.UnreadCount, 0), COALESCE(ChatStats.UnreadCount, 0),
COALESCE(ChatStats.UnreadMentions, 0),
COALESCE(ReportCount.Count, 0), COALESCE(ReportCount.Count, 0),
COALESCE(ChatStats.MinUnread, 0), COALESCE(ChatStats.MinUnread, 0),
g.unread_chat g.unread_chat
FROM groups g FROM groups g
LEFT JOIN ( LEFT JOIN (
SELECT group_id, COUNT(1) AS UnreadCount, MIN(chat_item_id) AS MinUnread SELECT group_id, COUNT(1) AS UnreadCount, SUM(user_mention) as UnreadMentions, MIN(chat_item_id) AS MinUnread
FROM chat_items FROM chat_items
WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ? WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ?
GROUP BY group_id GROUP BY group_id
@ -2259,7 +2267,7 @@ Query:
ORDER BY g.chat_ts DESC LIMIT ? ORDER BY g.chat_ts DESC LIMIT ?
Plan: Plan:
MATERIALIZE ChatStats MATERIALIZE ChatStats
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id>?)
MATERIALIZE ReportCount MATERIALIZE ReportCount
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?)
SEARCH g USING INDEX idx_groups_chat_ts (user_id=?) SEARCH g USING INDEX idx_groups_chat_ts (user_id=?)
@ -2280,12 +2288,13 @@ Query:
LIMIT 1 LIMIT 1
) AS chat_item_id, ) AS chat_item_id,
COALESCE(ChatStats.UnreadCount, 0), COALESCE(ChatStats.UnreadCount, 0),
COALESCE(ChatStats.UnreadMentions, 0),
COALESCE(ReportCount.Count, 0), COALESCE(ReportCount.Count, 0),
COALESCE(ChatStats.MinUnread, 0), COALESCE(ChatStats.MinUnread, 0),
g.unread_chat g.unread_chat
FROM groups g FROM groups g
LEFT JOIN ( LEFT JOIN (
SELECT group_id, COUNT(1) AS UnreadCount, MIN(chat_item_id) AS MinUnread SELECT group_id, COUNT(1) AS UnreadCount, SUM(user_mention) as UnreadMentions, MIN(chat_item_id) AS MinUnread
FROM chat_items FROM chat_items
WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ? WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ?
GROUP BY group_id GROUP BY group_id
@ -2300,7 +2309,7 @@ Query:
WHERE g.user_id = ? AND g.chat_ts < ? ORDER BY g.chat_ts DESC LIMIT ? WHERE g.user_id = ? AND g.chat_ts < ? ORDER BY g.chat_ts DESC LIMIT ?
Plan: Plan:
MATERIALIZE ChatStats MATERIALIZE ChatStats
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id>?)
MATERIALIZE ReportCount MATERIALIZE ReportCount
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?)
SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts<?) SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts<?)
@ -2321,12 +2330,13 @@ Query:
LIMIT 1 LIMIT 1
) AS chat_item_id, ) AS chat_item_id,
COALESCE(ChatStats.UnreadCount, 0), COALESCE(ChatStats.UnreadCount, 0),
COALESCE(ChatStats.UnreadMentions, 0),
COALESCE(ReportCount.Count, 0), COALESCE(ReportCount.Count, 0),
COALESCE(ChatStats.MinUnread, 0), COALESCE(ChatStats.MinUnread, 0),
g.unread_chat g.unread_chat
FROM groups g FROM groups g
LEFT JOIN ( LEFT JOIN (
SELECT group_id, COUNT(1) AS UnreadCount, MIN(chat_item_id) AS MinUnread SELECT group_id, COUNT(1) AS UnreadCount, SUM(user_mention) as UnreadMentions, MIN(chat_item_id) AS MinUnread
FROM chat_items FROM chat_items
WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ? WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ?
GROUP BY group_id GROUP BY group_id
@ -2341,7 +2351,7 @@ Query:
WHERE g.user_id = ? AND g.chat_ts > ? ORDER BY g.chat_ts ASC LIMIT ? WHERE g.user_id = ? AND g.chat_ts > ? ORDER BY g.chat_ts ASC LIMIT ?
Plan: Plan:
MATERIALIZE ChatStats MATERIALIZE ChatStats
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id>?)
MATERIALIZE ReportCount MATERIALIZE ReportCount
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?)
SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts>?) SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts>?)
@ -2362,12 +2372,13 @@ Query:
LIMIT 1 LIMIT 1
) AS chat_item_id, ) AS chat_item_id,
COALESCE(ChatStats.UnreadCount, 0), COALESCE(ChatStats.UnreadCount, 0),
COALESCE(ChatStats.UnreadMentions, 0),
COALESCE(ReportCount.Count, 0), COALESCE(ReportCount.Count, 0),
COALESCE(ChatStats.MinUnread, 0), COALESCE(ChatStats.MinUnread, 0),
g.unread_chat g.unread_chat
FROM groups g FROM groups g
LEFT JOIN ( LEFT JOIN (
SELECT group_id, COUNT(1) AS UnreadCount, MIN(chat_item_id) AS MinUnread SELECT group_id, COUNT(1) AS UnreadCount, SUM(user_mention) as UnreadMentions, MIN(chat_item_id) AS MinUnread
FROM chat_items FROM chat_items
WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ? WHERE user_id = ? AND group_id IS NOT NULL AND item_status = ?
GROUP BY group_id GROUP BY group_id
@ -2382,7 +2393,7 @@ Query:
WHERE g.user_id = ? ORDER BY g.chat_ts DESC LIMIT ? WHERE g.user_id = ? ORDER BY g.chat_ts DESC LIMIT ?
Plan: Plan:
MATERIALIZE ChatStats MATERIALIZE ChatStats
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id>?)
MATERIALIZE ReportCount MATERIALIZE ReportCount
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id>?)
SEARCH g USING INDEX idx_groups_chat_ts (user_id=?) SEARCH g USING INDEX idx_groups_chat_ts (user_id=?)
@ -2930,7 +2941,7 @@ Query:
LIMIT 1 LIMIT 1
Plan: Plan:
SEARCH chat_items USING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?) SEARCH chat_items USING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id=?)
USE TEMP B-TREE FOR ORDER BY USE TEMP B-TREE FOR ORDER BY
Query: Query:
@ -4080,7 +4091,7 @@ Query:
WHERE user_id = ? AND group_id = ? AND item_status = ? AND timed_ttl IS NOT NULL AND timed_delete_at IS NULL WHERE user_id = ? AND group_id = ? AND item_status = ? AND timed_ttl IS NOT NULL AND timed_delete_at IS NULL
Plan: Plan:
SEARCH chat_items USING INDEX idx_chat_items_groups (user_id=? AND group_id=? AND item_status=?) SEARCH chat_items USING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id=? AND item_status=?)
Query: Query:
SELECT group_snd_item_status, COUNT(1) SELECT group_snd_item_status, COUNT(1)
@ -4171,7 +4182,7 @@ Query:
WHERE user_id = ? AND group_id = ? AND item_status = ? WHERE user_id = ? AND group_id = ? AND item_status = ?
Plan: Plan:
SEARCH chat_items USING INDEX idx_chat_items_groups (user_id=? AND group_id=? AND item_status=?) SEARCH chat_items USING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id=? AND item_status=?)
Query: Query:
UPDATE chat_items SET item_status = ?, updated_at = ? UPDATE chat_items SET item_status = ?, updated_at = ?
@ -4666,7 +4677,7 @@ Query:
JOIN files f ON f.chat_item_id = i.chat_item_id JOIN files f ON f.chat_item_id = i.chat_item_id
WHERE i.user_id = ? WHERE i.user_id = ?
Plan: Plan:
SEARCH i USING COVERING INDEX idx_chat_items_groups_history (user_id=?) SEARCH i USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=?)
SEARCH f USING INDEX idx_files_chat_item_id (chat_item_id=?) SEARCH f USING INDEX idx_files_chat_item_id (chat_item_id=?)
Query: Query:
@ -4693,7 +4704,7 @@ Query:
JOIN files f ON f.chat_item_id = i.chat_item_id JOIN files f ON f.chat_item_id = i.chat_item_id
WHERE i.user_id = ? AND i.group_id = ? WHERE i.user_id = ? AND i.group_id = ?
Plan: Plan:
SEARCH i USING COVERING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?) SEARCH i USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id=?)
SEARCH f USING INDEX idx_files_chat_item_id (chat_item_id=?) SEARCH f USING INDEX idx_files_chat_item_id (chat_item_id=?)
Query: Query:
@ -5013,7 +5024,7 @@ SEARCH groups USING COVERING INDEX idx_groups_chat_item_id (chat_item_id=?)
Query: DELETE FROM chat_items WHERE user_id = ? AND group_id = ? Query: DELETE FROM chat_items WHERE user_id = ? AND group_id = ?
Plan: Plan:
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id=?)
SEARCH chat_item_mentions USING COVERING INDEX idx_chat_item_mentions_chat_item_id (chat_item_id=?) SEARCH chat_item_mentions USING COVERING INDEX idx_chat_item_mentions_chat_item_id (chat_item_id=?)
SEARCH group_snd_item_statuses USING COVERING INDEX idx_group_snd_item_statuses_chat_item_id (chat_item_id=?) SEARCH group_snd_item_statuses USING COVERING INDEX idx_group_snd_item_statuses_chat_item_id (chat_item_id=?)
SEARCH chat_item_versions USING COVERING INDEX idx_chat_item_versions_chat_item_id (chat_item_id=?) SEARCH chat_item_versions USING COVERING INDEX idx_chat_item_versions_chat_item_id (chat_item_id=?)
@ -5198,7 +5209,7 @@ SEARCH chat_tags_chats USING COVERING INDEX idx_chat_tags_chats_chat_tag_id_grou
SEARCH chat_item_moderations USING COVERING INDEX idx_chat_item_moderations_group_id (group_id=?) SEARCH chat_item_moderations USING COVERING INDEX idx_chat_item_moderations_group_id (group_id=?)
SEARCH chat_item_reactions USING COVERING INDEX idx_chat_item_reactions_group_id (group_id=?) SEARCH chat_item_reactions USING COVERING INDEX idx_chat_item_reactions_group_id (group_id=?)
SEARCH chat_items USING COVERING INDEX idx_chat_items_fwd_from_group_id (fwd_from_group_id=?) SEARCH chat_items USING COVERING INDEX idx_chat_items_fwd_from_group_id (fwd_from_group_id=?)
SCAN chat_items USING COVERING INDEX idx_chat_items_groups_item_ts SCAN chat_items USING COVERING INDEX idx_chat_items_groups_user_mention
SEARCH messages USING COVERING INDEX idx_messages_group_id (group_id=?) SEARCH messages USING COVERING INDEX idx_messages_group_id (group_id=?)
SEARCH user_contact_links USING COVERING INDEX idx_user_contact_links_group_id (group_id=?) SEARCH user_contact_links USING COVERING INDEX idx_user_contact_links_group_id (group_id=?)
SEARCH files USING COVERING INDEX idx_files_group_id (group_id=?) SEARCH files USING COVERING INDEX idx_files_group_id (group_id=?)
@ -5310,7 +5321,7 @@ SEARCH protocol_servers USING COVERING INDEX idx_smp_servers_user_id (user_id=?)
SEARCH settings USING COVERING INDEX idx_settings_user_id (user_id=?) SEARCH settings USING COVERING INDEX idx_settings_user_id (user_id=?)
SEARCH commands USING COVERING INDEX idx_commands_user_id (user_id=?) SEARCH commands USING COVERING INDEX idx_commands_user_id (user_id=?)
SEARCH calls USING COVERING INDEX idx_calls_user_id (user_id=?) SEARCH calls USING COVERING INDEX idx_calls_user_id (user_id=?)
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_history (user_id=?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=?)
SEARCH contact_requests USING COVERING INDEX sqlite_autoindex_contact_requests_2 (user_id=?) SEARCH contact_requests USING COVERING INDEX sqlite_autoindex_contact_requests_2 (user_id=?)
SEARCH user_contact_links USING COVERING INDEX sqlite_autoindex_user_contact_links_1 (user_id=?) SEARCH user_contact_links USING COVERING INDEX sqlite_autoindex_user_contact_links_1 (user_id=?)
SEARCH connections USING COVERING INDEX idx_connections_group_member (user_id=?) SEARCH connections USING COVERING INDEX idx_connections_group_member (user_id=?)
@ -5449,10 +5460,6 @@ Query: SELECT COUNT(1) FROM chat_item_versions WHERE chat_item_id = ?
Plan: Plan:
SEARCH chat_item_versions USING COVERING INDEX idx_chat_item_versions_chat_item_id (chat_item_id=?) SEARCH chat_item_versions USING COVERING INDEX idx_chat_item_versions_chat_item_id (chat_item_id=?)
Query: SELECT COUNT(1) FROM chat_items WHERE user_id = ? AND group_id = ? AND item_status = ?
Plan:
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups (user_id=? AND group_id=? AND item_status=?)
Query: SELECT COUNT(1) FROM chat_items WHERE user_id = ? AND group_id = ? AND msg_content_tag = ? AND item_deleted = ? AND item_sent = 0 Query: SELECT COUNT(1) FROM chat_items WHERE user_id = ? AND group_id = ? AND msg_content_tag = ? AND item_deleted = ? AND item_sent = 0
Plan: Plan:
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id=? AND msg_content_tag=? AND item_deleted=? AND item_sent=?) SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id=? AND msg_content_tag=? AND item_deleted=? AND item_sent=?)
@ -5465,6 +5472,10 @@ Query: SELECT COUNT(1) FROM groups WHERE user_id = ? AND chat_item_ttl > 0
Plan: Plan:
SEARCH groups USING INDEX idx_groups_chat_ts (user_id=?) SEARCH groups USING INDEX idx_groups_chat_ts (user_id=?)
Query: SELECT COUNT(1), COALESCE(SUM(user_mention), 0) FROM chat_items WHERE user_id = ? AND group_id = ? AND item_status = ?
Plan:
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id=? AND item_status=?)
Query: SELECT accepted_at FROM operator_usage_conditions WHERE server_operator_id = ? AND conditions_commit = ? Query: SELECT accepted_at FROM operator_usage_conditions WHERE server_operator_id = ? AND conditions_commit = ?
Plan: Plan:
SEARCH operator_usage_conditions USING INDEX idx_operator_usage_conditions_conditions_commit (conditions_commit=? AND server_operator_id=?) SEARCH operator_usage_conditions USING INDEX idx_operator_usage_conditions_conditions_commit (conditions_commit=? AND server_operator_id=?)

View file

@ -1011,3 +1011,9 @@ CREATE UNIQUE INDEX idx_chat_item_mentions_member_id ON chat_item_mentions(
chat_item_id, chat_item_id,
member_id member_id
); );
CREATE INDEX idx_chat_items_groups_user_mention ON chat_items(
user_id,
group_id,
item_status,
user_mention
);

View file

@ -191,8 +191,9 @@ chatGroupTests = do
describe "group member reports" $ do describe "group member reports" $ do
it "should send report to group owner, admins and moderators, but not other users" testGroupMemberReports it "should send report to group owner, admins and moderators, but not other users" testGroupMemberReports
describe "group member mentions" $ do describe "group member mentions" $ do
it "should send messages with member mentions" testMemberMention it "should send and edit messages with member mentions" testMemberMention
it "should forward and quote message updating mentioned member name" testForwardQuoteMention it "should forward and quote message updating mentioned member name" testForwardQuoteMention
it "should send updated mentions in history" testGroupHistoryWithMentions
describe "uniqueMsgMentions" testUniqueMsgMentions describe "uniqueMsgMentions" testUniqueMsgMentions
describe "updatedMentionNames" testUpdatedMentionNames describe "updatedMentionNames" testUpdatedMentionNames
where where
@ -6686,6 +6687,12 @@ testMemberMention =
[ alice <# "#team cath> hello @Alice", [ alice <# "#team cath> hello @Alice",
bob <# "#team cath> hello @Alice" bob <# "#team cath> hello @Alice"
] ]
cath ##> "! #team hello @alice @bob"
cath <# "#team [edited] hello @alice @bob"
concurrentlyN_
[ alice <# "#team cath> [edited] hello @alice @bob",
bob <# "#team cath> [edited] hello @alice @bob"
]
testForwardQuoteMention :: HasCallStack => TestParams -> IO () testForwardQuoteMention :: HasCallStack => TestParams -> IO ()
testForwardQuoteMention = testForwardQuoteMention =
@ -6753,6 +6760,41 @@ testForwardQuoteMention =
bob <# "alice> -> forwarded" bob <# "alice> -> forwarded"
bob <## " hello @alice @alice_1" bob <## " hello @alice @alice_1"
testGroupHistoryWithMentions :: HasCallStack => TestParams -> IO ()
testGroupHistoryWithMentions =
testChat3 aliceProfile bobProfile cathProfile $
\alice bob cath -> do
createGroup2 "team" alice bob
threadDelay 1000000
alice #> "#team hello @bob"
bob <# "#team alice!> hello @bob"
bob ##> "/p robert"
bob <## "user profile is changed to robert (your 1 contacts are notified)"
alice <## "contact bob changed to robert"
alice <## "use @robert <message> to send messages"
alice ##> "/create link #team"
gLink <- getGroupLink alice "team" GRMember True
cath ##> ("/c " <> gLink)
cath <## "connection request sent!"
alice <## "cath (Catherine): accepting request to join group #team..."
concurrentlyN_
[ alice <## "#team: cath joined the group",
cath
<### [ "#team: joining the group...",
"#team: you joined the group",
WithTime "#team alice> hello @robert [>>]",
"#team: member robert is connected"
],
do
bob <## "#team: alice added cath (Catherine) to the group (connecting...)"
bob <## "#team: new member cath is connected"
]
testUniqueMsgMentions :: SpecWith TestParams testUniqueMsgMentions :: SpecWith TestParams
testUniqueMsgMentions = do testUniqueMsgMentions = do
it "1 correct mention" $ \_ -> it "1 correct mention" $ \_ ->