diff --git a/src/Simplex/Chat/Store/Messages.hs b/src/Simplex/Chat/Store/Messages.hs index 1902fd002e..8c4419ef90 100644 --- a/src/Simplex/Chat/Store/Messages.hs +++ b/src/Simplex/Chat/Store/Messages.hs @@ -2319,9 +2319,9 @@ updateGroupCIMentions db g ci@ChatItem {mentions} mentions' unless (null mentions) $ deleteMentions if null mentions' then pure ci - -- This is a fallback for the error that should not happen in practice. + else -- This is a fallback for the error that should not happen in practice. -- In theory, it may happen in item mentions in database are different from item record. - else createMentions `E.catch` \e -> if constraintError e then deleteMentions >> createMentions else E.throwIO e + createMentions `E.catch` \e -> if constraintError e then deleteMentions >> createMentions else E.throwIO e where deleteMentions = DB.execute db "DELETE FROM chat_item_mentions WHERE chat_item_id = ?" (Only $ chatItemId' ci) createMentions = createGroupCIMentions db g ci mentions' @@ -3138,8 +3138,9 @@ getGroupSndStatusCounts db itemId = |] (Only itemId) +-- TODO [knocking] check idx_chat_items_groups_history in query plans getGroupHistoryItems :: DB.Connection -> User -> GroupInfo -> GroupMember -> Int -> IO [Either StoreError (CChatItem 'CTGroup)] -getGroupHistoryItems db user@User {userId} g@GroupInfo {groupId} m count = do +getGroupHistoryItems db user@User {userId} g@GroupInfo {groupId} GroupMember {groupMemberId} count = do ciIds <- getLastItemIds_ reverse <$> mapM (runExceptT . getGroupCIWithReactions db user g) ciIds where @@ -3148,6 +3149,7 @@ getGroupHistoryItems db user@User {userId} g@GroupInfo {groupId} m count = do map fromOnly <$> DB.query db + -- `i.group_member_id != ?` check is to exclude messages received from pending approval member [sql| SELECT i.chat_item_id FROM chat_items i @@ -3156,7 +3158,8 @@ getGroupHistoryItems db user@User {userId} g@GroupInfo {groupId} m count = do AND i.user_id = ? AND i.group_id = ? AND i.include_in_history = 1 AND i.item_deleted = 0 + AND (i.group_member_id != ? OR i.group_member_id IS NULL) ORDER BY i.item_ts DESC, i.chat_item_id DESC LIMIT ? |] - (groupMemberId' m, userId, groupId, count) + (groupMemberId, userId, groupId, groupMemberId, count) diff --git a/src/Simplex/Chat/Store/Postgres/Migrations/M20250227_member_acceptance.hs b/src/Simplex/Chat/Store/Postgres/Migrations/M20250227_member_acceptance.hs index d902c577a6..68fa03868c 100644 --- a/src/Simplex/Chat/Store/Postgres/Migrations/M20250227_member_acceptance.hs +++ b/src/Simplex/Chat/Store/Postgres/Migrations/M20250227_member_acceptance.hs @@ -10,7 +10,18 @@ m20250227_member_acceptance :: Text m20250227_member_acceptance = T.pack [r| -ALTER TABLE user_contact_links ADD COLUMN group_link_auto_accept TEXT NULL; +ALTER TABLE user_contact_links ADD COLUMN group_link_auto_accept TEXT; + +DROP INDEX idx_chat_items_groups_history; +CREATE INDEX idx_chat_items_groups_history ON chat_items( + user_id, + group_id, + include_in_history, + item_deleted, + group_member_id, + item_ts, + chat_item_id +); |] down_m20250227_member_acceptance :: Text @@ -18,4 +29,14 @@ down_m20250227_member_acceptance = T.pack [r| ALTER TABLE user_contact_links DROP COLUMN group_link_auto_accept; + +DROP INDEX idx_chat_items_groups_history; +CREATE INDEX idx_chat_items_groups_history ON chat_items( + user_id, + group_id, + include_in_history, + item_deleted, + item_ts, + chat_item_id +); |] diff --git a/src/Simplex/Chat/Store/SQLite/Migrations/M20250227_member_acceptance.hs b/src/Simplex/Chat/Store/SQLite/Migrations/M20250227_member_acceptance.hs index 06627a6285..281b3063cd 100644 --- a/src/Simplex/Chat/Store/SQLite/Migrations/M20250227_member_acceptance.hs +++ b/src/Simplex/Chat/Store/SQLite/Migrations/M20250227_member_acceptance.hs @@ -8,11 +8,32 @@ import Database.SQLite.Simple.QQ (sql) m20250227_member_acceptance :: Query m20250227_member_acceptance = [sql| -ALTER TABLE user_contact_links ADD COLUMN group_link_auto_accept TEXT NULL; +ALTER TABLE user_contact_links ADD COLUMN group_link_auto_accept TEXT; + +DROP INDEX idx_chat_items_groups_history; +CREATE INDEX idx_chat_items_groups_history ON chat_items( + user_id, + group_id, + include_in_history, + item_deleted, + group_member_id, + item_ts, + chat_item_id +); |] down_m20250227_member_acceptance :: Query down_m20250227_member_acceptance = [sql| ALTER TABLE user_contact_links DROP COLUMN group_link_auto_accept; + +DROP INDEX idx_chat_items_groups_history; +CREATE INDEX idx_chat_items_groups_history ON chat_items( + user_id, + group_id, + include_in_history, + item_deleted, + item_ts, + chat_item_id +); |] diff --git a/tests/ChatTests/Groups.hs b/tests/ChatTests/Groups.hs index ce2f3d6a36..62255e4430 100644 --- a/tests/ChatTests/Groups.hs +++ b/tests/ChatTests/Groups.hs @@ -100,7 +100,7 @@ chatGroupTests = do it "existing contact merged" testGroupLinkExistingContactMerged describe "group links - join rejection" $ do it "reject member joining via group link - blocked name" testGLinkRejectBlockedName - fdescribe "group links - manual acceptance" $ do + describe "group links - manual acceptance" $ do it "manually accept member joining via group link" testGLinkManualAcceptMember describe "group link connection plan" $ do it "ok to connect; known group" testPlanGroupLinkKnown @@ -2947,7 +2947,6 @@ testGLinkManualAcceptMember = cath <### [ "#team: you joined the group", WithTime "#team alice> hi group [>>]", - StartsWith "duplicate group message", -- TODO [knocking] <- bug - remove WithTime "#team bob> hey [>>]", "#team: member bob (Bob) is connected" ],