diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index 4524760bbc..eef3c38b3a 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -446,6 +446,9 @@ processChatCommand = \case withChatLock . procCmd $ do when (memberActive membership) . void $ sendGroupMessage gInfo members XGrpDel mapM_ deleteMemberConnection members + -- two functions below are called in separate transactions to prevent crashes on android + -- (possibly, race condition on integrity check?) + withStore' $ \db -> deleteGroupConnectionsAndFiles db userId g withStore' $ \db -> deleteGroup db user g pure $ CRGroupDeletedUser gInfo CTContactRequest -> pure $ chatCmdError "not supported" diff --git a/src/Simplex/Chat/Store.hs b/src/Simplex/Chat/Store.hs index 31cf52c72b..21b43fd351 100644 --- a/src/Simplex/Chat/Store.hs +++ b/src/Simplex/Chat/Store.hs @@ -70,6 +70,7 @@ module Simplex.Chat.Store getGroupInfoByName, getGroupMember, getGroupMembers, + deleteGroupConnectionsAndFiles, deleteGroup, getUserGroups, getUserGroupDetails, @@ -1340,10 +1341,21 @@ getGroup db user groupId = do members <- liftIO $ getGroupMembers db user gInfo pure $ Group gInfo members -deleteGroup :: DB.Connection -> User -> Group -> IO () -deleteGroup db User {userId} (Group GroupInfo {groupId, localDisplayName} members) = do +deleteGroupConnectionsAndFiles :: DB.Connection -> UserId -> Group -> IO () +deleteGroupConnectionsAndFiles db userId (Group GroupInfo {groupId} members) = do forM_ members $ \m -> DB.execute db "DELETE FROM connections WHERE user_id = ? AND group_member_id = ?" (userId, groupMemberId' m) + DB.execute db "DELETE FROM files WHERE user_id = ? AND group_id = ?" (userId, groupId) + +deleteGroup :: DB.Connection -> User -> Group -> IO () +deleteGroup db User {userId} (Group GroupInfo {groupId, localDisplayName} _) = do + DB.execute db "DELETE FROM chat_items WHERE user_id = ? AND group_id = ?" (userId, groupId) DB.execute db "DELETE FROM group_members WHERE user_id = ? AND group_id = ?" (userId, groupId) + deleteGroupProfile_ db userId groupId + DB.execute db "DELETE FROM groups WHERE user_id = ? AND group_id = ?" (userId, groupId) + DB.execute db "DELETE FROM display_names WHERE user_id = ? AND local_display_name = ?" (userId, localDisplayName) + +deleteGroupProfile_ :: DB.Connection -> UserId -> GroupId -> IO () +deleteGroupProfile_ db userId groupId = DB.execute db [sql| @@ -1355,8 +1367,6 @@ deleteGroup db User {userId} (Group GroupInfo {groupId, localDisplayName} member ) |] (userId, groupId) - DB.execute db "DELETE FROM groups WHERE user_id = ? AND group_id = ?" (userId, groupId) - DB.execute db "DELETE FROM display_names WHERE user_id = ? AND local_display_name = ?" (userId, localDisplayName) getUserGroups :: DB.Connection -> User -> IO [Group] getUserGroups db user@User {userId} = do