Parallelize SQL queries
This commit is contained in:
parent
86b4da1ec2
commit
c64762858e
178 changed files with 3377 additions and 3618 deletions
3
ts/CI.ts
3
ts/CI.ts
|
@ -7,7 +7,7 @@ import type { IPCResponse as ChallengeResponseType } from './challenge';
|
|||
import type { MessageAttributesType } from './model-types.d';
|
||||
import * as log from './logging/log';
|
||||
import { explodePromise } from './util/explodePromise';
|
||||
import { ipcInvoke } from './sql/channels';
|
||||
import { AccessType, ipcInvoke } from './sql/channels';
|
||||
import { backupsService } from './services/backups';
|
||||
import { SECOND } from './util/durations';
|
||||
import { isSignalRoute } from './util/signalRoutes';
|
||||
|
@ -128,6 +128,7 @@ export function getCI({ deviceName, backupData }: GetCIOptionsType): CIType {
|
|||
|
||||
async function getMessagesBySentAt(sentAt: number) {
|
||||
const messages = await ipcInvoke<ReadonlyArray<MessageAttributesType>>(
|
||||
AccessType.Read,
|
||||
'getMessagesBySentAt',
|
||||
[sentAt]
|
||||
);
|
||||
|
|
|
@ -6,6 +6,7 @@ import { v4 as uuid } from 'uuid';
|
|||
import { incrementMessageCounter } from '../util/incrementMessageCounter';
|
||||
import { ReadStatus } from '../messages/MessageReadStatus';
|
||||
import { SendStatus } from '../messages/MessageSendState';
|
||||
import { DataWriter } from '../sql/Client';
|
||||
import { BodyRange } from '../types/BodyRange';
|
||||
import { strictAssert } from '../util/assert';
|
||||
import { MINUTE } from '../util/durations';
|
||||
|
@ -86,13 +87,13 @@ export async function populateConversationWithMessages({
|
|||
timestamp += 1;
|
||||
}
|
||||
|
||||
await window.Signal.Data.saveMessages(messages, {
|
||||
await DataWriter.saveMessages(messages, {
|
||||
forceSave: true,
|
||||
ourAci,
|
||||
});
|
||||
|
||||
conversation.set('active_at', Date.now());
|
||||
await window.Signal.Data.updateConversation(conversation.attributes);
|
||||
await DataWriter.updateConversation(conversation.attributes);
|
||||
log.info(`${logId}: populating conversation complete`);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import type {
|
|||
} from './model-types.d';
|
||||
import type { ConversationModel } from './models/conversations';
|
||||
|
||||
import dataInterface from './sql/Client';
|
||||
import { DataReader, DataWriter } from './sql/Client';
|
||||
import * as log from './logging/log';
|
||||
import * as Errors from './types/errors';
|
||||
import { getAuthorId } from './messages/helpers';
|
||||
|
@ -127,11 +127,15 @@ const {
|
|||
getAllConversations,
|
||||
getAllGroupsInvolvingServiceId,
|
||||
getMessagesBySentAt,
|
||||
} = DataReader;
|
||||
|
||||
const {
|
||||
migrateConversationMessages,
|
||||
removeConversation,
|
||||
saveConversation,
|
||||
updateConversation,
|
||||
} = dataInterface;
|
||||
updateConversations,
|
||||
} = DataWriter;
|
||||
|
||||
// We have to run this in background.js, after all backbone models and collections on
|
||||
// Whisper.* have been created. Once those are in typescript we can use more reasonable
|
||||
|
@ -443,12 +447,12 @@ export class ConversationController {
|
|||
conversation.set({
|
||||
profileAvatar: { hash: SIGNAL_AVATAR_PATH, path: SIGNAL_AVATAR_PATH },
|
||||
});
|
||||
updateConversation(conversation.attributes);
|
||||
await updateConversation(conversation.attributes);
|
||||
}
|
||||
|
||||
if (!conversation.get('profileName')) {
|
||||
conversation.set({ profileName: 'Signal' });
|
||||
updateConversation(conversation.attributes);
|
||||
await updateConversation(conversation.attributes);
|
||||
}
|
||||
|
||||
this._signalConversationId = conversation.id;
|
||||
|
@ -934,7 +938,7 @@ export class ConversationController {
|
|||
);
|
||||
|
||||
existing.set({ e164: undefined });
|
||||
updateConversation(existing.attributes);
|
||||
drop(updateConversation(existing.attributes));
|
||||
|
||||
byE164[e164] = conversation;
|
||||
|
||||
|
@ -1144,7 +1148,7 @@ export class ConversationController {
|
|||
group.set({
|
||||
members: currentAdded,
|
||||
});
|
||||
updateConversation(group.attributes);
|
||||
drop(updateConversation(group.attributes));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1337,7 +1341,7 @@ export class ConversationController {
|
|||
);
|
||||
convo.set('isPinned', true);
|
||||
|
||||
window.Signal.Data.updateConversation(convo.attributes);
|
||||
drop(updateConversation(convo.attributes));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1353,7 +1357,7 @@ export class ConversationController {
|
|||
`updating ${sharedWith.length} conversations`
|
||||
);
|
||||
|
||||
await window.Signal.Data.updateConversations(
|
||||
await updateConversations(
|
||||
sharedWith.map(c => {
|
||||
c.unset('shareMyPhoneNumber');
|
||||
return c.attributes;
|
||||
|
@ -1440,7 +1444,7 @@ export class ConversationController {
|
|||
|
||||
const isChanged = maybeDeriveGroupV2Id(conversation);
|
||||
if (isChanged) {
|
||||
updateConversation(conversation.attributes);
|
||||
await updateConversation(conversation.attributes);
|
||||
}
|
||||
|
||||
// In case a too-large draft was saved to the database
|
||||
|
@ -1449,7 +1453,7 @@ export class ConversationController {
|
|||
conversation.set({
|
||||
draft: draft.slice(0, MAX_MESSAGE_BODY_LENGTH),
|
||||
});
|
||||
updateConversation(conversation.attributes);
|
||||
await updateConversation(conversation.attributes);
|
||||
}
|
||||
|
||||
// Clean up the conversations that have service id as their e164.
|
||||
|
@ -1457,7 +1461,7 @@ export class ConversationController {
|
|||
const serviceId = conversation.getServiceId();
|
||||
if (e164 && isServiceIdString(e164) && serviceId) {
|
||||
conversation.set({ e164: undefined });
|
||||
updateConversation(conversation.attributes);
|
||||
await updateConversation(conversation.attributes);
|
||||
|
||||
log.info(
|
||||
`Cleaning up conversation(${serviceId}) with invalid e164`
|
||||
|
|
|
@ -18,10 +18,13 @@ import {
|
|||
SignedPreKeyRecord,
|
||||
} from '@signalapp/libsignal-client';
|
||||
|
||||
import { DataReader, DataWriter } from './sql/Client';
|
||||
import type { ItemType } from './sql/Interface';
|
||||
import * as Bytes from './Bytes';
|
||||
import { constantTimeEqual, sha256 } from './Crypto';
|
||||
import { assertDev, strictAssert } from './util/assert';
|
||||
import { isNotNil } from './util/isNotNil';
|
||||
import { drop } from './util/drop';
|
||||
import { Zone } from './util/Zone';
|
||||
import { isMoreRecentThan } from './util/timestamp';
|
||||
import {
|
||||
|
@ -294,7 +297,9 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
await Promise.all([
|
||||
(async () => {
|
||||
this.ourIdentityKeys.clear();
|
||||
const map = await window.Signal.Data.getItemById('identityKeyMap');
|
||||
const map = (await DataReader.getItemById(
|
||||
'identityKeyMap'
|
||||
)) as unknown as ItemType<'identityKeyMap'>;
|
||||
if (!map) {
|
||||
return;
|
||||
}
|
||||
|
@ -313,7 +318,9 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
})(),
|
||||
(async () => {
|
||||
this.ourRegistrationIds.clear();
|
||||
const map = await window.Signal.Data.getItemById('registrationIdMap');
|
||||
const map = (await DataReader.getItemById(
|
||||
'registrationIdMap'
|
||||
)) as unknown as ItemType<'registrationIdMap'>;
|
||||
if (!map) {
|
||||
return;
|
||||
}
|
||||
|
@ -329,32 +336,32 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
_fillCaches<string, IdentityKeyType, PublicKey>(
|
||||
this,
|
||||
'identityKeys',
|
||||
window.Signal.Data.getAllIdentityKeys()
|
||||
DataReader.getAllIdentityKeys()
|
||||
),
|
||||
_fillCaches<string, KyberPreKeyType, KyberPreKeyRecord>(
|
||||
this,
|
||||
'kyberPreKeys',
|
||||
window.Signal.Data.getAllKyberPreKeys()
|
||||
DataReader.getAllKyberPreKeys()
|
||||
),
|
||||
_fillCaches<string, SessionType, SessionRecord>(
|
||||
this,
|
||||
'sessions',
|
||||
window.Signal.Data.getAllSessions()
|
||||
DataReader.getAllSessions()
|
||||
),
|
||||
_fillCaches<string, PreKeyType, PreKeyRecord>(
|
||||
this,
|
||||
'preKeys',
|
||||
window.Signal.Data.getAllPreKeys()
|
||||
DataReader.getAllPreKeys()
|
||||
),
|
||||
_fillCaches<string, SenderKeyType, SenderKeyRecord>(
|
||||
this,
|
||||
'senderKeys',
|
||||
window.Signal.Data.getAllSenderKeys()
|
||||
DataReader.getAllSenderKeys()
|
||||
),
|
||||
_fillCaches<string, SignedPreKeyType, SignedPreKeyRecord>(
|
||||
this,
|
||||
'signedPreKeys',
|
||||
window.Signal.Data.getAllSignedPreKeys()
|
||||
DataReader.getAllSignedPreKeys()
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
@ -470,7 +477,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
},
|
||||
};
|
||||
|
||||
await window.Signal.Data.createOrUpdateKyberPreKey(confirmedItem.fromDB);
|
||||
await DataWriter.createOrUpdateKyberPreKey(confirmedItem.fromDB);
|
||||
kyberPreKeyCache.set(id, confirmedItem);
|
||||
}
|
||||
|
||||
|
@ -505,7 +512,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
toSave.push(kyberPreKey);
|
||||
});
|
||||
|
||||
await window.Signal.Data.bulkAddKyberPreKeys(toSave);
|
||||
await DataWriter.bulkAddKyberPreKeys(toSave);
|
||||
toSave.forEach(kyberPreKey => {
|
||||
kyberPreKeyCache.set(kyberPreKey.id, {
|
||||
hydrated: false,
|
||||
|
@ -546,7 +553,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
const ids = keyIds.map(keyId => this._getKeyId(ourServiceId, keyId));
|
||||
|
||||
log.info('removeKyberPreKeys: Removing kyber prekeys:', formatKeys(keyIds));
|
||||
const changes = await window.Signal.Data.removeKyberPreKeyById(ids);
|
||||
const changes = await DataWriter.removeKyberPreKeyById(ids);
|
||||
log.info(`removeKyberPreKeys: Removed ${changes} kyber prekeys`);
|
||||
ids.forEach(id => {
|
||||
kyberPreKeyCache.delete(id);
|
||||
|
@ -564,7 +571,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
if (this.kyberPreKeys) {
|
||||
this.kyberPreKeys.clear();
|
||||
}
|
||||
const changes = await window.Signal.Data.removeAllKyberPreKeys();
|
||||
const changes = await DataWriter.removeAllKyberPreKeys();
|
||||
log.info(`clearKyberPreKeyStore: Removed ${changes} kyber prekeys`);
|
||||
}
|
||||
|
||||
|
@ -646,7 +653,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
});
|
||||
|
||||
log.info(`storePreKeys: Saving ${toSave.length} prekeys`);
|
||||
await window.Signal.Data.bulkAddPreKeys(toSave);
|
||||
await DataWriter.bulkAddPreKeys(toSave);
|
||||
toSave.forEach(preKey => {
|
||||
preKeyCache.set(preKey.id, {
|
||||
hydrated: false,
|
||||
|
@ -668,7 +675,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
|
||||
log.info('removePreKeys: Removing prekeys:', formatKeys(keyIds));
|
||||
|
||||
const changes = await window.Signal.Data.removePreKeyById(ids);
|
||||
const changes = await DataWriter.removePreKeyById(ids);
|
||||
log.info(`removePreKeys: Removed ${changes} prekeys`);
|
||||
ids.forEach(id => {
|
||||
preKeyCache.delete(id);
|
||||
|
@ -683,7 +690,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
if (this.preKeys) {
|
||||
this.preKeys.clear();
|
||||
}
|
||||
const changes = await window.Signal.Data.removeAllPreKeys();
|
||||
const changes = await DataWriter.removeAllPreKeys();
|
||||
log.info(`clearPreKeyStore: Removed ${changes} prekeys`);
|
||||
}
|
||||
|
||||
|
@ -769,7 +776,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
},
|
||||
};
|
||||
|
||||
await window.Signal.Data.createOrUpdateSignedPreKey(confirmedItem.fromDB);
|
||||
await DataWriter.createOrUpdateSignedPreKey(confirmedItem.fromDB);
|
||||
signedPreKeyCache.set(id, confirmedItem);
|
||||
}
|
||||
|
||||
|
@ -796,7 +803,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
confirmed: Boolean(confirmed),
|
||||
};
|
||||
|
||||
await window.Signal.Data.createOrUpdateSignedPreKey(fromDB);
|
||||
await DataWriter.createOrUpdateSignedPreKey(fromDB);
|
||||
this.signedPreKeys.set(id, {
|
||||
hydrated: false,
|
||||
fromDB,
|
||||
|
@ -818,7 +825,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
'removeSignedPreKeys: Removing signed prekeys:',
|
||||
formatKeys(keyIds)
|
||||
);
|
||||
await window.Signal.Data.removeSignedPreKeyById(ids);
|
||||
await DataWriter.removeSignedPreKeyById(ids);
|
||||
ids.forEach(id => {
|
||||
signedPreKeyCache.delete(id);
|
||||
});
|
||||
|
@ -828,7 +835,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
if (this.signedPreKeys) {
|
||||
this.signedPreKeys.clear();
|
||||
}
|
||||
const changes = await window.Signal.Data.removeAllSignedPreKeys();
|
||||
const changes = await DataWriter.removeAllSignedPreKeys();
|
||||
log.info(`clearSignedPreKeysStore: Removed ${changes} signed prekeys`);
|
||||
}
|
||||
|
||||
|
@ -992,7 +999,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
try {
|
||||
const id = this.getSenderKeyId(qualifiedAddress, distributionId);
|
||||
|
||||
await window.Signal.Data.removeSenderKeyById(id);
|
||||
await DataWriter.removeSenderKeyById(id);
|
||||
|
||||
this.senderKeys.delete(id);
|
||||
} catch (error) {
|
||||
|
@ -1011,7 +1018,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
if (this.pendingSenderKeys) {
|
||||
this.pendingSenderKeys.clear();
|
||||
}
|
||||
await window.Signal.Data.removeAllSenderKeys();
|
||||
await DataWriter.removeAllSenderKeys();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1191,7 +1198,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
|
||||
// Commit both sender keys, sessions and unprocessed in the same database transaction
|
||||
// to unroll both on error.
|
||||
await window.Signal.Data.commitDecryptResult({
|
||||
await DataWriter.commitDecryptResult({
|
||||
senderKeys: Array.from(pendingSenderKeys.values()).map(
|
||||
({ fromDB }) => fromDB
|
||||
),
|
||||
|
@ -1593,7 +1600,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
const id = qualifiedAddress.toString();
|
||||
log.info('removeSession: deleting session for', id);
|
||||
try {
|
||||
await window.Signal.Data.removeSessionById(id);
|
||||
await DataWriter.removeSessionById(id);
|
||||
this.sessions.delete(id);
|
||||
this.pendingSessions.delete(id);
|
||||
} catch (e) {
|
||||
|
@ -1640,7 +1647,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
await window.Signal.Data.removeSessionsByConversation(id);
|
||||
await DataWriter.removeSessionsByConversation(id);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -1665,7 +1672,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
await window.Signal.Data.removeSessionsByServiceId(serviceId);
|
||||
await DataWriter.removeSessionsByServiceId(serviceId);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1772,7 +1779,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
this.sessions.clear();
|
||||
}
|
||||
this.pendingSessions.clear();
|
||||
const changes = await window.Signal.Data.removeAllSessions();
|
||||
const changes = await DataWriter.removeAllSessions();
|
||||
log.info(`clearSessionStore: Removed ${changes} sessions`);
|
||||
});
|
||||
}
|
||||
|
@ -1893,9 +1900,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
await this._saveIdentityKey(newRecord);
|
||||
|
||||
this.identityKeys.delete(record.fromDB.id);
|
||||
const changes = await window.Signal.Data.removeIdentityKeyById(
|
||||
record.fromDB.id
|
||||
);
|
||||
const changes = await DataWriter.removeIdentityKeyById(record.fromDB.id);
|
||||
|
||||
log.info(
|
||||
`getOrMigrateIdentityRecord: Removed ${changes} old identity keys for ${record.fromDB.id}`
|
||||
|
@ -2042,7 +2047,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
|
||||
const { id } = data;
|
||||
|
||||
await window.Signal.Data.createOrUpdateIdentityKey(data);
|
||||
await DataWriter.createOrUpdateIdentityKey(data);
|
||||
this.identityKeys.set(id, {
|
||||
hydrated: false,
|
||||
fromDB: data,
|
||||
|
@ -2345,7 +2350,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
|
||||
// We only want to clear previousIdentityKey on a match, or on successfully emit.
|
||||
conversation.set({ previousIdentityKey: undefined });
|
||||
window.Signal.Data.updateConversation(conversation.attributes);
|
||||
drop(DataWriter.updateConversation(conversation.attributes));
|
||||
} catch (error) {
|
||||
log.error(
|
||||
'saveIdentity: error triggering keychange:',
|
||||
|
@ -2462,20 +2467,20 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
|
||||
const id = serviceId;
|
||||
this.identityKeys.delete(id);
|
||||
await window.Signal.Data.removeIdentityKeyById(serviceId);
|
||||
await DataWriter.removeIdentityKeyById(serviceId);
|
||||
await this.removeSessionsByServiceId(serviceId);
|
||||
}
|
||||
|
||||
// Not yet processed messages - for resiliency
|
||||
getUnprocessedCount(): Promise<number> {
|
||||
return this.withZone(GLOBAL_ZONE, 'getUnprocessedCount', async () => {
|
||||
return window.Signal.Data.getUnprocessedCount();
|
||||
return DataReader.getUnprocessedCount();
|
||||
});
|
||||
}
|
||||
|
||||
getAllUnprocessedIds(): Promise<Array<string>> {
|
||||
return this.withZone(GLOBAL_ZONE, 'getAllUnprocessedIds', () => {
|
||||
return window.Signal.Data.getAllUnprocessedIds();
|
||||
return DataWriter.getAllUnprocessedIds();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2486,14 +2491,14 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
GLOBAL_ZONE,
|
||||
'getAllUnprocessedByIdsAndIncrementAttempts',
|
||||
async () => {
|
||||
return window.Signal.Data.getUnprocessedByIdsAndIncrementAttempts(ids);
|
||||
return DataWriter.getUnprocessedByIdsAndIncrementAttempts(ids);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
getUnprocessedById(id: string): Promise<UnprocessedType | undefined> {
|
||||
return this.withZone(GLOBAL_ZONE, 'getUnprocessedById', async () => {
|
||||
return window.Signal.Data.getUnprocessedById(id);
|
||||
return DataReader.getUnprocessedById(id);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2531,7 +2536,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
data: UnprocessedUpdateType
|
||||
): Promise<void> {
|
||||
return this.withZone(GLOBAL_ZONE, 'updateUnprocessedWithData', async () => {
|
||||
await window.Signal.Data.updateUnprocessedWithData(id, data);
|
||||
await DataWriter.updateUnprocessedWithData(id, data);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2542,14 +2547,14 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
GLOBAL_ZONE,
|
||||
'updateUnprocessedsWithData',
|
||||
async () => {
|
||||
await window.Signal.Data.updateUnprocessedsWithData(items);
|
||||
await DataWriter.updateUnprocessedsWithData(items);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
removeUnprocessed(idOrArray: string | Array<string>): Promise<void> {
|
||||
return this.withZone(GLOBAL_ZONE, 'removeUnprocessed', async () => {
|
||||
await window.Signal.Data.removeUnprocessed(idOrArray);
|
||||
await DataWriter.removeUnprocessed(idOrArray);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2557,7 +2562,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
removeAllUnprocessed(): Promise<void> {
|
||||
log.info('removeAllUnprocessed');
|
||||
return this.withZone(GLOBAL_ZONE, 'removeAllUnprocessed', async () => {
|
||||
await window.Signal.Data.removeAllUnprocessed();
|
||||
await DataWriter.removeAllUnprocessed();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2603,9 +2608,9 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
'registrationIdMap',
|
||||
omit(storage.get('registrationIdMap') || {}, oldPni)
|
||||
),
|
||||
window.Signal.Data.removePreKeysByServiceId(oldPni),
|
||||
window.Signal.Data.removeSignedPreKeysByServiceId(oldPni),
|
||||
window.Signal.Data.removeKyberPreKeysByServiceId(oldPni),
|
||||
DataWriter.removePreKeysByServiceId(oldPni),
|
||||
DataWriter.removeSignedPreKeysByServiceId(oldPni),
|
||||
DataWriter.removeKyberPreKeysByServiceId(oldPni),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -2695,7 +2700,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
}
|
||||
|
||||
async removeAllData(): Promise<void> {
|
||||
await window.Signal.Data.removeAll();
|
||||
await DataWriter.removeAll();
|
||||
await this.hydrateCaches();
|
||||
|
||||
window.storage.reset();
|
||||
|
@ -2716,7 +2721,7 @@ export class SignalProtocolStore extends EventEmitter {
|
|||
conversation.unset('senderKeyInfo');
|
||||
});
|
||||
|
||||
await window.Signal.Data.removeAllConfiguration();
|
||||
await DataWriter.removeAllConfiguration();
|
||||
|
||||
await this.hydrateCaches();
|
||||
|
||||
|
|
|
@ -209,6 +209,7 @@ import { isEnabled } from './RemoteConfig';
|
|||
import { AttachmentBackupManager } from './jobs/AttachmentBackupManager';
|
||||
import { getConversationIdForLogging } from './util/idForLogging';
|
||||
import { encryptConversationAttachments } from './util/encryptConversationAttachments';
|
||||
import { DataReader, DataWriter } from './sql/Client';
|
||||
|
||||
export function isOverHourIntoPast(timestamp: number): boolean {
|
||||
return isNumber(timestamp) && isOlderThan(timestamp, HOUR);
|
||||
|
@ -256,7 +257,7 @@ export async function startApp(): Promise<void> {
|
|||
let initialBadgesState: BadgesStateType = { byId: {} };
|
||||
async function loadInitialBadgesState(): Promise<void> {
|
||||
initialBadgesState = {
|
||||
byId: makeLookup(await window.Signal.Data.getAllBadges(), 'id'),
|
||||
byId: makeLookup(await DataReader.getAllBadges(), 'id'),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -436,7 +437,7 @@ export async function startApp(): Promise<void> {
|
|||
window.i18n
|
||||
);
|
||||
|
||||
const version = await window.Signal.Data.getItemById('version');
|
||||
const version = await DataReader.getItemById('version');
|
||||
if (!version) {
|
||||
const isIndexedDBPresent = await indexedDb.doesDatabaseExist();
|
||||
if (isIndexedDBPresent) {
|
||||
|
@ -472,8 +473,8 @@ export async function startApp(): Promise<void> {
|
|||
|
||||
await Promise.all([
|
||||
indexedDb.removeDatabase(),
|
||||
window.Signal.Data.removeAll(),
|
||||
window.Signal.Data.removeIndexedDBFiles(),
|
||||
DataWriter.removeAll(),
|
||||
DataWriter.removeIndexedDBFiles(),
|
||||
]);
|
||||
log.info('Done with SQL deletion and IndexedDB file deletion.');
|
||||
} catch (error) {
|
||||
|
@ -485,7 +486,7 @@ export async function startApp(): Promise<void> {
|
|||
|
||||
// Set a flag to delete IndexedDB on next startup if it wasn't deleted just now.
|
||||
// We need to use direct data calls, since window.storage isn't ready yet.
|
||||
await window.Signal.Data.createOrUpdateItem({
|
||||
await DataWriter.createOrUpdateItem({
|
||||
id: 'indexeddb-delete-needed',
|
||||
value: true,
|
||||
});
|
||||
|
@ -826,7 +827,7 @@ export async function startApp(): Promise<void> {
|
|||
log.info('background/shutdown: closing the database');
|
||||
|
||||
// Shut down the data interface cleanly
|
||||
await window.Signal.Data.shutdown();
|
||||
await DataWriter.shutdown();
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -926,12 +927,12 @@ export async function startApp(): Promise<void> {
|
|||
key: legacyChallengeKey,
|
||||
});
|
||||
|
||||
await window.Signal.Data.clearAllErrorStickerPackAttempts();
|
||||
await DataWriter.clearAllErrorStickerPackAttempts();
|
||||
}
|
||||
|
||||
if (window.isBeforeVersion(lastVersion, 'v5.51.0-beta.2')) {
|
||||
await window.storage.put('groupCredentials', []);
|
||||
await window.Signal.Data.removeAllProfileKeyCredentials();
|
||||
await DataWriter.removeAllProfileKeyCredentials();
|
||||
}
|
||||
|
||||
if (window.isBeforeVersion(lastVersion, 'v6.38.0-beta.1')) {
|
||||
|
@ -963,9 +964,9 @@ export async function startApp(): Promise<void> {
|
|||
|
||||
if (newVersion || window.storage.get('needOrphanedAttachmentCheck')) {
|
||||
await window.storage.remove('needOrphanedAttachmentCheck');
|
||||
await window.Signal.Data.cleanupOrphanedAttachments();
|
||||
await DataWriter.cleanupOrphanedAttachments();
|
||||
|
||||
drop(window.Signal.Data.ensureFilePermissions());
|
||||
drop(DataWriter.ensureFilePermissions());
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -1004,9 +1005,8 @@ export async function startApp(): Promise<void> {
|
|||
const batchWithIndex = await migrateMessageData({
|
||||
numMessagesPerBatch: NUM_MESSAGES_PER_BATCH,
|
||||
upgradeMessageSchema,
|
||||
getMessagesNeedingUpgrade:
|
||||
window.Signal.Data.getMessagesNeedingUpgrade,
|
||||
saveMessages: window.Signal.Data.saveMessages,
|
||||
getMessagesNeedingUpgrade: DataReader.getMessagesNeedingUpgrade,
|
||||
saveMessages: DataWriter.saveMessages,
|
||||
});
|
||||
log.info('idleDetector/idle: Upgraded messages:', batchWithIndex);
|
||||
isMigrationWithIndexComplete = batchWithIndex.done;
|
||||
|
@ -1056,9 +1056,7 @@ export async function startApp(): Promise<void> {
|
|||
}
|
||||
|
||||
try {
|
||||
await window.Signal.Data.deleteSentProtosOlderThan(
|
||||
now - sentProtoMaxAge
|
||||
);
|
||||
await DataWriter.deleteSentProtosOlderThan(now - sentProtoMaxAge);
|
||||
} catch (error) {
|
||||
log.error(
|
||||
'background/onready/setInterval: Error deleting sent protos: ',
|
||||
|
@ -1412,7 +1410,7 @@ export async function startApp(): Promise<void> {
|
|||
|
||||
log.info('Expiration start timestamp cleanup: starting...');
|
||||
const messagesUnexpectedlyMissingExpirationStartTimestamp =
|
||||
await window.Signal.Data.getMessagesUnexpectedlyMissingExpirationStartTimestamp();
|
||||
await DataReader.getMessagesUnexpectedlyMissingExpirationStartTimestamp();
|
||||
log.info(
|
||||
`Expiration start timestamp cleanup: Found ${messagesUnexpectedlyMissingExpirationStartTimestamp.length} messages for cleanup`
|
||||
);
|
||||
|
@ -1446,7 +1444,7 @@ export async function startApp(): Promise<void> {
|
|||
};
|
||||
});
|
||||
|
||||
await window.Signal.Data.saveMessages(newMessageAttributes, {
|
||||
await DataWriter.saveMessages(newMessageAttributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
}
|
||||
|
@ -1454,10 +1452,10 @@ export async function startApp(): Promise<void> {
|
|||
|
||||
{
|
||||
log.info('Startup/syncTasks: Fetching tasks');
|
||||
const syncTasks = await window.Signal.Data.getAllSyncTasks();
|
||||
const syncTasks = await DataWriter.getAllSyncTasks();
|
||||
|
||||
log.info(`Startup/syncTasks: Queueing ${syncTasks.length} sync tasks`);
|
||||
await queueSyncTasks(syncTasks, window.Signal.Data.removeSyncTaskById);
|
||||
await queueSyncTasks(syncTasks, DataWriter.removeSyncTaskById);
|
||||
|
||||
log.info('`Startup/syncTasks: Done');
|
||||
}
|
||||
|
@ -2402,7 +2400,7 @@ export async function startApp(): Promise<void> {
|
|||
`for ${sender.idForLogging()}`
|
||||
);
|
||||
sender.set({ shareMyPhoneNumber: true });
|
||||
window.Signal.Data.updateConversation(sender.attributes);
|
||||
drop(DataWriter.updateConversation(sender.attributes));
|
||||
}
|
||||
|
||||
if (!message.get('unidentifiedDeliveryReceived')) {
|
||||
|
@ -2585,7 +2583,7 @@ export async function startApp(): Promise<void> {
|
|||
const conversation = window.ConversationController.get(id)!;
|
||||
|
||||
conversation.enableProfileSharing();
|
||||
window.Signal.Data.updateConversation(conversation.attributes);
|
||||
await DataWriter.updateConversation(conversation.attributes);
|
||||
|
||||
// Then we update our own profileKey if it's different from what we have
|
||||
const ourId = window.ConversationController.getOurConversationId();
|
||||
|
@ -3037,14 +3035,14 @@ export async function startApp(): Promise<void> {
|
|||
window.ConversationController.getOurConversation();
|
||||
if (ourConversation) {
|
||||
ourConversation.unset('username');
|
||||
window.Signal.Data.updateConversation(ourConversation.attributes);
|
||||
await DataWriter.updateConversation(ourConversation.attributes);
|
||||
}
|
||||
|
||||
// Then make sure outstanding conversation saves are flushed
|
||||
await window.Signal.Data.flushUpdateConversationBatcher();
|
||||
await DataWriter.flushUpdateConversationBatcher();
|
||||
|
||||
// Then make sure that all previously-outstanding database saves are flushed
|
||||
await window.Signal.Data.getItemById('manifestVersion');
|
||||
await DataReader.getItemById('manifestVersion');
|
||||
|
||||
// Finally, conversations in the database, and delete all config tables
|
||||
await window.textsecure.storage.protocol.removeAllConfiguration();
|
||||
|
@ -3319,13 +3317,13 @@ export async function startApp(): Promise<void> {
|
|||
|
||||
log.info(`${logId}: Saving ${syncTasks.length} sync tasks`);
|
||||
|
||||
await window.Signal.Data.saveSyncTasks(syncTasks);
|
||||
await DataWriter.saveSyncTasks(syncTasks);
|
||||
|
||||
confirm();
|
||||
|
||||
log.info(`${logId}: Queuing ${syncTasks.length} sync tasks`);
|
||||
|
||||
await queueSyncTasks(syncTasks, window.Signal.Data.removeSyncTaskById);
|
||||
await queueSyncTasks(syncTasks, DataWriter.removeSyncTaskById);
|
||||
|
||||
log.info(`${logId}: Done`);
|
||||
}
|
||||
|
@ -3391,13 +3389,13 @@ export async function startApp(): Promise<void> {
|
|||
|
||||
log.info(`${logId}: Saving ${syncTasks.length} sync tasks`);
|
||||
|
||||
await window.Signal.Data.saveSyncTasks(syncTasks);
|
||||
await DataWriter.saveSyncTasks(syncTasks);
|
||||
|
||||
confirm();
|
||||
|
||||
log.info(`${logId}: Queuing ${syncTasks.length} sync tasks`);
|
||||
|
||||
await queueSyncTasks(syncTasks, window.Signal.Data.removeSyncTaskById);
|
||||
await queueSyncTasks(syncTasks, DataWriter.removeSyncTaskById);
|
||||
|
||||
log.info(`${logId}: Done`);
|
||||
}
|
||||
|
@ -3463,13 +3461,13 @@ export async function startApp(): Promise<void> {
|
|||
|
||||
log.info(`${logId}: Saving ${syncTasks.length} sync tasks`);
|
||||
|
||||
await window.Signal.Data.saveSyncTasks(syncTasks);
|
||||
await DataWriter.saveSyncTasks(syncTasks);
|
||||
|
||||
confirm();
|
||||
|
||||
log.info(`${logId}: Queuing ${syncTasks.length} sync tasks`);
|
||||
|
||||
await queueSyncTasks(syncTasks, window.Signal.Data.removeSyncTaskById);
|
||||
await queueSyncTasks(syncTasks, DataWriter.removeSyncTaskById);
|
||||
|
||||
log.info(`${logId}: Done`);
|
||||
}
|
||||
|
@ -3544,13 +3542,13 @@ export async function startApp(): Promise<void> {
|
|||
|
||||
log.info(`${logId}: Saving ${syncTasks.length} sync tasks`);
|
||||
|
||||
await window.Signal.Data.saveSyncTasks(syncTasks);
|
||||
await DataWriter.saveSyncTasks(syncTasks);
|
||||
|
||||
confirm();
|
||||
|
||||
log.info(`${logId}: Queuing ${syncTasks.length} sync tasks`);
|
||||
|
||||
await queueSyncTasks(syncTasks, window.Signal.Data.removeSyncTaskById);
|
||||
await queueSyncTasks(syncTasks, DataWriter.removeSyncTaskById);
|
||||
|
||||
log.info(`${logId}: Done`);
|
||||
}
|
||||
|
@ -3579,13 +3577,13 @@ export async function startApp(): Promise<void> {
|
|||
sentAt: timestamp,
|
||||
type: item.type,
|
||||
}));
|
||||
await window.Signal.Data.saveSyncTasks(syncTasks);
|
||||
await DataWriter.saveSyncTasks(syncTasks);
|
||||
|
||||
confirm();
|
||||
|
||||
log.info(`${logId}: Queuing ${syncTasks.length} sync tasks`);
|
||||
|
||||
await queueSyncTasks(syncTasks, window.Signal.Data.removeSyncTaskById);
|
||||
await queueSyncTasks(syncTasks, DataWriter.removeSyncTaskById);
|
||||
|
||||
log.info(`${logId}: Done`);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import PQueue from 'p-queue';
|
||||
import { DataWriter } from '../sql/Client';
|
||||
import * as log from '../logging/log';
|
||||
import { MINUTE } from '../util/durations';
|
||||
import { missingCaseError } from '../util/missingCaseError';
|
||||
|
@ -100,7 +101,7 @@ async function downloadBadgeImageFile(url: string): Promise<string> {
|
|||
imageFileData
|
||||
);
|
||||
|
||||
await window.Signal.Data.badgeImageFileDownloaded(url, localPath);
|
||||
await DataWriter.badgeImageFileDownloaded(url, localPath);
|
||||
|
||||
window.reduxActions.badges.badgeImageFileDownloaded(url, localPath);
|
||||
|
||||
|
|
36
ts/groups.ts
36
ts/groups.ts
|
@ -19,7 +19,7 @@ import {
|
|||
maybeFetchNewCredentials,
|
||||
} from './services/groupCredentialFetcher';
|
||||
import { storageServiceUploadJob } from './services/storage';
|
||||
import dataInterface from './sql/Client';
|
||||
import { DataReader, DataWriter } from './sql/Client';
|
||||
import { toWebSafeBase64, fromWebSafeBase64 } from './util/webSafeBase64';
|
||||
import { assertDev, strictAssert } from './util/assert';
|
||||
import { isMoreRecentThan } from './util/timestamp';
|
||||
|
@ -263,7 +263,7 @@ const groupFieldsCache = new LRU<string, GroupFields>({
|
|||
max: MAX_CACHED_GROUP_FIELDS,
|
||||
});
|
||||
|
||||
const { updateConversation } = dataInterface;
|
||||
const { updateConversation } = DataWriter;
|
||||
|
||||
if (!isNumber(MAX_MESSAGE_SCHEMA)) {
|
||||
throw new Error(
|
||||
|
@ -1602,9 +1602,7 @@ export async function modifyGroupV2({
|
|||
groupMembersV2: membersV2,
|
||||
});
|
||||
|
||||
await dataInterface.replaceAllEndorsementsForGroup(
|
||||
groupEndorsementData
|
||||
);
|
||||
await DataWriter.replaceAllEndorsementsForGroup(groupEndorsementData);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1921,7 +1919,7 @@ export async function createGroupV2(
|
|||
groupMembersV2: membersV2,
|
||||
});
|
||||
|
||||
await dataInterface.replaceAllEndorsementsForGroup(groupEndorsementData);
|
||||
await DataWriter.replaceAllEndorsementsForGroup(groupEndorsementData);
|
||||
} catch (error) {
|
||||
if (!(error instanceof HTTPError)) {
|
||||
throw error;
|
||||
|
@ -2023,7 +2021,7 @@ export async function createGroupV2(
|
|||
details: [{ type: 'create' }],
|
||||
},
|
||||
};
|
||||
await dataInterface.saveMessages([createdTheGroupMessage], {
|
||||
await DataWriter.saveMessages([createdTheGroupMessage], {
|
||||
forceSave: true,
|
||||
ourAci,
|
||||
});
|
||||
|
@ -2482,7 +2480,7 @@ export async function initiateMigrationToGroupV2(
|
|||
}
|
||||
|
||||
// Save these most recent updates to conversation
|
||||
updateConversation(conversation.attributes);
|
||||
await updateConversation(conversation.attributes);
|
||||
|
||||
strictAssert(
|
||||
Bytes.isNotEmpty(groupSendEndorsementResponse),
|
||||
|
@ -2496,7 +2494,7 @@ export async function initiateMigrationToGroupV2(
|
|||
groupMembersV2: membersV2,
|
||||
});
|
||||
|
||||
await dataInterface.replaceAllEndorsementsForGroup(groupEndorsementData);
|
||||
await DataWriter.replaceAllEndorsementsForGroup(groupEndorsementData);
|
||||
});
|
||||
} catch (error) {
|
||||
const logId = conversation.idForLogging();
|
||||
|
@ -2960,7 +2958,7 @@ export async function respondToGroupV2Migration({
|
|||
}
|
||||
|
||||
// Save these most recent updates to conversation
|
||||
updateConversation(conversation.attributes);
|
||||
await updateConversation(conversation.attributes);
|
||||
|
||||
// Finally, check for any changes to the group since its initial creation using normal
|
||||
// group update codepaths.
|
||||
|
@ -2983,7 +2981,7 @@ export async function respondToGroupV2Migration({
|
|||
groupMembersV2: membersV2,
|
||||
});
|
||||
|
||||
await dataInterface.replaceAllEndorsementsForGroup(groupEndorsementData);
|
||||
await DataWriter.replaceAllEndorsementsForGroup(groupEndorsementData);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3364,7 +3362,7 @@ async function appendChangeMessages(
|
|||
|
||||
const ourAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
let lastMessage = await dataInterface.getLastConversationMessage({
|
||||
let lastMessage = await DataReader.getLastConversationMessage({
|
||||
conversationId: conversation.id,
|
||||
});
|
||||
|
||||
|
@ -3400,7 +3398,7 @@ async function appendChangeMessages(
|
|||
strictAssert(first !== undefined, 'First message must be there');
|
||||
|
||||
log.info(`appendChangeMessages/${logId}: updating ${first.id}`);
|
||||
await dataInterface.saveMessage(first, {
|
||||
await DataWriter.saveMessage(first, {
|
||||
ourAci,
|
||||
|
||||
// We don't use forceSave here because this is an update of existing
|
||||
|
@ -3410,7 +3408,7 @@ async function appendChangeMessages(
|
|||
log.info(
|
||||
`appendChangeMessages/${logId}: saving ${rest.length} new messages`
|
||||
);
|
||||
await dataInterface.saveMessages(rest, {
|
||||
await DataWriter.saveMessages(rest, {
|
||||
ourAci,
|
||||
forceSave: true,
|
||||
});
|
||||
|
@ -3418,7 +3416,7 @@ async function appendChangeMessages(
|
|||
log.info(
|
||||
`appendChangeMessages/${logId}: saving ${mergedMessages.length} new messages`
|
||||
);
|
||||
await dataInterface.saveMessages(mergedMessages, {
|
||||
await DataWriter.saveMessages(mergedMessages, {
|
||||
ourAci,
|
||||
forceSave: true,
|
||||
});
|
||||
|
@ -3766,7 +3764,7 @@ async function updateGroupViaState({
|
|||
groupMembersV2: membersV2,
|
||||
});
|
||||
|
||||
await dataInterface.replaceAllEndorsementsForGroup(groupEndorsementData);
|
||||
await DataWriter.replaceAllEndorsementsForGroup(groupEndorsementData);
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -3890,7 +3888,7 @@ async function updateGroupViaLogs({
|
|||
strictAssert(groupId != null, 'Group must have groupId');
|
||||
|
||||
let cachedEndorsementsExpiration =
|
||||
await dataInterface.getGroupSendCombinedEndorsementExpiration(groupId);
|
||||
await DataReader.getGroupSendCombinedEndorsementExpiration(groupId);
|
||||
|
||||
let response: GroupLogResponseType;
|
||||
let groupSendEndorsementResponse: Uint8Array | null = null;
|
||||
|
@ -3925,7 +3923,7 @@ async function updateGroupViaLogs({
|
|||
'updateGroupViaLogs: Received paginated response, deleting group endorsements'
|
||||
);
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await dataInterface.deleteAllEndorsementsForGroup(groupId);
|
||||
await DataWriter.deleteAllEndorsementsForGroup(groupId);
|
||||
cachedEndorsementsExpiration = null; // gets sent as 0 in header
|
||||
}
|
||||
|
||||
|
@ -3971,7 +3969,7 @@ async function updateGroupViaLogs({
|
|||
groupSecretParamsBase64: secretParams,
|
||||
});
|
||||
|
||||
await dataInterface.replaceAllEndorsementsForGroup(groupEndorsementData);
|
||||
await DataWriter.replaceAllEndorsementsForGroup(groupEndorsementData);
|
||||
}
|
||||
|
||||
return updates;
|
||||
|
|
|
@ -7,6 +7,7 @@ import type { ConversationAttributesType } from '../model-types.d';
|
|||
import type { ConversationModel } from '../models/conversations';
|
||||
import type { PreJoinConversationType } from '../state/ducks/conversations';
|
||||
|
||||
import { DataWriter } from '../sql/Client';
|
||||
import * as Bytes from '../Bytes';
|
||||
import * as Errors from '../types/errors';
|
||||
import * as log from '../logging/log';
|
||||
|
@ -160,7 +161,7 @@ export async function joinViaLink(value: string): Promise<void> {
|
|||
const active_at = existingConversation.get('active_at') || Date.now();
|
||||
// eslint-disable-next-line camelcase
|
||||
existingConversation.set({ active_at, timestamp });
|
||||
window.Signal.Data.updateConversation(existingConversation.attributes);
|
||||
await DataWriter.updateConversation(existingConversation.attributes);
|
||||
|
||||
// We're waiting for the left pane to re-sort before we navigate to that conversation
|
||||
await sleep(200);
|
||||
|
@ -320,7 +321,7 @@ export async function joinViaLink(value: string): Promise<void> {
|
|||
temporaryMemberCount: memberCount,
|
||||
timestamp,
|
||||
});
|
||||
window.Signal.Data.updateConversation(
|
||||
await DataWriter.updateConversation(
|
||||
targetConversation.attributes
|
||||
);
|
||||
}
|
||||
|
@ -343,9 +344,7 @@ export async function joinViaLink(value: string): Promise<void> {
|
|||
// We want to keep this conversation around, since the join succeeded
|
||||
isTemporary: undefined,
|
||||
});
|
||||
window.Signal.Data.updateConversation(
|
||||
tempConversation.attributes
|
||||
);
|
||||
await DataWriter.updateConversation(tempConversation.attributes);
|
||||
}
|
||||
|
||||
window.reduxActions.conversations.showConversation({
|
||||
|
@ -357,7 +356,7 @@ export async function joinViaLink(value: string): Promise<void> {
|
|||
window.ConversationController.dangerouslyRemoveById(
|
||||
tempConversation.id
|
||||
);
|
||||
await window.Signal.Data.removeConversation(tempConversation.id);
|
||||
await DataWriter.removeConversation(tempConversation.id);
|
||||
}
|
||||
|
||||
throw error;
|
||||
|
|
|
@ -7,7 +7,7 @@ import { PassThrough } from 'node:stream';
|
|||
|
||||
import * as durations from '../util/durations';
|
||||
import * as log from '../logging/log';
|
||||
import dataInterface from '../sql/Client';
|
||||
import { DataWriter } from '../sql/Client';
|
||||
|
||||
import * as Errors from '../types/errors';
|
||||
import { redactGenericText } from '../util/privacy';
|
||||
|
@ -81,10 +81,10 @@ const THUMBNAIL_RETRY_CONFIG = {
|
|||
export class AttachmentBackupManager extends JobManager<CoreAttachmentBackupJobType> {
|
||||
private static _instance: AttachmentBackupManager | undefined;
|
||||
static defaultParams: JobManagerParamsType<CoreAttachmentBackupJobType> = {
|
||||
markAllJobsInactive: dataInterface.markAllAttachmentBackupJobsInactive,
|
||||
saveJob: dataInterface.saveAttachmentBackupJob,
|
||||
removeJob: dataInterface.removeAttachmentBackupJob,
|
||||
getNextJobs: dataInterface.getNextAttachmentBackupJobs,
|
||||
markAllJobsInactive: DataWriter.markAllAttachmentBackupJobsInactive,
|
||||
saveJob: DataWriter.saveAttachmentBackupJob,
|
||||
removeJob: DataWriter.removeAttachmentBackupJob,
|
||||
getNextJobs: DataWriter.getNextAttachmentBackupJobs,
|
||||
runJob: runAttachmentBackupJob,
|
||||
shouldHoldOffOnStartingQueuedJobs: () => {
|
||||
const reduxState = window.reduxStore?.getState();
|
||||
|
@ -604,7 +604,7 @@ async function copyToBackupTier({
|
|||
|
||||
// Update our local understanding of what's in the backup cdn
|
||||
const sizeOnBackupCdn = getAesCbcCiphertextLength(ciphertextLength);
|
||||
await window.Signal.Data.saveBackupCdnObjectMetadata([
|
||||
await DataWriter.saveBackupCdnObjectMetadata([
|
||||
{ mediaId, cdnNumber: response.cdn, sizeOnBackupCdn },
|
||||
]);
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
AttachmentPermanentlyUndownloadableError,
|
||||
downloadAttachment as downloadAttachmentUtil,
|
||||
} from '../util/downloadAttachment';
|
||||
import dataInterface from '../sql/Client';
|
||||
import { DataWriter } from '../sql/Client';
|
||||
import { getValue } from '../RemoteConfig';
|
||||
|
||||
import { isInCall as isInCallSelector } from '../state/selectors/calling';
|
||||
|
@ -103,10 +103,10 @@ export class AttachmentDownloadManager extends JobManager<CoreAttachmentDownload
|
|||
override logPrefix = 'AttachmentDownloadManager';
|
||||
|
||||
static defaultParams: AttachmentDownloadManagerParamsType = {
|
||||
markAllJobsInactive: dataInterface.resetAttachmentDownloadActive,
|
||||
saveJob: dataInterface.saveAttachmentDownloadJob,
|
||||
removeJob: dataInterface.removeAttachmentDownloadJob,
|
||||
getNextJobs: dataInterface.getNextAttachmentDownloadJobs,
|
||||
markAllJobsInactive: DataWriter.resetAttachmentDownloadActive,
|
||||
saveJob: DataWriter.saveAttachmentDownloadJob,
|
||||
removeJob: DataWriter.removeAttachmentDownloadJob,
|
||||
getNextJobs: DataWriter.getNextAttachmentDownloadJobs,
|
||||
runDownloadAttachmentJob,
|
||||
shouldHoldOffOnStartingQueuedJobs: () => {
|
||||
const reduxState = window.reduxStore?.getState();
|
||||
|
@ -321,7 +321,7 @@ async function runDownloadAttachmentJob({
|
|||
} finally {
|
||||
// This will fail if the message has been deleted before the download finished, which
|
||||
// is good
|
||||
await dataInterface.saveMessage(message.attributes, {
|
||||
await DataWriter.saveMessage(message.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import { AsyncQueue } from '../util/AsyncQueue';
|
|||
import { concat, wrapPromise } from '../util/asyncIterables';
|
||||
import type { JobQueueStore, StoredJob } from './types';
|
||||
import { formatJobForInsert } from './formatJobForInsert';
|
||||
import databaseInterface from '../sql/Client';
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
import * as log from '../logging/log';
|
||||
|
||||
type Database = {
|
||||
|
@ -107,6 +107,8 @@ export class JobQueueDatabaseStore implements JobQueueStore {
|
|||
}
|
||||
}
|
||||
|
||||
export const jobQueueDatabaseStore = new JobQueueDatabaseStore(
|
||||
databaseInterface
|
||||
);
|
||||
export const jobQueueDatabaseStore = new JobQueueDatabaseStore({
|
||||
getJobsInQueue: DataReader.getJobsInQueue,
|
||||
insertJob: DataWriter.insertJob,
|
||||
deleteJob: DataWriter.deleteJob,
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@ import * as z from 'zod';
|
|||
import type { LoggerType } from '../types/Logging';
|
||||
import { applyNewAvatar } from '../groups';
|
||||
import { isGroupV2 } from '../util/whatTypeOfConversation';
|
||||
import Data from '../sql/Client';
|
||||
import { DataWriter } from '../sql/Client';
|
||||
|
||||
import type { JOB_STATUS } from './JobQueue';
|
||||
import { JobQueue } from './JobQueue';
|
||||
|
@ -46,7 +46,7 @@ export class GroupAvatarJobQueue extends JobQueue<GroupAvatarJobData> {
|
|||
const patch = await applyNewAvatar(newAvatarUrl, attributes, logId);
|
||||
|
||||
convo.set(patch);
|
||||
await Data.updateConversation(convo.attributes);
|
||||
await DataWriter.updateConversation(convo.attributes);
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
} from './handleMultipleSendErrors';
|
||||
import { ourProfileKeyService } from '../../services/ourProfileKey';
|
||||
import { wrapWithSyncMessageSend } from '../../util/wrapWithSyncMessageSend';
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
|
||||
import type { ConversationModel } from '../../models/conversations';
|
||||
import type {
|
||||
|
@ -302,7 +303,7 @@ async function updateMessageWithSuccessfulSends(
|
|||
deletedForEveryoneSendStatus: {},
|
||||
deletedForEveryoneFailed: undefined,
|
||||
});
|
||||
await window.Signal.Data.saveMessage(message.attributes, {
|
||||
await DataWriter.saveMessage(message.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
|
||||
|
@ -325,7 +326,7 @@ async function updateMessageWithSuccessfulSends(
|
|||
deletedForEveryoneSendStatus,
|
||||
deletedForEveryoneFailed: undefined,
|
||||
});
|
||||
await window.Signal.Data.saveMessage(message.attributes, {
|
||||
await DataWriter.saveMessage(message.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
}
|
||||
|
@ -341,7 +342,7 @@ async function updateMessageWithFailure(
|
|||
);
|
||||
|
||||
message.set({ deletedForEveryoneFailed: true });
|
||||
await window.Signal.Data.saveMessage(message.attributes, {
|
||||
await DataWriter.saveMessage(message.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
maybeExpandErrors,
|
||||
} from './handleMultipleSendErrors';
|
||||
import { ourProfileKeyService } from '../../services/ourProfileKey';
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
|
||||
import type { ConversationModel } from '../../models/conversations';
|
||||
import type {
|
||||
|
@ -277,7 +278,7 @@ async function updateMessageWithSuccessfulSends(
|
|||
deletedForEveryoneSendStatus: {},
|
||||
deletedForEveryoneFailed: undefined,
|
||||
});
|
||||
await window.Signal.Data.saveMessage(message.attributes, {
|
||||
await DataWriter.saveMessage(message.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
|
||||
|
@ -300,7 +301,7 @@ async function updateMessageWithSuccessfulSends(
|
|||
deletedForEveryoneSendStatus,
|
||||
deletedForEveryoneFailed: undefined,
|
||||
});
|
||||
await window.Signal.Data.saveMessage(message.attributes, {
|
||||
await DataWriter.saveMessage(message.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
}
|
||||
|
@ -316,7 +317,7 @@ async function updateMessageWithFailure(
|
|||
);
|
||||
|
||||
message.set({ deletedForEveryoneFailed: true });
|
||||
await window.Signal.Data.saveMessage(message.attributes, {
|
||||
await DataWriter.saveMessage(message.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import { isNumber } from 'lodash';
|
|||
import PQueue from 'p-queue';
|
||||
import { v4 as generateUuid } from 'uuid';
|
||||
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
import * as Errors from '../../types/errors';
|
||||
import { strictAssert } from '../../util/assert';
|
||||
import type { MessageModel } from '../../models/messages';
|
||||
|
@ -650,7 +651,7 @@ async function getMessageSendData({
|
|||
]);
|
||||
|
||||
// Save message after uploading attachments
|
||||
await window.Signal.Data.saveMessage(message.attributes, {
|
||||
await DataWriter.saveMessage(message.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
|
||||
|
@ -1106,7 +1107,7 @@ async function markMessageFailed({
|
|||
}): Promise<void> {
|
||||
message.markFailed(targetTimestamp);
|
||||
void message.saveErrors(errors, { skipSave: true });
|
||||
await window.Signal.Data.saveMessage(message.attributes, {
|
||||
await DataWriter.saveMessage(message.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import type { CallbackResultType } from '../../textsecure/Types.d';
|
|||
import type { MessageModel } from '../../models/messages';
|
||||
import type { MessageReactionType } from '../../model-types.d';
|
||||
import type { ConversationModel } from '../../models/conversations';
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
|
||||
import * as reactionUtil from '../../reactions/util';
|
||||
import { isSent, SendStatus } from '../../messages/MessageSendState';
|
||||
|
@ -86,7 +87,7 @@ export async function sendReaction(
|
|||
if (!canReact(message.attributes, ourConversationId, findAndFormatContact)) {
|
||||
log.info(`could not react to ${messageId}. Removing this pending reaction`);
|
||||
markReactionFailed(message, pendingReaction);
|
||||
await window.Signal.Data.saveMessage(message.attributes, { ourAci });
|
||||
await DataWriter.saveMessage(message.attributes, { ourAci });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -95,7 +96,7 @@ export async function sendReaction(
|
|||
`reacting to message ${messageId} ran out of time. Giving up on sending it`
|
||||
);
|
||||
markReactionFailed(message, pendingReaction);
|
||||
await window.Signal.Data.saveMessage(message.attributes, { ourAci });
|
||||
await DataWriter.saveMessage(message.attributes, { ourAci });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -335,7 +336,7 @@ export async function sendReaction(
|
|||
await reactionMessage.hydrateStoryContext(message.attributes, {
|
||||
shouldSave: false,
|
||||
});
|
||||
await window.Signal.Data.saveMessage(reactionMessage.attributes, {
|
||||
await DataWriter.saveMessage(reactionMessage.attributes, {
|
||||
ourAci,
|
||||
forceSave: true,
|
||||
});
|
||||
|
@ -374,7 +375,7 @@ export async function sendReaction(
|
|||
toThrow: originalError || thrownError,
|
||||
});
|
||||
} finally {
|
||||
await window.Signal.Data.saveMessage(message.attributes, { ourAci });
|
||||
await DataWriter.saveMessage(message.attributes, { ourAci });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import type { ServiceIdString } from '../../types/ServiceId';
|
|||
import type { StoryDistributionIdString } from '../../types/StoryDistributionId';
|
||||
import * as Errors from '../../types/errors';
|
||||
import type { StoryMessageRecipientsType } from '../../types/Stories';
|
||||
import dataInterface from '../../sql/Client';
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import { SignalService as Proto } from '../../protobuf';
|
||||
import { getMessagesById } from '../../messages/getMessagesById';
|
||||
import {
|
||||
|
@ -252,7 +252,7 @@ export async function sendStory(
|
|||
|
||||
const distributionList = isGroupV2(conversation.attributes)
|
||||
? undefined
|
||||
: await dataInterface.getStoryDistributionWithMembers(receiverId);
|
||||
: await DataReader.getStoryDistributionWithMembers(receiverId);
|
||||
|
||||
let messageSendErrors: Array<Error> = [];
|
||||
|
||||
|
@ -541,7 +541,7 @@ export async function sendStory(
|
|||
}
|
||||
|
||||
message.set('sendStateByConversationId', newSendStateByConversationId);
|
||||
return window.Signal.Data.saveMessage(message.attributes, {
|
||||
return DataWriter.saveMessage(message.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
})
|
||||
|
@ -688,7 +688,7 @@ async function markMessageFailed(
|
|||
): Promise<void> {
|
||||
message.markFailed();
|
||||
void message.saveErrors(errors, { skipSave: true });
|
||||
await window.Signal.Data.saveMessage(message.attributes, {
|
||||
await DataWriter.saveMessage(message.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import type { MessageAttributesType } from '../model-types.d';
|
||||
import { getAuthorId } from '../messages/helpers';
|
||||
import { DataReader } from '../sql/Client';
|
||||
import * as log from '../logging/log';
|
||||
import * as Errors from '../types/errors';
|
||||
import { deleteForEveryone } from '../util/deleteForEveryone';
|
||||
|
@ -72,7 +73,7 @@ export async function onDelete(del: DeleteAttributesType): Promise<void> {
|
|||
targetConversation.queueJob('Deletes.onDelete', async () => {
|
||||
log.info(`${logId}: Handling DOE`);
|
||||
|
||||
const messages = await window.Signal.Data.getMessagesBySentAt(
|
||||
const messages = await DataReader.getMessagesBySentAt(
|
||||
del.targetSentTimestamp
|
||||
);
|
||||
|
||||
|
|
|
@ -18,9 +18,9 @@ import {
|
|||
getConversationFromTarget,
|
||||
getMessageQueryFromTarget,
|
||||
} from '../util/deleteForMe';
|
||||
import dataInterface from '../sql/Client';
|
||||
import { DataWriter } from '../sql/Client';
|
||||
|
||||
const { removeSyncTaskById } = dataInterface;
|
||||
const { removeSyncTaskById } = DataWriter;
|
||||
|
||||
export type DeleteForMeAttributesType = {
|
||||
conversation: ConversationToDelete;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import type { MessageAttributesType } from '../model-types.d';
|
||||
import * as Errors from '../types/errors';
|
||||
import * as log from '../logging/log';
|
||||
import { DataReader } from '../sql/Client';
|
||||
import { drop } from '../util/drop';
|
||||
import { getAuthorId } from '../messages/helpers';
|
||||
import { handleEditMessage } from '../util/handleEditMessage';
|
||||
|
@ -117,7 +118,7 @@ export async function onEdit(edit: EditAttributesType): Promise<void> {
|
|||
targetConversation.queueJob('Edits.onEdit', async () => {
|
||||
log.info(`${logId}: Handling edit`);
|
||||
|
||||
const messages = await window.Signal.Data.getMessagesBySentAt(
|
||||
const messages = await DataReader.getMessagesBySentAt(
|
||||
edit.targetSentTimestamp
|
||||
);
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@ import {
|
|||
UNDELIVERED_SEND_STATUSES,
|
||||
sendStateReducer,
|
||||
} from '../messages/MessageSendState';
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
import type { DeleteSentProtoRecipientOptionsType } from '../sql/Interface';
|
||||
import dataInterface from '../sql/Client';
|
||||
import * as log from '../logging/log';
|
||||
import { getSourceServiceId } from '../messages/helpers';
|
||||
import { getMessageSentTimestamp } from '../util/getMessageSentTimestamp';
|
||||
|
@ -31,7 +31,7 @@ import {
|
|||
} from '../types/Receipt';
|
||||
import { drop } from '../util/drop';
|
||||
|
||||
const { deleteSentProtoRecipient, removeSyncTaskById } = dataInterface;
|
||||
const { deleteSentProtoRecipient, removeSyncTaskById } = DataWriter;
|
||||
|
||||
export const messageReceiptTypeSchema = z.enum(['Delivery', 'Read', 'View']);
|
||||
|
||||
|
@ -99,11 +99,11 @@ const processReceiptBatcher = createWaitBatcher({
|
|||
|
||||
const messagesMatchingTimestamp =
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await window.Signal.Data.getMessagesBySentAt(sentAt);
|
||||
await DataReader.getMessagesBySentAt(sentAt);
|
||||
|
||||
if (messagesMatchingTimestamp.length === 0) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const reaction = await window.Signal.Data.getReactionByTimestamp(
|
||||
const reaction = await DataReader.getReactionByTimestamp(
|
||||
window.ConversationController.getOurConversationIdOrThrow(),
|
||||
sentAt
|
||||
);
|
||||
|
|
|
@ -5,6 +5,7 @@ import type { AciString } from '../types/ServiceId';
|
|||
import type { MessageAttributesType } from '../model-types.d';
|
||||
import type { MessageModel } from '../models/messages';
|
||||
import type { ReactionSource } from '../reactions/ReactionSource';
|
||||
import { DataReader } from '../sql/Client';
|
||||
import * as Errors from '../types/errors';
|
||||
import * as log from '../logging/log';
|
||||
import { getAuthor } from '../messages/helpers';
|
||||
|
@ -66,9 +67,7 @@ async function findMessageForReaction({
|
|||
reactionSenderConversationId: string;
|
||||
logId: string;
|
||||
}): Promise<MessageAttributesType | undefined> {
|
||||
const messages = await window.Signal.Data.getMessagesBySentAt(
|
||||
targetTimestamp
|
||||
);
|
||||
const messages = await DataReader.getMessagesBySentAt(targetTimestamp);
|
||||
|
||||
const matchingMessages = messages.filter(message =>
|
||||
isMessageAMatchForReaction({
|
||||
|
|
|
@ -16,9 +16,9 @@ import { notificationService } from '../services/notifications';
|
|||
import { queueUpdateMessage } from '../util/messageBatcher';
|
||||
import { strictAssert } from '../util/assert';
|
||||
import { isAciString } from '../util/isAciString';
|
||||
import dataInterface from '../sql/Client';
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
|
||||
const { removeSyncTaskById } = dataInterface;
|
||||
const { removeSyncTaskById } = DataWriter;
|
||||
|
||||
export const readSyncTaskSchema = z.object({
|
||||
type: z.literal('ReadSync').readonly(),
|
||||
|
@ -51,7 +51,7 @@ async function maybeItIsAReactionReadSync(
|
|||
const { readSync } = sync;
|
||||
const logId = `ReadSyncs.onSync(timestamp=${readSync.timestamp})`;
|
||||
|
||||
const readReaction = await window.Signal.Data.markReactionAsRead(
|
||||
const readReaction = await DataWriter.markReactionAsRead(
|
||||
readSync.senderAci,
|
||||
Number(readSync.timestamp)
|
||||
);
|
||||
|
@ -129,9 +129,7 @@ export async function onSync(sync: ReadSyncAttributesType): Promise<void> {
|
|||
const logId = `ReadSyncs.onSync(timestamp=${readSync.timestamp})`;
|
||||
|
||||
try {
|
||||
const messages = await window.Signal.Data.getMessagesBySentAt(
|
||||
readSync.timestamp
|
||||
);
|
||||
const messages = await DataReader.getMessagesBySentAt(readSync.timestamp);
|
||||
|
||||
const found = messages.find(item => {
|
||||
const sender = window.ConversationController.lookupOrCreate({
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import type { AciString } from '../types/ServiceId';
|
||||
import type { MessageModel } from '../models/messages';
|
||||
import { DataReader } from '../sql/Client';
|
||||
import * as Errors from '../types/errors';
|
||||
import * as log from '../logging/log';
|
||||
import { getMessageIdForLogging } from '../util/idForLogging';
|
||||
|
@ -66,9 +67,7 @@ export async function onSync(
|
|||
const logId = `ViewOnceOpenSyncs.onSync(timestamp=${sync.timestamp})`;
|
||||
|
||||
try {
|
||||
const messages = await window.Signal.Data.getMessagesBySentAt(
|
||||
sync.timestamp
|
||||
);
|
||||
const messages = await DataReader.getMessagesBySentAt(sync.timestamp);
|
||||
|
||||
const found = messages.find(item => {
|
||||
const itemSourceAci = item.sourceServiceId;
|
||||
|
|
|
@ -18,9 +18,7 @@ import { queueAttachmentDownloads } from '../util/queueAttachmentDownloads';
|
|||
import { queueUpdateMessage } from '../util/messageBatcher';
|
||||
import { AttachmentDownloadUrgency } from '../jobs/AttachmentDownloadManager';
|
||||
import { isAciString } from '../util/isAciString';
|
||||
import dataInterface from '../sql/Client';
|
||||
|
||||
const { removeSyncTaskById } = dataInterface;
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
|
||||
export const viewSyncTaskSchema = z.object({
|
||||
type: z.literal('ViewSync').readonly(),
|
||||
|
@ -42,7 +40,7 @@ export type ViewSyncAttributesType = {
|
|||
const viewSyncs = new Map<string, ViewSyncAttributesType>();
|
||||
|
||||
async function remove(sync: ViewSyncAttributesType): Promise<void> {
|
||||
await removeSyncTaskById(sync.syncTaskId);
|
||||
await DataWriter.removeSyncTaskById(sync.syncTaskId);
|
||||
}
|
||||
|
||||
export async function forMessage(
|
||||
|
@ -92,9 +90,7 @@ export async function onSync(sync: ViewSyncAttributesType): Promise<void> {
|
|||
const logId = `ViewSyncs.onSync(timestamp=${viewSync.timestamp})`;
|
||||
|
||||
try {
|
||||
const messages = await window.Signal.Data.getMessagesBySentAt(
|
||||
viewSync.timestamp
|
||||
);
|
||||
const messages = await DataReader.getMessagesBySentAt(viewSync.timestamp);
|
||||
|
||||
const found = messages.find(item => {
|
||||
const sender = window.ConversationController.lookupOrCreate({
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import { omit } from 'lodash';
|
||||
|
||||
import * as log from '../logging/log';
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
import type { QuotedMessageType } from '../model-types';
|
||||
import type { MessageModel } from '../models/messages';
|
||||
import { SignalService } from '../protobuf';
|
||||
|
@ -50,7 +51,7 @@ export const copyFromQuotedMessage = async (
|
|||
queryMessage = matchingMessage;
|
||||
} else {
|
||||
log.info('copyFromQuotedMessage: db lookup needed', id);
|
||||
const messages = await window.Signal.Data.getMessagesBySentAt(id);
|
||||
const messages = await DataReader.getMessagesBySentAt(id);
|
||||
const found = messages.find(item =>
|
||||
isQuoteAMatch(item, conversationId, result)
|
||||
);
|
||||
|
@ -142,7 +143,7 @@ export const copyQuoteContentFromOriginal = async (
|
|||
originalMessage.attributes
|
||||
);
|
||||
originalMessage.set(upgradedMessage);
|
||||
await window.Signal.Data.saveMessage(upgradedMessage, {
|
||||
await DataWriter.saveMessage(upgradedMessage, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import * as log from '../logging/log';
|
||||
import { DataReader } from '../sql/Client';
|
||||
import type { MessageAttributesType } from '../model-types.d';
|
||||
import * as Errors from '../types/errors';
|
||||
import type { MessageModel } from '../models/messages';
|
||||
|
@ -16,7 +17,7 @@ export async function __DEPRECATED$getMessageById(
|
|||
|
||||
let found: MessageAttributesType | undefined;
|
||||
try {
|
||||
found = await window.Signal.Data.getMessageById(messageId);
|
||||
found = await DataReader.getMessageById(messageId);
|
||||
} catch (err: unknown) {
|
||||
log.error(
|
||||
`failed to load message with id ${messageId} ` +
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import * as log from '../logging/log';
|
||||
import { DataReader } from '../sql/Client';
|
||||
import type { MessageModel } from '../models/messages';
|
||||
import type { MessageAttributesType } from '../model-types.d';
|
||||
import * as Errors from '../types/errors';
|
||||
|
@ -23,7 +24,7 @@ export async function getMessagesById(
|
|||
|
||||
let rawMessagesFromDatabase: Array<MessageAttributesType>;
|
||||
try {
|
||||
rawMessagesFromDatabase = await window.Signal.Data.getMessagesById(
|
||||
rawMessagesFromDatabase = await DataReader.getMessagesById(
|
||||
messageIdsToLookUpInDatabase
|
||||
);
|
||||
} catch (err: unknown) {
|
||||
|
|
|
@ -15,6 +15,7 @@ import type {
|
|||
QuotedMessageType,
|
||||
SenderKeyInfoType,
|
||||
} from '../model-types.d';
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
import { getConversation } from '../util/getConversation';
|
||||
import { drop } from '../util/drop';
|
||||
import { isShallowEqual } from '../util/isShallowEqual';
|
||||
|
@ -195,7 +196,6 @@ const {
|
|||
writeNewAttachmentData,
|
||||
} = window.Signal.Migrations;
|
||||
const {
|
||||
addStickerPackReference,
|
||||
getConversationRangeCenteredOnMessage,
|
||||
getOlderMessagesByConversation,
|
||||
getMessageMetricsForConversation,
|
||||
|
@ -203,7 +203,8 @@ const {
|
|||
getMostRecentAddressableMessages,
|
||||
getMostRecentAddressableNondisappearingMessages,
|
||||
getNewerMessagesByConversation,
|
||||
} = window.Signal.Data;
|
||||
} = DataReader;
|
||||
const { addStickerPackReference } = DataWriter;
|
||||
|
||||
const FIVE_MINUTES = MINUTE * 5;
|
||||
const FETCH_TIMEOUT = SECOND * 30;
|
||||
|
@ -471,7 +472,7 @@ export class ConversationModel extends window.Backbone
|
|||
getSenderKeyInfo: () => this.get('senderKeyInfo'),
|
||||
saveSenderKeyInfo: async (senderKeyInfo: SenderKeyInfoType) => {
|
||||
this.set({ senderKeyInfo });
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -828,7 +829,7 @@ export class ConversationModel extends window.Backbone
|
|||
});
|
||||
|
||||
if (shouldSave) {
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
}
|
||||
|
||||
const e164 = this.get('e164');
|
||||
|
@ -882,7 +883,7 @@ export class ConversationModel extends window.Backbone
|
|||
});
|
||||
|
||||
if (shouldSave) {
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -1015,7 +1016,7 @@ export class ConversationModel extends window.Backbone
|
|||
drop(this.queueJob('removeContact', () => this.maybeSetContactRemoved()));
|
||||
|
||||
if (shouldSave) {
|
||||
await window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1048,7 +1049,7 @@ export class ConversationModel extends window.Backbone
|
|||
await this.maybeClearContactRemoved();
|
||||
|
||||
if (shouldSave) {
|
||||
await window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1239,7 +1240,7 @@ export class ConversationModel extends window.Backbone
|
|||
|
||||
this.set({ masterKey, secretParams, publicParams, groupVersion: 2 });
|
||||
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
}
|
||||
|
||||
getGroupV2Info(
|
||||
|
@ -1429,7 +1430,7 @@ export class ConversationModel extends window.Backbone
|
|||
removalStage: 'messageRequest',
|
||||
});
|
||||
await this.maybeClearContactRemoved();
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
}
|
||||
|
||||
void this.addSingleMessage(message);
|
||||
|
@ -1831,7 +1832,7 @@ export class ConversationModel extends window.Backbone
|
|||
const upgradedMessage = await upgradeMessageSchema(attributes);
|
||||
message.set(upgradedMessage);
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await window.Signal.Data.saveMessage(upgradedMessage, { ourAci });
|
||||
await DataWriter.saveMessage(upgradedMessage, { ourAci });
|
||||
upgraded += 1;
|
||||
}
|
||||
}
|
||||
|
@ -1900,7 +1901,7 @@ export class ConversationModel extends window.Backbone
|
|||
void this.addChangeNumberNotification(oldValue, e164);
|
||||
}
|
||||
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
this.trigger('idUpdated', this, 'e164', oldValue);
|
||||
this.captureChange('updateE164');
|
||||
}
|
||||
|
@ -1917,7 +1918,7 @@ export class ConversationModel extends window.Backbone
|
|||
? normalizeServiceId(serviceId, 'Conversation.updateServiceId')
|
||||
: undefined
|
||||
);
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
this.trigger('idUpdated', this, 'serviceId', oldValue);
|
||||
|
||||
// We should delete the old sessions and identity information in all situations except
|
||||
|
@ -1950,7 +1951,7 @@ export class ConversationModel extends window.Backbone
|
|||
this.set({
|
||||
previousIdentityKey: identityKey,
|
||||
});
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
}
|
||||
|
||||
updatePni(pni: PniString | undefined, pniSignatureVerified: boolean): void {
|
||||
|
@ -2025,7 +2026,7 @@ export class ConversationModel extends window.Backbone
|
|||
);
|
||||
}
|
||||
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
this.trigger('idUpdated', this, 'pni', oldValue);
|
||||
this.captureChange('updatePni');
|
||||
}
|
||||
|
@ -2034,7 +2035,7 @@ export class ConversationModel extends window.Backbone
|
|||
const oldValue = this.get('groupId');
|
||||
if (groupId && groupId !== oldValue) {
|
||||
this.set('groupId', groupId);
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
this.trigger('idUpdated', this, 'groupId', oldValue);
|
||||
}
|
||||
}
|
||||
|
@ -2048,14 +2049,14 @@ export class ConversationModel extends window.Backbone
|
|||
}
|
||||
|
||||
this.set('reportingToken', newValue);
|
||||
await window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
}
|
||||
|
||||
incrementMessageCount(): void {
|
||||
this.set({
|
||||
messageCount: (this.get('messageCount') || 0) + 1,
|
||||
});
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
}
|
||||
|
||||
incrementSentMessageCount({ dry = false }: { dry?: boolean } = {}):
|
||||
|
@ -2073,7 +2074,7 @@ export class ConversationModel extends window.Backbone
|
|||
return update;
|
||||
}
|
||||
this.set(update);
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
@ -2093,7 +2094,7 @@ export class ConversationModel extends window.Backbone
|
|||
const first = messages ? messages[0] : undefined;
|
||||
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
messages = await window.Signal.Data.getOlderMessagesByConversation({
|
||||
messages = await DataReader.getOlderMessagesByConversation({
|
||||
conversationId: this.get('id'),
|
||||
includeStoryReplies: !isGroup(this.attributes),
|
||||
limit: 100,
|
||||
|
@ -2143,7 +2144,7 @@ export class ConversationModel extends window.Backbone
|
|||
);
|
||||
const shouldSave = await registered.queueAttachmentDownloads();
|
||||
if (shouldSave) {
|
||||
await window.Signal.Data.saveMessage(registered.attributes, {
|
||||
await DataWriter.saveMessage(registered.attributes, {
|
||||
ourAci,
|
||||
});
|
||||
}
|
||||
|
@ -2178,7 +2179,7 @@ export class ConversationModel extends window.Backbone
|
|||
messageRequestResponseEvent: event,
|
||||
};
|
||||
|
||||
const id = await window.Signal.Data.saveMessage(message, {
|
||||
const id = await DataWriter.saveMessage(message, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
forceSave: true,
|
||||
});
|
||||
|
@ -2358,7 +2359,7 @@ export class ConversationModel extends window.Backbone
|
|||
}
|
||||
} finally {
|
||||
if (shouldSave) {
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2439,7 +2440,7 @@ export class ConversationModel extends window.Backbone
|
|||
messageRequestResponseType: messageRequestEnum.ACCEPT,
|
||||
active_at: this.get('active_at') || Date.now(),
|
||||
});
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
}
|
||||
|
||||
async cancelJoinRequest(): Promise<void> {
|
||||
|
@ -2631,7 +2632,7 @@ export class ConversationModel extends window.Backbone
|
|||
if (oldVerified !== verified) {
|
||||
this.set({ verified });
|
||||
this.captureChange(`updateVerified from=${oldVerified} to=${verified}`);
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -2694,7 +2695,7 @@ export class ConversationModel extends window.Backbone
|
|||
|
||||
this.set({ verified });
|
||||
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
|
||||
if (beginningVerified !== verified) {
|
||||
this.captureChange(
|
||||
|
@ -2938,7 +2939,7 @@ export class ConversationModel extends window.Backbone
|
|||
// this type does not fully implement the interface it is expected to
|
||||
} as unknown as MessageAttributesType;
|
||||
|
||||
const id = await window.Signal.Data.saveMessage(message, {
|
||||
const id = await DataWriter.saveMessage(message, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
const model = window.MessageCache.__DEPRECATED$register(
|
||||
|
@ -2990,7 +2991,7 @@ export class ConversationModel extends window.Backbone
|
|||
// this type does not fully implement the interface it is expected to
|
||||
} as unknown as MessageAttributesType;
|
||||
|
||||
const id = await window.Signal.Data.saveMessage(message, {
|
||||
const id = await DataWriter.saveMessage(message, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
const model = window.MessageCache.__DEPRECATED$register(
|
||||
|
@ -3044,7 +3045,7 @@ export class ConversationModel extends window.Backbone
|
|||
schemaVersion: Message.VERSION_NEEDED_FOR_DISPLAY,
|
||||
};
|
||||
|
||||
await window.Signal.Data.saveMessage(message, {
|
||||
await DataWriter.saveMessage(message, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
forceSave: true,
|
||||
});
|
||||
|
@ -3108,7 +3109,7 @@ export class ConversationModel extends window.Backbone
|
|||
schemaVersion: Message.VERSION_NEEDED_FOR_DISPLAY,
|
||||
};
|
||||
|
||||
const id = await window.Signal.Data.saveMessage(message, {
|
||||
const id = await DataWriter.saveMessage(message, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
forceSave: true,
|
||||
});
|
||||
|
@ -3161,7 +3162,7 @@ export class ConversationModel extends window.Backbone
|
|||
schemaVersion: Message.VERSION_NEEDED_FOR_DISPLAY,
|
||||
};
|
||||
|
||||
const id = await window.Signal.Data.saveMessage(message, {
|
||||
const id = await DataWriter.saveMessage(message, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
forceSave: true,
|
||||
});
|
||||
|
@ -3212,7 +3213,7 @@ export class ConversationModel extends window.Backbone
|
|||
verifiedChanged: verifiedChangeId,
|
||||
};
|
||||
|
||||
await window.Signal.Data.saveMessage(message, {
|
||||
await DataWriter.saveMessage(message, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
forceSave: true,
|
||||
});
|
||||
|
@ -3255,7 +3256,7 @@ export class ConversationModel extends window.Backbone
|
|||
// TODO: DESKTOP-722
|
||||
} as unknown as MessageAttributesType;
|
||||
|
||||
const id = await window.Signal.Data.saveMessage(message, {
|
||||
const id = await DataWriter.saveMessage(message, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
const model = window.MessageCache.__DEPRECATED$register(
|
||||
|
@ -3300,7 +3301,7 @@ export class ConversationModel extends window.Backbone
|
|||
...extra,
|
||||
};
|
||||
|
||||
const id = await window.Signal.Data.saveMessage(
|
||||
const id = await DataWriter.saveMessage(
|
||||
// TODO: DESKTOP-722
|
||||
message as MessageAttributesType,
|
||||
{
|
||||
|
@ -3395,7 +3396,7 @@ export class ConversationModel extends window.Backbone
|
|||
|
||||
const message = window.MessageCache.__DEPRECATED$getById(notificationId);
|
||||
if (message) {
|
||||
await window.Signal.Data.removeMessage(message.id, {
|
||||
await DataWriter.removeMessage(message.id, {
|
||||
singleProtoJobQueue,
|
||||
});
|
||||
}
|
||||
|
@ -3422,7 +3423,7 @@ export class ConversationModel extends window.Backbone
|
|||
'contact-removed-notification'
|
||||
);
|
||||
this.set('pendingRemovedContactNotification', notificationId);
|
||||
await window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
}
|
||||
|
||||
async maybeClearContactRemoved(): Promise<boolean> {
|
||||
|
@ -3438,7 +3439,7 @@ export class ConversationModel extends window.Backbone
|
|||
|
||||
const message = window.MessageCache.__DEPRECATED$getById(notificationId);
|
||||
if (message) {
|
||||
await window.Signal.Data.removeMessage(message.id, {
|
||||
await DataWriter.removeMessage(message.id, {
|
||||
singleProtoJobQueue,
|
||||
});
|
||||
}
|
||||
|
@ -4015,7 +4016,7 @@ export class ConversationModel extends window.Backbone
|
|||
log.info(
|
||||
`enqueueMessageForSend: saving message ${message.id} and job ${jobToInsert.id}`
|
||||
);
|
||||
await window.Signal.Data.saveMessage(message.attributes, {
|
||||
await DataWriter.saveMessage(message.attributes, {
|
||||
jobToInsert,
|
||||
forceSave: true,
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
|
@ -4063,7 +4064,7 @@ export class ConversationModel extends window.Backbone
|
|||
);
|
||||
}
|
||||
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
@ -4127,7 +4128,7 @@ export class ConversationModel extends window.Backbone
|
|||
});
|
||||
}
|
||||
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
this.captureChange('clearUsername');
|
||||
}
|
||||
|
||||
|
@ -4152,7 +4153,7 @@ export class ConversationModel extends window.Backbone
|
|||
this.captureChange('updateUsername');
|
||||
|
||||
if (shouldSave) {
|
||||
await window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4169,7 +4170,7 @@ export class ConversationModel extends window.Backbone
|
|||
|
||||
const conversationId = this.id;
|
||||
|
||||
const stats = await window.Signal.Data.getConversationMessageStats({
|
||||
const stats = await DataReader.getConversationMessageStats({
|
||||
conversationId,
|
||||
includeStoryReplies: !isGroup(this.attributes),
|
||||
});
|
||||
|
@ -4256,14 +4257,14 @@ export class ConversationModel extends window.Backbone
|
|||
: false,
|
||||
});
|
||||
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
}
|
||||
|
||||
setArchived(isArchived: boolean): void {
|
||||
const before = this.get('isArchived');
|
||||
|
||||
this.set({ isArchived });
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
|
||||
const after = this.get('isArchived');
|
||||
|
||||
|
@ -4279,7 +4280,7 @@ export class ConversationModel extends window.Backbone
|
|||
const previousMarkedUnread = this.get('markedUnread');
|
||||
|
||||
this.set({ markedUnread });
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
|
||||
if (Boolean(previousMarkedUnread) !== Boolean(markedUnread)) {
|
||||
this.captureChange('markedUnread');
|
||||
|
@ -4562,7 +4563,7 @@ export class ConversationModel extends window.Backbone
|
|||
// the pending flags.
|
||||
await this.maybeRemoveUniversalTimer();
|
||||
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
|
||||
// When we add a disappearing messages notification to the conversation, we want it
|
||||
// to be above the message that initiated that change, hence the subtraction.
|
||||
|
@ -4596,7 +4597,7 @@ export class ConversationModel extends window.Backbone
|
|||
type: 'timer-notification' as const,
|
||||
};
|
||||
|
||||
await window.Signal.Data.saveMessage(attributes, {
|
||||
await DataWriter.saveMessage(attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
forceSave: true,
|
||||
});
|
||||
|
@ -4655,11 +4656,8 @@ export class ConversationModel extends window.Backbone
|
|||
includeStoryReplies: !isGroup(this.attributes),
|
||||
};
|
||||
const [unreadCount, unreadMentionsCount] = await Promise.all([
|
||||
window.Signal.Data.getTotalUnreadForConversation(this.id, options),
|
||||
window.Signal.Data.getTotalUnreadMentionsOfMeForConversation(
|
||||
this.id,
|
||||
options
|
||||
),
|
||||
DataReader.getTotalUnreadForConversation(this.id, options),
|
||||
DataReader.getTotalUnreadMentionsOfMeForConversation(this.id, options),
|
||||
]);
|
||||
|
||||
const prevUnreadCount = this.get('unreadCount');
|
||||
|
@ -4672,7 +4670,7 @@ export class ConversationModel extends window.Backbone
|
|||
unreadCount,
|
||||
unreadMentionsCount,
|
||||
});
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4870,7 +4868,7 @@ export class ConversationModel extends window.Backbone
|
|||
|
||||
// We will update the conversation during storage service sync
|
||||
if (!viaStorageServiceSync) {
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -4971,7 +4969,7 @@ export class ConversationModel extends window.Backbone
|
|||
|
||||
this.set({ lastProfile: { profileKey, profileKeyVersion } });
|
||||
|
||||
await window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
}
|
||||
|
||||
async removeLastProfile(
|
||||
|
@ -4997,7 +4995,7 @@ export class ConversationModel extends window.Backbone
|
|||
profileAvatar: undefined,
|
||||
});
|
||||
|
||||
await window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
}
|
||||
|
||||
hasMember(serviceId: ServiceIdString): boolean {
|
||||
|
@ -5044,7 +5042,7 @@ export class ConversationModel extends window.Backbone
|
|||
active_at: null,
|
||||
pendingUniversalTimer: undefined,
|
||||
});
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
await DataWriter.updateConversation(this.attributes);
|
||||
|
||||
const ourConversation =
|
||||
window.ConversationController.getOurConversationOrThrow();
|
||||
|
@ -5114,7 +5112,7 @@ export class ConversationModel extends window.Backbone
|
|||
}
|
||||
|
||||
log.info(`${logId}: Starting delete`);
|
||||
await window.Signal.Data.removeMessagesInConversation(this.id, {
|
||||
await DataWriter.removeMessagesInConversation(this.id, {
|
||||
fromSync: source !== 'local-delete-sync',
|
||||
logId: this.idForLogging(),
|
||||
singleProtoJobQueue,
|
||||
|
@ -5227,7 +5225,7 @@ export class ConversationModel extends window.Backbone
|
|||
);
|
||||
this.set({ hideStory });
|
||||
this.captureChange('hideStory');
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
}
|
||||
|
||||
setMuteExpiration(
|
||||
|
@ -5247,7 +5245,7 @@ export class ConversationModel extends window.Backbone
|
|||
|
||||
if (!viaStorageServiceSync) {
|
||||
this.captureChange('mutedUntilTimestamp');
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5572,7 +5570,7 @@ export class ConversationModel extends window.Backbone
|
|||
if (this.get('isArchived')) {
|
||||
this.set({ isArchived: false });
|
||||
}
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
}
|
||||
|
||||
unpin(): void {
|
||||
|
@ -5591,7 +5589,7 @@ export class ConversationModel extends window.Backbone
|
|||
this.writePinnedConversations([...pinnedConversationIds]);
|
||||
|
||||
this.set('isPinned', false);
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
}
|
||||
|
||||
writePinnedConversations(pinnedConversationIds: Array<string>): void {
|
||||
|
@ -5612,7 +5610,7 @@ export class ConversationModel extends window.Backbone
|
|||
}
|
||||
|
||||
this.set({ dontNotifyForMentionsIfMuted: newValue });
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
this.captureChange('dontNotifyForMentionsIfMuted');
|
||||
}
|
||||
|
||||
|
@ -5620,7 +5618,7 @@ export class ConversationModel extends window.Backbone
|
|||
groupNameCollisions: ReadonlyDeep<GroupNameCollisionsWithIdsByTitle>
|
||||
): void {
|
||||
this.set('acknowledgedGroupNameCollisions', groupNameCollisions);
|
||||
window.Signal.Data.updateConversation(this.attributes);
|
||||
drop(DataWriter.updateConversation(this.attributes));
|
||||
}
|
||||
|
||||
onOpenStart(): void {
|
||||
|
|
|
@ -134,7 +134,7 @@ import {
|
|||
addToAttachmentDownloadQueue,
|
||||
shouldUseAttachmentDownloadQueue,
|
||||
} from '../util/attachmentDownloadQueue';
|
||||
import dataInterface from '../sql/Client';
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
import { shouldReplyNotifyUser } from '../util/shouldReplyNotifyUser';
|
||||
import type { RawBodyRange } from '../types/BodyRange';
|
||||
import { BodyRange } from '../types/BodyRange';
|
||||
|
@ -163,7 +163,7 @@ window.Whisper = window.Whisper || {};
|
|||
|
||||
const { Message: TypedMessage } = window.Signal.Types;
|
||||
const { upgradeMessageSchema } = window.Signal.Migrations;
|
||||
const { getMessageBySender } = window.Signal.Data;
|
||||
const { getMessageBySender } = DataReader;
|
||||
|
||||
export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||
CURRENT_PROTOCOL_VERSION?: number;
|
||||
|
@ -459,9 +459,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
isQuoteAMatch(message.attributes, this.get('conversationId'), quote)
|
||||
);
|
||||
if (!matchingMessage) {
|
||||
const messages = await window.Signal.Data.getMessagesBySentAt(
|
||||
Number(sentAt)
|
||||
);
|
||||
const messages = await DataReader.getMessagesBySentAt(Number(sentAt));
|
||||
const found = messages.find(item =>
|
||||
isQuoteAMatch(item, this.get('conversationId'), quote)
|
||||
);
|
||||
|
@ -540,12 +538,12 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
this.getConversation()?.debouncedUpdateLastMessage();
|
||||
|
||||
if (shouldPersist) {
|
||||
await window.Signal.Data.saveMessage(this.attributes, {
|
||||
await DataWriter.saveMessage(this.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
}
|
||||
|
||||
await window.Signal.Data.deleteSentProtoByMessageId(this.id);
|
||||
await DataWriter.deleteSentProtoByMessageId(this.id);
|
||||
}
|
||||
|
||||
override isEmpty(): boolean {
|
||||
|
@ -675,7 +673,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
this.set({ errors });
|
||||
|
||||
if (!skipSave && !this.doNotSave) {
|
||||
await window.Signal.Data.saveMessage(this.attributes, {
|
||||
await DataWriter.saveMessage(this.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
}
|
||||
|
@ -695,7 +693,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
|
||||
if (storyDistributionListId) {
|
||||
const storyDistribution =
|
||||
await dataInterface.getStoryDistributionWithMembers(
|
||||
await DataReader.getStoryDistributionWithMembers(
|
||||
storyDistributionListId
|
||||
);
|
||||
|
||||
|
@ -755,7 +753,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
timestamp: this.attributes.timestamp,
|
||||
},
|
||||
async jobToInsert => {
|
||||
await window.Signal.Data.saveMessage(this.attributes, {
|
||||
await DataWriter.saveMessage(this.attributes, {
|
||||
jobToInsert,
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
|
@ -770,7 +768,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
revision: conversation.get('revision'),
|
||||
},
|
||||
async jobToInsert => {
|
||||
await window.Signal.Data.saveMessage(this.attributes, {
|
||||
await DataWriter.saveMessage(this.attributes, {
|
||||
jobToInsert,
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
|
@ -918,7 +916,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
}
|
||||
|
||||
if (!this.doNotSave) {
|
||||
await window.Signal.Data.saveMessage(this.attributes, {
|
||||
await DataWriter.saveMessage(this.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
}
|
||||
|
@ -1092,7 +1090,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
}
|
||||
|
||||
if (!this.doNotSave) {
|
||||
await window.Signal.Data.saveMessage(this.attributes, {
|
||||
await DataWriter.saveMessage(this.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
}
|
||||
|
@ -1151,7 +1149,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
}
|
||||
throw error;
|
||||
} finally {
|
||||
await window.Signal.Data.saveMessage(this.attributes, {
|
||||
await DataWriter.saveMessage(this.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
|
||||
|
@ -1305,7 +1303,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
return result;
|
||||
}
|
||||
|
||||
await window.Signal.Data.saveMessage(this.attributes, {
|
||||
await DataWriter.saveMessage(this.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
return result;
|
||||
|
@ -1521,7 +1519,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
sendStateByConversationId,
|
||||
unidentifiedDeliveries: [...unidentifiedDeliveriesSet],
|
||||
});
|
||||
await window.Signal.Data.saveMessage(toUpdate.attributes, {
|
||||
await DataWriter.saveMessage(toUpdate.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
|
||||
|
@ -1780,7 +1778,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
|
||||
if (storyDistributionListId) {
|
||||
const storyDistribution =
|
||||
await dataInterface.getStoryDistributionWithMembers(
|
||||
await DataReader.getStoryDistributionWithMembers(
|
||||
storyDistributionListId
|
||||
);
|
||||
|
||||
|
@ -2056,7 +2054,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
conversation.setArchived(false);
|
||||
}
|
||||
|
||||
window.Signal.Data.updateConversation(conversation.attributes);
|
||||
await DataWriter.updateConversation(conversation.attributes);
|
||||
|
||||
const giftBadge = message.get('giftBadge');
|
||||
if (giftBadge) {
|
||||
|
@ -2295,7 +2293,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
shouldSave: false,
|
||||
});
|
||||
// Note: generatedMessage comes with an id, so we have to force this save
|
||||
await window.Signal.Data.saveMessage(generatedMessage.attributes, {
|
||||
await DataWriter.saveMessage(generatedMessage.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
forceSave: true,
|
||||
});
|
||||
|
@ -2320,9 +2318,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
targetConversation.set({
|
||||
active_at: messageToAdd.get('timestamp'),
|
||||
});
|
||||
window.Signal.Data.updateConversation(
|
||||
targetConversation.attributes
|
||||
);
|
||||
await DataWriter.updateConversation(targetConversation.attributes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2414,14 +2410,14 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
}
|
||||
|
||||
if (reaction.remove) {
|
||||
await window.Signal.Data.removeReactionFromConversation({
|
||||
await DataWriter.removeReactionFromConversation({
|
||||
emoji: reaction.emoji,
|
||||
fromId: reaction.fromId,
|
||||
targetAuthorServiceId: reaction.targetAuthorAci,
|
||||
targetTimestamp: reaction.targetTimestamp,
|
||||
});
|
||||
} else {
|
||||
await window.Signal.Data.addReaction(
|
||||
await DataWriter.addReaction(
|
||||
{
|
||||
conversationId: this.get('conversationId'),
|
||||
emoji: reaction.emoji,
|
||||
|
@ -2465,7 +2461,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
await generatedMessage.hydrateStoryContext(this.attributes, {
|
||||
shouldSave: false,
|
||||
});
|
||||
await window.Signal.Data.saveMessage(generatedMessage.attributes, {
|
||||
await DataWriter.saveMessage(generatedMessage.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
forceSave: true,
|
||||
});
|
||||
|
@ -2499,7 +2495,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
jobToInsert.id
|
||||
}`
|
||||
);
|
||||
await window.Signal.Data.saveMessage(this.attributes, {
|
||||
await DataWriter.saveMessage(this.attributes, {
|
||||
jobToInsert,
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
|
@ -2508,7 +2504,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
await conversationJobQueue.add(jobData);
|
||||
}
|
||||
} else if (shouldPersist && !isStory(this.attributes)) {
|
||||
await window.Signal.Data.saveMessage(this.attributes, {
|
||||
await DataWriter.saveMessage(this.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import noop from 'lodash/noop';
|
||||
import { v4 as generateUuid } from 'uuid';
|
||||
|
||||
import { DataWriter } from '../sql/Client';
|
||||
import type { ReactionAttributesType } from '../messageModifiers/Reactions';
|
||||
import { ReactionSource } from './ReactionSource';
|
||||
import { __DEPRECATED$getMessageById } from '../messages/getMessageById';
|
||||
|
@ -63,9 +64,7 @@ export async function enqueueReactionForSend({
|
|||
log.info('Enabling profile sharing for reaction send');
|
||||
if (!messageConversation.get('profileSharing')) {
|
||||
messageConversation.set('profileSharing', true);
|
||||
await window.Signal.Data.updateConversation(
|
||||
messageConversation.attributes
|
||||
);
|
||||
await DataWriter.updateConversation(messageConversation.attributes);
|
||||
}
|
||||
await messageConversation.restoreContact();
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import { throttle } from 'lodash';
|
|||
import LRU from 'lru-cache';
|
||||
import type { MessageAttributesType } from '../model-types.d';
|
||||
import type { MessageModel } from '../models/messages';
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
import * as Errors from '../types/errors';
|
||||
import * as log from '../logging/log';
|
||||
import { getEnvironment, Environment } from '../environment';
|
||||
|
@ -152,7 +153,7 @@ export class MessageCache {
|
|||
|
||||
let messageAttributesFromDatabase: MessageAttributesType | undefined;
|
||||
try {
|
||||
messageAttributesFromDatabase = await window.Signal.Data.getMessageById(
|
||||
messageAttributesFromDatabase = await DataReader.getMessageById(
|
||||
messageId
|
||||
);
|
||||
} catch (err: unknown) {
|
||||
|
@ -260,7 +261,7 @@ export class MessageCache {
|
|||
return;
|
||||
}
|
||||
|
||||
return window.Signal.Data.saveMessage(nextMessageAttributes, {
|
||||
return DataWriter.saveMessage(nextMessageAttributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -9,7 +9,12 @@ import pTimeout from 'p-timeout';
|
|||
import { Readable } from 'stream';
|
||||
|
||||
import { Backups, SignalService } from '../../protobuf';
|
||||
import Data from '../../sql/Client';
|
||||
import {
|
||||
DataReader,
|
||||
DataWriter,
|
||||
pauseWriteAccess,
|
||||
resumeWriteAccess,
|
||||
} from '../../sql/Client';
|
||||
import type { PageMessagesCursorType } from '../../sql/Interface';
|
||||
import * as log from '../../logging/log';
|
||||
import { GiftBadgeStates } from '../../components/conversation/Message';
|
||||
|
@ -183,15 +188,16 @@ export class BackupExportStream extends Readable {
|
|||
(async () => {
|
||||
log.info('BackupExportStream: starting...');
|
||||
drop(AttachmentBackupManager.stop());
|
||||
await Data.pauseWriteAccess();
|
||||
await pauseWriteAccess();
|
||||
try {
|
||||
await this.unsafeRun(backupLevel);
|
||||
} catch (error) {
|
||||
this.emit('error', error);
|
||||
} finally {
|
||||
await Data.resumeWriteAccess();
|
||||
await resumeWriteAccess();
|
||||
|
||||
// TODO (DESKTOP-7344): Clear & add backup jobs in a single transaction
|
||||
await Data.clearAllAttachmentBackupJobs();
|
||||
await DataWriter.clearAllAttachmentBackupJobs();
|
||||
await Promise.all(
|
||||
this.attachmentBackupJobs.map(job =>
|
||||
AttachmentBackupManager.addJobAndMaybeThumbnailJob(job)
|
||||
|
@ -248,7 +254,8 @@ export class BackupExportStream extends Readable {
|
|||
stats.conversations += 1;
|
||||
}
|
||||
|
||||
const distributionLists = await Data.getAllStoryDistributionsWithMembers();
|
||||
const distributionLists =
|
||||
await DataReader.getAllStoryDistributionsWithMembers();
|
||||
|
||||
for (const list of distributionLists) {
|
||||
const { PrivacyMode } = Backups.DistributionList;
|
||||
|
@ -296,7 +303,7 @@ export class BackupExportStream extends Readable {
|
|||
stats.distributionLists += 1;
|
||||
}
|
||||
|
||||
const stickerPacks = await Data.getInstalledStickerPacks();
|
||||
const stickerPacks = await DataReader.getInstalledStickerPacks();
|
||||
|
||||
for (const { id, key } of stickerPacks) {
|
||||
this.pushFrame({
|
||||
|
@ -379,7 +386,9 @@ export class BackupExportStream extends Readable {
|
|||
try {
|
||||
while (!cursor?.done) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const { messages, cursor: newCursor } = await Data.pageMessages(cursor);
|
||||
const { messages, cursor: newCursor } = await DataReader.pageMessages(
|
||||
cursor
|
||||
);
|
||||
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const items = await pMap(
|
||||
|
@ -413,7 +422,7 @@ export class BackupExportStream extends Readable {
|
|||
}
|
||||
} finally {
|
||||
if (cursor !== undefined) {
|
||||
await Data.finishPageMessages(cursor);
|
||||
await DataReader.finishPageMessages(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import { Writable } from 'stream';
|
|||
import { isNumber } from 'lodash';
|
||||
|
||||
import { Backups, SignalService } from '../../protobuf';
|
||||
import Data from '../../sql/Client';
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
import type { StoryDistributionWithMembersType } from '../../sql/Interface';
|
||||
import * as log from '../../logging/log';
|
||||
import { GiftBadgeStates } from '../../components/conversation/Message';
|
||||
|
@ -112,14 +112,14 @@ async function processConversationOpBatch(
|
|||
`updates=${updates.length}`
|
||||
);
|
||||
|
||||
await Data.saveConversations(saves);
|
||||
await Data.updateConversations(updates);
|
||||
await DataWriter.saveConversations(saves);
|
||||
await DataWriter.updateConversations(updates);
|
||||
}
|
||||
async function processMessagesBatch(
|
||||
ourAci: AciString,
|
||||
batch: ReadonlyArray<MessageAttributesType>
|
||||
): Promise<void> {
|
||||
const ids = await Data.saveMessages(batch, {
|
||||
const ids = await DataWriter.saveMessages(batch, {
|
||||
forceSave: true,
|
||||
ourAci,
|
||||
});
|
||||
|
@ -138,7 +138,7 @@ async function processMessagesBatch(
|
|||
|
||||
if (editHistory?.length) {
|
||||
drop(
|
||||
Data.saveEditedMessages(
|
||||
DataWriter.saveEditedMessages(
|
||||
attributes,
|
||||
ourAci,
|
||||
editHistory.slice(0, -1).map(({ timestamp }) => ({
|
||||
|
@ -966,7 +966,7 @@ export class BackupImportStream extends Writable {
|
|||
};
|
||||
}
|
||||
|
||||
await Data.createNewStoryDistribution(result);
|
||||
await DataWriter.createNewStoryDistribution(result);
|
||||
}
|
||||
|
||||
private async fromChat(chat: Backups.IChat): Promise<void> {
|
||||
|
|
|
@ -12,6 +12,7 @@ import { createCipheriv, createHmac, randomBytes } from 'crypto';
|
|||
import { noop } from 'lodash';
|
||||
import { BackupLevel } from '@signalapp/libsignal-client/zkgroup';
|
||||
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import * as log from '../../logging/log';
|
||||
import * as Bytes from '../../Bytes';
|
||||
import { strictAssert } from '../../util/assert';
|
||||
|
@ -187,7 +188,7 @@ export class BackupsService {
|
|||
|
||||
public async fetchAndSaveBackupCdnObjectMetadata(): Promise<void> {
|
||||
log.info('fetchAndSaveBackupCdnObjectMetadata: clearing existing metadata');
|
||||
await window.Signal.Data.clearAllBackupCdnObjectMetadata();
|
||||
await DataWriter.clearAllBackupCdnObjectMetadata();
|
||||
|
||||
let cursor: string | undefined;
|
||||
const PAGE_SIZE = 1000;
|
||||
|
@ -198,7 +199,7 @@ export class BackupsService {
|
|||
const listResult = await this.api.listMedia({ cursor, limit: PAGE_SIZE });
|
||||
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await window.Signal.Data.saveBackupCdnObjectMetadata(
|
||||
await DataWriter.saveBackupCdnObjectMetadata(
|
||||
listResult.storedMediaObjects.map(object => ({
|
||||
mediaId: object.mediaId,
|
||||
cdnNumber: object.cdn,
|
||||
|
@ -220,9 +221,7 @@ export class BackupsService {
|
|||
): Promise<
|
||||
{ isInBackupTier: true; cdnNumber: number } | { isInBackupTier: false }
|
||||
> {
|
||||
const storedInfo = await window.Signal.Data.getBackupCdnObjectMetadata(
|
||||
mediaId
|
||||
);
|
||||
const storedInfo = await DataReader.getBackupCdnObjectMetadata(mediaId);
|
||||
if (!storedInfo) {
|
||||
return { isInBackupTier: false };
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2024 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { DataReader } from '../../../sql/Client';
|
||||
import * as Bytes from '../../../Bytes';
|
||||
import { getBackupKey } from '../crypto';
|
||||
import type { AttachmentType } from '../../../types/Attachment';
|
||||
|
@ -63,9 +64,7 @@ export type GetBackupCdnInfoType = (
|
|||
export const getBackupCdnInfo: GetBackupCdnInfoType = async (
|
||||
mediaId: string
|
||||
) => {
|
||||
const savedInfo = await window.Signal.Data.getBackupCdnObjectMetadata(
|
||||
mediaId
|
||||
);
|
||||
const savedInfo = await DataReader.getBackupCdnObjectMetadata(mediaId);
|
||||
if (!savedInfo) {
|
||||
return { isInBackupTier: false };
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2023 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import dataInterface from '../sql/Client';
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
import type { CallHistoryDetails } from '../types/CallDisposition';
|
||||
import { strictAssert } from '../util/assert';
|
||||
|
||||
|
@ -9,9 +9,9 @@ let callsHistoryData: ReadonlyArray<CallHistoryDetails>;
|
|||
let callsHistoryUnreadCount: number;
|
||||
|
||||
export async function loadCallsHistory(): Promise<void> {
|
||||
await dataInterface.cleanupCallHistoryMessages();
|
||||
callsHistoryData = await dataInterface.getAllCallHistory();
|
||||
callsHistoryUnreadCount = await dataInterface.getCallHistoryUnreadCount();
|
||||
await DataWriter.cleanupCallHistoryMessages();
|
||||
callsHistoryData = await DataReader.getAllCallHistory();
|
||||
callsHistoryUnreadCount = await DataReader.getCallHistoryUnreadCount();
|
||||
}
|
||||
|
||||
export function getCallsHistoryForRedux(): ReadonlyArray<CallHistoryDetails> {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// Copyright 2023 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import dataInterface from '../sql/Client';
|
||||
import { DataReader } from '../sql/Client';
|
||||
import type { CallLinkType } from '../types/CallLink';
|
||||
import { strictAssert } from '../util/assert';
|
||||
|
||||
let callLinksData: ReadonlyArray<CallLinkType>;
|
||||
|
||||
export async function loadCallLinks(): Promise<void> {
|
||||
callLinksData = await dataInterface.getAllCallLinks();
|
||||
callLinksData = await DataReader.getAllCallLinks();
|
||||
}
|
||||
|
||||
export function getCallLinksForRedux(): ReadonlyArray<CallLinkType> {
|
||||
|
|
|
@ -105,7 +105,7 @@ import { callingMessageToProto } from '../util/callingMessageToProto';
|
|||
import { requestMicrophonePermissions } from '../util/requestMicrophonePermissions';
|
||||
import OS from '../util/os/osMain';
|
||||
import { SignalService as Proto } from '../protobuf';
|
||||
import dataInterface from '../sql/Client';
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
import {
|
||||
notificationService,
|
||||
NotificationSetting,
|
||||
|
@ -159,11 +159,11 @@ import type {
|
|||
import { CallLinkRestrictions } from '../types/CallLink';
|
||||
import { getConversationIdForLogging } from '../util/idForLogging';
|
||||
|
||||
const { wasGroupCallRingPreviouslyCanceled } = DataReader;
|
||||
const {
|
||||
processGroupCallRingCancellation,
|
||||
cleanExpiredGroupCallRingCancellations,
|
||||
wasGroupCallRingPreviouslyCanceled,
|
||||
} = dataInterface;
|
||||
} = DataWriter;
|
||||
|
||||
const RINGRTC_HTTP_METHOD_TO_OUR_HTTP_METHOD: Map<
|
||||
HttpMethod,
|
||||
|
@ -933,7 +933,7 @@ export class CallingClass {
|
|||
}
|
||||
|
||||
public async cleanupStaleRingingCalls(): Promise<void> {
|
||||
const calls = await dataInterface.getRecentStaleRingsAndMarkOlderMissed();
|
||||
const calls = await DataWriter.getRecentStaleRingsAndMarkOlderMissed();
|
||||
|
||||
const results = await Promise.all(
|
||||
calls.map(async call => {
|
||||
|
@ -950,7 +950,7 @@ export class CallingClass {
|
|||
return result.callId;
|
||||
});
|
||||
|
||||
await dataInterface.markCallHistoryMissed(staleCallIds);
|
||||
await DataWriter.markCallHistoryMissed(staleCallIds);
|
||||
}
|
||||
|
||||
public async peekGroupCall(conversationId: string): Promise<PeekInfo> {
|
||||
|
@ -3281,11 +3281,10 @@ export class CallingClass {
|
|||
return;
|
||||
}
|
||||
|
||||
const prevMessageId =
|
||||
await window.Signal.Data.getCallHistoryMessageByCallId({
|
||||
conversationId: conversation.id,
|
||||
callId: groupCallMeta.callId,
|
||||
});
|
||||
const prevMessageId = await DataReader.getCallHistoryMessageByCallId({
|
||||
conversationId: conversation.id,
|
||||
callId: groupCallMeta.callId,
|
||||
});
|
||||
|
||||
const isNewCall = prevMessageId == null;
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import PQueue from 'p-queue';
|
||||
|
||||
import { DataWriter } from '../sql/Client';
|
||||
import type { ContactSyncEvent } from '../textsecure/messageReceiverEvents';
|
||||
import type { ContactDetailsWithAvatar } from '../textsecure/ContactsParser';
|
||||
import { normalizeAci } from '../util/normalizeAci';
|
||||
|
@ -167,7 +168,7 @@ async function doContactSync({
|
|||
|
||||
// Save new conversation attributes
|
||||
promises.push(
|
||||
window.Signal.Data.updateConversations(
|
||||
DataWriter.updateConversations(
|
||||
[...updatedConversations, ...notUpdated].map(convo => convo.attributes)
|
||||
)
|
||||
);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import dataInterface from '../sql/Client';
|
||||
import { DataReader } from '../sql/Client';
|
||||
import type { StoryDistributionWithMembersType } from '../sql/Interface';
|
||||
import type { StoryDistributionListDataType } from '../state/ducks/storyDistributionLists';
|
||||
import { strictAssert } from '../util/assert';
|
||||
|
@ -9,7 +9,7 @@ import { strictAssert } from '../util/assert';
|
|||
let distributionLists: Array<StoryDistributionWithMembersType> | undefined;
|
||||
|
||||
export async function loadDistributionLists(): Promise<void> {
|
||||
distributionLists = await dataInterface.getAllStoryDistributionsWithMembers();
|
||||
distributionLists = await DataReader.getAllStoryDistributionsWithMembers();
|
||||
}
|
||||
|
||||
export function getDistributionListsForRedux(): Array<StoryDistributionListDataType> {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import { batch } from 'react-redux';
|
||||
import { debounce } from 'lodash';
|
||||
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
|
||||
import { sleep } from '../util/sleep';
|
||||
import { SECOND } from '../util/durations';
|
||||
|
@ -27,7 +28,7 @@ class ExpiringMessagesDeletionService {
|
|||
window.SignalContext.log.info(
|
||||
'destroyExpiredMessages: Loading messages...'
|
||||
);
|
||||
const messages = await window.Signal.Data.getExpiredMessages();
|
||||
const messages = await DataReader.getExpiredMessages();
|
||||
window.SignalContext.log.info(
|
||||
`destroyExpiredMessages: found ${messages.length} messages to expire`
|
||||
);
|
||||
|
@ -45,7 +46,7 @@ class ExpiringMessagesDeletionService {
|
|||
inMemoryMessages.push(message);
|
||||
});
|
||||
|
||||
await window.Signal.Data.removeMessages(messageIds, {
|
||||
await DataWriter.removeMessages(messageIds, {
|
||||
singleProtoJobQueue: this.singleProtoJobQueue,
|
||||
});
|
||||
|
||||
|
@ -82,7 +83,7 @@ class ExpiringMessagesDeletionService {
|
|||
'checkExpiringMessages: checking for expiring messages'
|
||||
);
|
||||
|
||||
const soonestExpiry = await window.Signal.Data.getSoonestMessageExpiry();
|
||||
const soonestExpiry = await DataReader.getSoonestMessageExpiry();
|
||||
if (!soonestExpiry) {
|
||||
window.SignalContext.log.info(
|
||||
'checkExpiringMessages: found no messages to expire'
|
||||
|
|
|
@ -11,6 +11,7 @@ import type {
|
|||
GetProfileUnauthOptionsType,
|
||||
} from '../textsecure/WebAPI';
|
||||
import type { ServiceIdString } from '../types/ServiceId';
|
||||
import { DataWriter } from '../sql/Client';
|
||||
import * as log from '../logging/log';
|
||||
import * as Errors from '../types/errors';
|
||||
import * as Bytes from '../Bytes';
|
||||
|
@ -594,7 +595,7 @@ async function doGetProfile(c: ConversationModel): Promise<void> {
|
|||
});
|
||||
}
|
||||
|
||||
window.Signal.Data.updateConversation(c.attributes);
|
||||
await DataWriter.updateConversation(c.attributes);
|
||||
}
|
||||
|
||||
export type UpdateIdentityKeyOptionsType = Readonly<{
|
||||
|
|
|
@ -5,7 +5,7 @@ import { debounce, isNumber, chunk } from 'lodash';
|
|||
import pMap from 'p-map';
|
||||
import Long from 'long';
|
||||
|
||||
import dataInterface from '../sql/Client';
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
import * as Bytes from '../Bytes';
|
||||
import {
|
||||
getRandomBytes,
|
||||
|
@ -71,13 +71,14 @@ import { redactExtendedStorageID, redactStorageID } from '../util/privacy';
|
|||
|
||||
type IManifestRecordIdentifier = Proto.ManifestRecord.IIdentifier;
|
||||
|
||||
const { getItemById } = DataReader;
|
||||
|
||||
const {
|
||||
eraseStorageServiceState,
|
||||
flushUpdateConversationBatcher,
|
||||
getItemById,
|
||||
updateConversation,
|
||||
updateConversations,
|
||||
} = dataInterface;
|
||||
} = DataWriter;
|
||||
|
||||
const uploadBucket: Array<number> = [];
|
||||
|
||||
|
@ -319,7 +320,7 @@ async function generateManifest(
|
|||
storageVersion: version,
|
||||
storageID,
|
||||
});
|
||||
updateConversation(conversation.attributes);
|
||||
drop(updateConversation(conversation.attributes));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -360,7 +361,7 @@ async function generateManifest(
|
|||
);
|
||||
deleteKeys.add(droppedID);
|
||||
|
||||
drop(dataInterface.deleteStoryDistribution(storyDistributionList.id));
|
||||
drop(DataWriter.deleteStoryDistribution(storyDistributionList.id));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -374,7 +375,7 @@ async function generateManifest(
|
|||
|
||||
if (isNewItem) {
|
||||
postUploadUpdateFunctions.push(() => {
|
||||
void dataInterface.modifyStoryDistribution({
|
||||
void DataWriter.modifyStoryDistribution({
|
||||
...storyDistributionList,
|
||||
storageID,
|
||||
storageVersion: version,
|
||||
|
@ -407,7 +408,7 @@ async function generateManifest(
|
|||
|
||||
if (isNewItem) {
|
||||
postUploadUpdateFunctions.push(() => {
|
||||
void dataInterface.addUninstalledStickerPack({
|
||||
void DataWriter.addUninstalledStickerPack({
|
||||
...stickerPack,
|
||||
storageID,
|
||||
storageVersion: version,
|
||||
|
@ -449,7 +450,7 @@ async function generateManifest(
|
|||
|
||||
if (isNewItem) {
|
||||
postUploadUpdateFunctions.push(() => {
|
||||
void dataInterface.createOrUpdateStickerPack({
|
||||
void DataWriter.createOrUpdateStickerPack({
|
||||
...stickerPack,
|
||||
storageID,
|
||||
storageVersion: version,
|
||||
|
@ -1088,9 +1089,9 @@ async function getNonConversationRecords(): Promise<NonConversationRecordsResult
|
|||
uninstalledStickerPacks,
|
||||
installedStickerPacks,
|
||||
] = await Promise.all([
|
||||
dataInterface.getAllStoryDistributionsWithMembers(),
|
||||
dataInterface.getUninstalledStickerPacks(),
|
||||
dataInterface.getInstalledStickerPacks(),
|
||||
DataReader.getAllStoryDistributionsWithMembers(),
|
||||
DataReader.getUninstalledStickerPacks(),
|
||||
DataReader.getInstalledStickerPacks(),
|
||||
]);
|
||||
|
||||
return {
|
||||
|
@ -1256,7 +1257,7 @@ async function processManifest(
|
|||
}
|
||||
conversation.unset('storageID');
|
||||
conversation.unset('storageVersion');
|
||||
updateConversation(conversation.attributes);
|
||||
drop(updateConversation(conversation.attributes));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1279,7 +1280,7 @@ async function processManifest(
|
|||
`storageService.process(${version}): localKey=${missingKey} was not ` +
|
||||
'in remote manifest'
|
||||
);
|
||||
void dataInterface.addUninstalledStickerPack({
|
||||
void DataWriter.addUninstalledStickerPack({
|
||||
...stickerPack,
|
||||
storageID: undefined,
|
||||
storageVersion: undefined,
|
||||
|
@ -1297,7 +1298,7 @@ async function processManifest(
|
|||
`storageService.process(${version}): localKey=${missingKey} was not ` +
|
||||
'in remote manifest'
|
||||
);
|
||||
void dataInterface.createOrUpdateStickerPack({
|
||||
void DataWriter.createOrUpdateStickerPack({
|
||||
...stickerPack,
|
||||
storageID: undefined,
|
||||
storageVersion: undefined,
|
||||
|
@ -1315,7 +1316,7 @@ async function processManifest(
|
|||
`storageService.process(${version}): localKey=${missingKey} was not ` +
|
||||
'in remote manifest'
|
||||
);
|
||||
void dataInterface.modifyStoryDistribution({
|
||||
void DataWriter.modifyStoryDistribution({
|
||||
...storyDistributionList,
|
||||
storageID: undefined,
|
||||
storageVersion: undefined,
|
||||
|
@ -1339,7 +1340,7 @@ async function processManifest(
|
|||
storageNeedsSync: true,
|
||||
};
|
||||
|
||||
await dataInterface.createNewStoryDistribution(storyDistribution);
|
||||
await DataWriter.createNewStoryDistribution(storyDistribution);
|
||||
|
||||
const shouldSave = false;
|
||||
window.reduxActions.storyDistributionLists.createDistributionList(
|
||||
|
|
|
@ -59,7 +59,7 @@ import type {
|
|||
StoryDistributionWithMembersType,
|
||||
StickerPackInfoType,
|
||||
} from '../sql/Interface';
|
||||
import dataInterface from '../sql/Client';
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
import { MY_STORY_ID, StorySendMode } from '../types/Stories';
|
||||
import { findAndDeleteOnboardingStoryIfExists } from '../util/findAndDeleteOnboardingStoryIfExists';
|
||||
import { downloadOnboardingStory } from '../util/downloadOnboardingStory';
|
||||
|
@ -1682,7 +1682,7 @@ export async function mergeStoryDistributionListRecord(
|
|||
}
|
||||
|
||||
const localStoryDistributionList =
|
||||
await dataInterface.getStoryDistributionWithMembers(listId);
|
||||
await DataReader.getStoryDistributionWithMembers(listId);
|
||||
|
||||
const remoteListMembers: Array<ServiceIdString> = (
|
||||
storyDistributionListRecord.recipientServiceIds || []
|
||||
|
@ -1714,7 +1714,7 @@ export async function mergeStoryDistributionListRecord(
|
|||
};
|
||||
|
||||
if (!localStoryDistributionList) {
|
||||
await dataInterface.createNewStoryDistribution(storyDistribution);
|
||||
await DataWriter.createNewStoryDistribution(storyDistribution);
|
||||
|
||||
const shouldSave = false;
|
||||
window.reduxActions.storyDistributionLists.createDistributionList(
|
||||
|
@ -1766,7 +1766,7 @@ export async function mergeStoryDistributionListRecord(
|
|||
);
|
||||
|
||||
details.push('updated');
|
||||
await dataInterface.modifyStoryDistributionWithMembers(storyDistribution, {
|
||||
await DataWriter.modifyStoryDistributionWithMembers(storyDistribution, {
|
||||
toAdd,
|
||||
toRemove,
|
||||
});
|
||||
|
@ -1804,7 +1804,7 @@ export async function mergeStickerPackRecord(
|
|||
const details: Array<string> = [];
|
||||
const id = Bytes.toHex(stickerPackRecord.packId);
|
||||
|
||||
const localStickerPack = await dataInterface.getStickerPackInfo(id);
|
||||
const localStickerPack = await DataReader.getStickerPackInfo(id);
|
||||
|
||||
if (stickerPackRecord.$unknownFields) {
|
||||
details.push('adding unknown fields');
|
||||
|
@ -1897,7 +1897,7 @@ export async function mergeStickerPackRecord(
|
|||
}
|
||||
}
|
||||
|
||||
await dataInterface.updateStickerPackInfo(stickerPack);
|
||||
await DataWriter.updateStickerPackInfo(stickerPack);
|
||||
|
||||
return {
|
||||
details: [...details, ...conflictDetails],
|
||||
|
|
|
@ -6,7 +6,7 @@ import type { MessageAttributesType } from '../model-types.d';
|
|||
import type { StoryDataType } from '../state/ducks/stories';
|
||||
import * as durations from '../util/durations';
|
||||
import * as log from '../logging/log';
|
||||
import dataInterface from '../sql/Client';
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
import type { GetAllStoriesResultType } from '../sql/Interface';
|
||||
import {
|
||||
getAttachmentsForMessage,
|
||||
|
@ -22,7 +22,7 @@ import { SIGNAL_ACI } from '../types/SignalConversation';
|
|||
let storyData: GetAllStoriesResultType | undefined;
|
||||
|
||||
export async function loadStories(): Promise<void> {
|
||||
storyData = await dataInterface.getAllStories({});
|
||||
storyData = await DataReader.getAllStories({});
|
||||
|
||||
await repairUnexpiredStories();
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ async function repairUnexpiredStories(): Promise<void> {
|
|||
|
||||
await Promise.all(
|
||||
storiesWithExpiry.map(messageAttributes => {
|
||||
return window.Signal.Data.saveMessage(messageAttributes, {
|
||||
return DataWriter.saveMessage(messageAttributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
});
|
||||
})
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { debounce } from 'lodash';
|
||||
import { DataReader } from '../sql/Client';
|
||||
import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
|
||||
import { DAY } from '../util/durations';
|
||||
import * as Errors from '../types/errors';
|
||||
|
@ -11,8 +12,7 @@ async function eraseTapToViewMessages() {
|
|||
window.SignalContext.log.info(
|
||||
'eraseTapToViewMessages: Loading messages...'
|
||||
);
|
||||
const messages =
|
||||
await window.Signal.Data.getTapToViewMessagesNeedingErase();
|
||||
const messages = await DataReader.getTapToViewMessagesNeedingErase();
|
||||
await Promise.all(
|
||||
messages.map(async fromDB => {
|
||||
const message = window.MessageCache.__DEPRECATED$register(
|
||||
|
@ -54,7 +54,7 @@ class TapToViewMessagesDeletionService {
|
|||
|
||||
private async checkTapToViewMessages() {
|
||||
const receivedAt =
|
||||
await window.Signal.Data.getNextTapToViewMessageTimestampToAgeOut();
|
||||
await DataReader.getNextTapToViewMessageTimestampToAgeOut();
|
||||
if (!receivedAt) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import dataInterface from '../sql/Client';
|
||||
import { DataWriter } from '../sql/Client';
|
||||
import type { ConversationType } from '../state/ducks/conversations';
|
||||
import * as Errors from '../types/errors';
|
||||
import * as log from '../logging/log';
|
||||
|
@ -134,7 +134,7 @@ export async function writeProfile(
|
|||
...maybeProfileAvatarUpdate,
|
||||
});
|
||||
|
||||
dataInterface.updateConversation(model.attributes);
|
||||
await DataWriter.updateConversation(model.attributes);
|
||||
model.captureChange('writeProfile');
|
||||
|
||||
try {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import * as log from '../logging/log';
|
||||
import { DataWriter } from '../sql/Client';
|
||||
import { deleteAllLogs } from '../util/deleteAllLogs';
|
||||
import * as Errors from '../types/errors';
|
||||
|
||||
|
@ -11,19 +12,19 @@ export async function deleteAllData(): Promise<void> {
|
|||
|
||||
log.info('deleteAllData: deleted all logs');
|
||||
|
||||
await window.Signal.Data.removeAll();
|
||||
await DataWriter.removeAll();
|
||||
|
||||
log.info('deleteAllData: emptied database');
|
||||
|
||||
await window.Signal.Data.close();
|
||||
await DataWriter.close();
|
||||
|
||||
log.info('deleteAllData: closed database');
|
||||
|
||||
await window.Signal.Data.removeDB();
|
||||
await DataWriter.removeDB();
|
||||
|
||||
log.info('deleteAllData: removed database');
|
||||
|
||||
await window.Signal.Data.removeOtherData();
|
||||
await DataWriter.removeOtherData();
|
||||
|
||||
log.info('deleteAllData: removed all other data');
|
||||
} catch (error) {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
import * as Crypto from './Crypto';
|
||||
import * as Curve from './Curve';
|
||||
import { start as conversationControllerStart } from './ConversationController';
|
||||
import Data from './sql/Client';
|
||||
import * as Groups from './groups';
|
||||
import OS from './util/os/osMain';
|
||||
import * as RemoteConfig from './RemoteConfig';
|
||||
|
@ -455,7 +454,6 @@ export const setup = (options: {
|
|||
Curve,
|
||||
// Note: used in test/index.html, and not type-checked!
|
||||
conversationControllerStart,
|
||||
Data,
|
||||
Groups,
|
||||
Migrations,
|
||||
OS,
|
||||
|
|
224
ts/sql/Client.ts
224
ts/sql/Client.ts
|
@ -3,7 +3,7 @@
|
|||
|
||||
import { ipcRenderer as ipc } from 'electron';
|
||||
|
||||
import { has, get, groupBy, isTypedArray, last, map, omit } from 'lodash';
|
||||
import { groupBy, isTypedArray, last, map, omit } from 'lodash';
|
||||
|
||||
import { deleteExternalFiles } from '../types/Conversation';
|
||||
import { update as updateExpiringMessagesService } from '../services/expiringMessagesDeletion';
|
||||
|
@ -23,13 +23,16 @@ import * as Errors from '../types/errors';
|
|||
import type { StoredJob } from '../jobs/types';
|
||||
import { formatJobForInsert } from '../jobs/formatJobForInsert';
|
||||
import { cleanupMessages } from '../util/cleanup';
|
||||
import { ipcInvoke, doShutdown } from './channels';
|
||||
import { AccessType, ipcInvoke, doShutdown } from './channels';
|
||||
|
||||
import type {
|
||||
ClientInterfaceWrap,
|
||||
AdjacentMessagesByConversationOptionsType,
|
||||
AllItemsType,
|
||||
ClientInterface,
|
||||
ClientExclusiveInterface,
|
||||
ServerReadableDirectInterface,
|
||||
ServerWritableDirectInterface,
|
||||
ClientReadableInterface,
|
||||
ClientWritableInterface,
|
||||
ClientSearchResultMessageType,
|
||||
ConversationType,
|
||||
GetConversationRangeCenteredOnMessageResultType,
|
||||
|
@ -45,13 +48,14 @@ import type {
|
|||
PreKeyIdType,
|
||||
PreKeyType,
|
||||
StoredPreKeyType,
|
||||
ServerInterface,
|
||||
ServerSearchResultMessageType,
|
||||
SignedPreKeyIdType,
|
||||
SignedPreKeyType,
|
||||
StoredSignedPreKeyType,
|
||||
KyberPreKeyType,
|
||||
StoredKyberPreKeyType,
|
||||
ClientOnlyReadableInterface,
|
||||
ClientOnlyWritableInterface,
|
||||
} from './Interface';
|
||||
import { getMessageIdForLogging } from '../util/idForLogging';
|
||||
import type { MessageAttributesType } from '../model-types';
|
||||
|
@ -67,44 +71,54 @@ const ERASE_TEMP_KEY = 'erase-temp';
|
|||
const ERASE_DRAFTS_KEY = 'erase-drafts';
|
||||
const CLEANUP_ORPHANED_ATTACHMENTS_KEY = 'cleanup-orphaned-attachments';
|
||||
const ENSURE_FILE_PERMISSIONS = 'ensure-file-permissions';
|
||||
const PAUSE_WRITE_ACCESS = 'pause-sql-writes';
|
||||
const RESUME_WRITE_ACCESS = 'resume-sql-writes';
|
||||
|
||||
const exclusiveInterface: ClientExclusiveInterface = {
|
||||
createOrUpdateIdentityKey,
|
||||
const clientOnlyReadable: ClientOnlyReadableInterface = {
|
||||
getIdentityKeyById,
|
||||
bulkAddIdentityKeys,
|
||||
getAllIdentityKeys,
|
||||
|
||||
createOrUpdateKyberPreKey,
|
||||
getKyberPreKeyById,
|
||||
bulkAddKyberPreKeys,
|
||||
getAllKyberPreKeys,
|
||||
|
||||
createOrUpdatePreKey,
|
||||
getPreKeyById,
|
||||
bulkAddPreKeys,
|
||||
getAllPreKeys,
|
||||
|
||||
createOrUpdateSignedPreKey,
|
||||
getSignedPreKeyById,
|
||||
bulkAddSignedPreKeys,
|
||||
getAllSignedPreKeys,
|
||||
|
||||
createOrUpdateItem,
|
||||
getItemById,
|
||||
getAllItems,
|
||||
|
||||
searchMessages,
|
||||
|
||||
getRecentStoryReplies,
|
||||
getOlderMessagesByConversation,
|
||||
getNewerMessagesByConversation,
|
||||
getConversationRangeCenteredOnMessage,
|
||||
};
|
||||
|
||||
const clientOnlyWritable: ClientOnlyWritableInterface = {
|
||||
createOrUpdateIdentityKey,
|
||||
bulkAddIdentityKeys,
|
||||
|
||||
createOrUpdateKyberPreKey,
|
||||
bulkAddKyberPreKeys,
|
||||
|
||||
createOrUpdatePreKey,
|
||||
bulkAddPreKeys,
|
||||
|
||||
createOrUpdateSignedPreKey,
|
||||
bulkAddSignedPreKeys,
|
||||
|
||||
createOrUpdateItem,
|
||||
|
||||
updateConversation,
|
||||
removeConversation,
|
||||
|
||||
searchMessages,
|
||||
removeMessage,
|
||||
removeMessages,
|
||||
|
||||
getRecentStoryReplies,
|
||||
getOlderMessagesByConversation,
|
||||
getConversationRangeCenteredOnMessage,
|
||||
getNewerMessagesByConversation,
|
||||
|
||||
// Client-side only
|
||||
|
||||
flushUpdateConversationBatcher,
|
||||
|
@ -117,48 +131,82 @@ const exclusiveInterface: ClientExclusiveInterface = {
|
|||
ensureFilePermissions,
|
||||
};
|
||||
|
||||
type ClientOverridesType = ClientExclusiveInterface &
|
||||
type ClientOverridesType = ClientOnlyWritableInterface &
|
||||
Pick<
|
||||
ServerInterface,
|
||||
ClientInterfaceWrap<ServerWritableDirectInterface>,
|
||||
| 'saveAttachmentDownloadJob'
|
||||
| 'saveMessage'
|
||||
| 'saveMessages'
|
||||
| 'updateConversations'
|
||||
>;
|
||||
|
||||
const channels: ServerInterface = new Proxy({} as ServerInterface, {
|
||||
get(_target, name) {
|
||||
return async (...args: ReadonlyArray<unknown>) =>
|
||||
ipcInvoke(String(name), args);
|
||||
},
|
||||
});
|
||||
|
||||
const clientExclusiveOverrides: ClientOverridesType = {
|
||||
...exclusiveInterface,
|
||||
const clientOnlyWritableOverrides: ClientOverridesType = {
|
||||
...clientOnlyWritable,
|
||||
saveAttachmentDownloadJob,
|
||||
saveMessage,
|
||||
saveMessages,
|
||||
updateConversations,
|
||||
};
|
||||
|
||||
const dataInterface: ClientInterface = new Proxy(
|
||||
type ReadableChannelInterface =
|
||||
ClientInterfaceWrap<ServerReadableDirectInterface>;
|
||||
|
||||
const readableChannel: ReadableChannelInterface = new Proxy(
|
||||
{} as ReadableChannelInterface,
|
||||
{
|
||||
...clientExclusiveOverrides,
|
||||
} as ClientInterface,
|
||||
get(_target, name) {
|
||||
return async (...args: ReadonlyArray<unknown>) =>
|
||||
ipcInvoke(AccessType.Read, String(name), args);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
type WritableChannelInterface =
|
||||
ClientInterfaceWrap<ServerWritableDirectInterface>;
|
||||
|
||||
const writableChannel: WritableChannelInterface = new Proxy(
|
||||
{} as WritableChannelInterface,
|
||||
{
|
||||
get(_target, name) {
|
||||
return async (...args: ReadonlyArray<unknown>) =>
|
||||
ipcInvoke(AccessType.Write, String(name), args);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
export const DataReader: ClientReadableInterface = new Proxy(
|
||||
{
|
||||
...clientOnlyReadable,
|
||||
} as ClientReadableInterface,
|
||||
{
|
||||
get(target, name) {
|
||||
return async (...args: ReadonlyArray<unknown>) => {
|
||||
if (has(target, name)) {
|
||||
return get(target, name)(...args);
|
||||
if (Reflect.has(target, name)) {
|
||||
return Reflect.get(target, name)(...args);
|
||||
}
|
||||
|
||||
return get(channels, name)(...args);
|
||||
return Reflect.get(readableChannel, name)(...args);
|
||||
};
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
export default dataInterface;
|
||||
export const DataWriter: ClientWritableInterface = new Proxy(
|
||||
{
|
||||
...clientOnlyWritableOverrides,
|
||||
} as ClientWritableInterface,
|
||||
{
|
||||
get(target, name) {
|
||||
return async (...args: ReadonlyArray<unknown>) => {
|
||||
if (Reflect.has(target, name)) {
|
||||
return Reflect.get(target, name)(...args);
|
||||
}
|
||||
|
||||
return Reflect.get(writableChannel, name)(...args);
|
||||
};
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
function _cleanData(
|
||||
data: unknown
|
||||
|
@ -246,9 +294,6 @@ async function shutdown(): Promise<void> {
|
|||
|
||||
// Stop accepting new SQL jobs, flush outstanding queue
|
||||
await doShutdown();
|
||||
|
||||
// Close database
|
||||
await channels.close();
|
||||
}
|
||||
|
||||
// Identity Keys
|
||||
|
@ -256,12 +301,12 @@ async function shutdown(): Promise<void> {
|
|||
const IDENTITY_KEY_SPEC = ['publicKey'];
|
||||
async function createOrUpdateIdentityKey(data: IdentityKeyType): Promise<void> {
|
||||
const updated: StoredIdentityKeyType = specFromBytes(IDENTITY_KEY_SPEC, data);
|
||||
await channels.createOrUpdateIdentityKey(updated);
|
||||
await writableChannel.createOrUpdateIdentityKey(updated);
|
||||
}
|
||||
async function getIdentityKeyById(
|
||||
id: IdentityKeyIdType
|
||||
): Promise<IdentityKeyType | undefined> {
|
||||
const data = await channels.getIdentityKeyById(id);
|
||||
const data = await readableChannel.getIdentityKeyById(id);
|
||||
|
||||
return specToBytes(IDENTITY_KEY_SPEC, data);
|
||||
}
|
||||
|
@ -271,10 +316,10 @@ async function bulkAddIdentityKeys(
|
|||
const updated: Array<StoredIdentityKeyType> = map(array, data =>
|
||||
specFromBytes(IDENTITY_KEY_SPEC, data)
|
||||
);
|
||||
await channels.bulkAddIdentityKeys(updated);
|
||||
await writableChannel.bulkAddIdentityKeys(updated);
|
||||
}
|
||||
async function getAllIdentityKeys(): Promise<Array<IdentityKeyType>> {
|
||||
const keys = await channels.getAllIdentityKeys();
|
||||
const keys = await readableChannel.getAllIdentityKeys();
|
||||
|
||||
return keys.map(key => specToBytes(IDENTITY_KEY_SPEC, key));
|
||||
}
|
||||
|
@ -287,12 +332,12 @@ async function createOrUpdateKyberPreKey(data: KyberPreKeyType): Promise<void> {
|
|||
KYBER_PRE_KEY_SPEC,
|
||||
data
|
||||
);
|
||||
await channels.createOrUpdateKyberPreKey(updated);
|
||||
await writableChannel.createOrUpdateKyberPreKey(updated);
|
||||
}
|
||||
async function getKyberPreKeyById(
|
||||
id: PreKeyIdType
|
||||
): Promise<KyberPreKeyType | undefined> {
|
||||
const data = await channels.getPreKeyById(id);
|
||||
const data = await readableChannel.getPreKeyById(id);
|
||||
|
||||
return specToBytes(KYBER_PRE_KEY_SPEC, data);
|
||||
}
|
||||
|
@ -302,10 +347,10 @@ async function bulkAddKyberPreKeys(
|
|||
const updated: Array<StoredKyberPreKeyType> = map(array, data =>
|
||||
specFromBytes(KYBER_PRE_KEY_SPEC, data)
|
||||
);
|
||||
await channels.bulkAddKyberPreKeys(updated);
|
||||
await writableChannel.bulkAddKyberPreKeys(updated);
|
||||
}
|
||||
async function getAllKyberPreKeys(): Promise<Array<KyberPreKeyType>> {
|
||||
const keys = await channels.getAllKyberPreKeys();
|
||||
const keys = await readableChannel.getAllKyberPreKeys();
|
||||
|
||||
return keys.map(key => specToBytes(KYBER_PRE_KEY_SPEC, key));
|
||||
}
|
||||
|
@ -314,12 +359,12 @@ async function getAllKyberPreKeys(): Promise<Array<KyberPreKeyType>> {
|
|||
|
||||
async function createOrUpdatePreKey(data: PreKeyType): Promise<void> {
|
||||
const updated: StoredPreKeyType = specFromBytes(PRE_KEY_SPEC, data);
|
||||
await channels.createOrUpdatePreKey(updated);
|
||||
await writableChannel.createOrUpdatePreKey(updated);
|
||||
}
|
||||
async function getPreKeyById(
|
||||
id: PreKeyIdType
|
||||
): Promise<PreKeyType | undefined> {
|
||||
const data = await channels.getPreKeyById(id);
|
||||
const data = await readableChannel.getPreKeyById(id);
|
||||
|
||||
return specToBytes(PRE_KEY_SPEC, data);
|
||||
}
|
||||
|
@ -327,10 +372,10 @@ async function bulkAddPreKeys(array: Array<PreKeyType>): Promise<void> {
|
|||
const updated: Array<StoredPreKeyType> = map(array, data =>
|
||||
specFromBytes(PRE_KEY_SPEC, data)
|
||||
);
|
||||
await channels.bulkAddPreKeys(updated);
|
||||
await writableChannel.bulkAddPreKeys(updated);
|
||||
}
|
||||
async function getAllPreKeys(): Promise<Array<PreKeyType>> {
|
||||
const keys = await channels.getAllPreKeys();
|
||||
const keys = await readableChannel.getAllPreKeys();
|
||||
|
||||
return keys.map(key => specToBytes(PRE_KEY_SPEC, key));
|
||||
}
|
||||
|
@ -342,17 +387,17 @@ async function createOrUpdateSignedPreKey(
|
|||
data: SignedPreKeyType
|
||||
): Promise<void> {
|
||||
const updated: StoredSignedPreKeyType = specFromBytes(PRE_KEY_SPEC, data);
|
||||
await channels.createOrUpdateSignedPreKey(updated);
|
||||
await writableChannel.createOrUpdateSignedPreKey(updated);
|
||||
}
|
||||
async function getSignedPreKeyById(
|
||||
id: SignedPreKeyIdType
|
||||
): Promise<SignedPreKeyType | undefined> {
|
||||
const data = await channels.getSignedPreKeyById(id);
|
||||
const data = await readableChannel.getSignedPreKeyById(id);
|
||||
|
||||
return specToBytes(PRE_KEY_SPEC, data);
|
||||
}
|
||||
async function getAllSignedPreKeys(): Promise<Array<SignedPreKeyType>> {
|
||||
const keys = await channels.getAllSignedPreKeys();
|
||||
const keys = await readableChannel.getAllSignedPreKeys();
|
||||
|
||||
return keys.map(key => specToBytes(PRE_KEY_SPEC, key));
|
||||
}
|
||||
|
@ -362,7 +407,7 @@ async function bulkAddSignedPreKeys(
|
|||
const updated: Array<StoredSignedPreKeyType> = map(array, data =>
|
||||
specFromBytes(PRE_KEY_SPEC, data)
|
||||
);
|
||||
await channels.bulkAddSignedPreKeys(updated);
|
||||
await writableChannel.bulkAddSignedPreKeys(updated);
|
||||
}
|
||||
|
||||
// Items
|
||||
|
@ -398,13 +443,13 @@ async function createOrUpdateItem<K extends ItemKeyType>(
|
|||
? specFromBytes(spec, data)
|
||||
: (data as unknown as StoredItemType<K>);
|
||||
|
||||
await channels.createOrUpdateItem(updated);
|
||||
await writableChannel.createOrUpdateItem(updated);
|
||||
}
|
||||
async function getItemById<K extends ItemKeyType>(
|
||||
id: K
|
||||
): Promise<ItemType<K> | undefined> {
|
||||
const spec = ITEM_SPECS[id];
|
||||
const data = await channels.getItemById(id);
|
||||
const data = await readableChannel.getItemById(id);
|
||||
|
||||
try {
|
||||
return spec ? specToBytes(spec, data) : (data as unknown as ItemType<K>);
|
||||
|
@ -414,7 +459,7 @@ async function getItemById<K extends ItemKeyType>(
|
|||
}
|
||||
}
|
||||
async function getAllItems(): Promise<AllItemsType> {
|
||||
const items = await channels.getAllItems();
|
||||
const items = await readableChannel.getAllItems();
|
||||
|
||||
const result = Object.create(null);
|
||||
|
||||
|
@ -458,7 +503,7 @@ const updateConversationBatcher = createBatcher<ConversationType>({
|
|||
},
|
||||
});
|
||||
|
||||
function updateConversation(data: ConversationType): void {
|
||||
async function updateConversation(data: ConversationType): Promise<void> {
|
||||
updateConversationBatcher.add(data);
|
||||
}
|
||||
async function flushUpdateConversationBatcher(): Promise<void> {
|
||||
|
@ -473,16 +518,16 @@ async function updateConversations(
|
|||
!pathsChanged.length,
|
||||
`Paths were cleaned: ${JSON.stringify(pathsChanged)}`
|
||||
);
|
||||
await channels.updateConversations(cleaned);
|
||||
await writableChannel.updateConversations(cleaned);
|
||||
}
|
||||
|
||||
async function removeConversation(id: string): Promise<void> {
|
||||
const existing = await channels.getConversationById(id);
|
||||
const existing = await readableChannel.getConversationById(id);
|
||||
|
||||
// Note: It's important to have a fully database-hydrated model to delete here because
|
||||
// it needs to delete all associated on-disk files along with the database delete.
|
||||
if (existing) {
|
||||
await channels.removeConversation(id);
|
||||
await writableChannel.removeConversation(id);
|
||||
await deleteExternalFiles(existing, {
|
||||
deleteAttachmentData: window.Signal.Migrations.deleteAttachmentData,
|
||||
});
|
||||
|
@ -528,7 +573,7 @@ async function searchMessages({
|
|||
contactServiceIdsMatchingQuery?: Array<ServiceIdString>;
|
||||
conversationId?: string;
|
||||
}): Promise<Array<ClientSearchResultMessageType>> {
|
||||
const messages = await channels.searchMessages({
|
||||
const messages = await readableChannel.searchMessages({
|
||||
query,
|
||||
conversationId,
|
||||
options,
|
||||
|
@ -548,7 +593,7 @@ async function saveMessage(
|
|||
ourAci: AciString;
|
||||
}
|
||||
): Promise<string> {
|
||||
const id = await channels.saveMessage(_cleanMessageData(data), {
|
||||
const id = await writableChannel.saveMessage(_cleanMessageData(data), {
|
||||
...options,
|
||||
jobToInsert: options.jobToInsert && formatJobForInsert(options.jobToInsert),
|
||||
});
|
||||
|
@ -565,7 +610,7 @@ async function saveMessages(
|
|||
arrayOfMessages: ReadonlyArray<MessageType>,
|
||||
options: { forceSave?: boolean; ourAci: AciString }
|
||||
): Promise<Array<string>> {
|
||||
const result = await channels.saveMessages(
|
||||
const result = await writableChannel.saveMessages(
|
||||
arrayOfMessages.map(message => _cleanMessageData(message)),
|
||||
options
|
||||
);
|
||||
|
@ -583,15 +628,15 @@ async function removeMessage(
|
|||
fromSync?: boolean;
|
||||
}
|
||||
): Promise<void> {
|
||||
const message = await channels.getMessageById(id);
|
||||
const message = await readableChannel.getMessageById(id);
|
||||
|
||||
// Note: It's important to have a fully database-hydrated model to delete here because
|
||||
// it needs to delete all associated on-disk files along with the database delete.
|
||||
if (message) {
|
||||
await channels.removeMessage(id);
|
||||
await writableChannel.removeMessage(id);
|
||||
await cleanupMessages([message], {
|
||||
...options,
|
||||
markCallHistoryDeleted: dataInterface.markCallHistoryDeleted,
|
||||
markCallHistoryDeleted: DataWriter.markCallHistoryDeleted,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -607,12 +652,12 @@ export async function deleteAndCleanup(
|
|||
const ids = messages.map(message => message.id);
|
||||
|
||||
log.info(`deleteAndCleanup/${logId}: Deleting ${ids.length} messages...`);
|
||||
await channels.removeMessages(ids);
|
||||
await writableChannel.removeMessages(ids);
|
||||
|
||||
log.info(`deleteAndCleanup/${logId}: Cleanup for ${ids.length} messages...`);
|
||||
await cleanupMessages(messages, {
|
||||
...options,
|
||||
markCallHistoryDeleted: dataInterface.markCallHistoryDeleted,
|
||||
markCallHistoryDeleted: DataWriter.markCallHistoryDeleted,
|
||||
});
|
||||
|
||||
log.info(`deleteAndCleanup/${logId}: Complete`);
|
||||
|
@ -625,12 +670,12 @@ async function removeMessages(
|
|||
singleProtoJobQueue: SingleProtoJobQueue;
|
||||
}
|
||||
): Promise<void> {
|
||||
const messages = await channels.getMessagesById(messageIds);
|
||||
const messages = await readableChannel.getMessagesById(messageIds);
|
||||
await cleanupMessages(messages, {
|
||||
...options,
|
||||
markCallHistoryDeleted: dataInterface.markCallHistoryDeleted,
|
||||
markCallHistoryDeleted: DataWriter.markCallHistoryDeleted,
|
||||
});
|
||||
await channels.removeMessages(messageIds);
|
||||
await writableChannel.removeMessages(messageIds);
|
||||
}
|
||||
|
||||
function handleMessageJSON(
|
||||
|
@ -642,7 +687,9 @@ function handleMessageJSON(
|
|||
async function getNewerMessagesByConversation(
|
||||
options: AdjacentMessagesByConversationOptionsType
|
||||
): Promise<Array<MessageType>> {
|
||||
const messages = await channels.getNewerMessagesByConversation(options);
|
||||
const messages = await readableChannel.getNewerMessagesByConversation(
|
||||
options
|
||||
);
|
||||
|
||||
return handleMessageJSON(messages);
|
||||
}
|
||||
|
@ -651,7 +698,10 @@ async function getRecentStoryReplies(
|
|||
storyId: string,
|
||||
options?: GetRecentStoryRepliesOptionsType
|
||||
): Promise<Array<MessageType>> {
|
||||
const messages = await channels.getRecentStoryReplies(storyId, options);
|
||||
const messages = await readableChannel.getRecentStoryReplies(
|
||||
storyId,
|
||||
options
|
||||
);
|
||||
|
||||
return handleMessageJSON(messages);
|
||||
}
|
||||
|
@ -659,7 +709,9 @@ async function getRecentStoryReplies(
|
|||
async function getOlderMessagesByConversation(
|
||||
options: AdjacentMessagesByConversationOptionsType
|
||||
): Promise<Array<MessageType>> {
|
||||
const messages = await channels.getOlderMessagesByConversation(options);
|
||||
const messages = await readableChannel.getOlderMessagesByConversation(
|
||||
options
|
||||
);
|
||||
|
||||
return handleMessageJSON(messages);
|
||||
}
|
||||
|
@ -667,7 +719,9 @@ async function getOlderMessagesByConversation(
|
|||
async function getConversationRangeCenteredOnMessage(
|
||||
options: AdjacentMessagesByConversationOptionsType
|
||||
): Promise<GetConversationRangeCenteredOnMessageResultType<MessageType>> {
|
||||
const result = await channels.getConversationRangeCenteredOnMessage(options);
|
||||
const result = await readableChannel.getConversationRangeCenteredOnMessage(
|
||||
options
|
||||
);
|
||||
|
||||
return {
|
||||
...result,
|
||||
|
@ -721,7 +775,7 @@ async function removeMessagesInConversation(
|
|||
async function saveAttachmentDownloadJob(
|
||||
job: AttachmentDownloadJobType
|
||||
): Promise<void> {
|
||||
await channels.saveAttachmentDownloadJob(_cleanData(job));
|
||||
await writableChannel.saveAttachmentDownloadJob(_cleanData(job));
|
||||
}
|
||||
|
||||
// Other
|
||||
|
@ -758,3 +812,11 @@ async function invokeWithTimeout(name: string): Promise<void> {
|
|||
`callChannel call to ${name}`
|
||||
)();
|
||||
}
|
||||
|
||||
export function pauseWriteAccess(): Promise<void> {
|
||||
return invokeWithTimeout(PAUSE_WRITE_ACCESS);
|
||||
}
|
||||
|
||||
export function resumeWriteAccess(): Promise<void> {
|
||||
return invokeWithTimeout(RESUME_WRITE_ACCESS);
|
||||
}
|
||||
|
|
1283
ts/sql/Interface.ts
1283
ts/sql/Interface.ts
File diff suppressed because it is too large
Load diff
2732
ts/sql/Server.ts
2732
ts/sql/Server.ts
File diff suppressed because it is too large
Load diff
|
@ -5,13 +5,21 @@ import { ipcRenderer } from 'electron';
|
|||
import * as log from '../logging/log';
|
||||
import createTaskWithTimeout from '../textsecure/TaskWithTimeout';
|
||||
import { explodePromise } from '../util/explodePromise';
|
||||
import { missingCaseError } from '../util/missingCaseError';
|
||||
|
||||
const SQL_CHANNEL_KEY = 'sql-channel';
|
||||
const SQL_READ_KEY = 'sql-channel:read';
|
||||
const SQL_WRITE_KEY = 'sql-channel:write';
|
||||
let activeJobCount = 0;
|
||||
let resolveShutdown: (() => void) | undefined;
|
||||
let shutdownPromise: Promise<void> | null = null;
|
||||
|
||||
export enum AccessType {
|
||||
Read = 'Read',
|
||||
Write = 'Write',
|
||||
}
|
||||
|
||||
export async function ipcInvoke<T>(
|
||||
access: AccessType,
|
||||
name: string,
|
||||
args: ReadonlyArray<unknown>
|
||||
): Promise<T> {
|
||||
|
@ -19,21 +27,31 @@ export async function ipcInvoke<T>(
|
|||
|
||||
if (shutdownPromise && name !== 'close') {
|
||||
throw new Error(
|
||||
`Rejecting SQL channel job (${fnName}); application is shutting down`
|
||||
`Rejecting SQL channel job (${access}, ${fnName}); ` +
|
||||
'application is shutting down'
|
||||
);
|
||||
}
|
||||
|
||||
let channel: string;
|
||||
if (access === AccessType.Read) {
|
||||
channel = SQL_READ_KEY;
|
||||
} else if (access === AccessType.Write) {
|
||||
channel = SQL_WRITE_KEY;
|
||||
} else {
|
||||
throw missingCaseError(access);
|
||||
}
|
||||
|
||||
activeJobCount += 1;
|
||||
return createTaskWithTimeout(async () => {
|
||||
try {
|
||||
return await ipcRenderer.invoke(SQL_CHANNEL_KEY, name, ...args);
|
||||
return await ipcRenderer.invoke(channel, name, ...args);
|
||||
} finally {
|
||||
activeJobCount -= 1;
|
||||
if (activeJobCount === 0) {
|
||||
resolveShutdown?.();
|
||||
}
|
||||
}
|
||||
}, `SQL channel call (${fnName})`)();
|
||||
}, `SQL channel call (${access}, ${fnName})`)();
|
||||
}
|
||||
|
||||
export async function doShutdown(): Promise<void> {
|
||||
|
|
406
ts/sql/main.ts
406
ts/sql/main.ts
|
@ -10,10 +10,15 @@ import { strictAssert } from '../util/assert';
|
|||
import { explodePromise } from '../util/explodePromise';
|
||||
import type { LoggerType } from '../types/Logging';
|
||||
import { SqliteErrorKind } from './errors';
|
||||
import type DB from './Server';
|
||||
import type {
|
||||
ServerReadableDirectInterface,
|
||||
ServerWritableDirectInterface,
|
||||
} from './Interface';
|
||||
|
||||
const MIN_TRACE_DURATION = 40;
|
||||
|
||||
const WORKER_COUNT = 4;
|
||||
|
||||
export type InitializeOptions = Readonly<{
|
||||
appVersion: string;
|
||||
configDir: string;
|
||||
|
@ -25,16 +30,19 @@ export type WorkerRequest = Readonly<
|
|||
| {
|
||||
type: 'init';
|
||||
options: Omit<InitializeOptions, 'logger'>;
|
||||
isPrimary: boolean;
|
||||
}
|
||||
| {
|
||||
type: 'close';
|
||||
type: 'close' | 'removeDB';
|
||||
}
|
||||
| {
|
||||
type: 'removeDB';
|
||||
type: 'sqlCall:read';
|
||||
method: keyof ServerReadableDirectInterface;
|
||||
args: ReadonlyArray<unknown>;
|
||||
}
|
||||
| {
|
||||
type: 'sqlCall';
|
||||
method: keyof typeof DB;
|
||||
type: 'sqlCall:write';
|
||||
method: keyof ServerWritableDirectInterface;
|
||||
args: ReadonlyArray<unknown>;
|
||||
}
|
||||
>;
|
||||
|
@ -71,14 +79,26 @@ type KnownErrorResolverType = Readonly<{
|
|||
resolve: (err: Error) => void;
|
||||
}>;
|
||||
|
||||
type CreateWorkerResultType = Readonly<{
|
||||
worker: Worker;
|
||||
onExit: Promise<void>;
|
||||
}>;
|
||||
|
||||
type PoolEntry = {
|
||||
readonly worker: Worker;
|
||||
load: number;
|
||||
};
|
||||
|
||||
export class MainSQL {
|
||||
private readonly worker: Worker;
|
||||
private readonly pool = new Array<PoolEntry>();
|
||||
|
||||
private pauseWaiters: Array<() => void> | undefined;
|
||||
|
||||
private isReady = false;
|
||||
|
||||
private onReady: Promise<void> | undefined;
|
||||
|
||||
private readonly onExit: Promise<void>;
|
||||
private readonly onExit: Promise<unknown>;
|
||||
|
||||
// Promise resolve callbacks for corruption and readonly errors.
|
||||
private errorResolvers = new Array<KnownErrorResolverType>();
|
||||
|
@ -93,10 +113,246 @@ export class MainSQL {
|
|||
private shouldTimeQueries = false;
|
||||
|
||||
constructor() {
|
||||
const scriptDir = join(app.getAppPath(), 'ts', 'sql', 'mainWorker.js');
|
||||
this.worker = new Worker(scriptDir);
|
||||
const exitPromises = new Array<Promise<void>>();
|
||||
for (let i = 0; i < WORKER_COUNT; i += 1) {
|
||||
const { worker, onExit } = this.createWorker();
|
||||
this.pool.push({ worker, load: 0 });
|
||||
|
||||
this.worker.on('message', (wrappedResponse: WrappedWorkerResponse) => {
|
||||
exitPromises.push(onExit);
|
||||
}
|
||||
this.onExit = Promise.all(exitPromises);
|
||||
}
|
||||
|
||||
public async initialize({
|
||||
appVersion,
|
||||
configDir,
|
||||
key,
|
||||
logger,
|
||||
}: InitializeOptions): Promise<void> {
|
||||
if (this.isReady || this.onReady) {
|
||||
throw new Error('Already initialized');
|
||||
}
|
||||
|
||||
this.shouldTimeQueries = Boolean(process.env.TIME_QUERIES);
|
||||
|
||||
this.logger = logger;
|
||||
|
||||
this.onReady = (async () => {
|
||||
const primary = this.pool[0];
|
||||
const rest = this.pool.slice(1);
|
||||
|
||||
await this.send(primary, {
|
||||
type: 'init',
|
||||
options: { appVersion, configDir, key },
|
||||
isPrimary: true,
|
||||
});
|
||||
|
||||
await Promise.all(
|
||||
rest.map(worker =>
|
||||
this.send(worker, {
|
||||
type: 'init',
|
||||
options: { appVersion, configDir, key },
|
||||
isPrimary: false,
|
||||
})
|
||||
)
|
||||
);
|
||||
})();
|
||||
|
||||
await this.onReady;
|
||||
|
||||
this.onReady = undefined;
|
||||
this.isReady = true;
|
||||
}
|
||||
|
||||
public pauseWriteAccess(): void {
|
||||
strictAssert(this.pauseWaiters == null, 'Already paused');
|
||||
|
||||
this.pauseWaiters = [];
|
||||
}
|
||||
|
||||
public resumeWriteAccess(): void {
|
||||
const { pauseWaiters } = this;
|
||||
strictAssert(pauseWaiters != null, 'Not paused');
|
||||
this.pauseWaiters = undefined;
|
||||
|
||||
for (const waiter of pauseWaiters) {
|
||||
waiter();
|
||||
}
|
||||
}
|
||||
|
||||
public whenCorrupted(): Promise<Error> {
|
||||
const { promise, resolve } = explodePromise<Error>();
|
||||
this.errorResolvers.push({ kind: SqliteErrorKind.Corrupted, resolve });
|
||||
return promise;
|
||||
}
|
||||
|
||||
public whenReadonly(): Promise<Error> {
|
||||
const { promise, resolve } = explodePromise<Error>();
|
||||
this.errorResolvers.push({ kind: SqliteErrorKind.Readonly, resolve });
|
||||
return promise;
|
||||
}
|
||||
|
||||
public async close(): Promise<void> {
|
||||
if (!this.isReady) {
|
||||
throw new Error('Not initialized');
|
||||
}
|
||||
|
||||
await this.terminate({ type: 'close' });
|
||||
await this.onExit;
|
||||
}
|
||||
|
||||
public async removeDB(): Promise<void> {
|
||||
await this.terminate({ type: 'removeDB' });
|
||||
}
|
||||
|
||||
public async sqlRead<Method extends keyof ServerReadableDirectInterface>(
|
||||
method: Method,
|
||||
...args: Parameters<ServerReadableDirectInterface[Method]>
|
||||
): Promise<ReturnType<ServerReadableDirectInterface[Method]>> {
|
||||
type SqlCallResult = Readonly<{
|
||||
result: ReturnType<ServerReadableDirectInterface[Method]>;
|
||||
duration: number;
|
||||
}>;
|
||||
|
||||
// pageMessages runs over several queries and needs to have access to
|
||||
// the same temporary table.
|
||||
const isPaging = method === 'pageMessages';
|
||||
|
||||
const entry = isPaging ? this.pool.at(-1) : this.getWorker();
|
||||
strictAssert(entry != null, 'Must have a pool entry');
|
||||
|
||||
const { result, duration } = await this.send<SqlCallResult>(entry, {
|
||||
type: 'sqlCall:read',
|
||||
method,
|
||||
args,
|
||||
});
|
||||
|
||||
this.traceDuration(method, duration);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async sqlWrite<Method extends keyof ServerWritableDirectInterface>(
|
||||
method: Method,
|
||||
...args: Parameters<ServerWritableDirectInterface[Method]>
|
||||
): Promise<ReturnType<ServerWritableDirectInterface[Method]>> {
|
||||
type Result = ReturnType<ServerWritableDirectInterface[Method]>;
|
||||
type SqlCallResult = Readonly<{
|
||||
result: Result;
|
||||
duration: number;
|
||||
}>;
|
||||
|
||||
while (this.pauseWaiters != null) {
|
||||
const { promise, resolve } = explodePromise<void>();
|
||||
this.pauseWaiters.push(resolve);
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await promise;
|
||||
}
|
||||
|
||||
// Special case since we need to broadcast this to every pool entry.
|
||||
if (method === 'removeDB') {
|
||||
return (await this.removeDB()) as Result;
|
||||
}
|
||||
|
||||
const primary = this.pool[0];
|
||||
|
||||
const { result, duration } = await this.send<SqlCallResult>(primary, {
|
||||
type: 'sqlCall:write',
|
||||
method,
|
||||
args,
|
||||
});
|
||||
|
||||
this.traceDuration(method, duration);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async send<Response>(
|
||||
entry: PoolEntry,
|
||||
request: WorkerRequest
|
||||
): Promise<Response> {
|
||||
if (request.type === 'sqlCall:read' || request.type === 'sqlCall:write') {
|
||||
if (this.onReady) {
|
||||
await this.onReady;
|
||||
}
|
||||
|
||||
if (!this.isReady) {
|
||||
throw new Error('Not initialized');
|
||||
}
|
||||
}
|
||||
|
||||
const { seq } = this;
|
||||
// eslint-disable-next-line no-bitwise
|
||||
this.seq = (this.seq + 1) >>> 0;
|
||||
|
||||
const { promise: result, resolve, reject } = explodePromise<Response>();
|
||||
this.onResponse.set(seq, { resolve, reject });
|
||||
|
||||
const wrappedRequest: WrappedWorkerRequest = {
|
||||
seq,
|
||||
request,
|
||||
};
|
||||
entry.worker.postMessage(wrappedRequest);
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
entry.load += 1;
|
||||
return await result;
|
||||
} finally {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
entry.load -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
private async terminate(request: WorkerRequest): Promise<void> {
|
||||
const primary = this.pool[0];
|
||||
const rest = this.pool.slice(1);
|
||||
|
||||
// Terminate non-primary workers first
|
||||
await Promise.all(rest.map(worker => this.send(worker, request)));
|
||||
|
||||
// Primary last
|
||||
await this.send(primary, request);
|
||||
}
|
||||
|
||||
private onError(errorKind: SqliteErrorKind, error: Error): void {
|
||||
if (errorKind === SqliteErrorKind.Unknown) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resolvers = new Array<(error: Error) => void>();
|
||||
this.errorResolvers = this.errorResolvers.filter(entry => {
|
||||
if (entry.kind === errorKind) {
|
||||
resolvers.push(entry.resolve);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
for (const resolve of resolvers) {
|
||||
resolve(error);
|
||||
}
|
||||
}
|
||||
|
||||
private traceDuration(method: string, duration: number): void {
|
||||
if (this.shouldTimeQueries && !app.isPackaged) {
|
||||
const twoDecimals = Math.round(100 * duration) / 100;
|
||||
this.logger?.info(`MainSQL query: ${method}, duration=${twoDecimals}ms`);
|
||||
}
|
||||
if (duration > MIN_TRACE_DURATION) {
|
||||
strictAssert(this.logger !== undefined, 'Logger not initialized');
|
||||
this.logger.info(
|
||||
`MainSQL: slow query ${method} duration=${Math.round(duration)}ms`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private createWorker(): CreateWorkerResultType {
|
||||
const scriptPath = join(app.getAppPath(), 'ts', 'sql', 'mainWorker.js');
|
||||
|
||||
const worker = new Worker(scriptPath);
|
||||
|
||||
worker.on('message', (wrappedResponse: WrappedWorkerResponse) => {
|
||||
if (wrappedResponse.type === 'log') {
|
||||
const { level, args } = wrappedResponse;
|
||||
strictAssert(this.logger !== undefined, 'Logger not initialized');
|
||||
|
@ -123,129 +379,21 @@ export class MainSQL {
|
|||
});
|
||||
|
||||
const { promise: onExit, resolve: resolveOnExit } = explodePromise<void>();
|
||||
this.onExit = onExit;
|
||||
this.worker.once('exit', resolveOnExit);
|
||||
worker.once('exit', resolveOnExit);
|
||||
|
||||
return { worker, onExit };
|
||||
}
|
||||
|
||||
public async initialize({
|
||||
appVersion,
|
||||
configDir,
|
||||
key,
|
||||
logger,
|
||||
}: InitializeOptions): Promise<void> {
|
||||
if (this.isReady || this.onReady) {
|
||||
throw new Error('Already initialized');
|
||||
}
|
||||
|
||||
this.shouldTimeQueries = Boolean(process.env.TIME_QUERIES);
|
||||
|
||||
this.logger = logger;
|
||||
|
||||
this.onReady = this.send({
|
||||
type: 'init',
|
||||
options: { appVersion, configDir, key },
|
||||
});
|
||||
|
||||
await this.onReady;
|
||||
|
||||
this.onReady = undefined;
|
||||
this.isReady = true;
|
||||
}
|
||||
|
||||
public whenCorrupted(): Promise<Error> {
|
||||
const { promise, resolve } = explodePromise<Error>();
|
||||
this.errorResolvers.push({ kind: SqliteErrorKind.Corrupted, resolve });
|
||||
return promise;
|
||||
}
|
||||
|
||||
public whenReadonly(): Promise<Error> {
|
||||
const { promise, resolve } = explodePromise<Error>();
|
||||
this.errorResolvers.push({ kind: SqliteErrorKind.Readonly, resolve });
|
||||
return promise;
|
||||
}
|
||||
|
||||
public async close(): Promise<void> {
|
||||
if (!this.isReady) {
|
||||
throw new Error('Not initialized');
|
||||
}
|
||||
|
||||
await this.send({ type: 'close' });
|
||||
await this.onExit;
|
||||
}
|
||||
|
||||
public async removeDB(): Promise<void> {
|
||||
await this.send({ type: 'removeDB' });
|
||||
}
|
||||
|
||||
public async sqlCall<Method extends keyof typeof DB>(
|
||||
method: Method,
|
||||
...args: Parameters<typeof DB[Method]>
|
||||
): Promise<ReturnType<typeof DB[Method]>> {
|
||||
if (this.onReady) {
|
||||
await this.onReady;
|
||||
}
|
||||
|
||||
if (!this.isReady) {
|
||||
throw new Error('Not initialized');
|
||||
}
|
||||
|
||||
type SqlCallResult = Readonly<{
|
||||
result: ReturnType<typeof DB[Method]>;
|
||||
duration: number;
|
||||
}>;
|
||||
|
||||
const { result, duration } = await this.send<SqlCallResult>({
|
||||
type: 'sqlCall',
|
||||
method,
|
||||
args,
|
||||
});
|
||||
|
||||
if (this.shouldTimeQueries && !app.isPackaged) {
|
||||
const twoDecimals = Math.round(100 * duration) / 100;
|
||||
this.logger?.info(`MainSQL query: ${method}, duration=${twoDecimals}ms`);
|
||||
}
|
||||
if (duration > MIN_TRACE_DURATION) {
|
||||
strictAssert(this.logger !== undefined, 'Logger not initialized');
|
||||
this.logger.info(
|
||||
`MainSQL: slow query ${method} duration=${Math.round(duration)}ms`
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async send<Response>(request: WorkerRequest): Promise<Response> {
|
||||
const { seq } = this;
|
||||
this.seq += 1;
|
||||
|
||||
const { promise: result, resolve, reject } = explodePromise<Response>();
|
||||
this.onResponse.set(seq, { resolve, reject });
|
||||
|
||||
const wrappedRequest: WrappedWorkerRequest = {
|
||||
seq,
|
||||
request,
|
||||
};
|
||||
this.worker.postMessage(wrappedRequest);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private onError(errorKind: SqliteErrorKind, error: Error): void {
|
||||
if (errorKind === SqliteErrorKind.Unknown) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resolvers = new Array<(error: Error) => void>();
|
||||
this.errorResolvers = this.errorResolvers.filter(entry => {
|
||||
if (entry.kind === errorKind) {
|
||||
resolvers.push(entry.resolve);
|
||||
return false;
|
||||
// Find first pool entry with minimal load
|
||||
private getWorker(): PoolEntry {
|
||||
let min = this.pool[0];
|
||||
for (const entry of this.pool) {
|
||||
if (min && min.load < entry.load) {
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
for (const resolve of resolvers) {
|
||||
resolve(error);
|
||||
min = entry;
|
||||
}
|
||||
return min;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ import type {
|
|||
WrappedWorkerResponse,
|
||||
WrappedWorkerLogEntry,
|
||||
} from './main';
|
||||
import db from './Server';
|
||||
import type { WritableDB } from './Interface';
|
||||
import { initialize, DataReader, DataWriter } from './Server';
|
||||
import { SqliteErrorKind, parseSqliteError } from './errors';
|
||||
|
||||
if (!parentPort) {
|
||||
|
@ -27,8 +28,8 @@ function respond(seq: number, error: Error | undefined, response?: any) {
|
|||
errorKind = parseSqliteError(error);
|
||||
errorString = Errors.toLogFormat(error);
|
||||
|
||||
if (errorKind === SqliteErrorKind.Corrupted) {
|
||||
db.runCorruptionChecks();
|
||||
if (errorKind === SqliteErrorKind.Corrupted && db != null) {
|
||||
DataWriter.runCorruptionChecks(db);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,11 +76,18 @@ const logger: LoggerType = {
|
|||
},
|
||||
};
|
||||
|
||||
port.on('message', async ({ seq, request }: WrappedWorkerRequest) => {
|
||||
let db: WritableDB | undefined;
|
||||
let isPrimary = false;
|
||||
let isRemoved = false;
|
||||
|
||||
port.on('message', ({ seq, request }: WrappedWorkerRequest) => {
|
||||
try {
|
||||
if (request.type === 'init') {
|
||||
await db.initialize({
|
||||
isPrimary = request.isPrimary;
|
||||
isRemoved = false;
|
||||
db = initialize({
|
||||
...request.options,
|
||||
isPrimary,
|
||||
logger,
|
||||
});
|
||||
|
||||
|
@ -87,8 +95,24 @@ port.on('message', async ({ seq, request }: WrappedWorkerRequest) => {
|
|||
return;
|
||||
}
|
||||
|
||||
// 'close' is sent on shutdown, but we already removed the database.
|
||||
if (isRemoved && request.type === 'close') {
|
||||
respond(seq, undefined, undefined);
|
||||
process.exit(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!db) {
|
||||
throw new Error('Not initialized');
|
||||
}
|
||||
|
||||
if (request.type === 'close') {
|
||||
await db.close();
|
||||
if (isPrimary) {
|
||||
DataWriter.close(db);
|
||||
} else {
|
||||
DataReader.close(db);
|
||||
}
|
||||
db = undefined;
|
||||
|
||||
respond(seq, undefined, undefined);
|
||||
process.exit(0);
|
||||
|
@ -96,21 +120,30 @@ port.on('message', async ({ seq, request }: WrappedWorkerRequest) => {
|
|||
}
|
||||
|
||||
if (request.type === 'removeDB') {
|
||||
await db.removeDB();
|
||||
if (isPrimary) {
|
||||
DataWriter.removeDB(db);
|
||||
} else {
|
||||
DataReader.close(db);
|
||||
}
|
||||
|
||||
isRemoved = true;
|
||||
db = undefined;
|
||||
|
||||
respond(seq, undefined, undefined);
|
||||
return;
|
||||
}
|
||||
|
||||
if (request.type === 'sqlCall') {
|
||||
if (request.type === 'sqlCall:read' || request.type === 'sqlCall:write') {
|
||||
const DataInterface =
|
||||
request.type === 'sqlCall:read' ? DataReader : DataWriter;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const method = (db as any)[request.method];
|
||||
const method = (DataInterface as any)[request.method];
|
||||
if (typeof method !== 'function') {
|
||||
throw new Error(`Invalid sql method: ${method}`);
|
||||
}
|
||||
|
||||
const start = performance.now();
|
||||
const result = await method.apply(db, request.args);
|
||||
const result = method(db, ...request.args);
|
||||
const end = performance.now();
|
||||
|
||||
respond(seq, undefined, { result, duration: end - start });
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
// Copyright 2024 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { Database } from '@signalapp/better-sqlite3';
|
||||
|
||||
import type { LoggerType } from '../../types/Logging';
|
||||
import { sql } from '../util';
|
||||
import type { WritableDB } from '../Interface';
|
||||
import { getOurUuid } from './41-uuid-keys';
|
||||
|
||||
export const version = 1020;
|
||||
|
||||
export function updateToSchemaVersion1020(
|
||||
currentVersion: number,
|
||||
db: Database,
|
||||
db: WritableDB,
|
||||
logger: LoggerType
|
||||
): void {
|
||||
if (currentVersion >= 1020) {
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { Database } from '@signalapp/better-sqlite3';
|
||||
|
||||
import type { LoggerType } from '../../types/Logging';
|
||||
import { isValidUuid } from '../../util/isValidUuid';
|
||||
import { assertSync } from '../../util/assert';
|
||||
import Helpers from '../../textsecure/Helpers';
|
||||
import { createOrUpdate, getById, removeById } from '../util';
|
||||
import type { EmptyQuery, Query } from '../util';
|
||||
import type { ItemKeyType } from '../Interface';
|
||||
import type { ItemKeyType, ReadableDB, WritableDB } from '../Interface';
|
||||
|
||||
export function getOurUuid(db: Database): string | undefined {
|
||||
export function getOurUuid(db: ReadableDB): string | undefined {
|
||||
const UUID_ID: ItemKeyType = 'uuid_id';
|
||||
|
||||
const row: { json: string } | undefined = db
|
||||
|
@ -30,7 +27,7 @@ export function getOurUuid(db: Database): string | undefined {
|
|||
|
||||
export default function updateToSchemaVersion41(
|
||||
currentVersion: number,
|
||||
db: Database,
|
||||
db: WritableDB,
|
||||
logger: LoggerType
|
||||
): void {
|
||||
if (currentVersion >= 41) {
|
||||
|
@ -92,8 +89,8 @@ export default function updateToSchemaVersion41(
|
|||
db.prepare('DELETE FROM preKeys').run().changes,
|
||||
].reduce((a: number, b: number): number => a + b);
|
||||
|
||||
assertSync(removeById<string>(db, 'items', 'identityKey'));
|
||||
assertSync(removeById<string>(db, 'items', 'registrationId'));
|
||||
removeById<string>(db, 'items', 'identityKey');
|
||||
removeById<string>(db, 'items', 'registrationId');
|
||||
|
||||
return keyCount;
|
||||
};
|
||||
|
@ -104,36 +101,34 @@ export default function updateToSchemaVersion41(
|
|||
publicKey: string;
|
||||
};
|
||||
|
||||
const identityKey = assertSync(
|
||||
getById<string, { value: IdentityKeyType }>(db, 'items', 'identityKey')
|
||||
const identityKey = getById<string, { value: IdentityKeyType }>(
|
||||
db,
|
||||
'items',
|
||||
'identityKey'
|
||||
);
|
||||
|
||||
type RegistrationId = number;
|
||||
|
||||
const registrationId = assertSync(
|
||||
getById<string, { value: RegistrationId }>(db, 'items', 'registrationId')
|
||||
const registrationId = getById<string, { value: RegistrationId }>(
|
||||
db,
|
||||
'items',
|
||||
'registrationId'
|
||||
);
|
||||
|
||||
if (identityKey) {
|
||||
assertSync(
|
||||
createOrUpdate<ItemKeyType>(db, 'items', {
|
||||
id: 'identityKeyMap',
|
||||
value: {
|
||||
[ourUuid]: identityKey.value,
|
||||
},
|
||||
})
|
||||
);
|
||||
createOrUpdate<ItemKeyType>(db, 'items', {
|
||||
id: 'identityKeyMap',
|
||||
value: {
|
||||
[ourUuid]: identityKey.value,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (registrationId) {
|
||||
assertSync(
|
||||
createOrUpdate<ItemKeyType>(db, 'items', {
|
||||
id: 'registrationIdMap',
|
||||
value: {
|
||||
[ourUuid]: registrationId.value,
|
||||
},
|
||||
})
|
||||
);
|
||||
createOrUpdate<ItemKeyType>(db, 'items', {
|
||||
id: 'registrationIdMap',
|
||||
value: {
|
||||
[ourUuid]: registrationId.value,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
db.exec(
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { Database } from '@signalapp/better-sqlite3';
|
||||
|
||||
import { batchMultiVarQuery } from '../util';
|
||||
import type { ArrayQuery } from '../util';
|
||||
import type { WritableDB } from '../Interface';
|
||||
import type { LoggerType } from '../../types/Logging';
|
||||
|
||||
export default function updateToSchemaVersion42(
|
||||
currentVersion: number,
|
||||
db: Database,
|
||||
db: WritableDB,
|
||||
logger: LoggerType
|
||||
): void {
|
||||
if (currentVersion >= 42) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { Database } from '@signalapp/better-sqlite3';
|
||||
import { omit } from 'lodash';
|
||||
|
||||
import type { LoggerType } from '../../types/Logging';
|
||||
|
@ -16,6 +15,7 @@ import {
|
|||
objectToJSON,
|
||||
} from '../util';
|
||||
import type { EmptyQuery, Query } from '../util';
|
||||
import type { WritableDB } from '../Interface';
|
||||
|
||||
type MessageType = Readonly<{
|
||||
id: string;
|
||||
|
@ -35,7 +35,7 @@ type ConversationType = Readonly<{
|
|||
|
||||
export default function updateToSchemaVersion43(
|
||||
currentVersion: number,
|
||||
db: Database,
|
||||
db: WritableDB,
|
||||
logger: LoggerType
|
||||
): void {
|
||||
if (currentVersion >= 43) {
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { Database } from '@signalapp/better-sqlite3';
|
||||
|
||||
import type { LoggerType } from '../../types/Logging';
|
||||
import { getOurUuid } from './41-uuid-keys';
|
||||
import type { WritableDB } from '../Interface';
|
||||
import type { Query } from '../util';
|
||||
|
||||
export default function updateToSchemaVersion47(
|
||||
currentVersion: number,
|
||||
db: Database,
|
||||
db: WritableDB,
|
||||
logger: LoggerType
|
||||
): void {
|
||||
if (currentVersion >= 47) {
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
// Copyright 2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { Database } from '@signalapp/better-sqlite3';
|
||||
|
||||
import type { LoggerType } from '../../types/Logging';
|
||||
import { isRecord } from '../../util/isRecord';
|
||||
import {
|
||||
getJobsInQueueSync,
|
||||
getMessageByIdSync,
|
||||
insertJobSync,
|
||||
} from '../Server';
|
||||
import type { WritableDB } from '../Interface';
|
||||
import { getJobsInQueue, getMessageById, insertJob } from '../Server';
|
||||
|
||||
export default function updateToSchemaVersion51(
|
||||
currentVersion: number,
|
||||
db: Database,
|
||||
db: WritableDB,
|
||||
logger: LoggerType
|
||||
): void {
|
||||
if (currentVersion >= 51) {
|
||||
|
@ -26,7 +21,7 @@ export default function updateToSchemaVersion51(
|
|||
);
|
||||
|
||||
// First, make sure that reactions job data has a type and conversationId
|
||||
const reactionsJobs = getJobsInQueueSync(db, 'reactions');
|
||||
const reactionsJobs = getJobsInQueue(db, 'reactions');
|
||||
deleteJobsInQueue.run({ queueType: 'reactions' });
|
||||
|
||||
reactionsJobs.forEach(job => {
|
||||
|
@ -47,7 +42,7 @@ export default function updateToSchemaVersion51(
|
|||
return;
|
||||
}
|
||||
|
||||
const message = getMessageByIdSync(db, messageId);
|
||||
const message = getMessageById(db, messageId);
|
||||
if (!message) {
|
||||
logger.warn(
|
||||
`updateToSchemaVersion51: Unable to find message for reaction job ${id}`
|
||||
|
@ -73,11 +68,11 @@ export default function updateToSchemaVersion51(
|
|||
},
|
||||
};
|
||||
|
||||
insertJobSync(db, newJob);
|
||||
insertJob(db, newJob);
|
||||
});
|
||||
|
||||
// Then make sure all normal send job data has a type
|
||||
const normalSendJobs = getJobsInQueueSync(db, 'normal send');
|
||||
const normalSendJobs = getJobsInQueue(db, 'normal send');
|
||||
deleteJobsInQueue.run({ queueType: 'normal send' });
|
||||
|
||||
normalSendJobs.forEach(job => {
|
||||
|
@ -99,7 +94,7 @@ export default function updateToSchemaVersion51(
|
|||
},
|
||||
};
|
||||
|
||||
insertJobSync(db, newJob);
|
||||
insertJob(db, newJob);
|
||||
});
|
||||
|
||||
db.pragma('user_version = 51');
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
// Copyright 2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { Database } from '@signalapp/better-sqlite3';
|
||||
import type { LoggerType } from '../../types/Logging';
|
||||
import { getJobsInQueueSync, insertJobSync } from '../Server';
|
||||
import { getJobsInQueue, insertJob } from '../Server';
|
||||
import type { WritableDB } from '../Interface';
|
||||
import { isRecord } from '../../util/isRecord';
|
||||
import { isIterable } from '../../util/iterables';
|
||||
|
||||
export default function updateToSchemaVersion55(
|
||||
currentVersion: number,
|
||||
db: Database,
|
||||
db: WritableDB,
|
||||
logger: LoggerType
|
||||
): void {
|
||||
if (currentVersion >= 55) {
|
||||
|
@ -22,7 +22,7 @@ export default function updateToSchemaVersion55(
|
|||
);
|
||||
|
||||
// First, make sure that report spam job data has e164 and serverGuids
|
||||
const reportSpamJobs = getJobsInQueueSync(db, 'report spam');
|
||||
const reportSpamJobs = getJobsInQueue(db, 'report spam');
|
||||
deleteJobsInQueue.run({ queueType: 'report spam' });
|
||||
|
||||
reportSpamJobs.forEach(job => {
|
||||
|
@ -59,7 +59,7 @@ export default function updateToSchemaVersion55(
|
|||
},
|
||||
};
|
||||
|
||||
insertJobSync(db, newJob);
|
||||
insertJob(db, newJob);
|
||||
});
|
||||
|
||||
db.pragma('user_version = 55');
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
// Copyright 2023 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { Database } from '@signalapp/better-sqlite3';
|
||||
|
||||
import type { LoggerType } from '../../types/Logging';
|
||||
import { isRecord } from '../../util/isRecord';
|
||||
import {
|
||||
getJobsInQueueSync,
|
||||
getMessageByIdSync,
|
||||
insertJobSync,
|
||||
} from '../Server';
|
||||
import type { WritableDB } from '../Interface';
|
||||
import { getJobsInQueue, getMessageById, insertJob } from '../Server';
|
||||
|
||||
export default function updateToSchemaVersion78(
|
||||
currentVersion: number,
|
||||
db: Database,
|
||||
db: WritableDB,
|
||||
logger: LoggerType
|
||||
): void {
|
||||
if (currentVersion >= 78) {
|
||||
|
@ -47,7 +42,7 @@ export default function updateToSchemaVersion78(
|
|||
];
|
||||
|
||||
for (const queue of queues) {
|
||||
const prevJobs = getJobsInQueueSync(db, queue.queueType);
|
||||
const prevJobs = getJobsInQueue(db, queue.queueType);
|
||||
deleteJobsInQueue.run({ queueType: queue.queueType });
|
||||
|
||||
prevJobs.forEach(job => {
|
||||
|
@ -67,7 +62,7 @@ export default function updateToSchemaVersion78(
|
|||
return;
|
||||
}
|
||||
|
||||
const message = getMessageByIdSync(db, messageId);
|
||||
const message = getMessageById(db, messageId);
|
||||
if (!message) {
|
||||
logger.warn(
|
||||
`updateToSchemaVersion78: Unable to find message for ${queue.queueType} job ${id}`
|
||||
|
@ -121,7 +116,7 @@ export default function updateToSchemaVersion78(
|
|||
},
|
||||
};
|
||||
|
||||
insertJobSync(db, newJob);
|
||||
insertJob(db, newJob);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright 2023 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { Database } from '@signalapp/better-sqlite3';
|
||||
import { callIdFromEra } from '@signalapp/ringrtc';
|
||||
import Long from 'long';
|
||||
import { v4 as generateUuid } from 'uuid';
|
||||
|
@ -20,7 +19,7 @@ import {
|
|||
callHistoryDetailsSchema,
|
||||
} from '../../types/CallDisposition';
|
||||
import { CallMode } from '../../types/Calling';
|
||||
import type { MessageType, ConversationType } from '../Interface';
|
||||
import type { WritableDB, MessageType, ConversationType } from '../Interface';
|
||||
import { strictAssert } from '../../util/assert';
|
||||
import { missingCaseError } from '../../util/missingCaseError';
|
||||
import { isAciString } from '../../util/isAciString';
|
||||
|
@ -188,7 +187,7 @@ function convertLegacyCallDetails(
|
|||
|
||||
export default function updateToSchemaVersion89(
|
||||
currentVersion: number,
|
||||
db: Database,
|
||||
db: WritableDB,
|
||||
logger: LoggerType
|
||||
): void {
|
||||
if (currentVersion >= 89) {
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
jsonToObject,
|
||||
} from '../util';
|
||||
import type { Query, EmptyQuery } from '../util';
|
||||
import type { WritableDB } from '../Interface';
|
||||
|
||||
import updateToSchemaVersion41 from './41-uuid-keys';
|
||||
import updateToSchemaVersion42 from './42-stale-reactions';
|
||||
|
@ -2075,7 +2076,7 @@ export function enableFTS5SecureDelete(db: Database, logger: LoggerType): void {
|
|||
}
|
||||
}
|
||||
|
||||
export function updateSchema(db: Database, logger: LoggerType): void {
|
||||
export function updateSchema(db: WritableDB, logger: LoggerType): void {
|
||||
const sqliteVersion = getSQLiteVersion(db);
|
||||
const sqlcipherVersion = getSQLCipherVersion(db);
|
||||
const startingVersion = getUserVersion(db);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright 2024 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { Database } from '@signalapp/better-sqlite3';
|
||||
import { CallLinkRootKey } from '@signalapp/ringrtc';
|
||||
import type { CallLinkStateType, CallLinkType } from '../../types/CallLink';
|
||||
import {
|
||||
|
@ -13,12 +12,12 @@ import {
|
|||
callLinkFromRecord,
|
||||
toAdminKeyBytes,
|
||||
} from '../../util/callLinks';
|
||||
import { getReadonlyInstance, getWritableInstance, prepare } from '../Server';
|
||||
import type { ReadableDB, WritableDB } from '../Interface';
|
||||
import { prepare } from '../Server';
|
||||
import { sql } from '../util';
|
||||
import { strictAssert } from '../../util/assert';
|
||||
|
||||
export async function callLinkExists(roomId: string): Promise<boolean> {
|
||||
const db = getReadonlyInstance();
|
||||
export function callLinkExists(db: ReadableDB, roomId: string): boolean {
|
||||
const [query, params] = sql`
|
||||
SELECT 1
|
||||
FROM callLinks
|
||||
|
@ -27,10 +26,10 @@ export async function callLinkExists(roomId: string): Promise<boolean> {
|
|||
return db.prepare(query).pluck(true).get(params) === 1;
|
||||
}
|
||||
|
||||
export async function getCallLinkByRoomId(
|
||||
export function getCallLinkByRoomId(
|
||||
db: ReadableDB,
|
||||
roomId: string
|
||||
): Promise<CallLinkType | undefined> {
|
||||
const db = getReadonlyInstance();
|
||||
): CallLinkType | undefined {
|
||||
const row = prepare(db, 'SELECT * FROM callLinks WHERE roomId = $roomId').get(
|
||||
{
|
||||
roomId,
|
||||
|
@ -44,8 +43,7 @@ export async function getCallLinkByRoomId(
|
|||
return callLinkFromRecord(callLinkRecordSchema.parse(row));
|
||||
}
|
||||
|
||||
export async function getAllCallLinks(): Promise<ReadonlyArray<CallLinkType>> {
|
||||
const db = getReadonlyInstance();
|
||||
export function getAllCallLinks(db: ReadableDB): ReadonlyArray<CallLinkType> {
|
||||
const [query] = sql`
|
||||
SELECT * FROM callLinks;
|
||||
`;
|
||||
|
@ -55,7 +53,7 @@ export async function getAllCallLinks(): Promise<ReadonlyArray<CallLinkType>> {
|
|||
.map(item => callLinkFromRecord(callLinkRecordSchema.parse(item)));
|
||||
}
|
||||
|
||||
function _insertCallLink(db: Database, callLink: CallLinkType): void {
|
||||
function _insertCallLink(db: WritableDB, callLink: CallLinkType): void {
|
||||
const { roomId, rootKey } = callLink;
|
||||
assertRoomIdMatchesRootKey(roomId, rootKey);
|
||||
|
||||
|
@ -84,17 +82,16 @@ function _insertCallLink(db: Database, callLink: CallLinkType): void {
|
|||
).run(data);
|
||||
}
|
||||
|
||||
export async function insertCallLink(callLink: CallLinkType): Promise<void> {
|
||||
const db = await getWritableInstance();
|
||||
export function insertCallLink(db: WritableDB, callLink: CallLinkType): void {
|
||||
_insertCallLink(db, callLink);
|
||||
}
|
||||
|
||||
export async function updateCallLinkState(
|
||||
export function updateCallLinkState(
|
||||
db: WritableDB,
|
||||
roomId: string,
|
||||
callLinkState: CallLinkStateType
|
||||
): Promise<CallLinkType> {
|
||||
): CallLinkType {
|
||||
const { name, restrictions, expiration, revoked } = callLinkState;
|
||||
const db = await getWritableInstance();
|
||||
const restrictionsValue = callLinkRestrictionsSchema.parse(restrictions);
|
||||
const [query, params] = sql`
|
||||
UPDATE callLinks
|
||||
|
@ -111,11 +108,11 @@ export async function updateCallLinkState(
|
|||
return callLinkFromRecord(callLinkRecordSchema.parse(row));
|
||||
}
|
||||
|
||||
export async function updateCallLinkAdminKeyByRoomId(
|
||||
export function updateCallLinkAdminKeyByRoomId(
|
||||
db: WritableDB,
|
||||
roomId: string,
|
||||
adminKey: string
|
||||
): Promise<void> {
|
||||
const db = await getWritableInstance();
|
||||
): void {
|
||||
const adminKeyBytes = toAdminKeyBytes(adminKey);
|
||||
prepare(
|
||||
db,
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
// Copyright 2024 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { Database } from '@signalapp/better-sqlite3';
|
||||
import type {
|
||||
GroupSendCombinedEndorsementRecord,
|
||||
GroupSendEndorsementsData,
|
||||
GroupSendMemberEndorsementRecord,
|
||||
} from '../../types/GroupSendEndorsements';
|
||||
import { groupSendEndorsementExpirationSchema } from '../../types/GroupSendEndorsements';
|
||||
import { getReadonlyInstance, getWritableInstance, prepare } from '../Server';
|
||||
import { prepare } from '../Server';
|
||||
import type { ReadableDB, WritableDB } from '../Interface';
|
||||
import { sql } from '../util';
|
||||
|
||||
/**
|
||||
* We don't need to store more than one endorsement per group or per member.
|
||||
*/
|
||||
export async function replaceAllEndorsementsForGroup(
|
||||
export function replaceAllEndorsementsForGroup(
|
||||
db: WritableDB,
|
||||
data: GroupSendEndorsementsData
|
||||
): Promise<void> {
|
||||
const db = await getWritableInstance();
|
||||
): void {
|
||||
db.transaction(() => {
|
||||
const { combinedEndorsement, memberEndorsements } = data;
|
||||
_replaceCombinedEndorsement(db, combinedEndorsement);
|
||||
|
@ -26,7 +26,7 @@ export async function replaceAllEndorsementsForGroup(
|
|||
}
|
||||
|
||||
function _replaceCombinedEndorsement(
|
||||
db: Database,
|
||||
db: WritableDB,
|
||||
combinedEndorsement: GroupSendCombinedEndorsementRecord
|
||||
): void {
|
||||
const { groupId, expiration, endorsement } = combinedEndorsement;
|
||||
|
@ -39,7 +39,7 @@ function _replaceCombinedEndorsement(
|
|||
}
|
||||
|
||||
function _replaceMemberEndorsements(
|
||||
db: Database,
|
||||
db: WritableDB,
|
||||
memberEndorsements: ReadonlyArray<GroupSendMemberEndorsementRecord>
|
||||
) {
|
||||
for (const memberEndorsement of memberEndorsements) {
|
||||
|
@ -53,10 +53,10 @@ function _replaceMemberEndorsements(
|
|||
}
|
||||
}
|
||||
|
||||
export async function deleteAllEndorsementsForGroup(
|
||||
export function deleteAllEndorsementsForGroup(
|
||||
db: WritableDB,
|
||||
groupId: string
|
||||
): Promise<void> {
|
||||
const db = await getWritableInstance();
|
||||
): void {
|
||||
db.transaction(() => {
|
||||
const [deleteCombined, deleteCombinedParams] = sql`
|
||||
DELETE FROM groupSendCombinedEndorsement
|
||||
|
@ -71,10 +71,10 @@ export async function deleteAllEndorsementsForGroup(
|
|||
})();
|
||||
}
|
||||
|
||||
export async function getGroupSendCombinedEndorsementExpiration(
|
||||
export function getGroupSendCombinedEndorsementExpiration(
|
||||
db: ReadableDB,
|
||||
groupId: string
|
||||
): Promise<number | null> {
|
||||
const db = getReadonlyInstance();
|
||||
): number | null {
|
||||
const [selectGroup, selectGroupParams] = sql`
|
||||
SELECT expiration FROM groupSendCombinedEndorsement
|
||||
WHERE groupId = ${groupId};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { Database } from '@signalapp/better-sqlite3';
|
||||
import { isNumber, last } from 'lodash';
|
||||
import type { ReadableDB, WritableDB } from './Interface';
|
||||
|
||||
export type EmptyQuery = [];
|
||||
export type ArrayQuery = Array<ReadonlyArray<null | number | bigint | string>>;
|
||||
|
@ -185,7 +185,7 @@ type QueryPlan = Readonly<{
|
|||
* ```
|
||||
*/
|
||||
export function explainQueryPlan(
|
||||
db: Database,
|
||||
db: ReadableDB,
|
||||
template: QueryTemplate
|
||||
): QueryPlan {
|
||||
const [query, params] = template;
|
||||
|
@ -197,7 +197,7 @@ export function explainQueryPlan(
|
|||
// Database helpers
|
||||
//
|
||||
|
||||
export function getSQLiteVersion(db: Database): string {
|
||||
export function getSQLiteVersion(db: ReadableDB): string {
|
||||
const { sqlite_version: version } = db
|
||||
.prepare<EmptyQuery>('select sqlite_version() AS sqlite_version')
|
||||
.get();
|
||||
|
@ -205,22 +205,22 @@ export function getSQLiteVersion(db: Database): string {
|
|||
return version;
|
||||
}
|
||||
|
||||
export function getSchemaVersion(db: Database): number {
|
||||
export function getSchemaVersion(db: ReadableDB): number {
|
||||
return db.pragma('schema_version', { simple: true });
|
||||
}
|
||||
|
||||
export function setUserVersion(db: Database, version: number): void {
|
||||
export function setUserVersion(db: WritableDB, version: number): void {
|
||||
if (!isNumber(version)) {
|
||||
throw new Error(`setUserVersion: version ${version} is not a number`);
|
||||
}
|
||||
db.pragma(`user_version = ${version}`);
|
||||
}
|
||||
|
||||
export function getUserVersion(db: Database): number {
|
||||
export function getUserVersion(db: ReadableDB): number {
|
||||
return db.pragma('user_version', { simple: true });
|
||||
}
|
||||
|
||||
export function getSQLCipherVersion(db: Database): string | undefined {
|
||||
export function getSQLCipherVersion(db: ReadableDB): string | undefined {
|
||||
return db.pragma('cipher_version', { simple: true });
|
||||
}
|
||||
|
||||
|
@ -229,18 +229,18 @@ export function getSQLCipherVersion(db: Database): string | undefined {
|
|||
//
|
||||
|
||||
export function batchMultiVarQuery<ValueT>(
|
||||
db: Database,
|
||||
db: ReadableDB,
|
||||
values: ReadonlyArray<ValueT>,
|
||||
query: (batch: ReadonlyArray<ValueT>) => void
|
||||
): [];
|
||||
export function batchMultiVarQuery<ValueT, ResultT>(
|
||||
db: Database,
|
||||
db: ReadableDB,
|
||||
values: ReadonlyArray<ValueT>,
|
||||
query: (batch: ReadonlyArray<ValueT>) => Array<ResultT>
|
||||
): Array<ResultT>;
|
||||
|
||||
export function batchMultiVarQuery<ValueT, ResultT>(
|
||||
db: Database,
|
||||
db: ReadableDB,
|
||||
values: ReadonlyArray<ValueT>,
|
||||
query:
|
||||
| ((batch: ReadonlyArray<ValueT>) => void)
|
||||
|
@ -265,7 +265,7 @@ export function batchMultiVarQuery<ValueT, ResultT>(
|
|||
}
|
||||
|
||||
export function createOrUpdate<Key extends string | number>(
|
||||
db: Database,
|
||||
db: WritableDB,
|
||||
table: TableType,
|
||||
data: Record<string, unknown> & { id: Key }
|
||||
): void {
|
||||
|
@ -291,7 +291,7 @@ export function createOrUpdate<Key extends string | number>(
|
|||
}
|
||||
|
||||
export function bulkAdd(
|
||||
db: Database,
|
||||
db: WritableDB,
|
||||
table: TableType,
|
||||
array: Array<Record<string, unknown> & { id: string | number }>
|
||||
): void {
|
||||
|
@ -303,7 +303,7 @@ export function bulkAdd(
|
|||
}
|
||||
|
||||
export function getById<Key extends string | number, Result = unknown>(
|
||||
db: Database,
|
||||
db: ReadableDB,
|
||||
table: TableType,
|
||||
id: Key
|
||||
): Result | undefined {
|
||||
|
@ -327,7 +327,7 @@ export function getById<Key extends string | number, Result = unknown>(
|
|||
}
|
||||
|
||||
export function removeById<Key extends string | number>(
|
||||
db: Database,
|
||||
db: WritableDB,
|
||||
tableName: TableType,
|
||||
id: Key | Array<Key>
|
||||
): number {
|
||||
|
@ -359,11 +359,11 @@ export function removeById<Key extends string | number>(
|
|||
return totalChanges;
|
||||
}
|
||||
|
||||
export function removeAllFromTable(db: Database, table: TableType): number {
|
||||
export function removeAllFromTable(db: WritableDB, table: TableType): number {
|
||||
return db.prepare<EmptyQuery>(`DELETE FROM ${table};`).run().changes;
|
||||
}
|
||||
|
||||
export function getAllFromTable<T>(db: Database, table: TableType): Array<T> {
|
||||
export function getAllFromTable<T>(db: ReadableDB, table: TableType): Array<T> {
|
||||
const rows: JSONRows = db
|
||||
.prepare<EmptyQuery>(`SELECT json FROM ${table};`)
|
||||
.all();
|
||||
|
@ -371,7 +371,7 @@ export function getAllFromTable<T>(db: Database, table: TableType): Array<T> {
|
|||
return rows.map(row => jsonToObject(row.json));
|
||||
}
|
||||
|
||||
export function getCountFromTable(db: Database, table: TableType): number {
|
||||
export function getCountFromTable(db: ReadableDB, table: TableType): number {
|
||||
const result: null | number = db
|
||||
.prepare<EmptyQuery>(`SELECT count(*) from ${table};`)
|
||||
.pluck(true)
|
||||
|
@ -384,7 +384,7 @@ export function getCountFromTable(db: Database, table: TableType): number {
|
|||
|
||||
export class TableIterator<ObjectType extends { id: string }> {
|
||||
constructor(
|
||||
private readonly db: Database,
|
||||
private readonly db: ReadableDB,
|
||||
private readonly table: TableType,
|
||||
private readonly pageSize = 500
|
||||
) {}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import type { ThunkAction } from 'redux-thunk';
|
||||
import { isEqual, mapValues } from 'lodash';
|
||||
import type { ReadonlyDeep } from 'type-fest';
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
import type { StateType as RootStateType } from '../reducer';
|
||||
import type { BadgeType, BadgeImageType } from '../../badges/types';
|
||||
import { getOwn } from '../../util/getOwn';
|
||||
|
@ -70,7 +71,7 @@ function updateOrCreate(
|
|||
// check (e.g., due to a crash), we won't download its image files. In the unlikely
|
||||
// event that this happens, we'll repair it the next time we check for undownloaded
|
||||
// image files.
|
||||
await window.Signal.Data.updateOrCreateBadges(badges);
|
||||
await DataWriter.updateOrCreateBadges(badges);
|
||||
|
||||
dispatch({
|
||||
type: UPDATE_OR_CREATE,
|
||||
|
|
|
@ -13,6 +13,7 @@ import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
|||
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||
import type { ToastActionType } from './toast';
|
||||
import { showToast } from './toast';
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import { ToastType } from '../../types/Toast';
|
||||
import type { CallHistoryDetails } from '../../types/CallDisposition';
|
||||
import * as log from '../../logging/log';
|
||||
|
@ -77,7 +78,7 @@ function updateCallHistoryUnreadCount(): ThunkAction<
|
|||
> {
|
||||
return async dispatch => {
|
||||
try {
|
||||
const unreadCount = await window.Signal.Data.getCallHistoryUnreadCount();
|
||||
const unreadCount = await DataReader.getCallHistoryUnreadCount();
|
||||
dispatch({ type: CALL_HISTORY_UPDATE_UNREAD, payload: unreadCount });
|
||||
} catch (error) {
|
||||
log.error(
|
||||
|
@ -94,7 +95,7 @@ function markCallHistoryRead(
|
|||
): ThunkAction<void, RootStateType, unknown, CallHistoryUpdateUnread> {
|
||||
return async dispatch => {
|
||||
try {
|
||||
await window.Signal.Data.markCallHistoryRead(callId);
|
||||
await DataWriter.markCallHistoryRead(callId);
|
||||
drop(window.ConversationController.get(conversationId)?.updateUnread());
|
||||
} catch (error) {
|
||||
log.error(
|
||||
|
|
|
@ -86,7 +86,7 @@ import type { ShowErrorModalActionType } from './globalModals';
|
|||
import { SHOW_ERROR_MODAL } from './globalModals';
|
||||
import { ButtonVariant } from '../../components/Button';
|
||||
import { getConversationIdForLogging } from '../../util/idForLogging';
|
||||
import dataInterface from '../../sql/Client';
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import { isAciString } from '../../util/isAciString';
|
||||
import type { CallHistoryDetails } from '../../types/CallDisposition';
|
||||
import {
|
||||
|
@ -1415,7 +1415,7 @@ function handleCallLinkUpdate(
|
|||
}
|
||||
|
||||
const { callLinkState: freshCallLinkState } = readResult;
|
||||
const existingCallLink = await dataInterface.getCallLinkByRoomId(roomId);
|
||||
const existingCallLink = await DataReader.getCallLinkByRoomId(roomId);
|
||||
const existingCallLinkState = pick(existingCallLink, [
|
||||
'name',
|
||||
'restrictions',
|
||||
|
@ -1434,16 +1434,16 @@ function handleCallLinkUpdate(
|
|||
|
||||
if (existingCallLink) {
|
||||
if (adminKey && adminKey !== existingCallLink.adminKey) {
|
||||
await dataInterface.updateCallLinkAdminKeyByRoomId(roomId, adminKey);
|
||||
await DataWriter.updateCallLinkAdminKeyByRoomId(roomId, adminKey);
|
||||
log.info(`${logId}: Updated existing call link with new adminKey`);
|
||||
}
|
||||
|
||||
if (freshCallLinkState) {
|
||||
await dataInterface.updateCallLinkState(roomId, freshCallLinkState);
|
||||
await DataWriter.updateCallLinkState(roomId, freshCallLinkState);
|
||||
log.info(`${logId}: Updated existing call link state`);
|
||||
}
|
||||
} else {
|
||||
await dataInterface.insertCallLink(callLink);
|
||||
await DataWriter.insertCallLink(callLink);
|
||||
log.info(`${logId}: Saved new call link`);
|
||||
}
|
||||
|
||||
|
@ -1985,8 +1985,8 @@ function createCallLink(
|
|||
status: AdhocCallStatus.Pending,
|
||||
};
|
||||
await Promise.all([
|
||||
dataInterface.insertCallLink(callLink),
|
||||
dataInterface.saveCallHistory(callHistory),
|
||||
DataWriter.insertCallLink(callLink),
|
||||
DataWriter.saveCallHistory(callHistory),
|
||||
]);
|
||||
dispatch({
|
||||
type: HANDLE_CALL_LINK_UPDATE,
|
||||
|
@ -2003,13 +2003,13 @@ function updateCallLinkName(
|
|||
name: string
|
||||
): ThunkAction<void, RootStateType, unknown, HandleCallLinkUpdateActionType> {
|
||||
return async dispatch => {
|
||||
const prevCallLink = await dataInterface.getCallLinkByRoomId(roomId);
|
||||
const prevCallLink = await DataReader.getCallLinkByRoomId(roomId);
|
||||
strictAssert(
|
||||
prevCallLink,
|
||||
`updateCallLinkName(${roomId}): call link not found`
|
||||
);
|
||||
const callLinkState = await calling.updateCallLinkName(prevCallLink, name);
|
||||
const callLink = await dataInterface.updateCallLinkState(
|
||||
const callLink = await DataWriter.updateCallLinkState(
|
||||
roomId,
|
||||
callLinkState
|
||||
);
|
||||
|
@ -2025,7 +2025,7 @@ function updateCallLinkRestrictions(
|
|||
restrictions: CallLinkRestrictions
|
||||
): ThunkAction<void, RootStateType, unknown, HandleCallLinkUpdateActionType> {
|
||||
return async dispatch => {
|
||||
const prevCallLink = await dataInterface.getCallLinkByRoomId(roomId);
|
||||
const prevCallLink = await DataReader.getCallLinkByRoomId(roomId);
|
||||
strictAssert(
|
||||
prevCallLink,
|
||||
`updateCallLinkRestrictions(${roomId}): call link not found`
|
||||
|
@ -2034,7 +2034,7 @@ function updateCallLinkRestrictions(
|
|||
prevCallLink,
|
||||
restrictions
|
||||
);
|
||||
const callLink = await dataInterface.updateCallLinkState(
|
||||
const callLink = await DataWriter.updateCallLinkState(
|
||||
roomId,
|
||||
callLinkState
|
||||
);
|
||||
|
@ -2126,13 +2126,13 @@ const _startCallLinkLobby = async ({
|
|||
}
|
||||
|
||||
try {
|
||||
const callLinkExists = await dataInterface.callLinkExists(roomId);
|
||||
const callLinkExists = await DataReader.callLinkExists(roomId);
|
||||
if (callLinkExists) {
|
||||
await dataInterface.updateCallLinkState(roomId, callLinkState);
|
||||
await DataWriter.updateCallLinkState(roomId, callLinkState);
|
||||
log.info('startCallLinkLobby: Updated existing call link', roomId);
|
||||
} else {
|
||||
const { name, restrictions, expiration, revoked } = callLinkState;
|
||||
await dataInterface.insertCallLink({
|
||||
await DataWriter.insertCallLink({
|
||||
roomId,
|
||||
rootKey,
|
||||
adminKey: null,
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
isVideoAttachment,
|
||||
isImageAttachment,
|
||||
} from '../../types/Attachment';
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||
import type { DraftBodyRanges } from '../../types/BodyRange';
|
||||
import type { LinkPreviewType } from '../../types/message/LinkPreviews';
|
||||
|
@ -336,7 +337,7 @@ function scrollToQuotedMessage({
|
|||
ShowToastActionType | ScrollToMessageActionType
|
||||
> {
|
||||
return async (dispatch, getState) => {
|
||||
const messages = await window.Signal.Data.getMessagesBySentAt(sentAt);
|
||||
const messages = await DataReader.getMessagesBySentAt(sentAt);
|
||||
const message = messages.find(item =>
|
||||
Boolean(
|
||||
item.conversationId === conversationId &&
|
||||
|
@ -765,7 +766,7 @@ export function setQuoteByMessageId(
|
|||
timestamp,
|
||||
});
|
||||
|
||||
window.Signal.Data.updateConversation(conversation.attributes);
|
||||
await DataWriter.updateConversation(conversation.attributes);
|
||||
}
|
||||
|
||||
if (message) {
|
||||
|
@ -866,7 +867,7 @@ function addAttachment(
|
|||
});
|
||||
}
|
||||
|
||||
window.Signal.Data.updateConversation(conversation.attributes);
|
||||
await DataWriter.updateConversation(conversation.attributes);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -904,7 +905,7 @@ function addPendingAttachment(
|
|||
if (conversation) {
|
||||
conversation.attributes.draftAttachments = nextAttachments;
|
||||
conversation.attributes.draftChanged = true;
|
||||
window.Signal.Data.updateConversation(conversation.attributes);
|
||||
drop(DataWriter.updateConversation(conversation.attributes));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1201,7 +1202,7 @@ function removeAttachment(
|
|||
if (conversation) {
|
||||
conversation.attributes.draftAttachments = nextAttachments;
|
||||
conversation.attributes.draftChanged = true;
|
||||
window.Signal.Data.updateConversation(conversation.attributes);
|
||||
await DataWriter.updateConversation(conversation.attributes);
|
||||
}
|
||||
|
||||
replaceAttachments(conversationId, nextAttachments)(
|
||||
|
@ -1312,7 +1313,7 @@ function saveDraft(
|
|||
draftChanged: true,
|
||||
draftBodyRanges: [],
|
||||
});
|
||||
window.Signal.Data.updateConversation(conversation.attributes);
|
||||
drop(DataWriter.updateConversation(conversation.attributes));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1336,7 +1337,7 @@ function saveDraft(
|
|||
draftChanged: true,
|
||||
timestamp,
|
||||
});
|
||||
window.Signal.Data.updateConversation(conversation.attributes);
|
||||
drop(DataWriter.updateConversation(conversation.attributes));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import type { PhoneNumber } from 'google-libphonenumber';
|
|||
|
||||
import { clipboard } from 'electron';
|
||||
import type { ReadonlyDeep } from 'type-fest';
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import type { AttachmentType } from '../../types/Attachment';
|
||||
import type { StateType as RootStateType } from '../reducer';
|
||||
import * as groups from '../../groups';
|
||||
|
@ -1480,7 +1481,7 @@ async function getAvatarsAndUpdateConversation(
|
|||
conversation.attributes.avatars = nextAvatars.map(avatarData =>
|
||||
omit(avatarData, ['buffer'])
|
||||
);
|
||||
window.Signal.Data.updateConversation(conversation.attributes);
|
||||
await DataWriter.updateConversation(conversation.attributes);
|
||||
|
||||
return nextAvatars;
|
||||
}
|
||||
|
@ -1750,21 +1751,20 @@ function deleteMessages({
|
|||
let nearbyMessageId: string | null = null;
|
||||
|
||||
if (nearbyMessageId == null && lastSelectedMessage != null) {
|
||||
const foundMessageId =
|
||||
await window.Signal.Data.getNearbyMessageFromDeletedSet({
|
||||
conversationId,
|
||||
lastSelectedMessage,
|
||||
deletedMessageIds: messageIds,
|
||||
includeStoryReplies: false,
|
||||
storyId: undefined,
|
||||
});
|
||||
const foundMessageId = await DataReader.getNearbyMessageFromDeletedSet({
|
||||
conversationId,
|
||||
lastSelectedMessage,
|
||||
deletedMessageIds: messageIds,
|
||||
includeStoryReplies: false,
|
||||
storyId: undefined,
|
||||
});
|
||||
|
||||
if (foundMessageId != null) {
|
||||
nearbyMessageId = foundMessageId;
|
||||
}
|
||||
}
|
||||
|
||||
await window.Signal.Data.removeMessages(messageIds, {
|
||||
await DataWriter.removeMessages(messageIds, {
|
||||
singleProtoJobQueue,
|
||||
});
|
||||
|
||||
|
@ -2189,7 +2189,7 @@ function removeCustomColorOnConversations(
|
|||
});
|
||||
|
||||
if (conversationsToUpdate.length) {
|
||||
await window.Signal.Data.updateConversations(conversationsToUpdate);
|
||||
await DataWriter.updateConversations(conversationsToUpdate);
|
||||
}
|
||||
|
||||
dispatch({
|
||||
|
@ -2209,7 +2209,7 @@ function resetAllChatColors(): ThunkAction<
|
|||
> {
|
||||
return async dispatch => {
|
||||
// Calling this with no args unsets all the colors in the db
|
||||
await window.Signal.Data.updateAllConversationColors();
|
||||
await DataWriter.updateAllConversationColors();
|
||||
|
||||
window.getConversations().forEach(conversation => {
|
||||
conversation.set({
|
||||
|
@ -2245,7 +2245,7 @@ function kickOffAttachmentDownload(
|
|||
|
||||
if (didUpdateValues) {
|
||||
drop(
|
||||
window.Signal.Data.saveMessage(message.attributes, {
|
||||
DataWriter.saveMessage(message.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
})
|
||||
);
|
||||
|
@ -2402,7 +2402,7 @@ export function setVoiceNotePlaybackRate({
|
|||
conversationModel.set({
|
||||
voiceNotePlaybackRate: rate === 1 ? undefined : rate,
|
||||
});
|
||||
window.Signal.Data.updateConversation(conversationModel.attributes);
|
||||
await DataWriter.updateConversation(conversationModel.attributes);
|
||||
}
|
||||
|
||||
const conversation = conversationModel?.format();
|
||||
|
@ -2456,7 +2456,7 @@ function colorSelected({
|
|||
});
|
||||
}
|
||||
|
||||
window.Signal.Data.updateConversation(conversation.attributes);
|
||||
await DataWriter.updateConversation(conversation.attributes);
|
||||
}
|
||||
|
||||
dispatch({
|
||||
|
@ -2779,20 +2779,17 @@ function toggleSelectMessage(
|
|||
message => message
|
||||
);
|
||||
|
||||
const betweenIds = await window.Signal.Data.getMessagesBetween(
|
||||
conversationId,
|
||||
{
|
||||
after: {
|
||||
sent_at: after.sent_at,
|
||||
received_at: after.received_at,
|
||||
},
|
||||
before: {
|
||||
sent_at: before.sent_at,
|
||||
received_at: before.received_at,
|
||||
},
|
||||
includeStoryReplies: !isGroup(conversation.attributes),
|
||||
}
|
||||
);
|
||||
const betweenIds = await DataReader.getMessagesBetween(conversationId, {
|
||||
after: {
|
||||
sent_at: after.sent_at,
|
||||
received_at: after.received_at,
|
||||
},
|
||||
before: {
|
||||
sent_at: before.sent_at,
|
||||
received_at: before.received_at,
|
||||
},
|
||||
includeStoryReplies: !isGroup(conversation.attributes),
|
||||
});
|
||||
|
||||
toggledMessageIds = [messageId, ...betweenIds];
|
||||
} else {
|
||||
|
@ -3434,7 +3431,7 @@ function reportSpam(
|
|||
addReportSpamJob({
|
||||
conversation,
|
||||
getMessageServerGuidsForSpam:
|
||||
window.Signal.Data.getMessageServerGuidsForSpam,
|
||||
DataReader.getMessageServerGuidsForSpam,
|
||||
jobQueue: reportSpamJobQueue,
|
||||
}),
|
||||
]);
|
||||
|
@ -3484,7 +3481,7 @@ function blockAndReportSpam(
|
|||
addReportSpamJob({
|
||||
conversation: conversationForSpam,
|
||||
getMessageServerGuidsForSpam:
|
||||
window.Signal.Data.getMessageServerGuidsForSpam,
|
||||
DataReader.getMessageServerGuidsForSpam,
|
||||
jobQueue: reportSpamJobQueue,
|
||||
}),
|
||||
]);
|
||||
|
@ -3654,12 +3651,9 @@ function loadRecentMediaItems(
|
|||
): ThunkAction<void, RootStateType, unknown, SetRecentMediaItemsActionType> {
|
||||
return async dispatch => {
|
||||
const messages: Array<MessageAttributesType> =
|
||||
await window.Signal.Data.getMessagesWithVisualMediaAttachments(
|
||||
conversationId,
|
||||
{
|
||||
limit,
|
||||
}
|
||||
);
|
||||
await DataReader.getMessagesWithVisualMediaAttachments(conversationId, {
|
||||
limit,
|
||||
});
|
||||
|
||||
// Cache these messages in memory to ensure Lightbox can find them
|
||||
messages.forEach(message => {
|
||||
|
@ -3839,7 +3833,7 @@ export function scrollToOldestUnreadMention(
|
|||
}
|
||||
|
||||
const oldestUnreadMention =
|
||||
await window.Signal.Data.getOldestUnreadMentionOfMeForConversation(
|
||||
await DataReader.getOldestUnreadMentionOfMeForConversation(
|
||||
conversationId,
|
||||
{
|
||||
includeStoryReplies: !isGroup(conversation),
|
||||
|
@ -4151,7 +4145,7 @@ function toggleGroupsForStorySend(
|
|||
conversation.set({
|
||||
storySendMode: newStorySendMode,
|
||||
});
|
||||
window.Signal.Data.updateConversation(conversation.attributes);
|
||||
await DataWriter.updateConversation(conversation.attributes);
|
||||
conversation.captureChange('storySendMode');
|
||||
})
|
||||
);
|
||||
|
@ -4413,7 +4407,7 @@ function onConversationClosed(
|
|||
});
|
||||
}
|
||||
|
||||
window.Signal.Data.updateConversation(conversation.attributes);
|
||||
await DataWriter.updateConversation(conversation.attributes);
|
||||
|
||||
drop(conversation.updateLastMessage());
|
||||
}
|
||||
|
@ -4784,7 +4778,7 @@ function updateNicknameAndNote(
|
|||
nicknameFamilyName: nickname?.familyName,
|
||||
note,
|
||||
});
|
||||
window.Signal.Data.updateConversation(conversationModel.attributes);
|
||||
await DataWriter.updateConversation(conversationModel.attributes);
|
||||
const conversation = conversationModel.format();
|
||||
dispatch(conversationChanged(conversationId, conversation));
|
||||
conversationModel.captureChange('nicknameAndNote');
|
||||
|
|
|
@ -5,11 +5,11 @@ import { take, uniq } from 'lodash';
|
|||
import type { ThunkAction } from 'redux-thunk';
|
||||
import type { ReadonlyDeep } from 'type-fest';
|
||||
import type { EmojiPickDataType } from '../../components/emoji/EmojiPicker';
|
||||
import dataInterface from '../../sql/Client';
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||
|
||||
const { updateEmojiUsage } = dataInterface;
|
||||
const { updateEmojiUsage } = DataWriter;
|
||||
|
||||
// State
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ import {
|
|||
} from './conversations';
|
||||
import { showStickerPackPreview } from './globalModals';
|
||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||
import dataInterface from '../../sql/Client';
|
||||
import { DataReader } from '../../sql/Client';
|
||||
|
||||
// eslint-disable-next-line local-rules/type-alias-readonlydeep
|
||||
export type LightboxStateType =
|
||||
|
@ -349,7 +349,7 @@ function showLightbox(opts: {
|
|||
}
|
||||
|
||||
const { older, newer } =
|
||||
await dataInterface.getConversationRangeCenteredOnMessage({
|
||||
await DataReader.getConversationRangeCenteredOnMessage({
|
||||
conversationId: message.get('conversationId'),
|
||||
messageId,
|
||||
receivedAt,
|
||||
|
@ -436,8 +436,8 @@ function showLightboxForAdjacentMessage(
|
|||
|
||||
const [adjacent] =
|
||||
direction === AdjacentMessageDirection.Previous
|
||||
? await dataInterface.getOlderMessagesByConversation(options)
|
||||
: await dataInterface.getNewerMessagesByConversation(options);
|
||||
? await DataReader.getOlderMessagesByConversation(options)
|
||||
: await DataReader.getNewerMessagesByConversation(options);
|
||||
|
||||
if (!adjacent) {
|
||||
log.warn(
|
||||
|
|
|
@ -15,7 +15,7 @@ import type { MIMEType } from '../../types/MIME';
|
|||
import type { MediaItemType } from '../../types/MediaItem';
|
||||
import type { StateType as RootStateType } from '../reducer';
|
||||
|
||||
import dataInterface from '../../sql/Client';
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import {
|
||||
CONVERSATION_UNLOADED,
|
||||
MESSAGE_CHANGED,
|
||||
|
@ -84,13 +84,13 @@ function loadMediaItems(
|
|||
|
||||
const ourAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
const rawMedia = await dataInterface.getMessagesWithVisualMediaAttachments(
|
||||
const rawMedia = await DataReader.getMessagesWithVisualMediaAttachments(
|
||||
conversationId,
|
||||
{
|
||||
limit: DEFAULT_MEDIA_FETCH_COUNT,
|
||||
}
|
||||
);
|
||||
const rawDocuments = await dataInterface.getMessagesWithFileAttachments(
|
||||
const rawDocuments = await DataReader.getMessagesWithFileAttachments(
|
||||
conversationId,
|
||||
{
|
||||
limit: DEFAULT_DOCUMENTS_FETCH_COUNT,
|
||||
|
@ -111,7 +111,7 @@ function loadMediaItems(
|
|||
const upgradedMsgAttributes = await upgradeMessageSchema(message);
|
||||
model.set(upgradedMsgAttributes);
|
||||
|
||||
await dataInterface.saveMessage(upgradedMsgAttributes, { ourAci });
|
||||
await DataWriter.saveMessage(upgradedMsgAttributes, { ourAci });
|
||||
}
|
||||
})
|
||||
);
|
||||
|
|
|
@ -7,11 +7,8 @@ import { debounce, omit, reject } from 'lodash';
|
|||
import type { ReadonlyDeep } from 'type-fest';
|
||||
import type { StateType as RootStateType } from '../reducer';
|
||||
import { filterAndSortConversations } from '../../util/filterAndSortConversations';
|
||||
import type {
|
||||
ClientSearchResultMessageType,
|
||||
ClientInterface,
|
||||
} from '../../sql/Interface';
|
||||
import dataInterface from '../../sql/Client';
|
||||
import type { ClientSearchResultMessageType } from '../../sql/Interface';
|
||||
import { DataReader } from '../../sql/Client';
|
||||
import { makeLookup } from '../../util/makeLookup';
|
||||
import { isNotNil } from '../../util/isNotNil';
|
||||
import type { ServiceIdString } from '../../types/ServiceId';
|
||||
|
@ -44,7 +41,7 @@ import * as log from '../../logging/log';
|
|||
import { searchConversationTitles } from '../../util/searchConversationTitles';
|
||||
import { isDirectConversation } from '../../util/whatTypeOfConversation';
|
||||
|
||||
const { searchMessages: dataSearchMessages }: ClientInterface = dataInterface;
|
||||
const { searchMessages: dataSearchMessages } = DataReader;
|
||||
|
||||
// State
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import type {
|
|||
StickerType as StickerDBType,
|
||||
StickerPackType as StickerPackDBType,
|
||||
} from '../../sql/Interface';
|
||||
import dataInterface from '../../sql/Client';
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import type { RecentStickerType } from '../../types/Stickers';
|
||||
import {
|
||||
downloadStickerPack as externalDownloadStickerPack,
|
||||
|
@ -25,7 +25,8 @@ import type { NoopActionType } from './noop';
|
|||
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||
|
||||
const { getRecentStickers, updateStickerLastUsed } = dataInterface;
|
||||
const { getRecentStickers } = DataReader;
|
||||
const { updateStickerLastUsed } = DataWriter;
|
||||
|
||||
// State
|
||||
|
||||
|
@ -241,7 +242,7 @@ async function doInstallStickerPack(
|
|||
} = options;
|
||||
|
||||
const timestamp = Date.now();
|
||||
await dataInterface.installStickerPack(packId, timestamp);
|
||||
await DataWriter.installStickerPack(packId, timestamp);
|
||||
|
||||
if (!fromSync && !fromStorageService && !fromBackup) {
|
||||
// Kick this off, but don't wait for it
|
||||
|
@ -283,7 +284,7 @@ async function doUninstallStickerPack(
|
|||
const { fromSync = false, fromStorageService = false } = options;
|
||||
|
||||
const timestamp = Date.now();
|
||||
await dataInterface.uninstallStickerPack(packId, timestamp);
|
||||
await DataWriter.uninstallStickerPack(packId, timestamp);
|
||||
|
||||
// If there are no more references, it should be removed
|
||||
await maybeDeletePack(packId);
|
||||
|
|
|
@ -25,7 +25,7 @@ import { isAciString } from '../../util/isAciString';
|
|||
import * as log from '../../logging/log';
|
||||
import { TARGETED_CONVERSATION_CHANGED } from './conversations';
|
||||
import { SIGNAL_ACI } from '../../types/SignalConversation';
|
||||
import dataInterface from '../../sql/Client';
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import { ReadStatus } from '../../messages/MessageReadStatus';
|
||||
import { SendStatus } from '../../messages/MessageSendState';
|
||||
import { SafetyNumberChangeSource } from '../../components/SafetyNumberChangeDialog';
|
||||
|
@ -285,7 +285,7 @@ function deleteGroupStoryReply(
|
|||
messageId: string
|
||||
): ThunkAction<void, RootStateType, unknown, StoryReplyDeletedActionType> {
|
||||
return async dispatch => {
|
||||
await window.Signal.Data.removeMessage(messageId, { singleProtoJobQueue });
|
||||
await DataWriter.removeMessage(messageId, { singleProtoJobQueue });
|
||||
dispatch({
|
||||
type: STORY_REPLY_DELETED,
|
||||
payload: messageId,
|
||||
|
@ -337,7 +337,7 @@ function loadStoryReplies(
|
|||
): ThunkAction<void, RootStateType, unknown, LoadStoryRepliesActionType> {
|
||||
return async (dispatch, getState) => {
|
||||
const conversation = getConversationSelector(getState())(conversationId);
|
||||
const replies = await dataInterface.getOlderMessagesByConversation({
|
||||
const replies = await DataReader.getOlderMessagesByConversation({
|
||||
conversationId,
|
||||
limit: 9000,
|
||||
storyId: messageId,
|
||||
|
@ -421,7 +421,7 @@ function markStoryRead(
|
|||
|
||||
message.set(markViewed(message.attributes, storyReadDate));
|
||||
drop(
|
||||
dataInterface.saveMessage(message.attributes, {
|
||||
DataWriter.saveMessage(message.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
})
|
||||
);
|
||||
|
@ -459,7 +459,7 @@ function markStoryRead(
|
|||
);
|
||||
}
|
||||
|
||||
await dataInterface.addNewStoryRead({
|
||||
await DataWriter.addNewStoryRead({
|
||||
authorId,
|
||||
conversationId: message.attributes.conversationId,
|
||||
storyId: messageId,
|
||||
|
@ -1409,7 +1409,7 @@ function removeAllContactStories(
|
|||
|
||||
log.info(`${logId}: removing ${messages.length} stories`);
|
||||
|
||||
await dataInterface.removeMessages(messageIds, { singleProtoJobQueue });
|
||||
await DataWriter.removeMessages(messageIds, { singleProtoJobQueue });
|
||||
|
||||
dispatch({
|
||||
type: 'NOOP',
|
||||
|
|
|
@ -10,7 +10,7 @@ import type { StoryDistributionWithMembersType } from '../../sql/Interface';
|
|||
import type { StoryDistributionIdString } from '../../types/StoryDistributionId';
|
||||
import type { ServiceIdString } from '../../types/ServiceId';
|
||||
import * as log from '../../logging/log';
|
||||
import dataInterface from '../../sql/Client';
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import { MY_STORY_ID } from '../../types/Stories';
|
||||
import { generateStoryDistributionId } from '../../types/StoryDistributionId';
|
||||
import { deleteStoryForEveryone } from '../../util/deleteStoryForEveryone';
|
||||
|
@ -112,8 +112,9 @@ function allowsRepliesChanged(
|
|||
allowsReplies: boolean
|
||||
): ThunkAction<void, RootStateType, null, AllowRepliesChangedActionType> {
|
||||
return async dispatch => {
|
||||
const storyDistribution =
|
||||
await dataInterface.getStoryDistributionWithMembers(listId);
|
||||
const storyDistribution = await DataReader.getStoryDistributionWithMembers(
|
||||
listId
|
||||
);
|
||||
|
||||
if (!storyDistribution) {
|
||||
log.warn(
|
||||
|
@ -131,7 +132,7 @@ function allowsRepliesChanged(
|
|||
return;
|
||||
}
|
||||
|
||||
await dataInterface.modifyStoryDistribution({
|
||||
await DataWriter.modifyStoryDistribution({
|
||||
...storyDistribution,
|
||||
allowsReplies,
|
||||
storageNeedsSync: true,
|
||||
|
@ -178,7 +179,7 @@ function createDistributionList(
|
|||
};
|
||||
|
||||
if (shouldSave) {
|
||||
await dataInterface.createNewStoryDistribution(storyDistribution);
|
||||
await DataWriter.createNewStoryDistribution(storyDistribution);
|
||||
}
|
||||
|
||||
if (storyDistribution.storageNeedsSync) {
|
||||
|
@ -207,15 +208,16 @@ function deleteDistributionList(
|
|||
return async (dispatch, getState) => {
|
||||
const deletedAtTimestamp = Date.now();
|
||||
|
||||
const storyDistribution =
|
||||
await dataInterface.getStoryDistributionWithMembers(listId);
|
||||
const storyDistribution = await DataReader.getStoryDistributionWithMembers(
|
||||
listId
|
||||
);
|
||||
|
||||
if (!storyDistribution) {
|
||||
log.warn('No story distribution found for id', listId);
|
||||
return;
|
||||
}
|
||||
|
||||
await dataInterface.modifyStoryDistributionWithMembers(
|
||||
await DataWriter.modifyStoryDistributionWithMembers(
|
||||
{
|
||||
...storyDistribution,
|
||||
deletedAtTimestamp,
|
||||
|
@ -266,7 +268,7 @@ function hideMyStoriesFrom(
|
|||
memberServiceIds: Array<ServiceIdString>
|
||||
): ThunkAction<void, RootStateType, null, HideMyStoriesFromActionType> {
|
||||
return async dispatch => {
|
||||
const myStories = await dataInterface.getStoryDistributionWithMembers(
|
||||
const myStories = await DataReader.getStoryDistributionWithMembers(
|
||||
MY_STORY_ID
|
||||
);
|
||||
|
||||
|
@ -279,7 +281,7 @@ function hideMyStoriesFrom(
|
|||
|
||||
const toAdd = new Set<ServiceIdString>(memberServiceIds);
|
||||
|
||||
await dataInterface.modifyStoryDistributionWithMembers(
|
||||
await DataWriter.modifyStoryDistributionWithMembers(
|
||||
{
|
||||
...myStories,
|
||||
isBlockList: true,
|
||||
|
@ -315,8 +317,9 @@ function removeMembersFromDistributionList(
|
|||
return;
|
||||
}
|
||||
|
||||
const storyDistribution =
|
||||
await dataInterface.getStoryDistributionWithMembers(listId);
|
||||
const storyDistribution = await DataReader.getStoryDistributionWithMembers(
|
||||
listId
|
||||
);
|
||||
|
||||
if (!storyDistribution) {
|
||||
log.warn(
|
||||
|
@ -343,7 +346,7 @@ function removeMembersFromDistributionList(
|
|||
await window.storage.put('hasSetMyStoriesPrivacy', true);
|
||||
}
|
||||
|
||||
await dataInterface.modifyStoryDistributionWithMembers(
|
||||
await DataWriter.modifyStoryDistributionWithMembers(
|
||||
{
|
||||
...storyDistribution,
|
||||
isBlockList,
|
||||
|
@ -385,7 +388,7 @@ function setMyStoriesToAllSignalConnections(): ThunkAction<
|
|||
ResetMyStoriesActionType
|
||||
> {
|
||||
return async dispatch => {
|
||||
const myStories = await dataInterface.getStoryDistributionWithMembers(
|
||||
const myStories = await DataReader.getStoryDistributionWithMembers(
|
||||
MY_STORY_ID
|
||||
);
|
||||
|
||||
|
@ -397,7 +400,7 @@ function setMyStoriesToAllSignalConnections(): ThunkAction<
|
|||
}
|
||||
|
||||
if (myStories.isBlockList || myStories.members.length > 0) {
|
||||
await dataInterface.modifyStoryDistributionWithMembers(
|
||||
await DataWriter.modifyStoryDistributionWithMembers(
|
||||
{
|
||||
...myStories,
|
||||
isBlockList: true,
|
||||
|
@ -425,8 +428,9 @@ function updateStoryViewers(
|
|||
memberServiceIds: Array<ServiceIdString>
|
||||
): ThunkAction<void, RootStateType, null, ViewersChangedActionType> {
|
||||
return async dispatch => {
|
||||
const storyDistribution =
|
||||
await dataInterface.getStoryDistributionWithMembers(listId);
|
||||
const storyDistribution = await DataReader.getStoryDistributionWithMembers(
|
||||
listId
|
||||
);
|
||||
|
||||
if (!storyDistribution) {
|
||||
log.warn(
|
||||
|
@ -456,7 +460,7 @@ function updateStoryViewers(
|
|||
}
|
||||
});
|
||||
|
||||
await dataInterface.modifyStoryDistributionWithMembers(
|
||||
await DataWriter.modifyStoryDistributionWithMembers(
|
||||
{
|
||||
...storyDistribution,
|
||||
isBlockList: false,
|
||||
|
@ -489,7 +493,7 @@ function removeMemberFromAllDistributionLists(
|
|||
): ThunkAction<void, RootStateType, null, ModifyListActionType> {
|
||||
return async dispatch => {
|
||||
const logId = `removeMemberFromAllDistributionLists(${member})`;
|
||||
const lists = await dataInterface.getAllStoryDistributionsWithMembers();
|
||||
const lists = await DataReader.getAllStoryDistributionsWithMembers();
|
||||
|
||||
const listsWithMember = lists.filter(({ members }) =>
|
||||
members.includes(member)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import React, { memo } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import type { VerificationTransport } from '../../types/VerificationTransport';
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
import { App } from '../../components/App';
|
||||
import OS from '../../util/os/osMain';
|
||||
import { getConversation } from '../../util/getConversation';
|
||||
|
@ -101,7 +102,7 @@ async function uploadProfile({
|
|||
us.set('profileName', firstName);
|
||||
us.set('profileFamilyName', lastName);
|
||||
us.captureChange('standaloneProfile');
|
||||
await window.Signal.Data.updateConversation(us.attributes);
|
||||
await DataWriter.updateConversation(us.attributes);
|
||||
|
||||
await writeProfile(getConversation(us), {
|
||||
keepAvatar: true,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
import React, { memo, useCallback, useEffect, useMemo } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { DataReader } from '../../sql/Client';
|
||||
import { useItemsActions } from '../ducks/items';
|
||||
import {
|
||||
getNavTabsCollapsed,
|
||||
|
@ -184,7 +185,7 @@ export const SmartCallsTab = memo(function SmartCallsTab() {
|
|||
if (callHistoryFilter == null) {
|
||||
return 0;
|
||||
}
|
||||
const count = await window.Signal.Data.getCallHistoryGroupsCount(
|
||||
const count = await DataReader.getCallHistoryGroupsCount(
|
||||
callHistoryFilter
|
||||
);
|
||||
return count;
|
||||
|
@ -206,7 +207,7 @@ export const SmartCallsTab = memo(function SmartCallsTab() {
|
|||
if (callHistoryFilter == null) {
|
||||
return [];
|
||||
}
|
||||
const results = await window.Signal.Data.getCallHistoryGroups(
|
||||
const results = await DataReader.getCallHistoryGroups(
|
||||
callHistoryFilter,
|
||||
pagination
|
||||
);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import { assert } from 'chai';
|
||||
|
||||
import { strictAssert } from '../util/assert';
|
||||
import { DataWriter } from '../sql/Client';
|
||||
|
||||
import type { ConversationModel } from '../models/conversations';
|
||||
import type { AciString, PniString, ServiceIdString } from '../types/ServiceId';
|
||||
|
@ -32,7 +33,7 @@ describe('ConversationController', () => {
|
|||
) => Promise<void>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await window.Signal.Data._removeAllConversations();
|
||||
await DataWriter._removeAllConversations();
|
||||
|
||||
window.ConversationController.reset();
|
||||
await window.ConversationController.load();
|
||||
|
|
|
@ -6,6 +6,7 @@ import { assert } from 'chai';
|
|||
|
||||
import { type AciString, generateAci } from '../types/ServiceId';
|
||||
import type { MessageAttributesType } from '../model-types';
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
import { SendStatus } from '../messages/MessageSendState';
|
||||
import type {
|
||||
MessageReceiptAttributesType,
|
||||
|
@ -77,7 +78,7 @@ describe('MessageReceipts', () => {
|
|||
},
|
||||
};
|
||||
|
||||
await window.Signal.Data.saveMessage(messageAttributes, {
|
||||
await DataWriter.saveMessage(messageAttributes, {
|
||||
forceSave: true,
|
||||
ourAci,
|
||||
});
|
||||
|
@ -97,7 +98,7 @@ describe('MessageReceipts', () => {
|
|||
),
|
||||
]);
|
||||
|
||||
const messageFromDatabase = await window.Signal.Data.getMessageById(id);
|
||||
const messageFromDatabase = await DataReader.getMessageById(id);
|
||||
const savedSendState = messageFromDatabase?.sendStateByConversationId;
|
||||
|
||||
assert.equal(savedSendState?.aaaa.status, SendStatus.Read, 'aaaa');
|
||||
|
@ -154,11 +155,11 @@ describe('MessageReceipts', () => {
|
|||
],
|
||||
};
|
||||
|
||||
await window.Signal.Data.saveMessage(messageAttributes, {
|
||||
await DataWriter.saveMessage(messageAttributes, {
|
||||
forceSave: true,
|
||||
ourAci,
|
||||
});
|
||||
await window.Signal.Data.saveEditedMessage(messageAttributes, ourAci, {
|
||||
await DataWriter.saveEditedMessage(messageAttributes, ourAci, {
|
||||
conversationId: messageAttributes.conversationId,
|
||||
messageId: messageAttributes.id,
|
||||
readStatus: ReadStatus.Read,
|
||||
|
@ -211,7 +212,7 @@ describe('MessageReceipts', () => {
|
|||
),
|
||||
]);
|
||||
|
||||
const messageFromDatabase = await window.Signal.Data.getMessageById(id);
|
||||
const messageFromDatabase = await DataReader.getMessageById(id);
|
||||
const rootSendState = messageFromDatabase?.sendStateByConversationId;
|
||||
|
||||
assert.deepEqual(
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
} from '@signalapp/libsignal-client';
|
||||
import { v4 as generateUuid } from 'uuid';
|
||||
|
||||
import { DataReader, DataWriter } from '../sql/Client';
|
||||
import { signal } from '../protobuf/compiled';
|
||||
import { sessionStructureToBytes } from '../util/sessionTranslation';
|
||||
import * as durations from '../util/durations';
|
||||
|
@ -295,21 +296,21 @@ describe('SignalProtocolStore', () => {
|
|||
await store.saveIdentity(identifier, testKey.pubKey);
|
||||
});
|
||||
it('marks the key firstUse', async () => {
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(theirAci);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
assert(identity.firstUse);
|
||||
});
|
||||
it('sets the timestamp', async () => {
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(theirAci);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
assert(identity.timestamp);
|
||||
});
|
||||
it('sets the verified status to DEFAULT', async () => {
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(theirAci);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
|
@ -321,7 +322,7 @@ describe('SignalProtocolStore', () => {
|
|||
const oldTimestamp = Date.now();
|
||||
|
||||
before(async () => {
|
||||
await window.Signal.Data.createOrUpdateIdentityKey({
|
||||
await DataWriter.createOrUpdateIdentityKey({
|
||||
id: theirAci,
|
||||
publicKey: testKey.pubKey,
|
||||
firstUse: true,
|
||||
|
@ -334,14 +335,14 @@ describe('SignalProtocolStore', () => {
|
|||
await store.saveIdentity(identifier, newIdentity);
|
||||
});
|
||||
it('marks the key not firstUse', async () => {
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(theirAci);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
assert(!identity.firstUse);
|
||||
});
|
||||
it('updates the timestamp', async () => {
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(theirAci);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
|
@ -350,7 +351,7 @@ describe('SignalProtocolStore', () => {
|
|||
|
||||
describe('The previous verified status was DEFAULT', () => {
|
||||
before(async () => {
|
||||
await window.Signal.Data.createOrUpdateIdentityKey({
|
||||
await DataWriter.createOrUpdateIdentityKey({
|
||||
id: theirAci,
|
||||
publicKey: testKey.pubKey,
|
||||
firstUse: true,
|
||||
|
@ -363,9 +364,7 @@ describe('SignalProtocolStore', () => {
|
|||
await store.saveIdentity(identifier, newIdentity);
|
||||
});
|
||||
it('sets the new key to default', async () => {
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(
|
||||
theirAci
|
||||
);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
|
@ -374,7 +373,7 @@ describe('SignalProtocolStore', () => {
|
|||
});
|
||||
describe('The previous verified status was VERIFIED', () => {
|
||||
before(async () => {
|
||||
await window.Signal.Data.createOrUpdateIdentityKey({
|
||||
await DataWriter.createOrUpdateIdentityKey({
|
||||
id: theirAci,
|
||||
publicKey: testKey.pubKey,
|
||||
firstUse: true,
|
||||
|
@ -387,9 +386,7 @@ describe('SignalProtocolStore', () => {
|
|||
await store.saveIdentity(identifier, newIdentity);
|
||||
});
|
||||
it('sets the new key to unverified', async () => {
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(
|
||||
theirAci
|
||||
);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
|
@ -401,7 +398,7 @@ describe('SignalProtocolStore', () => {
|
|||
});
|
||||
describe('The previous verified status was UNVERIFIED', () => {
|
||||
before(async () => {
|
||||
await window.Signal.Data.createOrUpdateIdentityKey({
|
||||
await DataWriter.createOrUpdateIdentityKey({
|
||||
id: theirAci,
|
||||
publicKey: testKey.pubKey,
|
||||
firstUse: true,
|
||||
|
@ -414,9 +411,7 @@ describe('SignalProtocolStore', () => {
|
|||
await store.saveIdentity(identifier, newIdentity);
|
||||
});
|
||||
it('sets the new key to unverified', async () => {
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(
|
||||
theirAci
|
||||
);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
|
@ -430,7 +425,7 @@ describe('SignalProtocolStore', () => {
|
|||
describe('When the key has not changed', () => {
|
||||
const oldTimestamp = Date.now();
|
||||
before(async () => {
|
||||
await window.Signal.Data.createOrUpdateIdentityKey({
|
||||
await DataWriter.createOrUpdateIdentityKey({
|
||||
id: theirAci,
|
||||
publicKey: testKey.pubKey,
|
||||
timestamp: oldTimestamp,
|
||||
|
@ -442,22 +437,18 @@ describe('SignalProtocolStore', () => {
|
|||
});
|
||||
describe('If it is marked firstUse', () => {
|
||||
before(async () => {
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(
|
||||
theirAci
|
||||
);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
identity.firstUse = true;
|
||||
await window.Signal.Data.createOrUpdateIdentityKey(identity);
|
||||
await DataWriter.createOrUpdateIdentityKey(identity);
|
||||
await store.hydrateCaches();
|
||||
});
|
||||
it('nothing changes', async () => {
|
||||
await store.saveIdentity(identifier, testKey.pubKey, true);
|
||||
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(
|
||||
theirAci
|
||||
);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
|
@ -467,36 +458,30 @@ describe('SignalProtocolStore', () => {
|
|||
});
|
||||
describe('If it is not marked firstUse', () => {
|
||||
before(async () => {
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(
|
||||
theirAci
|
||||
);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
identity.firstUse = false;
|
||||
await window.Signal.Data.createOrUpdateIdentityKey(identity);
|
||||
await DataWriter.createOrUpdateIdentityKey(identity);
|
||||
await store.hydrateCaches();
|
||||
});
|
||||
describe('If nonblocking approval is required', () => {
|
||||
let now: number;
|
||||
before(async () => {
|
||||
now = Date.now();
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(
|
||||
theirAci
|
||||
);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
identity.timestamp = now;
|
||||
await window.Signal.Data.createOrUpdateIdentityKey(identity);
|
||||
await DataWriter.createOrUpdateIdentityKey(identity);
|
||||
await store.hydrateCaches();
|
||||
});
|
||||
it('sets non-blocking approval', async () => {
|
||||
await store.saveIdentity(identifier, testKey.pubKey, true);
|
||||
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(
|
||||
theirAci
|
||||
);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
|
@ -532,35 +517,35 @@ describe('SignalProtocolStore', () => {
|
|||
});
|
||||
|
||||
it('publicKey is saved', async () => {
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(theirAci);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
assert.isTrue(constantTimeEqual(identity.publicKey, testKey.pubKey));
|
||||
});
|
||||
it('firstUse is saved', async () => {
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(theirAci);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
assert.strictEqual(identity.firstUse, true);
|
||||
});
|
||||
it('timestamp is saved', async () => {
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(theirAci);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
assert.strictEqual(identity.timestamp, now);
|
||||
});
|
||||
it('verified is saved', async () => {
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(theirAci);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
assert.strictEqual(identity.verified, store.VerifiedStatus.VERIFIED);
|
||||
});
|
||||
it('nonblockingApproval is saved', async () => {
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(theirAci);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
|
@ -607,7 +592,7 @@ describe('SignalProtocolStore', () => {
|
|||
describe('setApproval', () => {
|
||||
it('sets nonblockingApproval', async () => {
|
||||
await store.setApproval(theirAci, true);
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(theirAci);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
|
@ -617,7 +602,7 @@ describe('SignalProtocolStore', () => {
|
|||
});
|
||||
describe('setVerified', () => {
|
||||
async function saveRecordDefault() {
|
||||
await window.Signal.Data.createOrUpdateIdentityKey({
|
||||
await DataWriter.createOrUpdateIdentityKey({
|
||||
id: theirAci,
|
||||
publicKey: testKey.pubKey,
|
||||
firstUse: true,
|
||||
|
@ -632,7 +617,7 @@ describe('SignalProtocolStore', () => {
|
|||
it('updates the verified status', async () => {
|
||||
await store.setVerified(theirAci, store.VerifiedStatus.VERIFIED);
|
||||
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(theirAci);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
|
@ -646,7 +631,7 @@ describe('SignalProtocolStore', () => {
|
|||
it('updates the verified status', async () => {
|
||||
await store.setVerified(theirAci, store.VerifiedStatus.VERIFIED);
|
||||
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(theirAci);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
|
@ -667,7 +652,7 @@ describe('SignalProtocolStore', () => {
|
|||
keychangeTriggered += 1;
|
||||
});
|
||||
|
||||
await window.Signal.Data.createOrUpdateIdentityKey({
|
||||
await DataWriter.createOrUpdateIdentityKey({
|
||||
id: theirAci,
|
||||
publicKey: testKey.pubKey,
|
||||
timestamp: Date.now() - 10 * 1000 * 60,
|
||||
|
@ -693,7 +678,7 @@ describe('SignalProtocolStore', () => {
|
|||
assert.isFalse(needsNotification);
|
||||
assert.strictEqual(keychangeTriggered, 0);
|
||||
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(newAci);
|
||||
const identity = await DataReader.getIdentityKeyById(newAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
|
@ -712,7 +697,7 @@ describe('SignalProtocolStore', () => {
|
|||
assert.isTrue(needsNotification);
|
||||
assert.strictEqual(keychangeTriggered, 0);
|
||||
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(newAci);
|
||||
const identity = await DataReader.getIdentityKeyById(newAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
|
@ -729,7 +714,7 @@ describe('SignalProtocolStore', () => {
|
|||
assert.isFalse(needsNotification);
|
||||
assert.strictEqual(keychangeTriggered, 1);
|
||||
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(theirAci);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
|
@ -746,7 +731,7 @@ describe('SignalProtocolStore', () => {
|
|||
assert.isTrue(needsNotification);
|
||||
assert.strictEqual(keychangeTriggered, 0);
|
||||
|
||||
const identity = await window.Signal.Data.getIdentityKeyById(theirAci);
|
||||
const identity = await DataReader.getIdentityKeyById(theirAci);
|
||||
if (!identity) {
|
||||
throw new Error('Missing identity!');
|
||||
}
|
||||
|
@ -757,7 +742,7 @@ describe('SignalProtocolStore', () => {
|
|||
|
||||
describe('isUntrusted', () => {
|
||||
it('returns false if identity key old enough', async () => {
|
||||
await window.Signal.Data.createOrUpdateIdentityKey({
|
||||
await DataWriter.createOrUpdateIdentityKey({
|
||||
id: theirAci,
|
||||
publicKey: testKey.pubKey,
|
||||
timestamp: Date.now() - 10 * 1000 * 60,
|
||||
|
@ -772,7 +757,7 @@ describe('SignalProtocolStore', () => {
|
|||
});
|
||||
|
||||
it('returns false if new but nonblockingApproval is true', async () => {
|
||||
await window.Signal.Data.createOrUpdateIdentityKey({
|
||||
await DataWriter.createOrUpdateIdentityKey({
|
||||
id: theirAci,
|
||||
publicKey: testKey.pubKey,
|
||||
timestamp: Date.now(),
|
||||
|
@ -787,7 +772,7 @@ describe('SignalProtocolStore', () => {
|
|||
});
|
||||
|
||||
it('returns false if new but firstUse is true', async () => {
|
||||
await window.Signal.Data.createOrUpdateIdentityKey({
|
||||
await DataWriter.createOrUpdateIdentityKey({
|
||||
id: theirAci,
|
||||
publicKey: testKey.pubKey,
|
||||
timestamp: Date.now(),
|
||||
|
@ -802,7 +787,7 @@ describe('SignalProtocolStore', () => {
|
|||
});
|
||||
|
||||
it('returns true if new, and no flags are set', async () => {
|
||||
await window.Signal.Data.createOrUpdateIdentityKey({
|
||||
await DataWriter.createOrUpdateIdentityKey({
|
||||
id: theirAci,
|
||||
publicKey: testKey.pubKey,
|
||||
timestamp: Date.now(),
|
||||
|
|
|
@ -10,7 +10,7 @@ import { assert } from 'chai';
|
|||
|
||||
import type { ConversationModel } from '../../models/conversations';
|
||||
import * as Bytes from '../../Bytes';
|
||||
import Data from '../../sql/Client';
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
import { type AciString, generateAci } from '../../types/ServiceId';
|
||||
import { ReadStatus } from '../../messages/MessageReadStatus';
|
||||
import { SeenStatus } from '../../MessageSeenStatus';
|
||||
|
@ -39,8 +39,8 @@ describe('backup/attachments', () => {
|
|||
let contactA: ConversationModel;
|
||||
|
||||
beforeEach(async () => {
|
||||
await Data._removeAllMessages();
|
||||
await Data._removeAllConversations();
|
||||
await DataWriter._removeAllMessages();
|
||||
await DataWriter._removeAllConversations();
|
||||
window.storage.reset();
|
||||
|
||||
await setupBasics();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import { v4 as generateGuid } from 'uuid';
|
||||
|
||||
import Data from '../../sql/Client';
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
import { SignalService as Proto } from '../../protobuf';
|
||||
|
||||
import { generateAci, generatePni } from '../../types/ServiceId';
|
||||
|
@ -73,8 +73,8 @@ function createMessage(
|
|||
|
||||
describe('backup/groupv2/notifications', () => {
|
||||
beforeEach(async () => {
|
||||
await Data._removeAllMessages();
|
||||
await Data._removeAllConversations();
|
||||
await DataWriter._removeAllMessages();
|
||||
await DataWriter._removeAllConversations();
|
||||
window.storage.reset();
|
||||
|
||||
await setupBasics();
|
||||
|
|
|
@ -7,7 +7,7 @@ import { SendStatus } from '../../messages/MessageSendState';
|
|||
import type { ConversationModel } from '../../models/conversations';
|
||||
import { GiftBadgeStates } from '../../components/conversation/Message';
|
||||
|
||||
import Data from '../../sql/Client';
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
import { getRandomBytes } from '../../Crypto';
|
||||
import * as Bytes from '../../Bytes';
|
||||
import { generateAci } from '../../types/ServiceId';
|
||||
|
@ -39,8 +39,8 @@ describe('backup/bubble messages', () => {
|
|||
let gv1: ConversationModel;
|
||||
|
||||
beforeEach(async () => {
|
||||
await Data._removeAllMessages();
|
||||
await Data._removeAllConversations();
|
||||
await DataWriter._removeAllMessages();
|
||||
await DataWriter._removeAllConversations();
|
||||
window.storage.reset();
|
||||
|
||||
await setupBasics();
|
||||
|
|
|
@ -5,6 +5,7 @@ import Long from 'long';
|
|||
import { join } from 'path';
|
||||
import * as sinon from 'sinon';
|
||||
import { BackupLevel } from '@signalapp/libsignal-client/zkgroup';
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
import { Backups } from '../../protobuf';
|
||||
import {
|
||||
getFilePointerForAttachment,
|
||||
|
@ -552,7 +553,7 @@ describe('getBackupJobForAttachmentAndFilePointer', async () => {
|
|||
await window.storage.put('masterKey', Bytes.toBase64(getRandomBytes(32)));
|
||||
});
|
||||
afterEach(async () => {
|
||||
await window.Signal.Data.removeAll();
|
||||
await DataWriter.removeAll();
|
||||
});
|
||||
const attachment = composeAttachment();
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import type {
|
|||
import { backupsService } from '../../services/backups';
|
||||
import { isUnsupportedMessage } from '../../state/selectors/message';
|
||||
import { generateAci, generatePni } from '../../types/ServiceId';
|
||||
import Data from '../../sql/Client';
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import { getRandomBytes } from '../../Crypto';
|
||||
import * as Bytes from '../../Bytes';
|
||||
|
||||
|
@ -145,7 +145,7 @@ export async function symmetricRoundtripHarness(
|
|||
}
|
||||
|
||||
async function updateConvoIdToTitle() {
|
||||
const all = await Data.getAllConversations();
|
||||
const all = await DataReader.getAllConversations();
|
||||
for (const convo of all) {
|
||||
CONVO_ID_TO_STABLE_ID.set(
|
||||
convo.id,
|
||||
|
@ -167,7 +167,7 @@ export async function asymmetricRoundtripHarness(
|
|||
try {
|
||||
const targetOutputFile = path.join(outDir, 'backup.bin');
|
||||
|
||||
await Data.saveMessages(before, { forceSave: true, ourAci: OUR_ACI });
|
||||
await DataWriter.saveMessages(before, { forceSave: true, ourAci: OUR_ACI });
|
||||
|
||||
await backupsService.exportToDisk(targetOutputFile, options.backupLevel);
|
||||
|
||||
|
@ -177,7 +177,7 @@ export async function asymmetricRoundtripHarness(
|
|||
|
||||
await backupsService.importBackup(() => createReadStream(targetOutputFile));
|
||||
|
||||
const messagesFromDatabase = await Data._getAllMessages();
|
||||
const messagesFromDatabase = await DataReader._getAllMessages();
|
||||
|
||||
await updateConvoIdToTitle();
|
||||
|
||||
|
@ -199,9 +199,9 @@ export async function asymmetricRoundtripHarness(
|
|||
}
|
||||
|
||||
async function clearData() {
|
||||
await Data._removeAllMessages();
|
||||
await Data._removeAllConversations();
|
||||
await Data.removeAllItems();
|
||||
await DataWriter._removeAllMessages();
|
||||
await DataWriter._removeAllConversations();
|
||||
await DataWriter.removeAllItems();
|
||||
window.storage.reset();
|
||||
window.ConversationController.reset();
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import type { ConversationModel } from '../../models/conversations';
|
|||
import { getRandomBytes } from '../../Crypto';
|
||||
import * as Bytes from '../../Bytes';
|
||||
import { SignalService as Proto, Backups } from '../../protobuf';
|
||||
import Data from '../../sql/Client';
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
import { generateAci } from '../../types/ServiceId';
|
||||
import { PaymentEventKind } from '../../types/Payment';
|
||||
import { ContactFormType } from '../../types/EmbeddedContact';
|
||||
|
@ -32,8 +32,8 @@ describe('backup/non-bubble messages', () => {
|
|||
let group: ConversationModel;
|
||||
|
||||
beforeEach(async () => {
|
||||
await Data._removeAllMessages();
|
||||
await Data._removeAllConversations();
|
||||
await DataWriter._removeAllMessages();
|
||||
await DataWriter._removeAllConversations();
|
||||
window.storage.reset();
|
||||
|
||||
await setupBasics();
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import { assert } from 'chai';
|
||||
import { v4 as generateUuid } from 'uuid';
|
||||
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
import { SendStatus } from '../../messages/MessageSendState';
|
||||
import { IMAGE_PNG } from '../../types/MIME';
|
||||
import { generateAci, generatePni } from '../../types/ServiceId';
|
||||
|
@ -79,7 +80,7 @@ describe('Conversations', () => {
|
|||
});
|
||||
|
||||
// Saving to db and updating the convo's last message
|
||||
await window.Signal.Data.saveMessage(message.attributes, {
|
||||
await DataWriter.saveMessage(message.attributes, {
|
||||
forceSave: true,
|
||||
ourAci,
|
||||
});
|
||||
|
@ -88,7 +89,7 @@ describe('Conversations', () => {
|
|||
message,
|
||||
'test'
|
||||
);
|
||||
await window.Signal.Data.updateConversation(conversation.attributes);
|
||||
await DataWriter.updateConversation(conversation.attributes);
|
||||
await conversation.updateLastMessage();
|
||||
|
||||
// Should be set to bananas because that's the last message sent.
|
||||
|
|
|
@ -13,6 +13,7 @@ import type { MessageModel } from '../../models/messages';
|
|||
import type { RawBodyRange } from '../../types/BodyRange';
|
||||
import type { StorageAccessType } from '../../types/Storage.d';
|
||||
import type { WebAPIType } from '../../textsecure/WebAPI';
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
import MessageSender from '../../textsecure/SendMessage';
|
||||
import enMessages from '../../../_locales/en/messages.json';
|
||||
import { SendStatus } from '../../messages/MessageSendState';
|
||||
|
@ -78,7 +79,7 @@ describe('Message', () => {
|
|||
});
|
||||
|
||||
after(async () => {
|
||||
await window.Signal.Data.removeAll();
|
||||
await DataWriter.removeAll();
|
||||
await window.storage.fetch();
|
||||
|
||||
await Promise.all(
|
||||
|
|
|
@ -19,7 +19,7 @@ import type {
|
|||
StandardAttachmentBackupJobType,
|
||||
ThumbnailAttachmentBackupJobType,
|
||||
} from '../../types/AttachmentBackup';
|
||||
import dataInterface from '../../sql/Client';
|
||||
import { DataWriter } from '../../sql/Client';
|
||||
import { getRandomBytes } from '../../Crypto';
|
||||
import { APPLICATION_OCTET_STREAM, VIDEO_MP4 } from '../../types/MIME';
|
||||
import { createName, getRelativePath } from '../../util/attachmentPath';
|
||||
|
@ -98,7 +98,7 @@ describe('AttachmentBackupManager/JobManager', () => {
|
|||
}
|
||||
|
||||
beforeEach(async () => {
|
||||
await dataInterface.removeAll();
|
||||
await DataWriter.removeAll();
|
||||
await window.storage.put('masterKey', Bytes.toBase64(getRandomBytes(32)));
|
||||
|
||||
sandbox = sinon.createSandbox();
|
||||
|
@ -214,7 +214,7 @@ describe('AttachmentBackupManager/JobManager', () => {
|
|||
}
|
||||
|
||||
async function getAllSavedJobs(): Promise<Array<AttachmentBackupJobType>> {
|
||||
return dataInterface.getNextAttachmentBackupJobs({
|
||||
return DataWriter.getNextAttachmentBackupJobs({
|
||||
limit: 1000,
|
||||
timestamp: Infinity,
|
||||
});
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
type NewAttachmentDownloadJobType,
|
||||
} from '../../jobs/AttachmentDownloadManager';
|
||||
import type { AttachmentDownloadJobType } from '../../types/AttachmentDownload';
|
||||
import dataInterface from '../../sql/Client';
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import { MINUTE } from '../../util/durations';
|
||||
import { type AciString } from '../../types/ServiceId';
|
||||
import { type AttachmentType, AttachmentVariant } from '../../types/Attachment';
|
||||
|
@ -60,7 +60,7 @@ describe('AttachmentDownloadManager/JobManager', () => {
|
|||
let isInCall: sinon.SinonStub;
|
||||
|
||||
beforeEach(async () => {
|
||||
await dataInterface.removeAll();
|
||||
await DataWriter.removeAll();
|
||||
|
||||
sandbox = sinon.createSandbox();
|
||||
clock = sandbox.useFakeTimers();
|
||||
|
@ -99,7 +99,7 @@ describe('AttachmentDownloadManager/JobManager', () => {
|
|||
urgency: AttachmentDownloadUrgency
|
||||
) {
|
||||
// Save message first to satisfy foreign key constraint
|
||||
await dataInterface.saveMessage(
|
||||
await DataWriter.saveMessage(
|
||||
{
|
||||
id: job.messageId,
|
||||
type: 'incoming',
|
||||
|
@ -162,13 +162,13 @@ describe('AttachmentDownloadManager/JobManager', () => {
|
|||
// first. In cases like maybeStartJobs where we prevent re-entrancy, without this,
|
||||
// prior (unfinished) invocations can prevent subsequent calls after the clock is
|
||||
// ticked forward and make tests unreliable
|
||||
await dataInterface.getAllItems();
|
||||
await DataReader.getAllItems();
|
||||
const now = Date.now();
|
||||
while (Date.now() < now + ms) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await clock.tickAsync(downloadManager?.tickInterval ?? 1000);
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await dataInterface.getAllItems();
|
||||
await DataReader.getAllItems();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,7 +187,7 @@ describe('AttachmentDownloadManager/JobManager', () => {
|
|||
it('runs 3 jobs at a time in descending receivedAt order', async () => {
|
||||
const jobs = await addJobs(5);
|
||||
// Confirm they are saved to DB
|
||||
const allJobs = await dataInterface.getNextAttachmentDownloadJobs({
|
||||
const allJobs = await DataWriter.getNextAttachmentDownloadJobs({
|
||||
limit: 100,
|
||||
});
|
||||
|
||||
|
@ -298,8 +298,8 @@ describe('AttachmentDownloadManager/JobManager', () => {
|
|||
assert.strictEqual(runJob.callCount, 2);
|
||||
assertRunJobCalledWith([jobs[1], jobs[0]]);
|
||||
|
||||
const retriedJob = await dataInterface.getAttachmentDownloadJob(jobs[1]);
|
||||
const finishedJob = await dataInterface.getAttachmentDownloadJob(jobs[0]);
|
||||
const retriedJob = await DataReader.getAttachmentDownloadJob(jobs[1]);
|
||||
const finishedJob = await DataReader.getAttachmentDownloadJob(jobs[0]);
|
||||
|
||||
assert.isUndefined(finishedJob);
|
||||
assert.strictEqual(retriedJob?.attempts, 1);
|
||||
|
@ -332,7 +332,7 @@ describe('AttachmentDownloadManager/JobManager', () => {
|
|||
]);
|
||||
|
||||
// Ensure it's been removed after completed
|
||||
assert.isUndefined(await dataInterface.getAttachmentDownloadJob(jobs[1]));
|
||||
assert.isUndefined(await DataReader.getAttachmentDownloadJob(jobs[1]));
|
||||
});
|
||||
|
||||
it('will reset attempts if addJob is called again', async () => {
|
||||
|
@ -382,7 +382,7 @@ describe('AttachmentDownloadManager/JobManager', () => {
|
|||
assert.strictEqual(runJob.callCount, 8);
|
||||
|
||||
// Ensure it's been removed
|
||||
assert.isUndefined(await dataInterface.getAttachmentDownloadJob(jobs[0]));
|
||||
assert.isUndefined(await DataReader.getAttachmentDownloadJob(jobs[0]));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import { assert } from 'chai';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import type { MessageAttributesType } from '../../model-types.d';
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import { MessageModel } from '../../models/messages';
|
||||
import { strictAssert } from '../../util/assert';
|
||||
|
||||
|
@ -358,7 +359,7 @@ describe('MessageCache', () => {
|
|||
timestamp: Date.now(),
|
||||
type: 'incoming',
|
||||
};
|
||||
await window.Signal.Data.saveMessage(messageAttributes, {
|
||||
await DataWriter.saveMessage(messageAttributes, {
|
||||
forceSave: true,
|
||||
ourAci,
|
||||
});
|
||||
|
@ -379,7 +380,7 @@ describe('MessageCache', () => {
|
|||
skipSaveToDatabase: false,
|
||||
});
|
||||
|
||||
const messageFromDatabase = await window.Signal.Data.getMessageById(id);
|
||||
const messageFromDatabase = await DataReader.getMessageById(id);
|
||||
|
||||
assert.deepEqual(newAttributes, messageFromDatabase);
|
||||
});
|
||||
|
|
|
@ -4,18 +4,17 @@
|
|||
import { assert } from 'chai';
|
||||
import { v4 as generateUuid } from 'uuid';
|
||||
|
||||
import dataInterface from '../../sql/Client';
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import { generateAci } from '../../types/ServiceId';
|
||||
|
||||
import type { MessageAttributesType } from '../../model-types.d';
|
||||
|
||||
const {
|
||||
removeAll,
|
||||
_getAllMessages,
|
||||
saveMessages,
|
||||
getMessagesWithVisualMediaAttachments,
|
||||
getMessagesWithFileAttachments,
|
||||
} = dataInterface;
|
||||
} = DataReader;
|
||||
const { removeAll, saveMessages } = DataWriter;
|
||||
|
||||
describe('sql/allMedia', () => {
|
||||
beforeEach(async () => {
|
||||
|
|
|
@ -4,18 +4,14 @@
|
|||
import { assert } from 'chai';
|
||||
import { v4 as generateUuid } from 'uuid';
|
||||
|
||||
import dataInterface from '../../sql/Client';
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import { generateAci } from '../../types/ServiceId';
|
||||
import { DurationInSeconds } from '../../util/durations';
|
||||
|
||||
import type { MessageAttributesType } from '../../model-types.d';
|
||||
|
||||
const {
|
||||
removeAll,
|
||||
_getAllMessages,
|
||||
saveMessages,
|
||||
getConversationMessageStats,
|
||||
} = dataInterface;
|
||||
const { _getAllMessages, getConversationMessageStats } = DataReader;
|
||||
const { removeAll, saveMessages } = DataWriter;
|
||||
|
||||
describe('sql/conversationSummary', () => {
|
||||
beforeEach(async () => {
|
||||
|
|
|
@ -4,18 +4,13 @@
|
|||
import { assert } from 'chai';
|
||||
import { v4 as generateUuid } from 'uuid';
|
||||
|
||||
import dataInterface from '../../sql/Client';
|
||||
import { DataReader, DataWriter } from '../../sql/Client';
|
||||
import { generateAci } from '../../types/ServiceId';
|
||||
|
||||
import type { MessageAttributesType } from '../../model-types.d';
|
||||
|
||||
const {
|
||||
removeAll,
|
||||
_getAllMessages,
|
||||
saveMessages,
|
||||
saveMessage,
|
||||
searchMessages,
|
||||
} = dataInterface;
|
||||
const { _getAllMessages, searchMessages } = DataReader;
|
||||
const { removeAll, saveMessages, saveMessage } = DataWriter;
|
||||
|
||||
describe('sql/searchMessages', () => {
|
||||
beforeEach(async () => {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue