From 78a2c1753e2886bbf394cdb6d065d08ece00ce00 Mon Sep 17 00:00:00 2001 From: zadam Date: Wed, 1 Jul 2020 22:42:59 +0200 Subject: [PATCH] consistency checks fixes --- src/entities/note.js | 1 - src/entities/note_revision.js | 1 - src/services/consistency_checks.js | 77 ++++++++++++++++-------------- src/services/utils.js | 3 +- 4 files changed, 43 insertions(+), 39 deletions(-) diff --git a/src/entities/note.js b/src/entities/note.js index caac1885b..6c759691a 100644 --- a/src/entities/note.js +++ b/src/entities/note.js @@ -117,7 +117,6 @@ class Note extends Entity { return JSON.parse(content); } - /** @returns {Promise} */ setContent(content) { if (content === null || content === undefined) { throw new Error(`Cannot set null content to note ${this.noteId}`); diff --git a/src/entities/note_revision.js b/src/entities/note_revision.js index ae4c2135e..41ec8159c 100644 --- a/src/entities/note_revision.js +++ b/src/entities/note_revision.js @@ -100,7 +100,6 @@ class NoteRevision extends Entity { } } - /** @returns {Promise} */ setContent(content) { // force updating note itself so that utcDateModified is represented correctly even for the content this.forcedChange = true; diff --git a/src/services/consistency_checks.js b/src/services/consistency_checks.js index fc2bd651e..19588f79b 100644 --- a/src/services/consistency_checks.js +++ b/src/services/consistency_checks.js @@ -24,7 +24,7 @@ class ConsistencyChecks { for (const res of results) { try { - fixerCb(res); + sql.transactional(() => fixerCb(res)); if (this.autoFix) { this.fixedIssues = true; @@ -94,7 +94,7 @@ class ConsistencyChecks { this.findAndFixIssues(` SELECT branchId, branches.noteId FROM branches - LEFT JOIN notes USING (noteId) + LEFT JOIN notes USING (noteId) WHERE branches.isDeleted = 0 AND notes.noteId IS NULL`, ({branchId, noteId}) => { @@ -112,7 +112,7 @@ class ConsistencyChecks { this.findAndFixIssues(` SELECT branchId, branches.noteId AS parentNoteId FROM branches - LEFT JOIN notes ON notes.noteId = branches.parentNoteId + LEFT JOIN notes ON notes.noteId = branches.parentNoteId WHERE branches.isDeleted = 0 AND branches.branchId != 'root' AND notes.noteId IS NULL`, @@ -131,7 +131,7 @@ class ConsistencyChecks { this.findAndFixIssues(` SELECT attributeId, attributes.noteId FROM attributes - LEFT JOIN notes USING (noteId) + LEFT JOIN notes USING (noteId) WHERE attributes.isDeleted = 0 AND notes.noteId IS NULL`, ({attributeId, noteId}) => { @@ -149,7 +149,7 @@ class ConsistencyChecks { this.findAndFixIssues(` SELECT attributeId, attributes.value AS noteId FROM attributes - LEFT JOIN notes ON notes.noteId = attributes.value + LEFT JOIN notes ON notes.noteId = attributes.value WHERE attributes.isDeleted = 0 AND attributes.type = 'relation' AND notes.noteId IS NULL`, @@ -176,7 +176,7 @@ class ConsistencyChecks { SELECT branchId, noteId FROM branches - JOIN notes USING (noteId) + JOIN notes USING (noteId) WHERE notes.isDeleted = 1 AND branches.isDeleted = 0`, ({branchId, noteId}) => { @@ -195,7 +195,7 @@ class ConsistencyChecks { SELECT branchId, parentNoteId FROM branches - JOIN notes AS parentNote ON parentNote.noteId = branches.parentNoteId + JOIN notes AS parentNote ON parentNote.noteId = branches.parentNoteId WHERE parentNote.isDeleted = 1 AND branches.isDeleted = 0 `, ({branchId, parentNoteId}) => { @@ -213,7 +213,7 @@ class ConsistencyChecks { this.findAndFixIssues(` SELECT DISTINCT notes.noteId FROM notes - LEFT JOIN branches ON notes.noteId = branches.noteId AND branches.isDeleted = 0 + LEFT JOIN branches ON notes.noteId = branches.noteId AND branches.isDeleted = 0 WHERE notes.isDeleted = 0 AND branches.branchId IS NULL `, ({noteId}) => { @@ -285,7 +285,7 @@ class ConsistencyChecks { this.findAndFixIssues(` SELECT notes.noteId FROM notes - LEFT JOIN note_contents USING (noteId) + LEFT JOIN note_contents USING (noteId) WHERE note_contents.noteId IS NULL`, ({noteId}) => { if (this.autoFix) { @@ -316,7 +316,7 @@ class ConsistencyChecks { this.findAndFixIssues(` SELECT noteId FROM notes - JOIN note_contents USING (noteId) + JOIN note_contents USING (noteId) WHERE isDeleted = 0 AND isProtected = 0 AND content IS NULL`, @@ -335,7 +335,7 @@ class ConsistencyChecks { this.findAndFixIssues(` SELECT noteId FROM notes - JOIN note_contents USING (noteId) + JOIN note_contents USING (noteId) WHERE isErased = 1 AND content IS NOT NULL`, ({noteId}) => { @@ -363,7 +363,7 @@ class ConsistencyChecks { this.findAndFixIssues(` SELECT noteId, noteRevisionId FROM notes - JOIN note_revisions USING (noteId) + JOIN note_revisions USING (noteId) WHERE notes.isErased = 1 AND note_revisions.isErased = 0`, ({noteId, noteRevisionId}) => { @@ -382,7 +382,7 @@ class ConsistencyChecks { this.findAndFixIssues(` SELECT note_revisions.noteRevisionId FROM note_revisions - LEFT JOIN note_revision_contents USING (noteRevisionId) + LEFT JOIN note_revision_contents USING (noteRevisionId) WHERE note_revision_contents.noteRevisionId IS NULL AND note_revisions.isProtected = 0`, ({noteRevisionId}) => { @@ -401,7 +401,7 @@ class ConsistencyChecks { this.findAndFixIssues(` SELECT noteRevisionId FROM note_revisions - JOIN note_revision_contents USING (noteRevisionId) + JOIN note_revision_contents USING (noteRevisionId) WHERE isErased = 0 AND content IS NULL`, ({noteRevisionId}) => { @@ -454,7 +454,7 @@ class ConsistencyChecks { this.findAndFixIssues(` SELECT parentNoteId FROM branches - JOIN notes ON notes.noteId = branches.parentNoteId + JOIN notes ON notes.noteId = branches.parentNoteId WHERE notes.isDeleted = 0 AND notes.type == 'search' AND branches.isDeleted = 0`, @@ -519,7 +519,7 @@ class ConsistencyChecks { SELECT attributeId, attributes.noteId FROM attributes - JOIN notes ON attributes.noteId = notes.noteId + JOIN notes ON attributes.noteId = notes.noteId WHERE attributes.isDeleted = 0 AND notes.isDeleted = 1`, ({attributeId, noteId}) => { @@ -538,7 +538,7 @@ class ConsistencyChecks { SELECT attributeId, attributes.value AS targetNoteId FROM attributes - JOIN notes ON attributes.value = notes.noteId + JOIN notes ON attributes.value = notes.noteId WHERE attributes.type = 'relation' AND attributes.isDeleted = 0 AND notes.isDeleted = 1`, @@ -605,7 +605,7 @@ class ConsistencyChecks { this.runSyncRowChecks("options", "name"); } - runAllChecks() { + runAllChecksAndFixers() { this.unrecoveredConsistencyErrors = false; this.fixedIssues = false; @@ -639,34 +639,39 @@ class ConsistencyChecks { } runDbDiagnostics() { - this.showEntityStat("Notes", `SELECT isDeleted, count(1) - FROM notes - GROUP BY isDeleted`); - this.showEntityStat("Note revisions", `SELECT isErased, count(1) - FROM note_revisions - GROUP BY isErased`); - this.showEntityStat("Branches", `SELECT isDeleted, count(1) - FROM branches - GROUP BY isDeleted`); - this.showEntityStat("Attributes", `SELECT isDeleted, count(1) - FROM attributes - GROUP BY isDeleted`); - this.showEntityStat("API tokens", `SELECT isDeleted, count(1) - FROM api_tokens - GROUP BY isDeleted`); + this.showEntityStat("Notes", + `SELECT isDeleted, count(1) + FROM notes + GROUP BY isDeleted`); + this.showEntityStat("Note revisions", + `SELECT isErased, count(1) + FROM note_revisions + GROUP BY isErased`); + this.showEntityStat("Branches", + `SELECT isDeleted, count(1) + FROM branches + GROUP BY isDeleted`); + this.showEntityStat("Attributes", + `SELECT isDeleted, count(1) + FROM attributes + GROUP BY isDeleted`); + this.showEntityStat("API tokens", + `SELECT isDeleted, count(1) + FROM api_tokens + GROUP BY isDeleted`); } async runChecks() { let elapsedTimeMs; await syncMutexService.doExclusively(() => { - const startTime = new Date(); + const startTimeMs = Date.now(); this.runDbDiagnostics(); - this.runAllChecks(); + this.runAllChecksAndFixers(); - elapsedTimeMs = Date.now() - startTime.getTime(); + elapsedTimeMs = Date.now() - startTimeMs; }); if (this.unrecoveredConsistencyErrors) { diff --git a/src/services/utils.js b/src/services/utils.js index 7e4bc76f6..c180bea5b 100644 --- a/src/services/utils.js +++ b/src/services/utils.js @@ -158,7 +158,8 @@ function getContentDisposition(filename) { const STRING_MIME_TYPES = ["application/x-javascript", "image/svg+xml"]; function isStringNote(type, mime) { - return ["text", "code", "relation-map", "search"].includes(type) + // render and book are string note in the sense that they are expected to contain empty string + return ["text", "code", "relation-map", "search", "render", "book"].includes(type) || mime.startsWith('text/') || STRING_MIME_TYPES.includes(mime); }