core: delete unused group contacts, don't create new ones (#5590)

* core: delete unused group contacts, don't create new ones

* remove from exceptions

* plans

* fix tests

* remove fixtures

* update plans

* update migration

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
spaced4ndyandEvgeny Poberezkin authored and GitHub committed 2025-01-31 10:32:07 +04:00
1 parent 7f09de18d9
commit 5d18a49726
20 files changed
+416 -1397

No files matched your search

+4 -10
View File
@@ -46,7 +46,6 @@ module Simplex.Chat.Store.Direct
updateContactConnectionAlias,
updatePCCIncognito,
deletePCCIncognitoProfile,
updateContactUsed,
updateContactUnreadChat,
setUserChatsRead,
updateContactStatus,
@@ -240,10 +239,10 @@ createIncognitoProfile db User {userId} p = do
createdAt <- getCurrentTime
createIncognitoProfile_ db userId createdAt p
createDirectContact :: DB.Connection -> User -> Connection -> Profile -> Bool -> ExceptT StoreError IO Contact
createDirectContact db user@User {userId} conn@Connection {connId, localAlias} p@Profile {preferences} contactUsed = do
createDirectContact :: DB.Connection -> User -> Connection -> Profile -> ExceptT StoreError IO Contact
createDirectContact db user@User {userId} conn@Connection {connId, localAlias} p@Profile {preferences} = do
currentTs <- liftIO getCurrentTime
(localDisplayName, contactId, profileId) <- createContact_ db userId p localAlias Nothing currentTs contactUsed
(localDisplayName, contactId, profileId) <- createContact_ db userId p localAlias Nothing currentTs
liftIO $ DB.execute db "UPDATE connections SET contact_id = ?, updated_at = ? WHERE connection_id = ?" (contactId, currentTs, connId)
let profile = toLocalProfile profileId p localAlias
userPreferences = emptyChatPrefs
@@ -255,7 +254,7 @@ createDirectContact db user@User {userId} conn@Connection {connId, localAlias} p
profile,
activeConn = Just conn,
viaGroup = Nothing,
contactUsed,
contactUsed = True,
contactStatus = CSActive,
chatSettings = defaultChatSettings,
userPreferences,
@@ -471,11 +470,6 @@ deletePCCIncognitoProfile db User {userId} profileId =
|]
(userId, profileId)
updateContactUsed :: DB.Connection -> User -> Contact -> IO ()
updateContactUsed db User {userId} Contact {contactId} = do
updatedAt <- getCurrentTime
DB.execute db "UPDATE contacts SET contact_used = 1, updated_at = ? WHERE user_id = ? AND contact_id = ?" (updatedAt, userId, contactId)
updateContactUnreadChat :: DB.Connection -> User -> Contact -> Bool -> IO ()
updateContactUnreadChat db User {userId} Contact {contactId} unreadChat = do
updatedAt <- getCurrentTime
+4 -51
View File
@@ -110,7 +110,6 @@ module Simplex.Chat.Store.Groups
updateGroupMemberSettings,
updateGroupMemberBlocked,
getXGrpMemIntroContDirect,
getXGrpMemIntroContGroup,
getHostConnId,
createMemberContact,
getMemberContact,
@@ -1397,33 +1396,23 @@ getForwardInvitedMembers db vr user forwardMember highlyAvailable = do
WHERE re_group_member_id = ? AND intro_status NOT IN (?,?,?)
|]
createIntroReMember :: DB.Connection -> User -> GroupInfo -> GroupMember -> VersionChat -> MemberInfo -> Maybe MemberRestrictions -> (CommandId, ConnId) -> Maybe (CommandId, ConnId) -> Maybe ProfileId -> SubscriptionMode -> ExceptT StoreError IO GroupMember
createIntroReMember :: DB.Connection -> User -> GroupInfo -> GroupMember -> VersionChat -> MemberInfo -> Maybe MemberRestrictions -> (CommandId, ConnId) -> SubscriptionMode -> ExceptT StoreError IO GroupMember
createIntroReMember
db
user@User {userId}
gInfo@GroupInfo {groupId}
gInfo
_host@GroupMember {memberContactId, activeConn}
chatV
memInfo@(MemberInfo _ _ memChatVRange memberProfile)
memRestrictions_
(groupCmdId, groupAgentConnId)
directConnIds
customUserProfileId
subMode = do
let mcvr = maybe chatInitialVRange fromChatVRange memChatVRange
cLevel = 1 + maybe 0 (\Connection {connLevel} -> connLevel) activeConn
memRestriction = restriction <$> memRestrictions_
currentTs <- liftIO getCurrentTime
newMember <- case directConnIds of
Just (directCmdId, directAgentConnId) -> do
Connection {connId = directConnId} <- liftIO $ createConnection_ db userId ConnContact Nothing directAgentConnId ConnNew chatV mcvr memberContactId Nothing customUserProfileId cLevel currentTs subMode PQSupportOff
liftIO $ setCommandConnId db user directCmdId directConnId
(localDisplayName, contactId, memProfileId) <- createContact_ db userId memberProfile "" (Just groupId) currentTs False
liftIO $ DB.execute db "UPDATE connections SET contact_id = ?, updated_at = ? WHERE connection_id = ?" (contactId, currentTs, directConnId)
pure $ NewGroupMember {memInfo, memCategory = GCPreMember, memStatus = GSMemIntroduced, memRestriction, memInvitedBy = IBUnknown, memInvitedByGroupMemberId = Nothing, localDisplayName, memContactId = Just contactId, memProfileId}
Nothing -> do
(localDisplayName, memProfileId) <- createNewMemberProfile_ db user memberProfile currentTs
pure $ NewGroupMember {memInfo, memCategory = GCPreMember, memStatus = GSMemIntroduced, memRestriction, memInvitedBy = IBUnknown, memInvitedByGroupMemberId = Nothing, localDisplayName, memContactId = Nothing, memProfileId}
(localDisplayName, memProfileId) <- createNewMemberProfile_ db user memberProfile currentTs
let newMember = NewGroupMember {memInfo, memCategory = GCPreMember, memStatus = GSMemIntroduced, memRestriction, memInvitedBy = IBUnknown, memInvitedByGroupMemberId = Nothing, localDisplayName, memContactId = Nothing, memProfileId}
liftIO $ do
member <- createNewMember_ db user gInfo newMember currentTs
conn@Connection {connId = groupConnId} <- createMemberConnection_ db userId (groupMemberId' member) groupAgentConnId chatV mcvr memberContactId cLevel currentTs subMode
@@ -1850,12 +1839,6 @@ mergeContactRecords db vr user@User {userId} to@Contact {localDisplayName = keep
assertNotUser db user fromCt
liftIO $ do
currentTs <- getCurrentTime
-- next query fixes incorrect unused contacts deletion
when (contactDirect toCt && not (contactUsed toCt)) $
DB.execute
db
"UPDATE contacts SET contact_used = 1, updated_at = ? WHERE user_id = ? AND contact_id = ?"
(currentTs, userId, toContactId)
DB.execute
db
"UPDATE connections SET contact_id = ?, updated_at = ? WHERE contact_id = ? AND user_id = ?"
@@ -2061,36 +2044,6 @@ getXGrpMemIntroContDirect db User {userId} Contact {contactId} = do
Just groupConnReq -> Just (hostConnId, XGrpMemIntroCont {groupId, groupMemberId, memberId, groupConnReq})
_ -> Nothing
getXGrpMemIntroContGroup :: DB.Connection -> User -> GroupMember -> IO (Maybe (Int64, ConnReqInvitation))
getXGrpMemIntroContGroup db User {userId} GroupMember {groupMemberId} = do
fmap join . maybeFirstRow toCont $
DB.query
db
[sql|
SELECT ch.connection_id, c.conn_req_inv
FROM group_members m
JOIN contacts ct ON ct.contact_id = m.contact_id
LEFT JOIN connections c ON c.connection_id = (
SELECT MAX(cc.connection_id)
FROM connections cc
WHERE cc.contact_id = ct.contact_id
)
JOIN groups g ON g.group_id = m.group_id AND g.group_id = ct.via_group
JOIN group_members mh ON mh.group_id = g.group_id
LEFT JOIN connections ch ON ch.connection_id = (
SELECT max(cc.connection_id)
FROM connections cc
where cc.user_id = ? AND cc.group_member_id = mh.group_member_id
)
WHERE m.user_id = ? AND m.group_member_id = ? AND mh.member_category = ? AND ct.deleted = 0
|]
(userId, userId, groupMemberId, GCHostMember)
where
toCont :: (Int64, Maybe ConnReqInvitation) -> Maybe (Int64, ConnReqInvitation)
toCont (hostConnId, connReq_) = case connReq_ of
Just connReq -> Just (hostConnId, connReq)
_ -> Nothing
getHostConnId :: DB.Connection -> User -> GroupId -> ExceptT StoreError IO GroupMemberId
getHostConnId db user@User {userId} groupId = do
hostMemberId <- getHostMemberId_ db user groupId
+1 -2
View File
@@ -2562,8 +2562,7 @@ getGroupChatItemIdByText db User {userId, localDisplayName = userName} groupId c
SELECT i.chat_item_id
FROM chat_items i
JOIN group_members m ON m.group_member_id = i.group_member_id
JOIN contacts c ON c.contact_id = m.contact_id
WHERE i.user_id = ? AND i.group_id = ? AND c.local_display_name = ? AND i.item_text like ?
WHERE i.user_id = ? AND i.group_id = ? AND m.local_display_name = ? AND i.item_text like ?
ORDER BY i.chat_item_id DESC
LIMIT 1
|]
+3 -1
View File
@@ -126,6 +126,7 @@ import Simplex.Chat.Store.SQLite.Migrations.M20250105_indexes
import Simplex.Chat.Store.SQLite.Migrations.M20250115_chat_ttl
import Simplex.Chat.Store.SQLite.Migrations.M20250122_chat_items_include_in_history
import Simplex.Chat.Store.SQLite.Migrations.M20250126_mentions
import Simplex.Chat.Store.SQLite.Migrations.M20250129_delete_unused_contacts
import Simplex.Messaging.Agent.Store.Shared (Migration (..))
schemaMigrations :: [(String, Query, Maybe Query)]
@@ -251,7 +252,8 @@ schemaMigrations =
("20250105_indexes", m20250105_indexes, Just down_m20250105_indexes),
("20250115_chat_ttl", m20250115_chat_ttl, Just down_m20250115_chat_ttl),
("20250122_chat_items_include_in_history", m20250122_chat_items_include_in_history, Just down_m20250122_chat_items_include_in_history),
("20250126_mentions", m20250126_mentions, Just down_m20250126_mentions)
("20250126_mentions", m20250126_mentions, Just down_m20250126_mentions),
("20250129_delete_unused_contacts", m20250129_delete_unused_contacts, Just down_m20250129_delete_unused_contacts)
]
-- | The list of migrations in ascending order by date
@@ -0,0 +1,64 @@
{-# LANGUAGE QuasiQuotes #-}
module Simplex.Chat.Store.SQLite.Migrations.M20250129_delete_unused_contacts where
import Database.SQLite.Simple (Query)
import Database.SQLite.Simple.QQ (sql)
m20250129_delete_unused_contacts :: Query
m20250129_delete_unused_contacts =
[sql|
CREATE TEMPORARY TABLE temp_delete_contacts (
contact_id INTEGER PRIMARY KEY,
contact_profile_id INTEGER NOT NULL,
local_display_name TEXT NOT NULL
);
INSERT INTO temp_delete_contacts(contact_id, contact_profile_id, local_display_name)
SELECT contact_id, contact_profile_id, local_display_name
FROM contacts
WHERE contact_used = 0 AND is_user = 0
AND contact_id NOT IN (SELECT contact_id FROM users)
AND contact_id NOT IN (SELECT contact_id FROM contact_requests);
CREATE TEMPORARY TABLE temp_delete_profiles (contact_profile_id INTEGER PRIMARY KEY);
INSERT OR IGNORE INTO temp_delete_profiles(contact_profile_id)
SELECT custom_user_profile_id FROM connections
WHERE contact_id IN (SELECT contact_id FROM temp_delete_contacts)
AND custom_user_profile_id IS NOT NULL;
UPDATE group_members SET contact_id = NULL
WHERE contact_id IN (SELECT contact_id FROM temp_delete_contacts);
DELETE FROM connections
WHERE contact_id IN (SELECT contact_id FROM temp_delete_contacts);
DELETE FROM contacts
WHERE contact_id IN (SELECT contact_id FROM temp_delete_contacts);
DELETE FROM contact_profiles
WHERE
(contact_profile_id IN (SELECT contact_profile_id FROM temp_delete_profiles)
OR contact_profile_id IN (SELECT contact_profile_id FROM temp_delete_contacts))
AND contact_profile_id NOT IN (SELECT contact_profile_id FROM group_members)
AND contact_profile_id NOT IN (SELECT member_profile_id FROM group_members)
AND contact_profile_id NOT IN (SELECT contact_profile_id FROM contact_requests)
AND contact_profile_id NOT IN (SELECT custom_user_profile_id FROM connections);
DELETE FROM display_names
WHERE local_display_name IN (SELECT local_display_name FROM temp_delete_contacts)
AND local_display_name NOT IN (SELECT local_display_name FROM group_members)
AND local_display_name NOT IN (SELECT local_display_name FROM users)
AND local_display_name NOT IN (SELECT local_display_name FROM groups)
AND local_display_name NOT IN (SELECT local_display_name FROM user_contact_links)
AND local_display_name NOT IN (SELECT local_display_name FROM contact_requests);
DROP TABLE temp_delete_contacts;
DROP TABLE temp_delete_profiles;
|]
down_m20250129_delete_unused_contacts :: Query
down_m20250129_delete_unused_contacts =
[sql|
|]
@@ -646,30 +646,6 @@ Query:
Plan:
Query:
INSERT INTO contacts (contact_profile_id, via_group, local_display_name, user_id, created_at, updated_at, chat_ts)
SELECT contact_profile_id, group_id, ?, ?, ?, ?, ?
FROM group_members
WHERE group_member_id = ?
Plan:
SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
SEARCH chat_tags_chats USING COVERING INDEX idx_chat_tags_chats_chat_tag_id_contact_id (contact_id=?)
SEARCH received_probes USING COVERING INDEX idx_received_probes_contact_id (contact_id=?)
SEARCH sent_probe_hashes USING COVERING INDEX idx_sent_probe_hashes_contact_id (contact_id=?)
SEARCH sent_probes USING COVERING INDEX idx_sent_probes_contact_id (contact_id=?)
SEARCH chat_item_reactions USING COVERING INDEX idx_chat_item_reactions_contact_id (contact_id=?)
SEARCH calls USING COVERING INDEX idx_calls_contact_id (contact_id=?)
SEARCH chat_items USING COVERING INDEX idx_chat_items_fwd_from_contact_id (fwd_from_contact_id=?)
SEARCH chat_items USING COVERING INDEX idx_chat_items_contact_id (contact_id=?)
SEARCH contact_requests USING COVERING INDEX idx_contact_requests_contact_id (contact_id=?)
SEARCH connections USING COVERING INDEX idx_connections_contact_id (contact_id=?)
SEARCH connections USING COVERING INDEX idx_connections_via_contact (via_contact=?)
SEARCH files USING COVERING INDEX idx_files_contact_id (contact_id=?)
SEARCH group_members USING COVERING INDEX idx_group_members_contact_id (contact_id=?)
SEARCH group_members USING COVERING INDEX idx_group_members_invited_by (invited_by=?)
SEARCH users USING COVERING INDEX sqlite_autoindex_users_1 (contact_id=?)
Query:
INSERT INTO group_members
( group_id, member_id, member_role, member_category, member_status, invited_by, invited_by_group_member_id,
@@ -1145,15 +1121,13 @@ Query:
SELECT i.chat_item_id
FROM chat_items i
JOIN group_members m ON m.group_member_id = i.group_member_id
JOIN contacts c ON c.contact_id = m.contact_id
WHERE i.user_id = ? AND i.group_id = ? AND c.local_display_name = ? AND i.item_text like ?
WHERE i.user_id = ? AND i.group_id = ? AND m.local_display_name = ? AND i.item_text like ?
ORDER BY i.chat_item_id DESC
LIMIT 1
Plan:
SEARCH i USING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id=?)
SEARCH m USING INTEGER PRIMARY KEY (rowid=?)
SEARCH c USING INTEGER PRIMARY KEY (rowid=?)
USE TEMP B-TREE FOR ORDER BY
Query:
@@ -1227,14 +1201,6 @@ Query:
Plan:
SEARCH contacts USING INTEGER PRIMARY KEY (rowid=?)
Query:
UPDATE group_members
SET contact_id = ?, updated_at = ?
WHERE group_member_id = ?
Plan:
SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
Query:
UPDATE group_members
SET contact_id = ?, updated_at = ?
@@ -2787,66 +2753,6 @@ Plan:
SEARCH c USING INDEX idx_connections_updated_at (user_id=?)
SEARCH uc USING INTEGER PRIMARY KEY (rowid=?)
Query:
SELECT ch.connection_id, c.conn_req_inv
FROM group_members m
JOIN contacts ct ON ct.contact_id = m.contact_id
LEFT JOIN connections c ON c.connection_id = (
SELECT MAX(cc.connection_id)
FROM connections cc
WHERE cc.contact_id = ct.contact_id
)
JOIN groups g ON g.group_id = m.group_id AND g.group_id = ct.via_group
JOIN group_members mh ON mh.group_id = g.group_id
LEFT JOIN connections ch ON ch.connection_id = (
SELECT max(cc.connection_id)
FROM connections cc
where cc.user_id = ? AND cc.group_member_id = mh.group_member_id
)
WHERE m.user_id = ? AND m.group_member_id = ? AND mh.member_category = ? AND ct.deleted = 0
Plan:
SEARCH m USING INTEGER PRIMARY KEY (rowid=?)
SEARCH ct USING INTEGER PRIMARY KEY (rowid=?)
SEARCH c USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
CORRELATED SCALAR SUBQUERY 1
SEARCH cc USING COVERING INDEX idx_connections_contact_id (contact_id=?)
SEARCH g USING INTEGER PRIMARY KEY (rowid=?)
SEARCH mh USING INDEX sqlite_autoindex_group_members_1 (group_id=?)
SEARCH ch USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
CORRELATED SCALAR SUBQUERY 2
SEARCH cc USING COVERING INDEX idx_connections_group_member (user_id=? AND group_member_id=?)
Query:
SELECT ch.connection_id, g.group_id, m.group_member_id, m.member_id, c.conn_req_inv
FROM contacts ct
JOIN group_members m ON m.contact_id = ct.contact_id
LEFT JOIN connections c ON c.connection_id = (
SELECT MAX(cc.connection_id)
FROM connections cc
WHERE cc.group_member_id = m.group_member_id
)
JOIN groups g ON g.group_id = m.group_id AND g.group_id = ct.via_group
JOIN group_members mh ON mh.group_id = g.group_id
LEFT JOIN connections ch ON ch.connection_id = (
SELECT max(cc.connection_id)
FROM connections cc
where cc.user_id = ? AND cc.group_member_id = mh.group_member_id
)
WHERE ct.user_id = ? AND ct.contact_id = ? AND ct.deleted = 0 AND mh.member_category = ?
Plan:
SEARCH ct USING INTEGER PRIMARY KEY (rowid=?)
SEARCH g USING INTEGER PRIMARY KEY (rowid=?)
SEARCH m USING INDEX sqlite_autoindex_group_members_1 (group_id=?)
SEARCH c USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
CORRELATED SCALAR SUBQUERY 1
SEARCH cc
SEARCH mh USING INDEX sqlite_autoindex_group_members_1 (group_id=?)
SEARCH ch USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
CORRELATED SCALAR SUBQUERY 2
SEARCH cc USING COVERING INDEX idx_connections_group_member (user_id=? AND group_member_id=?)
Query:
SELECT chat_item_id
FROM chat_item_messages
@@ -3112,30 +3018,6 @@ Plan:
SEARCH ct USING INDEX idx_contacts_chat_ts (user_id=?)
SEARCH p USING INTEGER PRIMARY KEY (rowid=?)
Query:
SELECT ct.contact_id
FROM contacts ct
JOIN contact_profiles p ON ct.contact_profile_id = p.contact_profile_id
WHERE ct.user_id = ? AND ct.contact_id != ?
AND ct.contact_status = ? AND ct.deleted = 0 AND ct.is_user = 0
AND p.display_name = ? AND p.full_name = ?
AND p.image = ?
Plan:
SEARCH ct USING INDEX idx_contacts_chat_ts (user_id=?)
SEARCH p USING INTEGER PRIMARY KEY (rowid=?)
Query:
SELECT ct.contact_id
FROM contacts ct
JOIN contact_profiles p ON ct.contact_profile_id = p.contact_profile_id
WHERE ct.user_id = ? AND ct.contact_id != ?
AND ct.contact_status = ? AND ct.deleted = 0 AND ct.is_user = 0
AND p.display_name = ? AND p.full_name = ?
AND p.image is NULL
Plan:
SEARCH ct USING INDEX idx_contacts_chat_ts (user_id=?)
SEARCH p USING INTEGER PRIMARY KEY (rowid=?)
Query:
SELECT d.file_descr_id, d.file_descr_text, d.file_descr_part_no, d.file_descr_complete
FROM xftp_file_descriptions d
@@ -3269,18 +3151,6 @@ Plan:
SEARCH m USING INDEX idx_group_members_user_id (user_id=?)
SEARCH p USING INTEGER PRIMARY KEY (rowid=?)
Query:
SELECT m.member_role, gp.preferences
FROM groups g
JOIN group_profiles gp USING (group_profile_id)
JOIN group_members m USING (group_id)
WHERE g.user_id = ? AND m.contact_id = ?
Plan:
SEARCH m USING INDEX idx_group_members_contact_id (contact_id=?)
SEARCH g USING INTEGER PRIMARY KEY (rowid=?)
SEARCH gp USING INTEGER PRIMARY KEY (rowid=?)
Query:
SELECT pgm.message_id, m.shared_msg_id, m.msg_body, m.chat_msg_event, pgm.group_member_intro_id
FROM pending_group_messages pgm
@@ -3482,22 +3352,6 @@ Query:
Plan:
SEARCH group_member_intros USING INTEGER PRIMARY KEY (rowid=?)
Query:
UPDATE group_members
SET contact_id = ?,
local_display_name = (SELECT local_display_name FROM contacts WHERE contact_id = ?),
contact_profile_id = (SELECT contact_profile_id FROM contacts WHERE contact_id = ?),
updated_at = ?
WHERE contact_id = ?
AND user_id = ?
Plan:
SEARCH group_members USING INDEX idx_group_members_user_id (user_id=?)
SCALAR SUBQUERY 1
SEARCH contacts USING INTEGER PRIMARY KEY (rowid=?)
SCALAR SUBQUERY 2
SEARCH contacts USING INTEGER PRIMARY KEY (rowid=?)
Query:
UPDATE group_members
SET contact_id = ?, local_display_name = ?, contact_profile_id = ?, updated_at = ?
@@ -5092,25 +4946,6 @@ Query: DELETE FROM contact_requests WHERE user_id = ? AND contact_request_id = ?
Plan:
SEARCH contact_requests USING INTEGER PRIMARY KEY (rowid=?)
Query: DELETE FROM contacts WHERE contact_id = ? AND user_id = ?
Plan:
SEARCH contacts USING INTEGER PRIMARY KEY (rowid=?)
SEARCH chat_tags_chats USING COVERING INDEX idx_chat_tags_chats_chat_tag_id_contact_id (contact_id=?)
SEARCH received_probes USING COVERING INDEX idx_received_probes_contact_id (contact_id=?)
SEARCH sent_probe_hashes USING COVERING INDEX idx_sent_probe_hashes_contact_id (contact_id=?)
SEARCH sent_probes USING COVERING INDEX idx_sent_probes_contact_id (contact_id=?)
SEARCH chat_item_reactions USING COVERING INDEX idx_chat_item_reactions_contact_id (contact_id=?)
SEARCH calls USING COVERING INDEX idx_calls_contact_id (contact_id=?)
SEARCH chat_items USING COVERING INDEX idx_chat_items_fwd_from_contact_id (fwd_from_contact_id=?)
SEARCH chat_items USING COVERING INDEX idx_chat_items_contact_id (contact_id=?)
SEARCH contact_requests USING COVERING INDEX idx_contact_requests_contact_id (contact_id=?)
SEARCH connections USING COVERING INDEX idx_connections_contact_id (contact_id=?)
SEARCH connections USING COVERING INDEX idx_connections_via_contact (via_contact=?)
SEARCH files USING COVERING INDEX idx_files_contact_id (contact_id=?)
SEARCH group_members USING COVERING INDEX idx_group_members_contact_id (contact_id=?)
SEARCH group_members USING COVERING INDEX idx_group_members_invited_by (invited_by=?)
SEARCH users USING COVERING INDEX sqlite_autoindex_users_1 (contact_id=?)
Query: DELETE FROM contacts WHERE user_id = ? AND contact_id = ?
Plan:
SEARCH contacts USING INTEGER PRIMARY KEY (rowid=?)
@@ -5596,10 +5431,6 @@ Query: SELECT group_id FROM group_members WHERE group_member_id = ?
Plan:
SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
Query: SELECT group_id FROM group_members WHERE user_id = ? AND contact_id = ? LIMIT 1
Plan:
SEARCH group_members USING INDEX idx_group_members_user_id (user_id=?)
Query: SELECT group_id FROM groups WHERE inv_queue_info = ? AND user_id = ? LIMIT 1
Plan:
SEARCH groups USING INDEX idx_groups_chat_ts (user_id=?)
@@ -5620,10 +5451,6 @@ Query: SELECT group_id FROM user_contact_links WHERE user_id = ? AND user_contac
Plan:
SEARCH user_contact_links USING INTEGER PRIMARY KEY (rowid=?)
Query: SELECT group_link_id FROM user_contact_links WHERE user_id = ? AND group_id = ? LIMIT 1
Plan:
SEARCH user_contact_links USING INDEX idx_user_contact_links_group_id (group_id=?)
Query: SELECT group_member_id FROM group_members WHERE user_id = ? AND contact_profile_id = ? AND group_member_id != ? LIMIT 1
Plan:
SEARCH group_members USING INDEX idx_group_members_user_id (user_id=?)
@@ -5684,10 +5511,6 @@ Query: SELECT xgrplinkmem_received FROM group_members WHERE group_member_id = ?
Plan:
SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
Query: UPDATE chat_items SET contact_id = ?, updated_at = ? WHERE contact_id = ? AND user_id = ?
Plan:
SEARCH chat_items USING COVERING INDEX idx_chat_items_contacts_created_at (user_id=? AND contact_id=?)
Query: UPDATE chat_items SET item_status = ?, updated_at = ? WHERE user_id = ? AND contact_id = ? AND chat_item_id = ?
Plan:
SEARCH chat_items USING INTEGER PRIMARY KEY (rowid=?)
@@ -5740,10 +5563,6 @@ Query: UPDATE connections SET contact_id = ?, updated_at = ? WHERE connection_id
Plan:
SEARCH connections USING INTEGER PRIMARY KEY (rowid=?)
Query: UPDATE connections SET contact_id = ?, updated_at = ? WHERE contact_id = ? AND user_id = ?
Plan:
SEARCH connections USING INDEX idx_connections_contact_id (contact_id=?)
Query: UPDATE connections SET quota_err_counter = ?, updated_at = ? WHERE user_id = ? AND connection_id = ?
Plan:
SEARCH connections USING INTEGER PRIMARY KEY (rowid=?)
@@ -5756,10 +5575,6 @@ Query: UPDATE connections SET to_subscribe = 0 WHERE to_subscribe = 1
Plan:
SEARCH connections USING INDEX idx_connections_to_subscribe (to_subscribe=?)
Query: UPDATE connections SET via_contact = ?, updated_at = ? WHERE via_contact = ? AND user_id = ?
Plan:
SEARCH connections USING INDEX idx_connections_via_contact (via_contact=?)
Query: UPDATE contact_requests SET contact_id = ? WHERE user_id = ? AND local_display_name = ?
Plan:
SEARCH contact_requests USING INDEX sqlite_autoindex_contact_requests_1 (user_id=? AND local_display_name=?)
@@ -5780,18 +5595,10 @@ Query: UPDATE contacts SET contact_grp_inv_sent = ?, updated_at = ? WHERE contac
Plan:
SEARCH contacts USING INTEGER PRIMARY KEY (rowid=?)
Query: UPDATE contacts SET contact_used = 1, updated_at = ? WHERE user_id = ? AND contact_id = ?
Plan:
SEARCH contacts USING INTEGER PRIMARY KEY (rowid=?)
Query: UPDATE contacts SET contact_used = ? WHERE user_id = ? AND contact_id = ?
Plan:
SEARCH contacts USING INTEGER PRIMARY KEY (rowid=?)
Query: UPDATE contacts SET deleted = 1, updated_at = ? WHERE user_id = ? AND contact_id = ?
Plan:
SEARCH contacts USING INTEGER PRIMARY KEY (rowid=?)
Query: UPDATE contacts SET enable_ntfs = ?, send_rcpts = ?, favorite = ? WHERE user_id = ? AND contact_id = ?
Plan:
SEARCH contacts USING INTEGER PRIMARY KEY (rowid=?)
@@ -5864,10 +5671,6 @@ Query: UPDATE group_members SET contact_id = NULL, updated_at = ? WHERE user_id
Plan:
SEARCH group_members USING INDEX idx_group_members_user_id (user_id=?)
Query: UPDATE group_members SET invited_by = ?, updated_at = ? WHERE invited_by = ? AND user_id = ?
Plan:
SEARCH group_members USING INDEX idx_group_members_invited_by (invited_by=?)
Query: UPDATE group_members SET local_display_name = ?, updated_at = ? WHERE user_id = ? AND contact_id = ?
Plan:
SEARCH group_members USING INDEX idx_group_members_user_id (user_id=?)
@@ -5884,10 +5687,6 @@ Query: UPDATE group_members SET member_role = ? WHERE user_id = ? AND group_memb
Plan:
SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
Query: UPDATE group_members SET sent_inv_queue_info = ?, updated_at = ? WHERE user_id = ? AND group_member_id = ?
Plan:
SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
Query: UPDATE group_members SET xgrplinkmem_received = ?, updated_at = ? WHERE group_member_id = ?
Plan:
SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
@@ -5980,10 +5779,6 @@ Query: UPDATE usage_conditions SET notified_at = ? WHERE usage_conditions_id = ?
Plan:
SEARCH usage_conditions USING INTEGER PRIMARY KEY (rowid=?)
Query: UPDATE user_contact_links SET group_link_member_role = ? WHERE user_id = ? AND user_contact_link_id = ?
Plan:
SEARCH user_contact_links USING INTEGER PRIMARY KEY (rowid=?)
Query: UPDATE users SET active_user = 0
Plan:
SCAN users
+4 -4
View File
@@ -381,10 +381,10 @@ setCommandConnId db User {userId} cmdId connId = do
createContact :: DB.Connection -> User -> Profile -> ExceptT StoreError IO ()
createContact db User {userId} profile = do
currentTs <- liftIO getCurrentTime
void $ createContact_ db userId profile "" Nothing currentTs True
void $ createContact_ db userId profile "" Nothing currentTs
createContact_ :: DB.Connection -> UserId -> Profile -> LocalAlias -> Maybe Int64 -> UTCTime -> Bool -> ExceptT StoreError IO (Text, ContactId, ProfileId)
createContact_ db userId Profile {displayName, fullName, image, contactLink, preferences} localAlias viaGroup currentTs contactUsed =
createContact_ :: DB.Connection -> UserId -> Profile -> LocalAlias -> Maybe Int64 -> UTCTime -> ExceptT StoreError IO (Text, ContactId, ProfileId)
createContact_ db userId Profile {displayName, fullName, image, contactLink, preferences} localAlias viaGroup currentTs =
ExceptT . withLocalDisplayName db userId displayName $ \ldn -> do
DB.execute
db
@@ -394,7 +394,7 @@ createContact_ db userId Profile {displayName, fullName, image, contactLink, pre
DB.execute
db
"INSERT INTO contacts (contact_profile_id, local_display_name, user_id, via_group, created_at, updated_at, chat_ts, contact_used) VALUES (?,?,?,?,?,?,?,?)"
(profileId, ldn, userId, viaGroup, currentTs, currentTs, currentTs, BI contactUsed)
(profileId, ldn, userId, viaGroup, currentTs, currentTs, currentTs, BI True)
contactId <- insertedRowId db
pure $ Right (ldn, contactId, profileId)