Receive support for View Once photos
This commit is contained in:
parent
fccf1eec30
commit
e62a1a7812
38 changed files with 1937 additions and 102 deletions
171
app/sql.js
171
app/sql.js
|
@ -94,6 +94,9 @@ module.exports = {
|
|||
getOutgoingWithoutExpiresAt,
|
||||
getNextExpiringMessage,
|
||||
getMessagesByConversation,
|
||||
getNextTapToViewMessageToExpire,
|
||||
getNextTapToViewMessageToAgeOut,
|
||||
getTapToViewMessagesNeedingErase,
|
||||
|
||||
getUnprocessedCount,
|
||||
getAllUnprocessed,
|
||||
|
@ -868,6 +871,87 @@ async function updateToSchemaVersion15(currentVersion, instance) {
|
|||
}
|
||||
}
|
||||
|
||||
async function updateToSchemaVersion16(currentVersion, instance) {
|
||||
if (currentVersion >= 16) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('updateToSchemaVersion16: starting...');
|
||||
await instance.run('BEGIN TRANSACTION;');
|
||||
|
||||
try {
|
||||
await instance.run(
|
||||
`ALTER TABLE messages
|
||||
ADD COLUMN messageTimer INTEGER;`
|
||||
);
|
||||
await instance.run(
|
||||
`ALTER TABLE messages
|
||||
ADD COLUMN messageTimerStart INTEGER;`
|
||||
);
|
||||
await instance.run(
|
||||
`ALTER TABLE messages
|
||||
ADD COLUMN messageTimerExpiresAt INTEGER;`
|
||||
);
|
||||
await instance.run(
|
||||
`ALTER TABLE messages
|
||||
ADD COLUMN isErased INTEGER;`
|
||||
);
|
||||
|
||||
await instance.run(`CREATE INDEX messages_message_timer ON messages (
|
||||
messageTimer,
|
||||
messageTimerStart,
|
||||
messageTimerExpiresAt,
|
||||
isErased
|
||||
) WHERE messageTimer IS NOT NULL;`);
|
||||
|
||||
// Updating full-text triggers to avoid anything with a messageTimer set
|
||||
|
||||
await instance.run('DROP TRIGGER messages_on_insert;');
|
||||
await instance.run('DROP TRIGGER messages_on_delete;');
|
||||
await instance.run('DROP TRIGGER messages_on_update;');
|
||||
|
||||
await instance.run(`
|
||||
CREATE TRIGGER messages_on_insert AFTER INSERT ON messages
|
||||
WHEN new.messageTimer IS NULL
|
||||
BEGIN
|
||||
INSERT INTO messages_fts (
|
||||
id,
|
||||
body
|
||||
) VALUES (
|
||||
new.id,
|
||||
new.body
|
||||
);
|
||||
END;
|
||||
`);
|
||||
await instance.run(`
|
||||
CREATE TRIGGER messages_on_delete AFTER DELETE ON messages BEGIN
|
||||
DELETE FROM messages_fts WHERE id = old.id;
|
||||
END;
|
||||
`);
|
||||
await instance.run(`
|
||||
CREATE TRIGGER messages_on_update AFTER UPDATE ON messages
|
||||
WHEN new.messageTimer IS NULL
|
||||
BEGIN
|
||||
DELETE FROM messages_fts WHERE id = old.id;
|
||||
INSERT INTO messages_fts(
|
||||
id,
|
||||
body
|
||||
) VALUES (
|
||||
new.id,
|
||||
new.body
|
||||
);
|
||||
END;
|
||||
`);
|
||||
|
||||
await instance.run('PRAGMA schema_version = 16;');
|
||||
await instance.run('COMMIT TRANSACTION;');
|
||||
console.log('updateToSchemaVersion16: success!');
|
||||
} catch (error) {
|
||||
await instance.run('ROLLBACK;');
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
const SCHEMA_VERSIONS = [
|
||||
updateToSchemaVersion1,
|
||||
updateToSchemaVersion2,
|
||||
|
@ -884,6 +968,7 @@ const SCHEMA_VERSIONS = [
|
|||
updateToSchemaVersion13,
|
||||
updateToSchemaVersion14,
|
||||
updateToSchemaVersion15,
|
||||
updateToSchemaVersion16,
|
||||
];
|
||||
|
||||
async function updateSchema(instance) {
|
||||
|
@ -1480,6 +1565,10 @@ async function saveMessage(data, { forceSave } = {}) {
|
|||
hasFileAttachments,
|
||||
hasVisualMediaAttachments,
|
||||
id,
|
||||
isErased,
|
||||
messageTimer,
|
||||
messageTimerStart,
|
||||
messageTimerExpiresAt,
|
||||
// eslint-disable-next-line camelcase
|
||||
received_at,
|
||||
schemaVersion,
|
||||
|
@ -1505,6 +1594,10 @@ async function saveMessage(data, { forceSave } = {}) {
|
|||
$hasAttachments: hasAttachments,
|
||||
$hasFileAttachments: hasFileAttachments,
|
||||
$hasVisualMediaAttachments: hasVisualMediaAttachments,
|
||||
$isErased: isErased,
|
||||
$messageTimer: messageTimer,
|
||||
$messageTimerStart: messageTimerStart,
|
||||
$messageTimerExpiresAt: messageTimerExpiresAt,
|
||||
$received_at: received_at,
|
||||
$schemaVersion: schemaVersion,
|
||||
$sent_at: sent_at,
|
||||
|
@ -1517,7 +1610,9 @@ async function saveMessage(data, { forceSave } = {}) {
|
|||
if (id && !forceSave) {
|
||||
await db.run(
|
||||
`UPDATE messages SET
|
||||
id = $id,
|
||||
json = $json,
|
||||
|
||||
body = $body,
|
||||
conversationId = $conversationId,
|
||||
expirationStartTimestamp = $expirationStartTimestamp,
|
||||
|
@ -1526,7 +1621,10 @@ async function saveMessage(data, { forceSave } = {}) {
|
|||
hasAttachments = $hasAttachments,
|
||||
hasFileAttachments = $hasFileAttachments,
|
||||
hasVisualMediaAttachments = $hasVisualMediaAttachments,
|
||||
id = $id,
|
||||
isErased = $isErased,
|
||||
messageTimer = $messageTimer,
|
||||
messageTimerStart = $messageTimerStart,
|
||||
messageTimerExpiresAt = $messageTimerExpiresAt,
|
||||
received_at = $received_at,
|
||||
schemaVersion = $schemaVersion,
|
||||
sent_at = $sent_at,
|
||||
|
@ -1559,6 +1657,10 @@ async function saveMessage(data, { forceSave } = {}) {
|
|||
hasAttachments,
|
||||
hasFileAttachments,
|
||||
hasVisualMediaAttachments,
|
||||
isErased,
|
||||
messageTimer,
|
||||
messageTimerStart,
|
||||
messageTimerExpiresAt,
|
||||
received_at,
|
||||
schemaVersion,
|
||||
sent_at,
|
||||
|
@ -1578,6 +1680,10 @@ async function saveMessage(data, { forceSave } = {}) {
|
|||
$hasAttachments,
|
||||
$hasFileAttachments,
|
||||
$hasVisualMediaAttachments,
|
||||
$isErased,
|
||||
$messageTimer,
|
||||
$messageTimerStart,
|
||||
$messageTimerExpiresAt,
|
||||
$received_at,
|
||||
$schemaVersion,
|
||||
$sent_at,
|
||||
|
@ -1756,6 +1862,69 @@ async function getNextExpiringMessage() {
|
|||
return map(rows, row => jsonToObject(row.json));
|
||||
}
|
||||
|
||||
async function getNextTapToViewMessageToExpire() {
|
||||
// Note: we avoid 'IS NOT NULL' here because it does seem to bypass our index
|
||||
const rows = await db.all(`
|
||||
SELECT json FROM messages
|
||||
WHERE
|
||||
messageTimer > 0
|
||||
AND messageTimerExpiresAt > 0
|
||||
AND (isErased IS NULL OR isErased != 1)
|
||||
ORDER BY messageTimerExpiresAt ASC
|
||||
LIMIT 1;
|
||||
`);
|
||||
|
||||
if (!rows || rows.length < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return jsonToObject(rows[0].json);
|
||||
}
|
||||
|
||||
async function getNextTapToViewMessageToAgeOut() {
|
||||
// Note: we avoid 'IS NOT NULL' here because it does seem to bypass our index
|
||||
const rows = await db.all(`
|
||||
SELECT json FROM messages
|
||||
WHERE
|
||||
messageTimer > 0
|
||||
AND (isErased IS NULL OR isErased != 1)
|
||||
ORDER BY received_at ASC
|
||||
LIMIT 1;
|
||||
`);
|
||||
|
||||
if (!rows || rows.length < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return jsonToObject(rows[0].json);
|
||||
}
|
||||
|
||||
async function getTapToViewMessagesNeedingErase() {
|
||||
const THIRTY_DAYS_AGO = Date.now() - 30 * 24 * 60 * 60 * 1000;
|
||||
const NOW = Date.now();
|
||||
|
||||
// Note: we avoid 'IS NOT NULL' here because it does seem to bypass our index
|
||||
const rows = await db.all(
|
||||
`SELECT json FROM messages
|
||||
WHERE
|
||||
messageTimer > 0
|
||||
AND (isErased IS NULL OR isErased != 1)
|
||||
AND (
|
||||
(messageTimerExpiresAt > 0
|
||||
AND messageTimerExpiresAt <= $NOW)
|
||||
OR
|
||||
received_at <= $THIRTY_DAYS_AGO
|
||||
)
|
||||
ORDER BY received_at ASC;`,
|
||||
{
|
||||
$NOW: NOW,
|
||||
$THIRTY_DAYS_AGO: THIRTY_DAYS_AGO,
|
||||
}
|
||||
);
|
||||
|
||||
return map(rows, row => jsonToObject(row.json));
|
||||
}
|
||||
|
||||
async function saveUnprocessed(data, { forceSave } = {}) {
|
||||
const { id, timestamp, version, attempts, envelope } = data;
|
||||
if (!id) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue