Disable message insert triggers during backup import

This commit is contained in:
trevor-signal 2024-11-27 13:34:02 -05:00 committed by GitHub
parent 7dced11b57
commit 34ef8dc2c8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 101 additions and 1 deletions

View file

@ -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);
}
})();
}