remove the forceSave logic for a message, always insert or replace

pull/1495/head
Audric Ackermann 4 years ago
parent 7e77a3f3b6
commit 3ee0ccfac8

@ -1716,7 +1716,7 @@ async function getMessageCount() {
return row['count(*)'];
}
async function saveMessage(data, { forceSave } = {}) {
async function saveMessage(data) {
const {
body,
conversationId,
@ -1742,6 +1742,14 @@ async function saveMessage(data, { forceSave } = {}) {
expirationStartTimestamp,
} = data;
if (!id) {
throw new Error('id is required');
}
if (!conversationId) {
throw new Error('conversationId is required');
}
const payload = {
$id: id,
$json: objectToJSON(data),
@ -1766,46 +1774,10 @@ async function saveMessage(data, { forceSave } = {}) {
$unread: unread,
};
if (id && !forceSave) {
await db.run(
`UPDATE messages SET
json = $json,
serverId = $serverId,
serverTimestamp = $serverTimestamp,
body = $body,
conversationId = $conversationId,
expirationStartTimestamp = $expirationStartTimestamp,
expires_at = $expires_at,
expireTimer = $expireTimer,
hasAttachments = $hasAttachments,
hasFileAttachments = $hasFileAttachments,
hasVisualMediaAttachments = $hasVisualMediaAttachments,
id = $id,
received_at = $received_at,
schemaVersion = $schemaVersion,
sent = $sent,
sent_at = $sent_at,
source = $source,
sourceDevice = $sourceDevice,
type = $type,
unread = $unread
WHERE id = $id;`,
payload
);
return id;
}
const toCreate = {
...data,
id: id || uuidv4(),
};
await db.run(
`INSERT INTO messages (
`INSERT OR REPLACE INTO ${MESSAGES_TABLE} (
id,
json,
serverId,
serverTimestamp,
body,
@ -1827,7 +1799,6 @@ async function saveMessage(data, { forceSave } = {}) {
) values (
$id,
$json,
$serverId,
$serverTimestamp,
$body,
@ -1849,12 +1820,11 @@ async function saveMessage(data, { forceSave } = {}) {
);`,
{
...payload,
$id: toCreate.id,
$json: objectToJSON(toCreate),
$json: objectToJSON(data),
}
);
return toCreate.id;
return id;
}
async function saveSeenMessageHashes(arrayOfHashes) {
@ -1926,13 +1896,13 @@ async function cleanSeenMessages() {
});
}
async function saveMessages(arrayOfMessages, { forceSave } = {}) {
async function saveMessages(arrayOfMessages) {
let promise;
db.serialize(() => {
promise = Promise.all([
db.run('BEGIN TRANSACTION;'),
...map(arrayOfMessages, message => saveMessage(message, { forceSave })),
...map(arrayOfMessages, message => saveMessage(message)),
db.run('COMMIT TRANSACTION;'),
]);
});
@ -2175,7 +2145,7 @@ async function getNextExpiringMessage() {
async function saveUnprocessed(data, { forceSave } = {}) {
const { id, timestamp, version, attempts, envelope, senderIdentity } = data;
if (!id) {
throw new Error('saveUnprocessed: id was falsey');
throw new Error(`saveUnprocessed: id was falsey: ${id}`);
}
if (forceSave) {

@ -386,7 +386,6 @@ window.autoOrientImage = autoOrientImage;
window.loadImage = require('blueimp-load-image');
window.dataURLToBlobSync = require('blueimp-canvas-to-blob');
window.filesize = require('filesize');
window.getGuid = require('uuid/v4');
window.profileImages = require('./app/profile_images');
window.React = require('react');

@ -489,7 +489,6 @@ describe('Backup', () => {
const message = await upgradeMessageSchema(messageWithAttachments);
await window.Signal.Data.saveMessage(message, {
Message: window.models.Message.MessageModel,
forceSave: true,
});
const conversation = {

@ -65,8 +65,6 @@ export type ServerToken = {
};
const channelsToMake = {
_cleanData,
shutdown,
close,
removeDB,
@ -205,7 +203,7 @@ export function init() {
// When IPC arguments are prepared for the cross-process send, they are JSON.stringified.
// We can't send ArrayBuffers or BigNumbers (what we get from proto library for dates).
export async function _cleanData(data: any): Promise<any> {
function _cleanData(data: any): any {
const keys = Object.keys(data);
for (let index = 0, max = keys.length; index < max; index += 1) {
const key = keys[index];
@ -691,13 +689,8 @@ export async function updateLastHash(data: any): Promise<void> {
await channels.updateLastHash(_cleanData(data));
}
export async function saveMessage(
data: MessageModel,
options?: { forceSave: boolean }
): Promise<string> {
const id = await channels.saveMessage(_cleanData(data), {
forceSave: options?.forceSave,
});
export async function saveMessage(data: MessageModel): Promise<string> {
const id = await channels.saveMessage(_cleanData(data));
window.Whisper.ExpiringMessagesListener.update();
return id;
}
@ -797,7 +790,6 @@ export async function getMessagesByConversation(
receivedAt,
type,
});
return new MessageCollection(messages);
}

@ -936,7 +936,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
destination: this.id,
recipients: isOutgoing ? this.getRecipients() : undefined,
};
const message = await this.addSingleMessage(messageAttributes);
// tell the UI this conversation was updated

@ -44,6 +44,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
// this.on('expired', this.onExpired);
void this.setToExpire();
autoBind(this);
this.markRead = this.markRead.bind(this);
// Keep props ready
const generateProps = (triggerEvent = true) => {
@ -207,14 +208,16 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
return window.i18n('mediaMessage');
}
if (this.isExpirationTimerUpdate()) {
const { expireTimer } = this.get('expirationTimerUpdate');
if (!expireTimer) {
const expireTimerUpdate = this.get('expirationTimerUpdate');
if (!expireTimerUpdate || !expireTimerUpdate.expireTimer) {
return window.i18n('disappearingMessagesDisabled');
}
return window.i18n(
'timerSetTo',
window.Whisper.ExpirationTimerOptions.getAbbreviated(expireTimer || 0)
window.Whisper.ExpirationTimerOptions.getAbbreviated(
expireTimerUpdate.expireTimer || 0
)
);
}
const contacts = this.get('contact');
@ -1234,11 +1237,11 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
await this.commit();
}
public async commit(forceSave = false) {
// TODO investigate the meaning of the forceSave
const id = await saveMessage(this.attributes, {
forceSave,
});
public async commit() {
if (!this.attributes.id) {
throw new Error('A message always needs an id');
}
const id = await saveMessage(this.attributes);
this.trigger('change');
return id;
}

@ -1,5 +1,6 @@
import { DefaultTheme } from 'styled-components';
import _ from 'underscore';
import uuidv4 from 'uuid';
import { QuotedAttachmentType } from '../components/conversation/Quote';
import { AttachmentType } from '../types/Attachment';
import { Contact } from '../types/Contact';
@ -43,7 +44,12 @@ export interface MessageAttributes {
hasFileAttachments: boolean;
hasVisualMediaAttachments: boolean;
schemaVersion: number;
expirationTimerUpdate?: any;
expirationTimerUpdate?: {
expireTimer: number;
source: string;
fromSync?: boolean;
fromGroupUpdate?: boolean;
};
unread: boolean;
group?: any;
timestamp?: number;
@ -91,7 +97,12 @@ export interface MessageAttributesOptionals {
hasFileAttachments?: boolean;
hasVisualMediaAttachments?: boolean;
schemaVersion?: number;
expirationTimerUpdate?: any;
expirationTimerUpdate?: {
expireTimer: number;
source: string;
fromSync?: boolean;
fromGroupUpdate?: boolean;
};
unread?: boolean;
group?: any;
timestamp?: number;
@ -120,6 +131,7 @@ export const fillMessageAttributesWithDefaults = (
//FIXME audric to do put the default
return _.defaults(optAttributes, {
expireTimer: 0, // disabled
id: uuidv4(),
});
};

@ -37,13 +37,10 @@ export async function addToCache(
if (envelope.senderIdentity) {
data.senderIdentity = envelope.senderIdentity;
}
return saveUnprocessed(data, { forceSave: true });
}
async function fetchAllFromCache(): Promise<Array<any>> {
const { textsecure } = window;
const count = await getUnprocessedCount();
if (count > 1500) {
@ -63,7 +60,6 @@ export async function getAllFromCache() {
const items = await fetchAllFromCache();
window.log.info('getAllFromCache loaded', items.length, 'saved envelopes');
const { textsecure } = window;
return Promise.all(
_.map(items, async (item: any) => {
@ -104,7 +100,6 @@ export async function getAllFromCacheForSource(source: string) {
itemsFromSource.length,
'saved envelopes'
);
const { textsecure } = window;
return Promise.all(
_.map(items, async (item: any) => {

@ -2,6 +2,7 @@
import { EnvelopePlus } from './types';
export { downloadAttachment } from './attachments';
import uuidv4 from 'uuid';
import {
addToCache,
@ -27,6 +28,7 @@ import { getEnvelopeId } from './common';
import { StringUtils, UserUtils } from '../session/utils';
import { SignalService } from '../protobuf';
import { ConversationController } from '../session/conversations';
import { removeUnprocessed } from '../data/data';
// TODO: check if some of these exports no longer needed
@ -131,7 +133,7 @@ async function handleRequestDetail(
envelope.senderIdentity = senderIdentity;
}
envelope.id = envelope.serverGuid || window.getGuid();
envelope.id = envelope.serverGuid || uuidv4();
envelope.serverTimestamp = envelope.serverTimestamp
? envelope.serverTimestamp.toNumber()
: null;

@ -92,7 +92,10 @@ export class ChatMessage extends DataMessage {
profileKey: dataMessage.profileKey,
};
if ((dataMessage as any)?.$type?.name !== 'DataMessage' && !(dataMessage instanceof DataMessage)) {
if (
(dataMessage as any)?.$type?.name !== 'DataMessage' &&
!(dataMessage instanceof DataMessage)
) {
throw new Error(
'Tried to build a sync message from something else than a DataMessage'
);

1
ts/window.d.ts vendored

@ -90,7 +90,6 @@ declare global {
versionInfo: any;
getStoragePubKey: (key: string) => string;
getConversations: () => ConversationCollection;
getGuid: any;
SwarmPolling: SwarmPolling;
SnodePool: {
getSnodesFor: (string) => any;

Loading…
Cancel
Save