From 8a777d9d8c7f4c2643374b6aa840cf4a9680a178 Mon Sep 17 00:00:00 2001 From: losfair Date: Mon, 1 Aug 2022 17:52:58 +0000 Subject: [PATCH] Run zip import in a transaction. --- src/services/import/zip.js | 51 ++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/src/services/import/zip.js b/src/services/import/zip.js index 09639c3b18..ea6aea7bad 100644 --- a/src/services/import/zip.js +++ b/src/services/import/zip.js @@ -5,6 +5,7 @@ const utils = require('../../services/utils'); const log = require('../../services/log'); const noteService = require('../../services/notes'); const attributeService = require('../../services/attributes'); +const sql = require("../../services/sql"); const Branch = require('../../becca/entities/branch'); const path = require('path'); const commonmark = require('commonmark'); @@ -479,44 +480,52 @@ async function importZip(taskContext, fileBuffer, importRootNote) { zipfile.readEntry(); }); + const tasks = []; + await readZipFile(fileBuffer, async (zipfile, entry) => { const filePath = normalizeFilePath(entry.fileName); if (/\/$/.test(entry.fileName)) { - saveDirectory(filePath); + tasks.push(() => saveDirectory(filePath)); } else if (filePath !== '!!!meta.json') { const content = await readContent(zipfile, entry); - saveNote(filePath, content); + tasks.push(() => saveNote(filePath, content)); } taskContext.increaseProgressCount(); zipfile.readEntry(); }); - for (const noteId in createdNoteIds) { // now the noteIds are unique - noteService.scanForLinks(becca.getNote(noteId)); - - if (!metaFile) { - // if there's no meta file then the notes are created based on the order in that zip file but that - // is usually quite random so we sort the notes in the way they would appear in the file manager - treeService.sortNotes(noteId, 'title', false, true); + sql.transactional(() => { + for (const task of tasks) { + task(); } - taskContext.increaseProgressCount(); - } - - // we're saving attributes and links only now so that all relation and link target notes - // are already in the database (we don't want to have "broken" relations, not even transitionally) - for (const attr of attributes) { - if (attr.type !== 'relation' || attr.value in createdNoteIds) { - new Attribute(attr).save(); - } - else { - log.info("Relation not imported since target note doesn't exist: " + JSON.stringify(attr)); + for (const noteId in createdNoteIds) { // now the noteIds are unique + noteService.scanForLinks(becca.getNote(noteId)); + + if (!metaFile) { + // if there's no meta file then the notes are created based on the order in that zip file but that + // is usually quite random so we sort the notes in the way they would appear in the file manager + treeService.sortNotes(noteId, 'title', false, true); + } + + taskContext.increaseProgressCount(); + } + + // we're saving attributes and links only now so that all relation and link target notes + // are already in the database (we don't want to have "broken" relations, not even transitionally) + for (const attr of attributes) { + if (attr.type !== 'relation' || attr.value in createdNoteIds) { + new Attribute(attr).save(); + } + else { + log.info("Relation not imported since target note doesn't exist: " + JSON.stringify(attr)); + } } - } + }); return firstNote; }