core: autoincrement database IDs (#7766)

* core: autoincrement database IDs

* migration

* update simplexmq

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
Evgeny
2026-10-19 12:14:19 +01:00
committed by GitHub
co-authored by Evgeny @ SimpleX Chat
parent 1cbbe82517
commit 634fa5ecff
11 changed files with 143 additions and 75 deletions
+1 -1
View File
@@ -21,7 +21,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package
type: git
location: https://github.com/simplex-chat/simplexmq.git
tag: cba13823567d7cd564d8a1f354046174fba375d8
tag: aabf4cdab98f9fb4c92dc6d9ec661a5f08f0e80f
source-repository-package
type: git
+1 -1
View File
@@ -1,5 +1,5 @@
{
"https://github.com/simplex-chat/simplexmq.git"."cba13823567d7cd564d8a1f354046174fba375d8" = "0nhd6zsmqs55b7shh945b0v9pn0qqkpx9djq9dldair82hsmw1if";
"https://github.com/simplex-chat/simplexmq.git"."aabf4cdab98f9fb4c92dc6d9ec661a5f08f0e80f" = "07w7rlc29gyd5p5yblgscgza1cv7sz01jygvxd6zp59xsygcd6zq";
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
"https://github.com/simplex-chat/direct-sqlcipher.git"."2330df3dc8c4b660674d3c02d76bb86f66c2abee" = "11pfj1vqsjdl26nplkr2l6z1xj7cn153qijj5gknmlzq3krn7x1i";
"https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";
+1
View File
@@ -353,6 +353,7 @@ library
Simplex.Chat.Store.SQLite.Migrations.M20261010_invite_member_via_group
Simplex.Chat.Store.SQLite.Migrations.M20261012_delivery_job_notification
Simplex.Chat.Store.SQLite.Migrations.M20261016_badge_store_receipts
Simplex.Chat.Store.SQLite.Migrations.M20261018_autoincrement_ids
other-modules:
Paths_simplex_chat
hs-source-dirs:
+3 -1
View File
@@ -180,6 +180,7 @@ import Simplex.Chat.Store.SQLite.Migrations.M20260925_badge_bindings
import Simplex.Chat.Store.SQLite.Migrations.M20261010_invite_member_via_group
import Simplex.Chat.Store.SQLite.Migrations.M20261012_delivery_job_notification
import Simplex.Chat.Store.SQLite.Migrations.M20261016_badge_store_receipts
import Simplex.Chat.Store.SQLite.Migrations.M20261018_autoincrement_ids
import Simplex.Messaging.Agent.Store.Shared (Migration (..))
schemaMigrations :: [(String, Query, Maybe Query)]
@@ -359,7 +360,8 @@ schemaMigrations =
("20260925_badge_bindings", m20260925_badge_bindings, Just down_m20260925_badge_bindings),
("20261010_invite_member_via_group", m20261010_invite_member_via_group, Just down_m20261010_invite_member_via_group),
("20261012_delivery_job_notification", m20261012_delivery_job_notification, Just down_m20261012_delivery_job_notification),
("20261016_badge_store_receipts", m20261016_badge_store_receipts, Just down_m20261016_badge_store_receipts)
("20261016_badge_store_receipts", m20261016_badge_store_receipts, Just down_m20261016_badge_store_receipts),
("20261018_autoincrement_ids", m20261018_autoincrement_ids, Just down_m20261018_autoincrement_ids)
]
-- | The list of migrations in ascending order by date
@@ -0,0 +1,110 @@
{-# LANGUAGE QuasiQuotes #-}
module Simplex.Chat.Store.SQLite.Migrations.M20261018_autoincrement_ids where
import Database.SQLite.Simple (Query)
import Database.SQLite.Simple.QQ (sql)
m20261018_autoincrement_ids :: Query
m20261018_autoincrement_ids =
[sql|
INSERT INTO sqlite_sequence (name, seq)
SELECT 'users', MAX(ROWID) FROM users;
INSERT INTO sqlite_sequence (name, seq)
SELECT 'contacts', MAX(ROWID) FROM contacts;
INSERT INTO sqlite_sequence (name, seq)
SELECT 'groups', MAX(ROWID) FROM groups;
INSERT INTO sqlite_sequence (name, seq)
SELECT 'group_members', MAX(ROWID) FROM group_members;
INSERT INTO sqlite_sequence (name, seq)
SELECT 'files', MAX(ROWID) FROM files;
INSERT INTO sqlite_sequence (name, seq)
SELECT 'connections', MAX(ROWID) FROM connections;
INSERT INTO sqlite_sequence (name, seq)
SELECT 'contact_requests', MAX(ROWID) FROM contact_requests;
INSERT INTO sqlite_sequence (name, seq)
SELECT 'rcv_roster_transfers', MAX(ROWID) FROM rcv_roster_transfers;
PRAGMA writable_schema=1;
UPDATE sqlite_master SET sql = replace(sql, 'user_id INTEGER PRIMARY KEY,', 'user_id INTEGER PRIMARY KEY AUTOINCREMENT,')
WHERE name = 'users' AND type = 'table';
UPDATE sqlite_master SET sql = replace(sql, 'contact_id INTEGER PRIMARY KEY,', 'contact_id INTEGER PRIMARY KEY AUTOINCREMENT,')
WHERE name = 'contacts' AND type = 'table';
UPDATE sqlite_master SET sql = replace(sql, 'group_id INTEGER PRIMARY KEY,', 'group_id INTEGER PRIMARY KEY AUTOINCREMENT,')
WHERE name = 'groups' AND type = 'table';
UPDATE sqlite_master SET sql = replace(sql, 'group_member_id INTEGER PRIMARY KEY,', 'group_member_id INTEGER PRIMARY KEY AUTOINCREMENT,')
WHERE name = 'group_members' AND type = 'table';
UPDATE sqlite_master SET sql = replace(sql, 'file_id INTEGER PRIMARY KEY,', 'file_id INTEGER PRIMARY KEY AUTOINCREMENT,')
WHERE name = 'files' AND type = 'table';
UPDATE sqlite_master SET sql = replace(sql, 'connection_id INTEGER PRIMARY KEY,', 'connection_id INTEGER PRIMARY KEY AUTOINCREMENT,')
WHERE name = 'connections' AND type = 'table';
UPDATE sqlite_master SET sql = replace(sql, 'contact_request_id INTEGER PRIMARY KEY,', 'contact_request_id INTEGER PRIMARY KEY AUTOINCREMENT,')
WHERE name = 'contact_requests' AND type = 'table';
UPDATE sqlite_master SET sql = replace(sql, 'roster_transfer_id INTEGER PRIMARY KEY,', 'roster_transfer_id INTEGER PRIMARY KEY AUTOINCREMENT,')
WHERE name = 'rcv_roster_transfers' AND type = 'table';
PRAGMA writable_schema=RESET;
|]
down_m20261018_autoincrement_ids :: Query
down_m20261018_autoincrement_ids =
[sql|
DELETE FROM sqlite_sequence WHERE name = 'users';
DELETE FROM sqlite_sequence WHERE name = 'contacts';
DELETE FROM sqlite_sequence WHERE name = 'groups';
DELETE FROM sqlite_sequence WHERE name = 'group_members';
DELETE FROM sqlite_sequence WHERE name = 'files';
DELETE FROM sqlite_sequence WHERE name = 'connections';
DELETE FROM sqlite_sequence WHERE name = 'contact_requests';
DELETE FROM sqlite_sequence WHERE name = 'rcv_roster_transfers';
PRAGMA writable_schema=1;
UPDATE sqlite_master SET sql = replace(sql, 'user_id INTEGER PRIMARY KEY AUTOINCREMENT,', 'user_id INTEGER PRIMARY KEY,')
WHERE name = 'users' AND type = 'table';
UPDATE sqlite_master SET sql = replace(sql, 'contact_id INTEGER PRIMARY KEY AUTOINCREMENT,', 'contact_id INTEGER PRIMARY KEY,')
WHERE name = 'contacts' AND type = 'table';
UPDATE sqlite_master SET sql = replace(sql, 'group_id INTEGER PRIMARY KEY AUTOINCREMENT,', 'group_id INTEGER PRIMARY KEY,')
WHERE name = 'groups' AND type = 'table';
UPDATE sqlite_master SET sql = replace(sql, 'group_member_id INTEGER PRIMARY KEY AUTOINCREMENT,', 'group_member_id INTEGER PRIMARY KEY,')
WHERE name = 'group_members' AND type = 'table';
UPDATE sqlite_master SET sql = replace(sql, 'file_id INTEGER PRIMARY KEY AUTOINCREMENT,', 'file_id INTEGER PRIMARY KEY,')
WHERE name = 'files' AND type = 'table';
UPDATE sqlite_master SET sql = replace(sql, 'connection_id INTEGER PRIMARY KEY AUTOINCREMENT,', 'connection_id INTEGER PRIMARY KEY,')
WHERE name = 'connections' AND type = 'table';
UPDATE sqlite_master SET sql = replace(sql, 'contact_request_id INTEGER PRIMARY KEY AUTOINCREMENT,', 'contact_request_id INTEGER PRIMARY KEY,')
WHERE name = 'contact_requests' AND type = 'table';
UPDATE sqlite_master SET sql = replace(sql, 'roster_transfer_id INTEGER PRIMARY KEY AUTOINCREMENT,', 'roster_transfer_id INTEGER PRIMARY KEY,')
WHERE name = 'rcv_roster_transfers' AND type = 'table';
PRAGMA writable_schema=RESET;
|]
@@ -614,6 +614,15 @@ Query:
Plan:
SEARCH address_ratchet_keys USING INDEX idx_address_ratchet_keys (conn_id=? AND ratchet_key_id=?)
Query:
UPDATE rcv_messages
SET receive_attempts = receive_attempts + 1
WHERE conn_id = ? AND internal_id = ?
RETURNING receive_attempts
Plan:
SEARCH rcv_messages USING COVERING INDEX idx_rcv_messages_conn_id_internal_id (conn_id=? AND internal_id=?)
Query:
DELETE FROM address_ratchet_keys
WHERE conn_id = ?
@@ -1526,6 +1535,10 @@ Query: UPDATE ratchets SET ratchet_state = ? WHERE conn_id = ?
Plan:
SEARCH ratchets USING PRIMARY KEY (conn_id=?)
Query: UPDATE rcv_file_chunk_replicas SET delay = ?, retries = retries + 1, updated_at = ? WHERE rcv_file_chunk_replica_id = ?
Plan:
SEARCH rcv_file_chunk_replicas USING INTEGER PRIMARY KEY (rowid=?)
Query: UPDATE rcv_file_chunk_replicas SET received = 1, updated_at = ? WHERE rcv_file_chunk_replica_id = ?
Plan:
SEARCH rcv_file_chunk_replicas USING INTEGER PRIMARY KEY (rowid=?)
@@ -36,7 +36,7 @@ CREATE TABLE contact_profiles(
preferences_json TEXT
) STRICT;
CREATE TABLE users(
user_id INTEGER PRIMARY KEY,
user_id INTEGER PRIMARY KEY AUTOINCREMENT,
contact_id INTEGER NOT NULL UNIQUE REFERENCES contacts ON DELETE RESTRICT
DEFERRABLE INITIALLY DEFERRED,
local_display_name TEXT NOT NULL UNIQUE,
@@ -63,6 +63,7 @@ CREATE TABLE users(
ON UPDATE CASCADE
DEFERRABLE INITIALLY DEFERRED
) STRICT;
CREATE TABLE sqlite_sequence(name,seq);
CREATE TABLE display_names(
user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
local_display_name TEXT NOT NULL,
@@ -74,7 +75,7 @@ CREATE TABLE display_names(
UNIQUE(user_id, ldn_base, ldn_suffix) ON CONFLICT FAIL
) WITHOUT ROWID, STRICT;
CREATE TABLE contacts(
contact_id INTEGER PRIMARY KEY,
contact_id INTEGER PRIMARY KEY AUTOINCREMENT,
contact_profile_id INTEGER REFERENCES contact_profiles ON DELETE SET NULL,
user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
local_display_name TEXT NOT NULL,
@@ -151,7 +152,7 @@ CREATE TABLE group_profiles(
preferences_json TEXT
) STRICT;
CREATE TABLE groups(
group_id INTEGER PRIMARY KEY, -- local group ID
group_id INTEGER PRIMARY KEY AUTOINCREMENT, -- local group ID
user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
local_display_name TEXT NOT NULL, -- local group name without spaces
group_profile_id INTEGER REFERENCES group_profiles ON DELETE SET NULL, -- shared group profile
@@ -222,7 +223,7 @@ CREATE TABLE groups(
) STRICT;
CREATE TABLE group_members(
-- group members, excluding the local user
group_member_id INTEGER PRIMARY KEY,
group_member_id INTEGER PRIMARY KEY AUTOINCREMENT,
group_id INTEGER NOT NULL REFERENCES groups ON DELETE CASCADE,
member_id BLOB NOT NULL, -- shared member ID, unique per group
member_role TEXT NOT NULL, -- owner, admin, member
@@ -280,7 +281,7 @@ CREATE TABLE group_member_intros(
UNIQUE(re_group_member_id, to_group_member_id)
) STRICT;
CREATE TABLE files(
file_id INTEGER PRIMARY KEY,
file_id INTEGER PRIMARY KEY AUTOINCREMENT,
contact_id INTEGER REFERENCES contacts ON DELETE CASCADE,
group_id INTEGER REFERENCES groups ON DELETE CASCADE,
file_name TEXT NOT NULL,
@@ -352,7 +353,7 @@ CREATE TABLE rcv_file_chunks(
) WITHOUT ROWID, STRICT;
CREATE TABLE connections(
-- all SMP agent connections
connection_id INTEGER PRIMARY KEY,
connection_id INTEGER PRIMARY KEY AUTOINCREMENT,
agent_conn_id BLOB NOT NULL UNIQUE,
conn_level INTEGER NOT NULL DEFAULT 0,
via_contact INTEGER REFERENCES contacts(contact_id) ON DELETE SET NULL,
@@ -419,7 +420,7 @@ CREATE TABLE user_contact_links(
UNIQUE(user_id, local_display_name)
) STRICT;
CREATE TABLE contact_requests(
contact_request_id INTEGER PRIMARY KEY,
contact_request_id INTEGER PRIMARY KEY AUTOINCREMENT,
user_contact_link_id INTEGER REFERENCES user_contact_links
ON UPDATE CASCADE ON DELETE SET NULL,
agent_invitation_id BLOB NOT NULL,
@@ -530,7 +531,6 @@ CREATE TABLE chat_items(
fwd_from_member_id BLOB,
fwd_from_shared_msg_id BLOB
) STRICT;
CREATE TABLE sqlite_sequence(name,seq);
CREATE TABLE chat_item_messages(
chat_item_id INTEGER NOT NULL REFERENCES chat_items ON DELETE CASCADE,
message_id INTEGER NOT NULL UNIQUE REFERENCES messages ON DELETE CASCADE,
@@ -848,7 +848,7 @@ CREATE TABLE group_relays(
base_web_url TEXT
) STRICT;
CREATE TABLE rcv_roster_transfers(
roster_transfer_id INTEGER PRIMARY KEY,
roster_transfer_id INTEGER PRIMARY KEY AUTOINCREMENT,
group_id INTEGER NOT NULL REFERENCES groups ON DELETE CASCADE,
from_member_id INTEGER NOT NULL REFERENCES group_members ON DELETE CASCADE,
roster_version INTEGER NOT NULL,
+2 -4
View File
@@ -60,7 +60,7 @@ import Simplex.Messaging.Client (ProtocolClientConfig (..))
import Simplex.Messaging.Client.Agent (defaultSMPClientAgentConfig)
import Simplex.Messaging.Protocol (ProtoServerWithAuth (..), ProtocolServer (..), ProtocolType (..))
import Simplex.Messaging.Server (runSMPServerBlocking)
import Simplex.Messaging.Server.Env.STM (ServerConfig (..), ServerStoreCfg (..), StartOptions (..), StorePaths (..), defaultMessageExpiration, defaultIdleQueueInterval, defaultNtfExpiration, defaultInactiveClientExpiration)
import Simplex.Messaging.Server.Env.STM (ServerConfig (..), ServerStoreCfg (..), StartOptions (..), StorePaths (..), defaultMaxClientCmdWait, defaultMessageExpiration, defaultNtfExpiration, defaultInactiveClientExpiration)
import NameResolver (NameRegistry, resolverNamesConfig, withNameResolver)
import Simplex.Messaging.Server.MsgStore.STM (STMMsgStore)
import Simplex.Messaging.Transport
@@ -638,8 +638,6 @@ smpServerCfg p =
{ transports = [(smpTestPort p, transport @TLS, False)],
tbqSize = 4,
msgQueueQuota = 16,
maxJournalMsgCount = 24,
maxJournalStateLines = 4,
queueIdBytes = 24,
msgIdBytes = 24,
serverStoreCfg = SSCMemory Nothing, -- $ Just StorePaths {storeLogFile = "tmp/smp-server-store.log", storeMsgsFile = Just "tmp/smp-server-messages.log"},
@@ -653,7 +651,6 @@ smpServerCfg p =
messageExpiration = Just defaultMessageExpiration,
expireMessagesOnStart = False,
expireMessagesOnSend = False,
idleQueueInterval = defaultIdleQueueInterval,
notificationExpiration = defaultNtfExpiration,
inactiveClientExpiration = Just defaultInactiveClientExpiration,
smpCredentials =
@@ -680,6 +677,7 @@ smpServerCfg p =
allowSMPProxy = True,
serverClientConcurrency = 16,
serverResolverConcurrency = 1000,
maxClientCmdWait = defaultMaxClientCmdWait,
namesConfig = Nothing,
information = Nothing,
startOptions = StartOptions {maintenance = False, compactLog = False, logLevel = LogError, skipWarnings = False, confirmMigrations = MCYesUp}
+1 -31
View File
@@ -12644,13 +12644,7 @@ testChannelMessageFile ps =
withNewTestChat ps "dan" danProfile $ \dan ->
withNewTestChat ps "eve" eveProfile $ \eve -> withXFTPServer ps $ do
createChannel1Relay "team" alice bob cath dan eve
-- the roster arrives as a file before this one; Postgres assigns it a new id and does not
-- reuse it on delete (SQLite does), so the received message file is id 2 here, 1 on SQLite.
#if defined(dbPostgres)
let rcvFileId = 2 :: Int
#else
let rcvFileId = 1 :: Int
#endif
-- owner sends file as channel message
alice #> "/f #team ./tests/fixtures/test.jpg"
alice <## "use /fc 1 to cancel sending"
@@ -12696,11 +12690,7 @@ testChannelMessageFileCancel ps =
withNewTestChat ps "dan" danProfile $ \dan ->
withNewTestChat ps "eve" eveProfile $ \eve -> withXFTPServer ps $ do
createChannel1Relay "team" alice bob cath dan eve
#if defined(dbPostgres)
let rcvFileId = 2 :: Int
#else
let rcvFileId = 1 :: Int
#endif
-- owner sends file as channel message
alice #> "/f #team ./tests/fixtures/test.jpg"
alice <## "use /fc 1 to cancel sending"
@@ -12876,11 +12866,7 @@ testChannelOwnerFileTransferAsMember ps =
withNewTestChat ps "dan" danProfile $ \dan ->
withNewTestChat ps "eve" eveProfile $ \eve -> withXFTPServer ps $ do
createChannel1Relay "team" alice bob cath dan eve
#if defined(dbPostgres)
let rcvFileId = 2 :: Int
#else
let rcvFileId = 1 :: Int
#endif
-- owner sends file as member (not as channel)
alice ##> "/_send #1(as_group=off) json [{\"filePath\": \"./tests/fixtures/test.jpg\", \"msgContent\": {\"type\": \"file\", \"text\": \"\"}}]"
alice <# "/f #team ./tests/fixtures/test.jpg"
@@ -13028,11 +13014,7 @@ testChannelFileBadgeProof ps = do
withNewTestChatCfg ps cfg "eve" eveProfile $ \eve -> withXFTPServer ps $ do
createChannel1Relay "team" alice bob cath dan eve
addTestBadge alice =<< issueTestBadge sk futureDate
#if defined(dbPostgres)
let rcvFileId = 2 :: Int
#else
let rcvFileId = 1 :: Int
#endif
alice ##> "/_send #1(as_group=off) json [{\"filePath\": \"./tests/fixtures/test.jpg\", \"msgContent\": {\"type\": \"file\", \"text\": \"\"}}]"
alice <# "/f #team ./tests/fixtures/test.jpg"
alice <## "use /fc 1 to cancel sending"
@@ -13095,11 +13077,7 @@ testChannelOwnerFileCancelAsMember ps =
withNewTestChat ps "dan" danProfile $ \dan ->
withNewTestChat ps "eve" eveProfile $ \eve -> withXFTPServer ps $ do
createChannel1Relay "team" alice bob cath dan eve
#if defined(dbPostgres)
let rcvFileId = 2 :: Int
#else
let rcvFileId = 1 :: Int
#endif
-- owner sends file as member (not as channel)
alice ##> "/_send #1(as_group=off) json [{\"filePath\": \"./tests/fixtures/test.jpg\", \"msgContent\": {\"type\": \"file\", \"text\": \"\"}}]"
alice <# "/f #team ./tests/fixtures/test.jpg"
@@ -13475,17 +13453,9 @@ testChannelSignedFile ps =
xftpCLI ["rand", testfile, "1mb"] `shouldReturn` ["File created: " <> testfile]
createChannel1Relay "team" alice bob cath dan eve
promoteChannelMember "team" alice bob cath [dan, eve]
-- roster serves arrive as files that Postgres deletes without reusing the id (SQLite reuses
-- it), so ids run higher here. cath's send and the subscribers' (dan, eve) receive both
-- follow only their join roster (id 2). The relay (bob) also received the roster re-served
-- on cath's promotion, so its file is id 3. The owner (alice) has no roster file, so id 1.
#if defined(dbPostgres)
-- roster files are deleted after the transfer, so ids run higher: cath, dan and eve use id 2, the relay (bob) id 3, the owner (alice) id 1.
let fileId = 2 :: Int
relayFileId = 3 :: Int
#else
let fileId = 1 :: Int
relayFileId = 1 :: Int
#endif
-- cath's first (signed) message introduces her to dan/eve
cath ##> "/_send #1 sign=on text hi"
-27
View File
@@ -2379,11 +2379,7 @@ testPlanAddressContactViaAddress =
bob @@@ [("@alice", "")]
-- GUI api
#if defined(dbPostgres)
bob ##> "/_connect contact 1 4"
#else
bob ##> "/_connect contact 1 2"
#endif
connecting alice bob
where
connecting alice bob = do
@@ -2441,11 +2437,7 @@ testPlanAddressContactViaShortAddress =
bob @@@ [("@alice", "")]
-- GUI api
#if defined(dbPostgres)
bob ##> "/_connect contact 1 4"
#else
bob ##> "/_connect contact 1 2"
#endif
connecting alice bob
where
connecting alice bob = do
@@ -3077,14 +3069,8 @@ testChangePCCUser = testChat2 aliceProfile bobProfile $
alice ##> "/user alisa"
showActiveUser alice "alisa"
-- Change connection back to other user
#if defined(dbPostgres)
alice ##> "/_set conn user :2 3"
alice <## "connection 2 changed from user alisa to user alisa2, new link:"
#else
-- connection ID does not change in SQLite because table has no auto-increment
alice ##> "/_set conn user :1 3"
alice <## "connection 1 changed from user alisa to user alisa2, new link:"
#endif
alice <## ""
_shortInv <- getTermLine alice
alice <## ""
@@ -3126,14 +3112,8 @@ testChangePCCUserFromIncognito = testChat2 aliceProfile bobProfile $
alice ##> "/user alisa"
showActiveUser alice "alisa"
-- Change connection back to initial user
#if defined(dbPostgres)
alice ##> "/_set conn user :2 1"
alice <## "connection 2 changed from user alisa to user alice, new link:"
#else
-- connection ID does not change in SQLite because table has no auto-increment
alice ##> "/_set conn user :1 1"
alice <## "connection 1 changed from user alisa to user alice, new link:"
#endif
alice <## ""
_shortInv <- getTermLine alice
alice <## ""
@@ -3171,16 +3151,9 @@ testChangePCCUserAndThenIncognito = testChat2 aliceProfile bobProfile $
alice ##> "/user alisa"
showActiveUser alice "alisa"
-- Change connection to incognito and make sure it's attached to the newly created user profile
#if defined(dbPostgres)
alice ##> "/_set incognito :2 on"
_ <- getTermLine alice
alice <## "connection 2 changed to incognito"
#else
-- connection ID does not change in SQLite because table has no auto-increment
alice ##> "/_set incognito :1 on"
_ <- getTermLine alice
alice <## "connection 1 changed to incognito"
#endif
bob ##> ("/connect " <> inv)
bob <## "confirmation sent!"
alisaIncognito <- getTermLine alice
+2 -1
View File
@@ -146,7 +146,8 @@ skipComparisonForDownMigrations =
-- appends; CREATE INDEX appends).
"20260529_delivery_job_senders",
-- group_domain is removed
"20260603_simplex_name"
"20260603_simplex_name",
"20261018_autoincrement_ids"
]
getSchema :: FilePath -> FilePath -> IO String