mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
consistency checks fixes
This commit is contained in:
parent
f0b608ddec
commit
78a2c1753e
@ -117,7 +117,6 @@ class Note extends Entity {
|
|||||||
return JSON.parse(content);
|
return JSON.parse(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {Promise} */
|
|
||||||
setContent(content) {
|
setContent(content) {
|
||||||
if (content === null || content === undefined) {
|
if (content === null || content === undefined) {
|
||||||
throw new Error(`Cannot set null content to note ${this.noteId}`);
|
throw new Error(`Cannot set null content to note ${this.noteId}`);
|
||||||
|
@ -100,7 +100,6 @@ class NoteRevision extends Entity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {Promise} */
|
|
||||||
setContent(content) {
|
setContent(content) {
|
||||||
// force updating note itself so that utcDateModified is represented correctly even for the content
|
// force updating note itself so that utcDateModified is represented correctly even for the content
|
||||||
this.forcedChange = true;
|
this.forcedChange = true;
|
||||||
|
@ -24,7 +24,7 @@ class ConsistencyChecks {
|
|||||||
|
|
||||||
for (const res of results) {
|
for (const res of results) {
|
||||||
try {
|
try {
|
||||||
fixerCb(res);
|
sql.transactional(() => fixerCb(res));
|
||||||
|
|
||||||
if (this.autoFix) {
|
if (this.autoFix) {
|
||||||
this.fixedIssues = true;
|
this.fixedIssues = true;
|
||||||
@ -94,7 +94,7 @@ class ConsistencyChecks {
|
|||||||
this.findAndFixIssues(`
|
this.findAndFixIssues(`
|
||||||
SELECT branchId, branches.noteId
|
SELECT branchId, branches.noteId
|
||||||
FROM branches
|
FROM branches
|
||||||
LEFT JOIN notes USING (noteId)
|
LEFT JOIN notes USING (noteId)
|
||||||
WHERE branches.isDeleted = 0
|
WHERE branches.isDeleted = 0
|
||||||
AND notes.noteId IS NULL`,
|
AND notes.noteId IS NULL`,
|
||||||
({branchId, noteId}) => {
|
({branchId, noteId}) => {
|
||||||
@ -112,7 +112,7 @@ class ConsistencyChecks {
|
|||||||
this.findAndFixIssues(`
|
this.findAndFixIssues(`
|
||||||
SELECT branchId, branches.noteId AS parentNoteId
|
SELECT branchId, branches.noteId AS parentNoteId
|
||||||
FROM branches
|
FROM branches
|
||||||
LEFT JOIN notes ON notes.noteId = branches.parentNoteId
|
LEFT JOIN notes ON notes.noteId = branches.parentNoteId
|
||||||
WHERE branches.isDeleted = 0
|
WHERE branches.isDeleted = 0
|
||||||
AND branches.branchId != 'root'
|
AND branches.branchId != 'root'
|
||||||
AND notes.noteId IS NULL`,
|
AND notes.noteId IS NULL`,
|
||||||
@ -131,7 +131,7 @@ class ConsistencyChecks {
|
|||||||
this.findAndFixIssues(`
|
this.findAndFixIssues(`
|
||||||
SELECT attributeId, attributes.noteId
|
SELECT attributeId, attributes.noteId
|
||||||
FROM attributes
|
FROM attributes
|
||||||
LEFT JOIN notes USING (noteId)
|
LEFT JOIN notes USING (noteId)
|
||||||
WHERE attributes.isDeleted = 0
|
WHERE attributes.isDeleted = 0
|
||||||
AND notes.noteId IS NULL`,
|
AND notes.noteId IS NULL`,
|
||||||
({attributeId, noteId}) => {
|
({attributeId, noteId}) => {
|
||||||
@ -149,7 +149,7 @@ class ConsistencyChecks {
|
|||||||
this.findAndFixIssues(`
|
this.findAndFixIssues(`
|
||||||
SELECT attributeId, attributes.value AS noteId
|
SELECT attributeId, attributes.value AS noteId
|
||||||
FROM attributes
|
FROM attributes
|
||||||
LEFT JOIN notes ON notes.noteId = attributes.value
|
LEFT JOIN notes ON notes.noteId = attributes.value
|
||||||
WHERE attributes.isDeleted = 0
|
WHERE attributes.isDeleted = 0
|
||||||
AND attributes.type = 'relation'
|
AND attributes.type = 'relation'
|
||||||
AND notes.noteId IS NULL`,
|
AND notes.noteId IS NULL`,
|
||||||
@ -176,7 +176,7 @@ class ConsistencyChecks {
|
|||||||
SELECT branchId,
|
SELECT branchId,
|
||||||
noteId
|
noteId
|
||||||
FROM branches
|
FROM branches
|
||||||
JOIN notes USING (noteId)
|
JOIN notes USING (noteId)
|
||||||
WHERE notes.isDeleted = 1
|
WHERE notes.isDeleted = 1
|
||||||
AND branches.isDeleted = 0`,
|
AND branches.isDeleted = 0`,
|
||||||
({branchId, noteId}) => {
|
({branchId, noteId}) => {
|
||||||
@ -195,7 +195,7 @@ class ConsistencyChecks {
|
|||||||
SELECT branchId,
|
SELECT branchId,
|
||||||
parentNoteId
|
parentNoteId
|
||||||
FROM branches
|
FROM branches
|
||||||
JOIN notes AS parentNote ON parentNote.noteId = branches.parentNoteId
|
JOIN notes AS parentNote ON parentNote.noteId = branches.parentNoteId
|
||||||
WHERE parentNote.isDeleted = 1
|
WHERE parentNote.isDeleted = 1
|
||||||
AND branches.isDeleted = 0
|
AND branches.isDeleted = 0
|
||||||
`, ({branchId, parentNoteId}) => {
|
`, ({branchId, parentNoteId}) => {
|
||||||
@ -213,7 +213,7 @@ class ConsistencyChecks {
|
|||||||
this.findAndFixIssues(`
|
this.findAndFixIssues(`
|
||||||
SELECT DISTINCT notes.noteId
|
SELECT DISTINCT notes.noteId
|
||||||
FROM notes
|
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
|
WHERE notes.isDeleted = 0
|
||||||
AND branches.branchId IS NULL
|
AND branches.branchId IS NULL
|
||||||
`, ({noteId}) => {
|
`, ({noteId}) => {
|
||||||
@ -285,7 +285,7 @@ class ConsistencyChecks {
|
|||||||
this.findAndFixIssues(`
|
this.findAndFixIssues(`
|
||||||
SELECT notes.noteId
|
SELECT notes.noteId
|
||||||
FROM notes
|
FROM notes
|
||||||
LEFT JOIN note_contents USING (noteId)
|
LEFT JOIN note_contents USING (noteId)
|
||||||
WHERE note_contents.noteId IS NULL`,
|
WHERE note_contents.noteId IS NULL`,
|
||||||
({noteId}) => {
|
({noteId}) => {
|
||||||
if (this.autoFix) {
|
if (this.autoFix) {
|
||||||
@ -316,7 +316,7 @@ class ConsistencyChecks {
|
|||||||
this.findAndFixIssues(`
|
this.findAndFixIssues(`
|
||||||
SELECT noteId
|
SELECT noteId
|
||||||
FROM notes
|
FROM notes
|
||||||
JOIN note_contents USING (noteId)
|
JOIN note_contents USING (noteId)
|
||||||
WHERE isDeleted = 0
|
WHERE isDeleted = 0
|
||||||
AND isProtected = 0
|
AND isProtected = 0
|
||||||
AND content IS NULL`,
|
AND content IS NULL`,
|
||||||
@ -335,7 +335,7 @@ class ConsistencyChecks {
|
|||||||
this.findAndFixIssues(`
|
this.findAndFixIssues(`
|
||||||
SELECT noteId
|
SELECT noteId
|
||||||
FROM notes
|
FROM notes
|
||||||
JOIN note_contents USING (noteId)
|
JOIN note_contents USING (noteId)
|
||||||
WHERE isErased = 1
|
WHERE isErased = 1
|
||||||
AND content IS NOT NULL`,
|
AND content IS NOT NULL`,
|
||||||
({noteId}) => {
|
({noteId}) => {
|
||||||
@ -363,7 +363,7 @@ class ConsistencyChecks {
|
|||||||
this.findAndFixIssues(`
|
this.findAndFixIssues(`
|
||||||
SELECT noteId, noteRevisionId
|
SELECT noteId, noteRevisionId
|
||||||
FROM notes
|
FROM notes
|
||||||
JOIN note_revisions USING (noteId)
|
JOIN note_revisions USING (noteId)
|
||||||
WHERE notes.isErased = 1
|
WHERE notes.isErased = 1
|
||||||
AND note_revisions.isErased = 0`,
|
AND note_revisions.isErased = 0`,
|
||||||
({noteId, noteRevisionId}) => {
|
({noteId, noteRevisionId}) => {
|
||||||
@ -382,7 +382,7 @@ class ConsistencyChecks {
|
|||||||
this.findAndFixIssues(`
|
this.findAndFixIssues(`
|
||||||
SELECT note_revisions.noteRevisionId
|
SELECT note_revisions.noteRevisionId
|
||||||
FROM note_revisions
|
FROM note_revisions
|
||||||
LEFT JOIN note_revision_contents USING (noteRevisionId)
|
LEFT JOIN note_revision_contents USING (noteRevisionId)
|
||||||
WHERE note_revision_contents.noteRevisionId IS NULL
|
WHERE note_revision_contents.noteRevisionId IS NULL
|
||||||
AND note_revisions.isProtected = 0`,
|
AND note_revisions.isProtected = 0`,
|
||||||
({noteRevisionId}) => {
|
({noteRevisionId}) => {
|
||||||
@ -401,7 +401,7 @@ class ConsistencyChecks {
|
|||||||
this.findAndFixIssues(`
|
this.findAndFixIssues(`
|
||||||
SELECT noteRevisionId
|
SELECT noteRevisionId
|
||||||
FROM note_revisions
|
FROM note_revisions
|
||||||
JOIN note_revision_contents USING (noteRevisionId)
|
JOIN note_revision_contents USING (noteRevisionId)
|
||||||
WHERE isErased = 0
|
WHERE isErased = 0
|
||||||
AND content IS NULL`,
|
AND content IS NULL`,
|
||||||
({noteRevisionId}) => {
|
({noteRevisionId}) => {
|
||||||
@ -454,7 +454,7 @@ class ConsistencyChecks {
|
|||||||
this.findAndFixIssues(`
|
this.findAndFixIssues(`
|
||||||
SELECT parentNoteId
|
SELECT parentNoteId
|
||||||
FROM branches
|
FROM branches
|
||||||
JOIN notes ON notes.noteId = branches.parentNoteId
|
JOIN notes ON notes.noteId = branches.parentNoteId
|
||||||
WHERE notes.isDeleted = 0
|
WHERE notes.isDeleted = 0
|
||||||
AND notes.type == 'search'
|
AND notes.type == 'search'
|
||||||
AND branches.isDeleted = 0`,
|
AND branches.isDeleted = 0`,
|
||||||
@ -519,7 +519,7 @@ class ConsistencyChecks {
|
|||||||
SELECT attributeId,
|
SELECT attributeId,
|
||||||
attributes.noteId
|
attributes.noteId
|
||||||
FROM attributes
|
FROM attributes
|
||||||
JOIN notes ON attributes.noteId = notes.noteId
|
JOIN notes ON attributes.noteId = notes.noteId
|
||||||
WHERE attributes.isDeleted = 0
|
WHERE attributes.isDeleted = 0
|
||||||
AND notes.isDeleted = 1`,
|
AND notes.isDeleted = 1`,
|
||||||
({attributeId, noteId}) => {
|
({attributeId, noteId}) => {
|
||||||
@ -538,7 +538,7 @@ class ConsistencyChecks {
|
|||||||
SELECT attributeId,
|
SELECT attributeId,
|
||||||
attributes.value AS targetNoteId
|
attributes.value AS targetNoteId
|
||||||
FROM attributes
|
FROM attributes
|
||||||
JOIN notes ON attributes.value = notes.noteId
|
JOIN notes ON attributes.value = notes.noteId
|
||||||
WHERE attributes.type = 'relation'
|
WHERE attributes.type = 'relation'
|
||||||
AND attributes.isDeleted = 0
|
AND attributes.isDeleted = 0
|
||||||
AND notes.isDeleted = 1`,
|
AND notes.isDeleted = 1`,
|
||||||
@ -605,7 +605,7 @@ class ConsistencyChecks {
|
|||||||
this.runSyncRowChecks("options", "name");
|
this.runSyncRowChecks("options", "name");
|
||||||
}
|
}
|
||||||
|
|
||||||
runAllChecks() {
|
runAllChecksAndFixers() {
|
||||||
this.unrecoveredConsistencyErrors = false;
|
this.unrecoveredConsistencyErrors = false;
|
||||||
this.fixedIssues = false;
|
this.fixedIssues = false;
|
||||||
|
|
||||||
@ -639,34 +639,39 @@ class ConsistencyChecks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runDbDiagnostics() {
|
runDbDiagnostics() {
|
||||||
this.showEntityStat("Notes", `SELECT isDeleted, count(1)
|
this.showEntityStat("Notes",
|
||||||
FROM notes
|
`SELECT isDeleted, count(1)
|
||||||
GROUP BY isDeleted`);
|
FROM notes
|
||||||
this.showEntityStat("Note revisions", `SELECT isErased, count(1)
|
GROUP BY isDeleted`);
|
||||||
FROM note_revisions
|
this.showEntityStat("Note revisions",
|
||||||
GROUP BY isErased`);
|
`SELECT isErased, count(1)
|
||||||
this.showEntityStat("Branches", `SELECT isDeleted, count(1)
|
FROM note_revisions
|
||||||
FROM branches
|
GROUP BY isErased`);
|
||||||
GROUP BY isDeleted`);
|
this.showEntityStat("Branches",
|
||||||
this.showEntityStat("Attributes", `SELECT isDeleted, count(1)
|
`SELECT isDeleted, count(1)
|
||||||
FROM attributes
|
FROM branches
|
||||||
GROUP BY isDeleted`);
|
GROUP BY isDeleted`);
|
||||||
this.showEntityStat("API tokens", `SELECT isDeleted, count(1)
|
this.showEntityStat("Attributes",
|
||||||
FROM api_tokens
|
`SELECT isDeleted, count(1)
|
||||||
GROUP BY isDeleted`);
|
FROM attributes
|
||||||
|
GROUP BY isDeleted`);
|
||||||
|
this.showEntityStat("API tokens",
|
||||||
|
`SELECT isDeleted, count(1)
|
||||||
|
FROM api_tokens
|
||||||
|
GROUP BY isDeleted`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async runChecks() {
|
async runChecks() {
|
||||||
let elapsedTimeMs;
|
let elapsedTimeMs;
|
||||||
|
|
||||||
await syncMutexService.doExclusively(() => {
|
await syncMutexService.doExclusively(() => {
|
||||||
const startTime = new Date();
|
const startTimeMs = Date.now();
|
||||||
|
|
||||||
this.runDbDiagnostics();
|
this.runDbDiagnostics();
|
||||||
|
|
||||||
this.runAllChecks();
|
this.runAllChecksAndFixers();
|
||||||
|
|
||||||
elapsedTimeMs = Date.now() - startTime.getTime();
|
elapsedTimeMs = Date.now() - startTimeMs;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.unrecoveredConsistencyErrors) {
|
if (this.unrecoveredConsistencyErrors) {
|
||||||
|
@ -158,7 +158,8 @@ function getContentDisposition(filename) {
|
|||||||
const STRING_MIME_TYPES = ["application/x-javascript", "image/svg+xml"];
|
const STRING_MIME_TYPES = ["application/x-javascript", "image/svg+xml"];
|
||||||
|
|
||||||
function isStringNote(type, mime) {
|
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/')
|
|| mime.startsWith('text/')
|
||||||
|| STRING_MIME_TYPES.includes(mime);
|
|| STRING_MIME_TYPES.includes(mime);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user