fix(schema): fix migration ordering hazard and FK guard for table rebuild

Remove federated_id from addMissingColumns so it no longer races with
migrateDmChannelsFederatedId on installs that have canonical_pair_id.
Wrap the table rebuild in PRAGMA foreign_keys = OFF/ON with a transaction
so the DROP TABLE succeeds even when dm_members/dm_messages hold FK refs.
This commit is contained in:
Jannis Braun
2026-03-26 20:04:34 +01:00
parent d9dc33bd36
commit 3b16d9e2ce
+8 -2
View File
@@ -183,7 +183,6 @@ export function runMigrations(db: Database.Database): void {
{ {
name: 'dm_channels', name: 'dm_channels',
columns: [ columns: [
{ name: 'federated_id', type: 'TEXT' },
{ name: 'owner_home_user_id', type: 'TEXT' }, { name: 'owner_home_user_id', type: 'TEXT' },
{ name: 'owner_home_instance', type: 'TEXT' }, { name: 'owner_home_instance', type: 'TEXT' },
{ name: 'deleted_at', type: 'INTEGER' }, { name: 'deleted_at', type: 'INTEGER' },
@@ -1494,8 +1493,11 @@ function migrateDmChannelsFederatedId(db: Database.Database): void {
} }
if (hasOldCol && !hasNewCol) { if (hasOldCol && !hasNewCol) {
// Full table rebuild to rename column and add new columns in one atomic step // Full table rebuild to rename column — disable FK enforcement during DROP
console.log('Migrating: Renaming canonical_pair_id → federated_id in dm_channels and adding group DM columns...'); console.log('Migrating: Renaming canonical_pair_id → federated_id in dm_channels and adding group DM columns...');
db.exec(`PRAGMA foreign_keys = OFF`);
try {
db.transaction(() => {
db.exec(` db.exec(`
CREATE TABLE dm_channels_new ( CREATE TABLE dm_channels_new (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
@@ -1511,6 +1513,10 @@ function migrateDmChannelsFederatedId(db: Database.Database): void {
DROP TABLE dm_channels; DROP TABLE dm_channels;
ALTER TABLE dm_channels_new RENAME TO dm_channels; ALTER TABLE dm_channels_new RENAME TO dm_channels;
`); `);
})();
} finally {
db.exec(`PRAGMA foreign_keys = ON`);
}
db.exec(`DROP INDEX IF EXISTS idx_dm_canonical_pair`); db.exec(`DROP INDEX IF EXISTS idx_dm_canonical_pair`);
db.exec(`CREATE UNIQUE INDEX IF NOT EXISTS idx_dm_federated ON dm_channels(federated_id) WHERE federated_id IS NOT NULL`); db.exec(`CREATE UNIQUE INDEX IF NOT EXISTS idx_dm_federated ON dm_channels(federated_id) WHERE federated_id IS NOT NULL`);
console.log('Migrating: dm_channels rename complete.'); console.log('Migrating: dm_channels rename complete.');