core: set via_group_link_uri for groups (#6137)

* core: set via_group_link_uri for groups

* schema

* plans

* schema

* add to type

* plans, api
This commit is contained in:
spaced4ndy
2025-08-01 16:23:52 +01:00
committed by GitHub
parent d3a5936d17
commit 18a00511a7
16 changed files with 139 additions and 68 deletions
+1
View File
@@ -2094,6 +2094,7 @@ MemberSupport:
- uiThemes: [UIThemeEntityOverrides](#uithemeentityoverrides)?
- customData: JSONObject?
- membersRequireAttention: int
- viaGroupLinkUri: string?
---
+2
View File
@@ -113,6 +113,7 @@ library
Simplex.Chat.Store.Postgres.Migrations.M20250709_profile_short_descr
Simplex.Chat.Store.Postgres.Migrations.M20250721_indexes
Simplex.Chat.Store.Postgres.Migrations.M20250729_member_contact_requests
Simplex.Chat.Store.Postgres.Migrations.M20250801_via_group_link_uri
else
exposed-modules:
Simplex.Chat.Archive
@@ -251,6 +252,7 @@ library
Simplex.Chat.Store.SQLite.Migrations.M20250709_profile_short_descr
Simplex.Chat.Store.SQLite.Migrations.M20250721_indexes
Simplex.Chat.Store.SQLite.Migrations.M20250729_member_contact_requests
Simplex.Chat.Store.SQLite.Migrations.M20250801_via_group_link_uri
other-modules:
Paths_simplex_chat
hs-source-dirs:
+12 -12
View File
@@ -3031,22 +3031,19 @@ processChatCommand vr nm = \case
connectViaContact :: User -> Maybe PreparedChatEntity -> IncognitoEnabled -> CreatedLinkContact -> Maybe SharedMsgId -> Maybe (SharedMsgId, MsgContent) -> CM ConnectViaContactResult
connectViaContact user@User {userId} preparedEntity_ incognito (CCLink cReq@(CRContactUri crData@ConnReqUriData {crClientData}) sLnk) welcomeSharedMsgId msg_ = withInvitationLock "connectViaContact" (strEncode cReq) $ do
let groupLinkId = crClientData >>= decodeJSON >>= \(CRDataGroup gli) -> Just gli
cReqHash = ConnReqUriHash . C.sha256Hash . strEncode
cReqHash1 = cReqHash $ CRContactUri crData {crScheme = SSSimplex}
cReqHash2 = cReqHash $ CRContactUri crData {crScheme = simplexChat}
-- groupLinkId is Nothing for business chats
when (isJust msg_ && isJust groupLinkId) $ throwChatError CEConnReqMessageProhibited
case preparedEntity_ of
Just (PCEContact ct@Contact {activeConn}) -> case activeConn of
Nothing -> connect' Nothing cReqHash1 Nothing
Nothing -> connect' Nothing Nothing
Just conn@Connection {connStatus, xContactId} -> case connStatus of
ConnPrepared -> joinPreparedConn' xContactId conn False
_ -> pure $ CVRConnectedContact ct
Just (PCEGroup _gInfo GroupMember {activeConn}) -> case activeConn of
Nothing -> connect' groupLinkId cReqHash1 Nothing
Nothing -> connect' groupLinkId Nothing
Just conn@Connection {connStatus, xContactId} -> case connStatus of
ConnPrepared -> joinPreparedConn' xContactId conn $ isJust groupLinkId
_ -> connect' groupLinkId cReqHash1 xContactId -- why not "already connected" for host member?
_ -> connect' groupLinkId xContactId -- why not "already connected" for host member?
Nothing ->
withFastStore' (\db -> getConnReqContactXContactId db vr user cReqHash1 cReqHash2) >>= \case
Right ct@Contact {activeConn} -> case groupLinkId of
@@ -3056,14 +3053,17 @@ processChatCommand vr nm = \case
Just gLinkId ->
-- allow repeat contact request
-- TODO [short links] is this branch needed? it probably remained from the time we created host contact
connect' (Just gLinkId) cReqHash1 Nothing
connect' (Just gLinkId) Nothing
Left conn_ -> case conn_ of
Just conn@Connection {connStatus = ConnPrepared, xContactId} -> joinPreparedConn' xContactId conn $ isJust groupLinkId
-- TODO [short links] this is executed on repeat request after success
-- it probably should send the second message without creating the second connection?
Just Connection {xContactId} -> connect' groupLinkId cReqHash1 xContactId
Nothing -> connect' groupLinkId cReqHash1 Nothing
Just Connection {xContactId} -> connect' groupLinkId xContactId
Nothing -> connect' groupLinkId Nothing
where
cReqHash = ConnReqUriHash . C.sha256Hash . strEncode
cReqHash1 = cReqHash $ CRContactUri crData {crScheme = SSSimplex}
cReqHash2 = cReqHash $ CRContactUri crData {crScheme = simplexChat}
joinPreparedConn' xContactId_ conn@Connection {customUserProfileId} inGroup = do
when (incognito /= isJust customUserProfileId) $ throwCmdError "incognito mode is different from prepared connection"
xContactId <- mkXContactId xContactId_
@@ -3071,7 +3071,7 @@ processChatCommand vr nm = \case
let incognitoProfile = fromLocalProfile <$> localIncognitoProfile
conn' <- joinContact user conn cReq incognitoProfile xContactId welcomeSharedMsgId msg_ inGroup PQSupportOn
pure $ CVRSentInvitation conn' incognitoProfile
connect' groupLinkId cReqHash xContactId_ = do
connect' groupLinkId xContactId_ = do
let inGroup = isJust groupLinkId
pqSup = if inGroup then PQSupportOff else PQSupportOn
(connId, chatV) <- prepareContact user cReq pqSup
@@ -3080,7 +3080,7 @@ processChatCommand vr nm = \case
incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing
subMode <- chatReadVar subscriptionMode
let sLnk' = serverShortLink <$> sLnk
conn <- withFastStore' $ \db -> createConnReqConnection db userId connId preparedEntity_ cReqHash sLnk' xContactId incognitoProfile groupLinkId subMode chatV pqSup
conn <- withFastStore' $ \db -> createConnReqConnection db userId connId preparedEntity_ cReq cReqHash1 sLnk' xContactId incognitoProfile groupLinkId subMode chatV pqSup
conn' <- joinContact user conn cReq incognitoProfile xContactId welcomeSharedMsgId msg_ inGroup pqSup
pure $ CVRSentInvitation conn' incognitoProfile
connectContactViaAddress :: User -> IncognitoEnabled -> Contact -> CreatedLinkContact -> CM ChatResponse
@@ -3095,7 +3095,7 @@ processChatCommand vr nm = \case
incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing
subMode <- chatReadVar subscriptionMode
let cReqHash = ConnReqUriHash . C.sha256Hash $ strEncode cReq
conn <- withFastStore' $ \db -> createConnReqConnection db userId connId (Just $ PCEContact ct) cReqHash shortLink newXContactId incognitoProfile Nothing subMode chatV pqSup
conn <- withFastStore' $ \db -> createConnReqConnection db userId connId (Just $ PCEContact ct) cReq cReqHash shortLink newXContactId incognitoProfile Nothing subMode chatV pqSup
void $ joinContact user conn cReq incognitoProfile newXContactId Nothing Nothing False pqSup
ct' <- withStore $ \db -> getContact db vr user contactId
pure $ CRSentInvitationToContact user ct' incognitoProfile
+1 -1
View File
@@ -2269,7 +2269,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
dm <- encodeConnInfo $ XGrpAcpt membershipMemId
connIds <- joinAgentConnectionAsync user True connRequest dm subMode
withStore' $ \db -> do
setViaGroupLinkHash db groupId connId
setViaGroupLinkUri db groupId connId
createMemberConnectionAsync db user hostId connIds connChatVersion peerChatVRange subMode
updateGroupMemberStatusById db userId hostId GSMemAccepted
updateGroupMemberStatus db userId membership GSMemAccepted
+1 -1
View File
@@ -143,7 +143,7 @@ getConnectionEntity db vr user@User {userId, userContactId} agentConnId = do
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at,
g.conn_full_link_to_connect, g.conn_short_link_to_connect, g.conn_link_prepared_connection, g.conn_link_started_connection, g.welcome_shared_msg_id, g.request_shared_msg_id,
g.business_chat, g.business_member_id, g.customer_member_id,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention, g.via_group_link_uri,
-- GroupInfo {membership}
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
mu.member_status, mu.show_messages, mu.member_restriction, mu.invited_by, mu.invited_by_group_member_id, mu.local_display_name, mu.contact_id, mu.contact_profile_id, pu.contact_profile_id,
+9 -9
View File
@@ -154,8 +154,8 @@ deletePendingContactConnection db userId connId =
|]
(userId, connId, ConnContact)
createConnReqConnection :: DB.Connection -> UserId -> ConnId -> Maybe PreparedChatEntity -> ConnReqUriHash -> Maybe ShortLinkContact -> XContactId -> Maybe Profile -> Maybe GroupLinkId -> SubscriptionMode -> VersionChat -> PQSupport -> IO Connection
createConnReqConnection db userId acId preparedEntity_ cReqHash sLnk xContactId incognitoProfile groupLinkId subMode chatV pqSup = do
createConnReqConnection :: DB.Connection -> UserId -> ConnId -> Maybe PreparedChatEntity -> ConnReqContact -> ConnReqUriHash -> Maybe ShortLinkContact -> XContactId -> Maybe Profile -> Maybe GroupLinkId -> SubscriptionMode -> VersionChat -> PQSupport -> IO Connection
createConnReqConnection db userId acId preparedEntity_ cReq cReqHash sLnk xContactId incognitoProfile groupLinkId subMode chatV pqSup = do
currentTs <- getCurrentTime
customUserProfileId <- mapM (createIncognitoProfile_ db userId currentTs) incognitoProfile
let connStatus = ConnPrepared
@@ -164,13 +164,13 @@ createConnReqConnection db userId acId preparedEntity_ cReqHash sLnk xContactId
[sql|
INSERT INTO connections (
user_id, agent_conn_id, conn_status, conn_type, contact_conn_initiated,
via_contact_uri_hash, via_short_link_contact, contact_id, group_member_id,
via_contact_uri, via_contact_uri_hash, via_short_link_contact, contact_id, group_member_id,
xcontact_id, custom_user_profile_id, via_group_link, group_link_id,
created_at, updated_at, to_subscribe, conn_chat_version, pq_support, pq_encryption
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|]
( (userId, acId, connStatus, connType, BI True)
:. (cReqHash, sLnk, contactId_, groupMemberId_)
:. (cReq, cReqHash, sLnk, contactId_, groupMemberId_)
:. (xContactId, customUserProfileId, BI (isJust groupLinkId), groupLinkId)
:. (currentTs, currentTs, BI (subMode == SMOnlyCreate), chatV, pqSup, pqSup)
)
@@ -217,8 +217,8 @@ createConnReqConnection db userId acId preparedEntity_ cReqHash sLnk xContactId
updatePreparedGroup GroupInfo {groupId, membership} customUserProfileId currentTs = do
DB.execute
db
"UPDATE groups SET via_group_link_uri_hash = ?, conn_link_prepared_connection = ?, updated_at = ? WHERE group_id = ?"
(cReqHash, BI True, currentTs, groupId)
"UPDATE groups SET via_group_link_uri = ?, via_group_link_uri_hash = ?, conn_link_prepared_connection = ?, updated_at = ? WHERE group_id = ?"
(cReq, cReqHash, BI True, currentTs, groupId)
when (isJust customUserProfileId) $
DB.execute
db
@@ -336,8 +336,8 @@ createDirectConnection_ db userId acId (CCLink cReq shortLinkInv) contactId_ pcc
( (userId, acId, cReq, shortLinkInv, pccConnStatus, ConnContact, contactId_, BI contactConnInitiated, customUserProfileId)
:. (createdAt, createdAt, BI (subMode == SMOnlyCreate), chatV, pqSup, pqSup)
)
dbConnId <- insertedRowId db
pure (dbConnId, customUserProfileId, contactConnInitiated)
connId <- insertedRowId db
pure (connId, customUserProfileId, contactConnInitiated)
createIncognitoProfile :: DB.Connection -> User -> Profile -> IO Int64
createIncognitoProfile db User {userId} p = do
+8 -6
View File
@@ -373,7 +373,8 @@ createNewGroup db vr gVar user@User {userId} groupProfile incognitoProfile = Exc
chatItemTTL = Nothing,
uiThemes = Nothing,
customData = Nothing,
membersRequireAttention = 0
membersRequireAttention = 0,
viaGroupLinkUri = Nothing
}
-- | creates a new group record for the group the current user was invited to, or returns an existing one
@@ -445,7 +446,8 @@ createGroupInvitation db vr user@User {userId} contact@Contact {contactId, activ
chatItemTTL = Nothing,
uiThemes = Nothing,
customData = Nothing,
membersRequireAttention = 0
membersRequireAttention = 0,
viaGroupLinkUri = Nothing
},
groupMemberId
)
@@ -744,7 +746,7 @@ createGroupViaLink'
liftIO $ DB.execute db "UPDATE connections SET conn_type = ?, group_member_id = ?, updated_at = ? WHERE connection_id = ?" (ConnMember, hostMemberId, currentTs, connId)
-- using IBUnknown since host is created without contact
void $ createContactMemberInv_ db user groupId (Just hostMemberId) user invitedMember GCUserMember membershipStatus IBUnknown customUserProfileId currentTs vr
liftIO $ setViaGroupLinkHash db groupId connId
liftIO $ setViaGroupLinkUri db groupId connId
(,) <$> getGroupInfo db vr user groupId <*> getGroupMemberById db vr user hostMemberId
where
insertHost_ currentTs groupId = do
@@ -906,7 +908,7 @@ cleanupHostGroupLinkConn db user@User {userId} GroupInfo {groupId} = do
DB.execute
db
[sql|
UPDATE connections SET via_contact_uri_hash = NULL, xcontact_id = NULL
UPDATE connections SET via_contact_uri = NULL, via_contact_uri_hash = NULL, xcontact_id = NULL
WHERE user_id = ? AND via_group_link = 1 AND contact_id IN (
SELECT contact_id
FROM group_members
@@ -954,7 +956,7 @@ getUserGroupDetails db vr User {userId, userContactId} _contactId_ search_ = do
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at,
g.conn_full_link_to_connect, g.conn_short_link_to_connect, g.conn_link_prepared_connection, g.conn_link_started_connection, g.welcome_shared_msg_id, g.request_shared_msg_id,
g.business_chat, g.business_member_id, g.customer_member_id,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention, g.via_group_link_uri,
mu.group_member_id, g.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category, mu.member_status, mu.show_messages, mu.member_restriction,
mu.invited_by, mu.invited_by_group_member_id, mu.local_display_name, mu.contact_id, mu.contact_profile_id, pu.contact_profile_id, pu.display_name, pu.full_name, pu.short_descr, pu.image, pu.contact_link, pu.local_alias, pu.preferences,
mu.created_at, mu.updated_at,
@@ -1911,7 +1913,7 @@ getViaGroupMember db vr User {userId, userContactId} Contact {contactId} = do
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at,
g.conn_full_link_to_connect, g.conn_short_link_to_connect, g.conn_link_prepared_connection, g.conn_link_started_connection, g.welcome_shared_msg_id, g.request_shared_msg_id,
g.business_chat, g.business_member_id, g.customer_member_id,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention, g.via_group_link_uri,
-- GroupInfo {membership}
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
mu.member_status, mu.show_messages, mu.member_restriction, mu.invited_by, mu.invited_by_group_member_id, mu.local_display_name, mu.contact_id, mu.contact_profile_id, pu.contact_profile_id,
@@ -14,6 +14,7 @@ import Simplex.Chat.Store.Postgres.Migrations.M20250704_groups_conn_link_prepare
import Simplex.Chat.Store.Postgres.Migrations.M20250709_profile_short_descr
import Simplex.Chat.Store.Postgres.Migrations.M20250721_indexes
import Simplex.Chat.Store.Postgres.Migrations.M20250729_member_contact_requests
import Simplex.Chat.Store.Postgres.Migrations.M20250801_via_group_link_uri
import Simplex.Messaging.Agent.Store.Shared (Migration (..))
schemaMigrations :: [(String, Text, Maybe Text)]
@@ -27,7 +28,8 @@ schemaMigrations =
("20250704_groups_conn_link_prepared_connection", m20250704_groups_conn_link_prepared_connection, Just down_m20250704_groups_conn_link_prepared_connection),
("20250709_profile_short_descr", m20250709_profile_short_descr, Just down_m20250709_profile_short_descr),
("20250721_indexes", m20250721_indexes, Just down_m20250721_indexes),
("20250729_member_contact_requests", m20250729_member_contact_requests, Just down_m20250729_member_contact_requests)
("20250729_member_contact_requests", m20250729_member_contact_requests, Just down_m20250729_member_contact_requests),
("20250801_via_group_link_uri", m20250801_via_group_link_uri, Just down_m20250801_via_group_link_uri)
]
-- | The list of migrations in ascending order by date
@@ -0,0 +1,23 @@
{-# LANGUAGE QuasiQuotes #-}
module Simplex.Chat.Store.Postgres.Migrations.M20250801_via_group_link_uri where
import Data.Text (Text)
import qualified Data.Text as T
import Text.RawString.QQ (r)
m20250801_via_group_link_uri :: Text
m20250801_via_group_link_uri =
T.pack
[r|
ALTER TABLE groups ADD COLUMN via_group_link_uri BYTEA;
ALTER TABLE connections ADD COLUMN via_contact_uri BYTEA;
|]
down_m20250801_via_group_link_uri :: Text
down_m20250801_via_group_link_uri =
T.pack
[r|
ALTER TABLE groups DROP COLUMN via_group_link_uri;
ALTER TABLE connections DROP COLUMN via_contact_uri;
|]
@@ -303,7 +303,8 @@ CREATE TABLE test_chat_schema.connections (
pq_rcv_enabled smallint,
quota_err_counter bigint DEFAULT 0 NOT NULL,
short_link_inv bytea,
via_short_link_contact bytea
via_short_link_contact bytea,
via_contact_uri bytea
);
@@ -653,7 +654,8 @@ CREATE TABLE test_chat_schema.groups (
conn_link_started_connection smallint DEFAULT 0 NOT NULL,
welcome_shared_msg_id bytea,
request_shared_msg_id bytea,
conn_link_prepared_connection smallint DEFAULT 0 NOT NULL
conn_link_prepared_connection smallint DEFAULT 0 NOT NULL,
via_group_link_uri bytea
);
+3 -1
View File
@@ -137,6 +137,7 @@ import Simplex.Chat.Store.SQLite.Migrations.M20250704_groups_conn_link_prepared_
import Simplex.Chat.Store.SQLite.Migrations.M20250709_profile_short_descr
import Simplex.Chat.Store.SQLite.Migrations.M20250721_indexes
import Simplex.Chat.Store.SQLite.Migrations.M20250729_member_contact_requests
import Simplex.Chat.Store.SQLite.Migrations.M20250801_via_group_link_uri
import Simplex.Messaging.Agent.Store.Shared (Migration (..))
schemaMigrations :: [(String, Query, Maybe Query)]
@@ -273,7 +274,8 @@ schemaMigrations =
("20250704_groups_conn_link_prepared_connection", m20250704_groups_conn_link_prepared_connection, Just down_m20250704_groups_conn_link_prepared_connection),
("20250709_profile_short_descr", m20250709_profile_short_descr, Just down_m20250709_profile_short_descr),
("20250721_indexes", m20250721_indexes, Just down_m20250721_indexes),
("20250729_member_contact_requests", m20250729_member_contact_requests, Just down_m20250729_member_contact_requests)
("20250729_member_contact_requests", m20250729_member_contact_requests, Just down_m20250729_member_contact_requests),
("20250801_via_group_link_uri", m20250801_via_group_link_uri, Just down_m20250801_via_group_link_uri)
]
-- | The list of migrations in ascending order by date
@@ -0,0 +1,20 @@
{-# LANGUAGE QuasiQuotes #-}
module Simplex.Chat.Store.SQLite.Migrations.M20250801_via_group_link_uri where
import Database.SQLite.Simple (Query)
import Database.SQLite.Simple.QQ (sql)
m20250801_via_group_link_uri :: Query
m20250801_via_group_link_uri =
[sql|
ALTER TABLE groups ADD COLUMN via_group_link_uri BLOB;
ALTER TABLE connections ADD COLUMN via_contact_uri BLOB;
|]
down_m20250801_via_group_link_uri :: Query
down_m20250801_via_group_link_uri =
[sql|
ALTER TABLE groups DROP COLUMN via_group_link_uri;
ALTER TABLE connections DROP COLUMN via_contact_uri;
|]
@@ -65,7 +65,7 @@ Query:
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at,
g.conn_full_link_to_connect, g.conn_short_link_to_connect, g.conn_link_prepared_connection, g.conn_link_started_connection, g.welcome_shared_msg_id, g.request_shared_msg_id,
g.business_chat, g.business_member_id, g.customer_member_id,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention, g.via_group_link_uri,
-- GroupInfo {membership}
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
mu.member_status, mu.show_messages, mu.member_restriction, mu.invited_by, mu.invited_by_group_member_id, mu.local_display_name, mu.contact_id, mu.contact_profile_id, pu.contact_profile_id,
@@ -973,7 +973,7 @@ Query:
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at,
g.conn_full_link_to_connect, g.conn_short_link_to_connect, g.conn_link_prepared_connection, g.conn_link_started_connection, g.welcome_shared_msg_id, g.request_shared_msg_id,
g.business_chat, g.business_member_id, g.customer_member_id,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention, g.via_group_link_uri,
-- GroupInfo {membership}
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
mu.member_status, mu.show_messages, mu.member_restriction, mu.invited_by, mu.invited_by_group_member_id, mu.local_display_name, mu.contact_id, mu.contact_profile_id, pu.contact_profile_id,
@@ -1023,7 +1023,7 @@ Query:
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at,
g.conn_full_link_to_connect, g.conn_short_link_to_connect, g.conn_link_prepared_connection, g.conn_link_started_connection, g.welcome_shared_msg_id, g.request_shared_msg_id,
g.business_chat, g.business_member_id, g.customer_member_id,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention, g.via_group_link_uri,
mu.group_member_id, g.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category, mu.member_status, mu.show_messages, mu.member_restriction,
mu.invited_by, mu.invited_by_group_member_id, mu.local_display_name, mu.contact_id, mu.contact_profile_id, pu.contact_profile_id, pu.display_name, pu.full_name, pu.short_descr, pu.image, pu.contact_link, pu.local_alias, pu.preferences,
mu.created_at, mu.updated_at,
@@ -1431,7 +1431,7 @@ SEARCH m USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
SEARCH g USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
Query:
UPDATE connections SET via_contact_uri_hash = NULL, xcontact_id = NULL
UPDATE connections SET via_contact_uri = NULL, via_contact_uri_hash = NULL, xcontact_id = NULL
WHERE user_id = ? AND via_group_link = 1 AND contact_id IN (
SELECT contact_id
FROM group_members
@@ -3660,6 +3660,14 @@ Query:
Plan:
SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
Query:
UPDATE groups
SET via_group_link_uri = ?, via_group_link_uri_hash = ?
WHERE group_id = ?
Plan:
SEARCH groups USING INTEGER PRIMARY KEY (rowid=?)
Query:
DELETE FROM chat_items
WHERE group_scope_group_member_id = ?
@@ -4190,10 +4198,10 @@ Plan:
Query:
INSERT INTO connections (
user_id, agent_conn_id, conn_status, conn_type, contact_conn_initiated,
via_contact_uri_hash, via_short_link_contact, contact_id, group_member_id,
via_contact_uri, via_contact_uri_hash, via_short_link_contact, contact_id, group_member_id,
xcontact_id, custom_user_profile_id, via_group_link, group_link_id,
created_at, updated_at, to_subscribe, conn_chat_version, pq_support, pq_encryption
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
Plan:
@@ -4620,16 +4628,6 @@ Query:
Plan:
SEARCH groups USING INTEGER PRIMARY KEY (rowid=?)
Query:
UPDATE groups
SET via_group_link_uri_hash = (SELECT via_contact_uri_hash FROM connections WHERE connection_id = ?)
WHERE group_id = ?
Plan:
SEARCH groups USING INTEGER PRIMARY KEY (rowid=?)
SCALAR SUBQUERY 1
SEARCH connections USING INTEGER PRIMARY KEY (rowid=?)
Query:
UPDATE msg_deliveries
SET delivery_status = ?, updated_at = ?
@@ -4751,7 +4749,7 @@ Query:
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at,
g.conn_full_link_to_connect, g.conn_short_link_to_connect, g.conn_link_prepared_connection, g.conn_link_started_connection, g.welcome_shared_msg_id, g.request_shared_msg_id,
g.business_chat, g.business_member_id, g.customer_member_id,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention, g.via_group_link_uri,
-- GroupMember - membership
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
mu.member_status, mu.show_messages, mu.member_restriction, mu.invited_by, mu.invited_by_group_member_id, mu.local_display_name, mu.contact_id, mu.contact_profile_id, pu.contact_profile_id,
@@ -4777,7 +4775,7 @@ Query:
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at,
g.conn_full_link_to_connect, g.conn_short_link_to_connect, g.conn_link_prepared_connection, g.conn_link_started_connection, g.welcome_shared_msg_id, g.request_shared_msg_id,
g.business_chat, g.business_member_id, g.customer_member_id,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention, g.via_group_link_uri,
-- GroupMember - membership
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
mu.member_status, mu.show_messages, mu.member_restriction, mu.invited_by, mu.invited_by_group_member_id, mu.local_display_name, mu.contact_id, mu.contact_profile_id, pu.contact_profile_id,
@@ -5328,6 +5326,9 @@ Error: SQLite3 returned ErrorError while attempting to perform prepare "explain
Query: CREATE TABLE temp_delete_members (contact_profile_id INTEGER, member_profile_id INTEGER, local_display_name TEXT)
Error: SQLite3 returned ErrorError while attempting to perform prepare "explain query plan CREATE TABLE temp_delete_members (contact_profile_id INTEGER, member_profile_id INTEGER, local_display_name TEXT)": table temp_delete_members already exists
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=?)
@@ -5717,6 +5718,9 @@ Plan:
Query: DROP TABLE temp_delete_members
Plan:
Query: INSERT INTO app_settings (app_settings) VALUES (?)
Plan:
Query: INSERT INTO chat_item_mentions (chat_item_id, group_id, member_id, display_name) VALUES (?, ?, ?, ?)
Plan:
@@ -6068,6 +6072,10 @@ Query: SELECT user_id FROM users WHERE local_display_name = ?
Plan:
SEARCH users USING COVERING INDEX sqlite_autoindex_users_2 (local_display_name=?)
Query: SELECT via_contact_uri, via_contact_uri_hash FROM connections WHERE connection_id = ?
Plan:
SEARCH connections USING INTEGER PRIMARY KEY (rowid=?)
Query: SELECT xgrplinkmem_received FROM group_members WHERE group_member_id = ?
Plan:
SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
@@ -6324,7 +6332,7 @@ Query: UPDATE groups SET user_member_profile_sent_at = ? WHERE user_id = ? AND g
Plan:
SEARCH groups USING INTEGER PRIMARY KEY (rowid=?)
Query: UPDATE groups SET via_group_link_uri_hash = ?, conn_link_prepared_connection = ?, updated_at = ? WHERE group_id = ?
Query: UPDATE groups SET via_group_link_uri = ?, via_group_link_uri_hash = ?, conn_link_prepared_connection = ?, updated_at = ? WHERE group_id = ?
Plan:
SEARCH groups USING INTEGER PRIMARY KEY (rowid=?)
@@ -154,7 +154,8 @@ CREATE TABLE groups(
conn_link_started_connection INTEGER NOT NULL DEFAULT 0,
welcome_shared_msg_id BLOB,
request_shared_msg_id BLOB,
conn_link_prepared_connection INTEGER NOT NULL DEFAULT 0, -- received
conn_link_prepared_connection INTEGER NOT NULL DEFAULT 0,
via_group_link_uri BLOB, -- received
FOREIGN KEY(user_id, local_display_name)
REFERENCES display_names(user_id, local_display_name)
ON DELETE CASCADE
@@ -327,6 +328,7 @@ CREATE TABLE connections(
quota_err_counter INTEGER NOT NULL DEFAULT 0,
short_link_inv BLOB,
via_short_link_contact BLOB,
via_contact_uri BLOB,
FOREIGN KEY(snd_file_id, connection_id)
REFERENCES snd_files(file_id, connection_id)
ON DELETE CASCADE
+20 -14
View File
@@ -638,21 +638,21 @@ type PreparedGroupRow = (Maybe ConnReqContact, Maybe ShortLinkContact, BoolInt,
type BusinessChatInfoRow = (Maybe BusinessChatType, Maybe MemberId, Maybe MemberId)
type GroupInfoRow = (Int64, GroupName, GroupName, Text, Maybe Text, Text, Maybe Text, Maybe ImageData) :. (Maybe MsgFilter, Maybe BoolInt, BoolInt, Maybe GroupPreferences, Maybe GroupMemberAdmission) :. (UTCTime, UTCTime, Maybe UTCTime, Maybe UTCTime) :. PreparedGroupRow :. BusinessChatInfoRow :. (Maybe UIThemeEntityOverrides, Maybe CustomData, Maybe Int64, Int) :. GroupMemberRow
type GroupInfoRow = (Int64, GroupName, GroupName, Text, Maybe Text, Text, Maybe Text, Maybe ImageData) :. (Maybe MsgFilter, Maybe BoolInt, BoolInt, Maybe GroupPreferences, Maybe GroupMemberAdmission) :. (UTCTime, UTCTime, Maybe UTCTime, Maybe UTCTime) :. PreparedGroupRow :. BusinessChatInfoRow :. (Maybe UIThemeEntityOverrides, Maybe CustomData, Maybe Int64, Int, Maybe ConnReqContact) :. GroupMemberRow
type GroupMemberRow = (Int64, Int64, MemberId, VersionChat, VersionChat, GroupMemberRole, GroupMemberCategory, GroupMemberStatus, BoolInt, Maybe MemberRestrictionStatus) :. (Maybe Int64, Maybe GroupMemberId, ContactName, Maybe ContactId, ProfileId) :. ProfileRow :. (UTCTime, UTCTime) :. (Maybe UTCTime, Int64, Int64, Int64, Maybe UTCTime)
type ProfileRow = (ProfileId, ContactName, Text, Maybe Text, Maybe ImageData, Maybe ConnLinkContact, LocalAlias, Maybe Preferences)
toGroupInfo :: VersionRangeChat -> Int64 -> [ChatTagId] -> GroupInfoRow -> GroupInfo
toGroupInfo vr userContactId chatTags ((groupId, localDisplayName, displayName, fullName, shortDescr, localAlias, description, image) :. (enableNtfs_, sendRcpts, BI favorite, groupPreferences, memberAdmission) :. (createdAt, updatedAt, chatTs, userMemberProfileSentAt) :. preparedGroupRow :. businessRow :. (uiThemes, customData, chatItemTTL, membersRequireAttention) :. userMemberRow) =
toGroupInfo vr userContactId chatTags ((groupId, localDisplayName, displayName, fullName, shortDescr, localAlias, description, image) :. (enableNtfs_, sendRcpts, BI favorite, groupPreferences, memberAdmission) :. (createdAt, updatedAt, chatTs, userMemberProfileSentAt) :. preparedGroupRow :. businessRow :. (uiThemes, customData, chatItemTTL, membersRequireAttention, viaGroupLinkUri) :. userMemberRow) =
let membership = (toGroupMember userContactId userMemberRow) {memberChatVRange = vr}
chatSettings = ChatSettings {enableNtfs = fromMaybe MFAll enableNtfs_, sendRcpts = unBI <$> sendRcpts, favorite}
fullGroupPreferences = mergeGroupPreferences groupPreferences
groupProfile = GroupProfile {displayName, fullName, shortDescr, description, image, groupPreferences, memberAdmission}
businessChat = toBusinessChatInfo businessRow
preparedGroup = toPreparedGroup preparedGroupRow
in GroupInfo {groupId, localDisplayName, groupProfile, localAlias, businessChat, fullGroupPreferences, membership, chatSettings, createdAt, updatedAt, chatTs, userMemberProfileSentAt, preparedGroup, chatTags, chatItemTTL, uiThemes, customData, membersRequireAttention}
in GroupInfo {groupId, localDisplayName, groupProfile, localAlias, businessChat, fullGroupPreferences, membership, chatSettings, createdAt, updatedAt, chatTs, userMemberProfileSentAt, preparedGroup, chatTags, chatItemTTL, uiThemes, customData, membersRequireAttention, viaGroupLinkUri}
toPreparedGroup :: PreparedGroupRow -> Maybe PreparedGroup
toPreparedGroup = \case
@@ -698,7 +698,7 @@ groupInfoQuery =
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at,
g.conn_full_link_to_connect, g.conn_short_link_to_connect, g.conn_link_prepared_connection, g.conn_link_started_connection, g.welcome_shared_msg_id, g.request_shared_msg_id,
g.business_chat, g.business_member_id, g.customer_member_id,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention,
g.ui_themes, g.custom_data, g.chat_item_ttl, g.members_require_attention, g.via_group_link_uri,
-- GroupMember - membership
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
mu.member_status, mu.show_messages, mu.member_restriction, mu.invited_by, mu.invited_by_group_member_id, mu.local_display_name, mu.contact_id, mu.contact_profile_id, pu.contact_profile_id,
@@ -784,16 +784,22 @@ addGroupChatTags db g@GroupInfo {groupId} = do
chatTags <- getGroupChatTags db groupId
pure (g :: GroupInfo) {chatTags}
setViaGroupLinkHash :: DB.Connection -> GroupId -> Int64 -> IO ()
setViaGroupLinkHash db groupId connId =
DB.execute
db
[sql|
UPDATE groups
SET via_group_link_uri_hash = (SELECT via_contact_uri_hash FROM connections WHERE connection_id = ?)
WHERE group_id = ?
|]
(connId, groupId)
setViaGroupLinkUri :: DB.Connection -> GroupId -> Int64 -> IO ()
setViaGroupLinkUri db groupId connId = do
r <-
DB.query
db
"SELECT via_contact_uri, via_contact_uri_hash FROM connections WHERE connection_id = ?"
(Only connId) :: IO [(Maybe ConnReqContact, Maybe ConnReqUriHash)]
forM_ (listToMaybe r) $ \(viaContactUri, viaContactUriHash) ->
DB.execute
db
[sql|
UPDATE groups
SET via_group_link_uri = ?, via_group_link_uri_hash = ?
WHERE group_id = ?
|]
(viaContactUri, viaContactUriHash, groupId)
deleteConnectionRecord :: DB.Connection -> User -> Int64 -> IO ()
deleteConnectionRecord db User {userId} cId = do
+2 -1
View File
@@ -486,7 +486,8 @@ data GroupInfo = GroupInfo
chatItemTTL :: Maybe Int64,
uiThemes :: Maybe UIThemeEntityOverrides,
customData :: Maybe CustomData,
membersRequireAttention :: Int
membersRequireAttention :: Int,
viaGroupLinkUri :: Maybe ConnReqContact
}
deriving (Eq, Show)