mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-23 00:02:28 +00:00
core: delete members with messages (#5711)
* core: delete members with messages (WIP) * remove messages * fix, test * update query plans
This commit is contained in:
1 parent
5bef7349d8
commit
a6631ce629
11 files changed
+302
-92
No files matched your search
@@ -21,6 +21,7 @@ module Simplex.Chat.Store.Messages
|
||||
-- * Message and chat item functions
|
||||
deleteContactCIs,
|
||||
getGroupFileInfo,
|
||||
getGroupMemberFileInfo,
|
||||
deleteGroupChatItemsMessages,
|
||||
createNewSndMessage,
|
||||
createSndMsgDelivery,
|
||||
@@ -57,8 +58,10 @@ module Simplex.Chat.Store.Messages
|
||||
updateGroupCIMentions,
|
||||
deleteGroupChatItem,
|
||||
updateGroupChatItemModerated,
|
||||
updateMemberCIsModerated,
|
||||
updateGroupCIBlockedByAdmin,
|
||||
markGroupChatItemDeleted,
|
||||
markMemberCIsDeleted,
|
||||
markGroupChatItemBlocked,
|
||||
markGroupCIBlockedByAdmin,
|
||||
markMessageReportsDeleted,
|
||||
@@ -193,6 +196,11 @@ getGroupFileInfo db User {userId} GroupInfo {groupId} =
|
||||
map toFileInfo
|
||||
<$> DB.query db (fileInfoQuery <> " WHERE i.user_id = ? AND i.group_id = ?") (userId, groupId)
|
||||
|
||||
getGroupMemberFileInfo :: DB.Connection -> User -> GroupInfo -> GroupMember -> IO [CIFileInfo]
|
||||
getGroupMemberFileInfo db User {userId} GroupInfo {groupId} GroupMember {groupMemberId} =
|
||||
map toFileInfo
|
||||
<$> DB.query db (fileInfoQuery <> " WHERE i.user_id = ? AND i.group_id = ? AND i.group_member_id = ?") (userId, groupId, groupMemberId)
|
||||
|
||||
deleteGroupChatItemsMessages :: DB.Connection -> User -> GroupInfo -> IO ()
|
||||
deleteGroupChatItemsMessages db User {userId} GroupInfo {groupId} = do
|
||||
DB.execute db "DELETE FROM messages WHERE group_id = ?" (Only groupId)
|
||||
@@ -2150,18 +2158,18 @@ deleteDirectChatItem db User {userId} Contact {contactId} ci = do
|
||||
(userId, contactId, itemId)
|
||||
|
||||
deleteChatItemMessages_ :: DB.Connection -> ChatItemId -> IO ()
|
||||
deleteChatItemMessages_ db itemId =
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
DELETE FROM messages
|
||||
WHERE message_id IN (
|
||||
SELECT message_id
|
||||
FROM chat_item_messages
|
||||
WHERE chat_item_id = ?
|
||||
)
|
||||
|]
|
||||
(Only itemId)
|
||||
deleteChatItemMessages_ db itemId = DB.execute db deleteChatItemMessagesQuery (Only itemId)
|
||||
|
||||
deleteChatItemMessagesQuery :: Query
|
||||
deleteChatItemMessagesQuery =
|
||||
[sql|
|
||||
DELETE FROM messages
|
||||
WHERE message_id IN (
|
||||
SELECT message_id
|
||||
FROM chat_item_messages
|
||||
WHERE chat_item_id = ?
|
||||
)
|
||||
|]
|
||||
|
||||
deleteChatItemVersions_ :: DB.Connection -> ChatItemId -> IO ()
|
||||
deleteChatItemVersions_ db itemId =
|
||||
@@ -2359,6 +2367,34 @@ updateGroupChatItemModerated db User {userId} GroupInfo {groupId} ci m@GroupMemb
|
||||
(deletedTs, groupMemberId, toContent, toText, currentTs, userId, groupId, itemId)
|
||||
pure ci {content = toContent, meta = (meta ci) {itemText = toText, itemDeleted = Just (CIModerated (Just deletedTs) m), editable = False, deletable = False}, formattedText = Nothing}
|
||||
|
||||
updateMemberCIsModerated :: MsgDirectionI d => DB.Connection -> User -> GroupInfo -> GroupMember -> GroupMember -> SMsgDirection d -> UTCTime -> IO ()
|
||||
updateMemberCIsModerated db User {userId} GroupInfo {groupId, membership} member byGroupMember md deletedTs = do
|
||||
itemIds <- updateCIs =<< getCurrentTime
|
||||
DB.executeMany db deleteChatItemMessagesQuery itemIds
|
||||
DB.executeMany db "DELETE FROM chat_item_versions WHERE chat_item_id = ?" itemIds
|
||||
where
|
||||
memId = groupMemberId' member
|
||||
updateQuery =
|
||||
[sql|
|
||||
UPDATE chat_items
|
||||
SET item_deleted = 1, item_deleted_ts = ?, item_deleted_by_group_member_id = ?, item_content = ?, item_text = ?, updated_at = ?
|
||||
WHERE user_id = ? AND group_id = ?
|
||||
|]
|
||||
updateCIs :: UTCTime -> IO [Only Int64]
|
||||
updateCIs currentTs
|
||||
| memId == groupMemberId' membership =
|
||||
DB.query
|
||||
db
|
||||
(updateQuery <> " AND group_member_id IS NULL AND item_sent = 1 RETURNING chat_item_id")
|
||||
(columns :. (userId, groupId))
|
||||
| otherwise =
|
||||
DB.query
|
||||
db
|
||||
(updateQuery <> " AND group_member_id = ? RETURNING chat_item_id")
|
||||
(columns :. (userId, groupId, memId))
|
||||
where
|
||||
columns = (deletedTs, groupMemberId' byGroupMember, msgDirToModeratedContent_ md, ciModeratedText, currentTs)
|
||||
|
||||
updateGroupCIBlockedByAdmin :: DB.Connection -> User -> GroupInfo -> ChatItem 'CTGroup d -> UTCTime -> IO (ChatItem 'CTGroup d)
|
||||
updateGroupCIBlockedByAdmin db User {userId} GroupInfo {groupId} ci deletedTs = do
|
||||
currentTs <- getCurrentTime
|
||||
@@ -2405,6 +2441,31 @@ markGroupChatItemDeleted db User {userId} GroupInfo {groupId} ci@ChatItem {meta}
|
||||
(DBCIDeleted, deletedTs, deletedByGroupMemberId, currentTs, userId, groupId, itemId)
|
||||
pure ci {meta = meta {itemDeleted, editable = False, deletable = False}}
|
||||
|
||||
markMemberCIsDeleted :: DB.Connection -> User -> GroupInfo -> GroupMember -> GroupMember -> UTCTime -> IO ()
|
||||
markMemberCIsDeleted db User {userId} GroupInfo {groupId, membership} member byGroupMember deletedTs =
|
||||
updateCIs =<< getCurrentTime
|
||||
where
|
||||
memId = groupMemberId' member
|
||||
updateQuery =
|
||||
[sql|
|
||||
UPDATE chat_items
|
||||
SET item_deleted = ?, item_deleted_ts = ?, item_deleted_by_group_member_id = ?, updated_at = ?
|
||||
WHERE user_id = ? AND group_id = ?
|
||||
|]
|
||||
updateCIs currentTs
|
||||
| memId == groupMemberId' membership =
|
||||
DB.execute
|
||||
db
|
||||
(updateQuery <> " AND group_member_id IS NULL AND item_sent = 1")
|
||||
(columns :. (userId, groupId))
|
||||
| otherwise =
|
||||
DB.execute
|
||||
db
|
||||
(updateQuery <> " AND group_member_id = ?")
|
||||
(columns :. (userId, groupId, memId))
|
||||
where
|
||||
columns = (DBCIDeleted, deletedTs, groupMemberId' byGroupMember, currentTs)
|
||||
|
||||
markGroupChatItemBlocked :: DB.Connection -> User -> GroupInfo -> ChatItem 'CTGroup 'MDRcv -> IO (ChatItem 'CTGroup 'MDRcv)
|
||||
markGroupChatItemBlocked db User {userId} GroupInfo {groupId} ci@ChatItem {meta} = do
|
||||
deletedTs <- getCurrentTime
|
||||
|
||||
@@ -3314,6 +3314,22 @@ Query:
|
||||
Plan:
|
||||
SEARCH usage_conditions USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
UPDATE chat_items
|
||||
SET item_deleted = 1, item_deleted_ts = ?, item_deleted_by_group_member_id = ?, item_content = ?, item_text = ?, updated_at = ?
|
||||
WHERE user_id = ? AND group_id = ?
|
||||
AND group_member_id = ? RETURNING chat_item_id
|
||||
Plan:
|
||||
SEARCH chat_items USING COVERING INDEX idx_chat_items_group_shared_msg_id (user_id=? AND group_id=? AND group_member_id=?)
|
||||
|
||||
Query:
|
||||
UPDATE chat_items
|
||||
SET item_deleted = 1, item_deleted_ts = ?, item_deleted_by_group_member_id = ?, item_content = ?, item_text = ?, updated_at = ?
|
||||
WHERE user_id = ? AND group_id = ?
|
||||
AND group_member_id IS NULL AND item_sent = 1 RETURNING chat_item_id
|
||||
Plan:
|
||||
SEARCH chat_items USING INDEX idx_chat_items_group_shared_msg_id (user_id=? AND group_id=? AND group_member_id=?)
|
||||
|
||||
Query:
|
||||
UPDATE chat_items
|
||||
SET item_deleted = 1, item_deleted_ts = ?, item_deleted_by_group_member_id = ?, item_content = ?, item_text = ?, updated_at = ?
|
||||
@@ -3322,6 +3338,22 @@ Query:
|
||||
Plan:
|
||||
SEARCH chat_items USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
UPDATE chat_items
|
||||
SET item_deleted = ?, item_deleted_ts = ?, item_deleted_by_group_member_id = ?, updated_at = ?
|
||||
WHERE user_id = ? AND group_id = ?
|
||||
AND group_member_id = ?
|
||||
Plan:
|
||||
SEARCH chat_items USING COVERING INDEX idx_chat_items_group_shared_msg_id (user_id=? AND group_id=? AND group_member_id=?)
|
||||
|
||||
Query:
|
||||
UPDATE chat_items
|
||||
SET item_deleted = ?, item_deleted_ts = ?, item_deleted_by_group_member_id = ?, updated_at = ?
|
||||
WHERE user_id = ? AND group_id = ?
|
||||
AND group_member_id IS NULL AND item_sent = 1
|
||||
Plan:
|
||||
SEARCH chat_items USING INDEX idx_chat_items_group_shared_msg_id (user_id=? AND group_id=? AND group_member_id=?)
|
||||
|
||||
Query:
|
||||
UPDATE chat_items
|
||||
SET item_deleted = ?, item_deleted_ts = ?, item_deleted_by_group_member_id = ?, updated_at = ?
|
||||
@@ -3861,25 +3893,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:
|
||||
DELETE FROM messages
|
||||
WHERE message_id IN (
|
||||
SELECT message_id
|
||||
FROM chat_item_messages
|
||||
WHERE chat_item_id = ?
|
||||
)
|
||||
|
||||
Plan:
|
||||
SEARCH messages USING INTEGER PRIMARY KEY (rowid=?)
|
||||
LIST SUBQUERY 1
|
||||
SEARCH chat_item_messages USING COVERING INDEX sqlite_autoindex_chat_item_messages_2 (chat_item_id=?)
|
||||
SEARCH msg_deliveries USING COVERING INDEX idx_msg_deliveries_message_id (message_id=?)
|
||||
SEARCH chat_item_moderations USING COVERING INDEX idx_chat_item_moderations_created_by_msg_id (created_by_msg_id=?)
|
||||
SEARCH chat_item_reactions USING COVERING INDEX idx_chat_item_reactions_created_by_msg_id (created_by_msg_id=?)
|
||||
SEARCH chat_item_messages USING COVERING INDEX sqlite_autoindex_chat_item_messages_1 (message_id=?)
|
||||
SEARCH chat_items USING COVERING INDEX sqlite_autoindex_chat_items_1 (created_by_msg_id=?)
|
||||
SEARCH pending_group_messages USING COVERING INDEX idx_pending_group_messages_message_id (message_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)
|
||||
@@ -4414,6 +4427,25 @@ Query:
|
||||
Plan:
|
||||
SEARCH xftp_file_descriptions USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
DELETE FROM messages
|
||||
WHERE message_id IN (
|
||||
SELECT message_id
|
||||
FROM chat_item_messages
|
||||
WHERE chat_item_id = ?
|
||||
)
|
||||
|
||||
Plan:
|
||||
SEARCH messages USING INTEGER PRIMARY KEY (rowid=?)
|
||||
LIST SUBQUERY 1
|
||||
SEARCH chat_item_messages USING COVERING INDEX sqlite_autoindex_chat_item_messages_2 (chat_item_id=?)
|
||||
SEARCH msg_deliveries USING COVERING INDEX idx_msg_deliveries_message_id (message_id=?)
|
||||
SEARCH chat_item_moderations USING COVERING INDEX idx_chat_item_moderations_created_by_msg_id (created_by_msg_id=?)
|
||||
SEARCH chat_item_reactions USING COVERING INDEX idx_chat_item_reactions_created_by_msg_id (created_by_msg_id=?)
|
||||
SEARCH chat_item_messages USING COVERING INDEX sqlite_autoindex_chat_item_messages_1 (message_id=?)
|
||||
SEARCH chat_items USING COVERING INDEX sqlite_autoindex_chat_items_1 (created_by_msg_id=?)
|
||||
SEARCH pending_group_messages USING COVERING INDEX idx_pending_group_messages_message_id (message_id=?)
|
||||
|
||||
Query:
|
||||
SELECT
|
||||
-- GroupInfo
|
||||
@@ -4654,6 +4686,15 @@ Plan:
|
||||
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=?)
|
||||
|
||||
Query:
|
||||
SELECT f.file_id, f.ci_file_status, f.file_path
|
||||
FROM chat_items i
|
||||
JOIN files f ON f.chat_item_id = i.chat_item_id
|
||||
WHERE i.user_id = ? AND i.group_id = ? AND i.group_member_id = ?
|
||||
Plan:
|
||||
SEARCH i USING COVERING INDEX idx_chat_items_group_shared_msg_id (user_id=? AND group_id=? AND group_member_id=?)
|
||||
SEARCH f USING INDEX idx_files_chat_item_id (chat_item_id=?)
|
||||
|
||||
Query:
|
||||
SELECT f.file_id, f.ci_file_status, f.file_path
|
||||
FROM chat_items i
|
||||
|
||||
Reference in new issue
Block a user