Disable message insert triggers during backup import
This commit is contained in:
parent
7dced11b57
commit
34ef8dc2c8
8 changed files with 101 additions and 1 deletions
|
@ -374,7 +374,6 @@ export class BackupImportStream extends Writable {
|
|||
toastType: ToastType.FailedToImportBackup,
|
||||
});
|
||||
}
|
||||
// TODO (DESKTOP-7934): throw in tests if we cannot process a frame
|
||||
} else {
|
||||
log.info(`${this.logId}: successfully processed all frames.`);
|
||||
}
|
||||
|
|
|
@ -305,6 +305,9 @@ export class BackupsService {
|
|||
log.info(`importBackup: starting ${backupType}...`);
|
||||
this.isRunning = 'import';
|
||||
const importStart = Date.now();
|
||||
|
||||
await DataWriter.disableMessageInsertTriggers();
|
||||
|
||||
try {
|
||||
const importStream = await BackupImportStream.create(backupType);
|
||||
if (backupType === BackupType.Ciphertext) {
|
||||
|
@ -397,6 +400,8 @@ export class BackupsService {
|
|||
throw error;
|
||||
} finally {
|
||||
this.isRunning = false;
|
||||
await DataWriter.enableMessageInsertTriggersAndBackfill();
|
||||
|
||||
window.IPC.stopTrackingQueryStats({ epochName: 'Backup Import' });
|
||||
if (window.SignalCI) {
|
||||
window.SignalCI.handleEvent('backupImportComplete', {
|
||||
|
|
|
@ -952,6 +952,10 @@ type WritableInterface = {
|
|||
insertJob(job: Readonly<StoredJob>): void;
|
||||
deleteJob(id: string): void;
|
||||
|
||||
disableMessageInsertTriggers(): void;
|
||||
enableMessageInsertTriggersAndBackfill(): void;
|
||||
ensureMessageInsertTriggersAreEnabled(): void;
|
||||
|
||||
processGroupCallRingCancellation(ringId: bigint): void;
|
||||
cleanExpiredGroupCallRingCancellations(): void;
|
||||
};
|
||||
|
|
|
@ -543,6 +543,10 @@ export const DataWriter: ServerWritableInterface = {
|
|||
processGroupCallRingCancellation,
|
||||
cleanExpiredGroupCallRingCancellations,
|
||||
|
||||
disableMessageInsertTriggers,
|
||||
enableMessageInsertTriggersAndBackfill,
|
||||
ensureMessageInsertTriggersAreEnabled,
|
||||
|
||||
// Server-only
|
||||
|
||||
removeKnownStickers,
|
||||
|
@ -7463,3 +7467,84 @@ function getUnreadEditedMessagesAndMarkRead(
|
|||
});
|
||||
})();
|
||||
}
|
||||
|
||||
function disableMessageInsertTriggers(db: WritableDB): void {
|
||||
db.transaction(() => {
|
||||
createOrUpdateItem(db, {
|
||||
id: 'messageInsertTriggersDisabled',
|
||||
value: true,
|
||||
});
|
||||
db.exec('DROP TRIGGER IF EXISTS messages_on_insert;');
|
||||
db.exec('DROP TRIGGER IF EXISTS messages_on_insert_insert_mentions;');
|
||||
})();
|
||||
}
|
||||
|
||||
const selectMentionsFromMessages = `
|
||||
SELECT messages.id, bodyRanges.value ->> 'mentionAci' as mentionAci,
|
||||
bodyRanges.value ->> 'start' as start,
|
||||
bodyRanges.value ->> 'length' as length
|
||||
FROM messages, json_each(messages.json ->> 'bodyRanges') as bodyRanges
|
||||
WHERE bodyRanges.value ->> 'mentionAci' IS NOT NULL
|
||||
`;
|
||||
|
||||
function enableMessageInsertTriggersAndBackfill(db: WritableDB): void {
|
||||
const createTriggersQuery = `
|
||||
DROP TRIGGER IF EXISTS messages_on_insert;
|
||||
CREATE TRIGGER messages_on_insert AFTER INSERT ON messages
|
||||
WHEN new.isViewOnce IS NOT 1 AND new.storyId IS NULL
|
||||
BEGIN
|
||||
INSERT INTO messages_fts
|
||||
(rowid, body)
|
||||
VALUES
|
||||
(new.rowid, new.body);
|
||||
END;
|
||||
|
||||
DROP TRIGGER IF EXISTS messages_on_insert_insert_mentions;
|
||||
CREATE TRIGGER messages_on_insert_insert_mentions AFTER INSERT ON messages
|
||||
BEGIN
|
||||
INSERT INTO mentions (messageId, mentionAci, start, length)
|
||||
${selectMentionsFromMessages}
|
||||
AND messages.id = new.id;
|
||||
END;
|
||||
`;
|
||||
db.transaction(() => {
|
||||
backfillMentionsTable(db);
|
||||
backfillMessagesFtsTable(db);
|
||||
db.exec(createTriggersQuery);
|
||||
createOrUpdateItem(db, {
|
||||
id: 'messageInsertTriggersDisabled',
|
||||
value: false,
|
||||
});
|
||||
})();
|
||||
}
|
||||
|
||||
function backfillMessagesFtsTable(db: WritableDB): void {
|
||||
db.exec(`
|
||||
DELETE FROM messages_fts;
|
||||
INSERT OR REPLACE INTO messages_fts (rowid, body)
|
||||
SELECT rowid, body
|
||||
FROM messages
|
||||
WHERE isViewOnce IS NOT 1 AND storyId IS NULL;
|
||||
`);
|
||||
}
|
||||
|
||||
function backfillMentionsTable(db: WritableDB): void {
|
||||
db.exec(`
|
||||
DELETE FROM mentions;
|
||||
INSERT INTO mentions (messageId, mentionAci, start, length)
|
||||
${selectMentionsFromMessages};
|
||||
`);
|
||||
}
|
||||
|
||||
function ensureMessageInsertTriggersAreEnabled(db: WritableDB): void {
|
||||
db.transaction(() => {
|
||||
const storedItem = getItemById(db, 'messageInsertTriggersDisabled');
|
||||
const triggersDisabled = storedItem?.value;
|
||||
if (triggersDisabled) {
|
||||
logger.warn(
|
||||
'Message insert triggers were disabled; reenabling and backfilling data'
|
||||
);
|
||||
enableMessageInsertTriggersAndBackfill(db);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
|
|
@ -51,6 +51,8 @@ export default function updateToSchemaVersion45(
|
|||
--- Message insert/update triggers to exclude stories and story replies
|
||||
|
||||
DROP TRIGGER messages_on_insert;
|
||||
-- Note: any changes to this trigger must be reflected in
|
||||
-- Server.ts: enableMessageInsertTriggersAndBackfill
|
||||
CREATE TRIGGER messages_on_insert AFTER INSERT ON messages
|
||||
WHEN new.isViewOnce IS NOT 1 AND new.storyId IS NULL
|
||||
BEGIN
|
||||
|
|
|
@ -35,6 +35,8 @@ export default function updateToSchemaVersion84(
|
|||
INSERT INTO mentions (messageId, mentionUuid, start, length)
|
||||
${selectMentionsFromMessages};
|
||||
|
||||
-- Note: any changes to this trigger must be reflected in
|
||||
-- Server.ts: enableMessageInsertTriggersAndBackfill
|
||||
CREATE TRIGGER messages_on_insert_insert_mentions AFTER INSERT ON messages
|
||||
BEGIN
|
||||
INSERT INTO mentions (messageId, mentionUuid, start, length)
|
||||
|
|
|
@ -105,6 +105,7 @@ import {
|
|||
updateToSchemaVersion1250,
|
||||
version as MAX_VERSION,
|
||||
} from './1250-defunct-call-links-storage';
|
||||
import { DataWriter } from '../Server';
|
||||
|
||||
function updateToSchemaVersion1(
|
||||
currentVersion: number,
|
||||
|
@ -2132,6 +2133,7 @@ export function updateSchema(db: WritableDB, logger: LoggerType): void {
|
|||
runSchemaUpdate(startingVersion, db, logger);
|
||||
}
|
||||
|
||||
DataWriter.ensureMessageInsertTriggersAreEnabled(db);
|
||||
enableFTS5SecureDelete(db, logger);
|
||||
|
||||
if (startingVersion !== MAX_VERSION) {
|
||||
|
|
1
ts/types/Storage.d.ts
vendored
1
ts/types/Storage.d.ts
vendored
|
@ -152,6 +152,7 @@ export type StorageAccessType = {
|
|||
backupMediaDownloadPaused: boolean;
|
||||
backupMediaDownloadBannerDismissed: boolean;
|
||||
backupMediaDownloadIdle: boolean;
|
||||
messageInsertTriggersDisabled: boolean;
|
||||
setBackupMessagesSignatureKey: boolean;
|
||||
setBackupMediaSignatureKey: boolean;
|
||||
lastReceivedAtCounter: number;
|
||||
|
|
Loading…
Reference in a new issue