Remove groups table, conversation is single source of truth
This commit is contained in:
parent
b69eea543c
commit
5b54c9554e
16 changed files with 214 additions and 912 deletions
|
@ -109,9 +109,9 @@ function createOutputStream(writer) {
|
|||
};
|
||||
}
|
||||
|
||||
async function exportContactAndGroupsToFile(parent) {
|
||||
async function exportConversationListToFile(parent) {
|
||||
const writer = await createFileAndWriter(parent, 'db.json');
|
||||
return exportContactsAndGroups(writer);
|
||||
return exportConversationList(writer);
|
||||
}
|
||||
|
||||
function writeArray(stream, array) {
|
||||
|
@ -137,7 +137,7 @@ function getPlainJS(collection) {
|
|||
return collection.map(model => model.attributes);
|
||||
}
|
||||
|
||||
async function exportContactsAndGroups(fileWriter) {
|
||||
async function exportConversationList(fileWriter) {
|
||||
const stream = createOutputStream(fileWriter);
|
||||
|
||||
stream.write('{');
|
||||
|
@ -149,13 +149,6 @@ async function exportContactsAndGroups(fileWriter) {
|
|||
window.log.info(`Exporting ${conversations.length} conversations`);
|
||||
writeArray(stream, getPlainJS(conversations));
|
||||
|
||||
stream.write(',');
|
||||
|
||||
stream.write('"groups": ');
|
||||
const groups = await window.Signal.Data.getAllGroups();
|
||||
window.log.info(`Exporting ${groups.length} groups`);
|
||||
writeArray(stream, groups);
|
||||
|
||||
stream.write('}');
|
||||
await stream.close();
|
||||
}
|
||||
|
@ -167,7 +160,7 @@ async function importNonMessages(parent, options) {
|
|||
}
|
||||
|
||||
function eliminateClientConfigInBackup(data, targetPath) {
|
||||
const cleaned = _.pick(data, 'conversations', 'groups');
|
||||
const cleaned = _.pick(data, 'conversations');
|
||||
window.log.info('Writing configuration-free backup file back to disk');
|
||||
try {
|
||||
fs.writeFileSync(targetPath, JSON.stringify(cleaned));
|
||||
|
@ -223,10 +216,8 @@ async function importFromJsonString(jsonString, targetPath, options) {
|
|||
_.defaults(options, {
|
||||
forceLightImport: false,
|
||||
conversationLookup: {},
|
||||
groupLookup: {},
|
||||
});
|
||||
|
||||
const { groupLookup } = options;
|
||||
const result = {
|
||||
fullImport: true,
|
||||
};
|
||||
|
@ -251,7 +242,7 @@ async function importFromJsonString(jsonString, targetPath, options) {
|
|||
|
||||
// We mutate the on-disk backup to prevent the user from importing client
|
||||
// configuration more than once - that causes lots of encryption errors.
|
||||
// This of course preserves the true data: conversations and groups.
|
||||
// This of course preserves the true data: conversations.
|
||||
eliminateClientConfigInBackup(importObject, targetPath);
|
||||
|
||||
const storeNames = _.keys(importObject);
|
||||
|
@ -262,12 +253,12 @@ async function importFromJsonString(jsonString, targetPath, options) {
|
|||
const remainingStoreNames = _.without(
|
||||
storeNames,
|
||||
'conversations',
|
||||
'unprocessed'
|
||||
'unprocessed',
|
||||
'groups' // in old data sets, but no longer included in database schema
|
||||
);
|
||||
await importConversationsFromJSON(conversations, options);
|
||||
|
||||
const SAVE_FUNCTIONS = {
|
||||
groups: window.Signal.Data.createOrUpdateGroup,
|
||||
identityKeys: window.Signal.Data.createOrUpdateIdentityKey,
|
||||
items: window.Signal.Data.createOrUpdateItem,
|
||||
preKeys: window.Signal.Data.createOrUpdatePreKey,
|
||||
|
@ -292,29 +283,17 @@ async function importFromJsonString(jsonString, targetPath, options) {
|
|||
return;
|
||||
}
|
||||
|
||||
let skipCount = 0;
|
||||
|
||||
for (let i = 0, max = toImport.length; i < max; i += 1) {
|
||||
const toAdd = unstringify(toImport[i]);
|
||||
|
||||
const haveGroupAlready =
|
||||
storeName === 'groups' && groupLookup[getGroupKey(toAdd)];
|
||||
|
||||
if (haveGroupAlready) {
|
||||
skipCount += 1;
|
||||
} else {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await save(toAdd);
|
||||
}
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await save(toAdd);
|
||||
}
|
||||
|
||||
window.log.info(
|
||||
'Done importing to store',
|
||||
storeName,
|
||||
'Total count:',
|
||||
toImport.length,
|
||||
'Skipped:',
|
||||
skipCount
|
||||
toImport.length
|
||||
);
|
||||
})
|
||||
);
|
||||
|
@ -1160,14 +1139,6 @@ async function loadConversationLookup() {
|
|||
return fromPairs(map(array, item => [getConversationKey(item), true]));
|
||||
}
|
||||
|
||||
function getGroupKey(group) {
|
||||
return group.id;
|
||||
}
|
||||
async function loadGroupsLookup() {
|
||||
const array = await window.Signal.Data.getAllGroupIds();
|
||||
return fromPairs(map(array, item => [getGroupKey(item), true]));
|
||||
}
|
||||
|
||||
function getDirectoryForExport() {
|
||||
return getDirectory();
|
||||
}
|
||||
|
@ -1254,7 +1225,7 @@ async function exportToDirectory(directory, options) {
|
|||
|
||||
const attachmentsDir = await createDirectory(directory, 'attachments');
|
||||
|
||||
await exportContactAndGroupsToFile(stagingDir);
|
||||
await exportConversationListToFile(stagingDir);
|
||||
await exportConversations(
|
||||
Object.assign({}, options, {
|
||||
messagesDir: stagingDir,
|
||||
|
@ -1298,13 +1269,11 @@ async function importFromDirectory(directory, options) {
|
|||
const lookups = await Promise.all([
|
||||
loadMessagesLookup(),
|
||||
loadConversationLookup(),
|
||||
loadGroupsLookup(),
|
||||
]);
|
||||
const [messageLookup, conversationLookup, groupLookup] = lookups;
|
||||
const [messageLookup, conversationLookup] = lookups;
|
||||
options = Object.assign({}, options, {
|
||||
messageLookup,
|
||||
conversationLookup,
|
||||
groupLookup,
|
||||
});
|
||||
|
||||
const archivePath = path.join(directory, ARCHIVE_NAME);
|
||||
|
|
|
@ -47,14 +47,6 @@ module.exports = {
|
|||
removeDB,
|
||||
removeIndexedDBFiles,
|
||||
|
||||
createOrUpdateGroup,
|
||||
getGroupById,
|
||||
getAllGroupIds,
|
||||
getAllGroups,
|
||||
bulkAddGroups,
|
||||
removeGroupById,
|
||||
removeAllGroups,
|
||||
|
||||
createOrUpdateIdentityKey,
|
||||
getIdentityKeyById,
|
||||
bulkAddIdentityKeys,
|
||||
|
@ -395,33 +387,6 @@ async function removeIndexedDBFiles() {
|
|||
await channels.removeIndexedDBFiles();
|
||||
}
|
||||
|
||||
// Groups
|
||||
|
||||
async function createOrUpdateGroup(data) {
|
||||
await channels.createOrUpdateGroup(data);
|
||||
}
|
||||
async function getGroupById(id) {
|
||||
const group = await channels.getGroupById(id);
|
||||
return group;
|
||||
}
|
||||
async function getAllGroupIds() {
|
||||
const ids = await channels.getAllGroupIds();
|
||||
return ids;
|
||||
}
|
||||
async function getAllGroups() {
|
||||
const groups = await channels.getAllGroups();
|
||||
return groups;
|
||||
}
|
||||
async function bulkAddGroups(array) {
|
||||
await channels.bulkAddGroups(array);
|
||||
}
|
||||
async function removeGroupById(id) {
|
||||
await channels.removeGroupById(id);
|
||||
}
|
||||
async function removeAllGroups() {
|
||||
await channels.removeAllGroups();
|
||||
}
|
||||
|
||||
// Identity Keys
|
||||
|
||||
const IDENTITY_KEY_KEYS = ['publicKey'];
|
||||
|
|
|
@ -2,14 +2,12 @@
|
|||
|
||||
const { includes, isFunction, isString, last, map } = require('lodash');
|
||||
const {
|
||||
bulkAddGroups,
|
||||
bulkAddSessions,
|
||||
bulkAddIdentityKeys,
|
||||
bulkAddPreKeys,
|
||||
bulkAddSignedPreKeys,
|
||||
bulkAddItems,
|
||||
|
||||
removeGroupById,
|
||||
removeSessionById,
|
||||
removeIdentityKeyById,
|
||||
removePreKeyById,
|
||||
|
@ -184,31 +182,6 @@ async function migrateToSQL({
|
|||
complete = false;
|
||||
lastIndex = null;
|
||||
|
||||
while (!complete) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const status = await migrateStoreToSQLite({
|
||||
db,
|
||||
// eslint-disable-next-line no-loop-func
|
||||
save: bulkAddGroups,
|
||||
remove: removeGroupById,
|
||||
storeName: 'groups',
|
||||
handleDOMException,
|
||||
lastIndex,
|
||||
batchSize: 10,
|
||||
});
|
||||
|
||||
({ complete, lastIndex } = status);
|
||||
}
|
||||
window.log.info('migrateToSQL: migrate of groups complete');
|
||||
try {
|
||||
await clearStores(['groups']);
|
||||
} catch (error) {
|
||||
window.log.warn('Failed to clear groups store');
|
||||
}
|
||||
|
||||
complete = false;
|
||||
lastIndex = null;
|
||||
|
||||
while (!complete) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const status = await migrateStoreToSQLite({
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue