From a47b139380de59d422a4f55e8ffc9076da2cdbfa Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Thu, 17 Jul 2025 19:02:53 +0400 Subject: [PATCH] fixes --- src/Simplex/Chat/Library/Commands.hs | 8 +- src/Simplex/Chat/Library/Subscriber.hs | 4 +- .../SQLite/Migrations/agent_query_plans.txt | 8 -- .../SQLite/Migrations/chat_query_plans.txt | 121 +++++++++++------- tests/ChatTests/Utils.hs | 5 +- 5 files changed, 86 insertions(+), 60 deletions(-) diff --git a/src/Simplex/Chat/Library/Commands.hs b/src/Simplex/Chat/Library/Commands.hs index 388c384b99..d52820f8fa 100644 --- a/src/Simplex/Chat/Library/Commands.hs +++ b/src/Simplex/Chat/Library/Commands.hs @@ -1766,7 +1766,7 @@ processChatCommand vr nm = \case groupPreferences = maybe defaultBusinessGroupPrefs businessGroupPrefs preferences groupProfile = businessGroupProfile profile groupPreferences (gInfo, hostMember) <- withStore $ \db -> createPreparedGroup db vr user groupProfile True ccLink welcomeSharedMsgId - createInternalChatItem user (CDGroupSnd gInfo Nothing) CIChatBanner (Just epochStart) + void $ createChatItem user (CDGroupSnd gInfo Nothing) False CIChatBanner Nothing (Just epochStart) let cd = CDGroupRcv gInfo Nothing hostMember createItem sharedMsgId content = createChatItem user cd True content sharedMsgId Nothing cInfo = GroupChat gInfo Nothing @@ -1778,7 +1778,7 @@ processChatCommand vr nm = \case pure $ CRNewPreparedChat user $ AChat SCTGroup chat ACCL _ (CCLink cReq _) -> do ct <- withStore $ \db -> createPreparedContact db user profile accLink welcomeSharedMsgId - createInternalChatItem user (CDDirectSnd ct) CIChatBanner (Just epochStart) + void $ createChatItem user (CDDirectSnd ct) False CIChatBanner Nothing (Just epochStart) let cd = CDDirectRcv ct createItem sharedMsgId content = createChatItem user cd False content sharedMsgId Nothing cInfo = DirectChat ct @@ -1793,7 +1793,7 @@ processChatCommand vr nm = \case let GroupShortLinkData {groupProfile = gp@GroupProfile {description}} = groupSLinkData welcomeSharedMsgId <- forM description $ \_ -> getSharedMsgId (gInfo, hostMember) <- withStore $ \db -> createPreparedGroup db vr user gp False ccLink welcomeSharedMsgId - createInternalChatItem user (CDGroupSnd gInfo Nothing) CIChatBanner (Just epochStart) + void $ createChatItem user (CDGroupSnd gInfo Nothing) False CIChatBanner Nothing (Just epochStart) let cd = CDGroupRcv gInfo Nothing hostMember cInfo = GroupChat gInfo Nothing void $ createGroupFeatureItems_ user cd True CIRcvGroupFeature gInfo @@ -2570,7 +2570,7 @@ processChatCommand vr nm = \case (connId, (CCLink cReq _, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True SCMInvitation Nothing Nothing IKPQOff subMode -- [incognito] reuse membership incognito profile ct <- withFastStore' $ \db -> createMemberContact db user connId cReq g m mConn subMode - createInternalChatItem user (CDDirectSnd ct) CIChatBanner (Just epochStart) + void $ createChatItem user (CDDirectSnd ct) False CIChatBanner Nothing (Just epochStart) -- TODO not sure it is correct to set connections status here? lift $ setContactNetworkStatus ct NSConnected pure $ CRNewMemberContact user ct g m diff --git a/src/Simplex/Chat/Library/Subscriber.hs b/src/Simplex/Chat/Library/Subscriber.hs index 123eec6e4b..9888e5e74e 100644 --- a/src/Simplex/Chat/Library/Subscriber.hs +++ b/src/Simplex/Chat/Library/Subscriber.hs @@ -1337,7 +1337,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = -- they will be updated after connection is accepted. upsertDirectRequestItem cd (requestMsg_, prevSharedMsgId_) Nothing -> do - createInternalChatItem user (CDDirectSnd ct) CIChatBanner (Just epochStart) + void $ createChatItem user (CDDirectSnd ct) False CIChatBanner Nothing (Just epochStart) let e2eContent = CIRcvDirectE2EEInfo $ E2EInfo $ Just $ CR.pqSupportToEnc $ reqPQSup void $ createChatItem user cd False e2eContent Nothing Nothing void $ createFeatureEnabledItems_ user ct @@ -2252,7 +2252,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = (gInfo, hostMember) <- withStore $ \db -> createGroupInvitation db vr user ct inv customUserProfileId let GroupInfo {groupId, localDisplayName, groupProfile, membership} = gInfo GroupMember {groupMemberId = hostGMId} = hostMember - createInternalChatItem user (CDGroupSnd gInfo Nothing) CIChatBanner (Just epochStart) + void $ createChatItem user (CDGroupSnd gInfo Nothing) False CIChatBanner Nothing (Just epochStart) let GroupMember {groupMemberId, memberId = membershipMemId} = membership if sameGroupLinkId groupLinkId groupLinkId' then do diff --git a/src/Simplex/Chat/Store/SQLite/Migrations/agent_query_plans.txt b/src/Simplex/Chat/Store/SQLite/Migrations/agent_query_plans.txt index 183e478fa9..8b727fde98 100644 --- a/src/Simplex/Chat/Store/SQLite/Migrations/agent_query_plans.txt +++ b/src/Simplex/Chat/Store/SQLite/Migrations/agent_query_plans.txt @@ -951,10 +951,6 @@ Plan: Query: INSERT INTO xftp_servers (xftp_host, xftp_port, xftp_key_hash) VALUES (?,?,?) Plan: -Query: SELECT 1 FROM connections WHERE conn_id = ? AND deleted_at_wait_delivery < ? LIMIT 1 -Plan: -SEARCH connections USING PRIMARY KEY (conn_id=?) - Query: SELECT 1 FROM encrypted_rcv_message_hashes WHERE conn_id = ? AND hash = ? LIMIT 1 Plan: SEARCH encrypted_rcv_message_hashes USING COVERING INDEX idx_encrypted_rcv_message_hashes_hash (conn_id=? AND hash=?) @@ -1139,10 +1135,6 @@ Query: UPDATE snd_file_chunk_replicas SET replica_status = ?, updated_at = ? WHE Plan: SEARCH snd_file_chunk_replicas USING INTEGER PRIMARY KEY (rowid=?) -Query: UPDATE snd_files SET deleted = 1, updated_at = ? WHERE snd_file_id = ? -Plan: -SEARCH snd_files USING INTEGER PRIMARY KEY (rowid=?) - Query: UPDATE snd_files SET prefix_path = NULL, status = ?, updated_at = ? WHERE snd_file_id = ? Plan: SEARCH snd_files USING INTEGER PRIMARY KEY (rowid=?) diff --git a/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt b/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt index a616742fd1..101104c975 100644 --- a/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt +++ b/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt @@ -3739,6 +3739,24 @@ SEARCH commands USING COVERING INDEX idx_commands_connection_id (connection_id=? SEARCH messages USING COVERING INDEX idx_messages_connection_id (connection_id=?) SEARCH snd_files USING COVERING INDEX idx_snd_files_connection_id (connection_id=?) +Query: + DELETE FROM connections WHERE connection_id IN ( + SELECT connection_id + FROM connections c + JOIN user_contact_links uc USING (user_contact_link_id) + WHERE uc.user_id = ? AND uc.group_id = ? + ) + +Plan: +SEARCH connections USING INTEGER PRIMARY KEY (rowid=?) +LIST SUBQUERY 1 +SEARCH uc USING INDEX idx_user_contact_links_group_id (group_id=?) +SEARCH c USING COVERING INDEX idx_connections_user_contact_link_id (user_contact_link_id=?) +SEARCH msg_deliveries USING COVERING INDEX idx_msg_deliveries_agent_msg_id (connection_id=?) +SEARCH commands USING COVERING INDEX idx_commands_connection_id (connection_id=?) +SEARCH messages USING COVERING INDEX idx_messages_connection_id (connection_id=?) +SEARCH snd_files USING COVERING INDEX idx_snd_files_connection_id (connection_id=?) + Query: DELETE FROM connections WHERE connection_id IN ( SELECT connection_id @@ -3822,6 +3840,26 @@ SEARCH group_members USING COVERING INDEX idx_group_members_member_profile_id (m SEARCH group_members USING COVERING INDEX idx_group_members_contact_profile_id (contact_profile_id=?) SEARCH contacts USING COVERING INDEX idx_contacts_contact_profile_id (contact_profile_id=?) +Query: + DELETE FROM contact_profiles + WHERE contact_profile_id in ( + SELECT cr.contact_profile_id + FROM contact_requests cr + JOIN user_contact_links uc USING (user_contact_link_id) + WHERE uc.user_id = ? AND uc.group_id = ? + ) + +Plan: +SEARCH contact_profiles USING INTEGER PRIMARY KEY (rowid=?) +LIST SUBQUERY 1 +SEARCH uc USING INDEX idx_user_contact_links_group_id (group_id=?) +SEARCH cr USING INDEX idx_contact_requests_user_contact_link_id (user_contact_link_id=?) +SEARCH contact_requests USING COVERING INDEX idx_contact_requests_contact_profile_id (contact_profile_id=?) +SEARCH connections USING COVERING INDEX idx_connections_custom_user_profile_id (custom_user_profile_id=?) +SEARCH group_members USING COVERING INDEX idx_group_members_member_profile_id (member_profile_id=?) +SEARCH group_members USING COVERING INDEX idx_group_members_contact_profile_id (contact_profile_id=?) +SEARCH contacts USING COVERING INDEX idx_contacts_contact_profile_id (contact_profile_id=?) + Query: DELETE FROM contact_profiles WHERE user_id = ? AND contact_profile_id = ? @@ -3929,6 +3967,30 @@ SEARCH groups USING COVERING INDEX sqlite_autoindex_groups_1 (user_id=? AND loca SEARCH contacts USING COVERING INDEX sqlite_autoindex_contacts_1 (user_id=? AND local_display_name=?) SEARCH users USING INTEGER PRIMARY KEY (rowid=?) +Query: + DELETE FROM display_names + WHERE user_id = ? + AND local_display_name in ( + SELECT cr.local_display_name + FROM contact_requests cr + JOIN user_contact_links uc USING (user_contact_link_id) + WHERE uc.user_id = ? AND uc.group_id = ? + ) + AND local_display_name NOT IN (SELECT local_display_name FROM users WHERE user_id = ?) + +Plan: +SEARCH display_names USING PRIMARY KEY (user_id=? AND local_display_name=?) +LIST SUBQUERY 1 +SEARCH uc USING INDEX idx_user_contact_links_group_id (group_id=?) +SEARCH cr USING INDEX idx_contact_requests_user_contact_link_id (user_contact_link_id=?) +LIST SUBQUERY 2 +SEARCH users USING INTEGER PRIMARY KEY (rowid=?) +SEARCH contact_requests USING COVERING INDEX sqlite_autoindex_contact_requests_1 (user_id=? AND local_display_name=?) +SEARCH group_members USING COVERING INDEX idx_group_members_user_id_local_display_name (user_id=? AND local_display_name=?) +SEARCH groups USING COVERING INDEX sqlite_autoindex_groups_1 (user_id=? AND local_display_name=?) +SEARCH contacts USING COVERING INDEX sqlite_autoindex_contacts_1 (user_id=? AND local_display_name=?) +SEARCH users USING INTEGER PRIMARY KEY (rowid=?) + Query: DELETE FROM display_names WHERE user_id = ? AND local_display_name = ( @@ -4048,13 +4110,6 @@ LIST SUBQUERY 1 SEARCH groups USING INTEGER PRIMARY KEY (rowid=?) SEARCH groups USING COVERING INDEX idx_groups_group_profile_id (group_profile_id=?) -Query: - INSERT INTO calls - (contact_id, shared_call_id, call_uuid, chat_item_id, call_state, call_ts, user_id, created_at, updated_at) - VALUES (?,?,?,?,?,?,?,?,?) - -Plan: - Query: INSERT INTO chat_item_moderations (group_id, moderator_member_id, item_member_id, shared_msg_id, created_by_msg_id, moderated_at) @@ -4169,14 +4224,6 @@ Query: Plan: SEARCH group_members USING INDEX sqlite_autoindex_group_members_1 (group_id=?) -Query: - SELECT chat_item_id, timed_ttl - FROM chat_items - WHERE user_id = ? AND contact_id = ? AND item_status = ? AND timed_ttl IS NOT NULL AND timed_delete_at IS NULL - -Plan: -SEARCH chat_items USING INDEX idx_chat_items_contacts (user_id=? AND contact_id=? AND item_status=?) - Query: SELECT chat_item_id, timed_ttl FROM chat_items @@ -4255,13 +4302,6 @@ Query: Plan: SEARCH chat_items USING INTEGER PRIMARY KEY (rowid=?) -Query: - UPDATE chat_items SET item_status = ?, updated_at = ? - WHERE user_id = ? AND contact_id = ? AND item_status = ? - -Plan: -SEARCH chat_items USING INDEX idx_chat_items_contacts (user_id=? AND contact_id=? AND item_status=?) - Query: UPDATE chat_items SET item_status = ?, updated_at = ? WHERE user_id = ? AND contact_id = ? AND item_status = ? AND chat_item_id = ? @@ -5227,6 +5267,10 @@ Query: SELECT chat_item_id FROM chat_items WHERE user_id = ? AND group_id = ? Plan: SEARCH chat_items USING COVERING INDEX idx_chat_items_group_scope_item_ts (user_id=? AND group_id=? AND group_scope_tag=? AND group_scope_group_member_id=?) +Query: SELECT chat_item_id FROM chat_items WHERE user_id = ? AND group_id = ? AND group_scope_tag IS NULL AND group_scope_group_member_id IS NULL AND LOWER(item_text) LIKE '%' || LOWER(?) || '%' ORDER BY item_ts DESC, chat_item_id DESC LIMIT ? +Plan: +SEARCH chat_items USING INDEX idx_chat_items_group_scope_item_ts (user_id=? AND group_id=? AND group_scope_tag=? AND group_scope_group_member_id=?) + Query: SELECT chat_item_id FROM chat_items WHERE user_id = ? AND group_id = ? AND group_scope_tag IS NULL AND group_scope_group_member_id IS NULL ORDER BY item_ts DESC, chat_item_id DESC LIMIT ? Plan: SEARCH chat_items USING COVERING INDEX idx_chat_items_group_scope_item_ts (user_id=? AND group_id=? AND group_scope_tag=? AND group_scope_group_member_id=?) @@ -5244,10 +5288,6 @@ Error: SQLite3 returned ErrorError while attempting to perform prepare "explain Query: DELETE FROM app_settings Plan: -Query: DELETE FROM calls WHERE user_id = ? AND contact_id = ? -Plan: -SEARCH calls USING INDEX idx_calls_contact_id (contact_id=?) - Query: DELETE FROM chat_item_mentions WHERE chat_item_id = ? Plan: SEARCH chat_item_mentions USING COVERING INDEX idx_chat_item_mentions_chat_item_id (chat_item_id=?) @@ -5292,7 +5332,7 @@ SEARCH chat_items USING COVERING INDEX idx_chat_items_fwd_from_chat_item_id (fwd SEARCH files USING COVERING INDEX idx_files_chat_item_id (chat_item_id=?) SEARCH groups USING COVERING INDEX idx_groups_chat_item_id (chat_item_id=?) -Query: DELETE FROM chat_items WHERE user_id = ? AND contact_id = ? AND created_at <= ? AND item_content_tag != 'chat_banner' +Query: DELETE FROM chat_items WHERE user_id = ? AND contact_id = ? AND created_at <= ? AND item_content_tag != 'chatBanner' Plan: SEARCH chat_items USING INDEX idx_chat_items_contacts_created_at (user_id=? AND contact_id=? AND created_at (a, c)) chatFeatures'' chatFeatures'' :: [((Int, String), Maybe (Int, String), Maybe String)] chatFeatures'' = - [ ((1, "chat banner"), Nothing, Nothing), - ((0, e2eeInfoPQStr), Nothing, Nothing), + [ ((0, e2eeInfoPQStr), Nothing, Nothing), ((0, "Disappearing messages: allowed"), Nothing, Nothing), ((0, "Full deletion: off"), Nothing, Nothing), ((0, "Message reactions: enabled"), Nothing, Nothing), @@ -310,7 +309,7 @@ groupFeatureStrs :: [String] groupFeatureStrs = map (\(a, _, _) -> snd a) $ groupFeatures'' 0 groupFeatures'' :: Int -> [((Int, String), Maybe (Int, String), Maybe String)] -groupFeatures'' dir = ((1, "chat banner"), Nothing, Nothing) : ((dir, e2eeInfoNoPQStr), Nothing, Nothing) : groupFeatures_ dir +groupFeatures'' dir = ((dir, e2eeInfoNoPQStr), Nothing, Nothing) : groupFeatures_ dir groupFeatures_ :: Int -> [((Int, String), Maybe (Int, String), Maybe String)] groupFeatures_ dir =