mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
refactoring consistency checks WIP
This commit is contained in:
parent
910cfe9a17
commit
40d2e6ea83
@ -88,38 +88,6 @@ async function checkTreeCycles() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runSyncRowChecks(entityName, key) {
|
|
||||||
await findAndFixIssues(`
|
|
||||||
SELECT
|
|
||||||
${key} as entityId
|
|
||||||
FROM
|
|
||||||
${entityName}
|
|
||||||
LEFT JOIN sync ON sync.entityName = '${entityName}' AND entityId = ${key}
|
|
||||||
WHERE
|
|
||||||
sync.id IS NULL AND ` + (entityName === 'options' ? 'isSynced = 1' : '1'),
|
|
||||||
async ({entityId}) => {
|
|
||||||
await syncTableService.addEntitySync(entityName, entityId);
|
|
||||||
|
|
||||||
logFix(`Created missing sync record entityName=${entityName}, entityId=${entityId}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
await findAndFixIssues(`
|
|
||||||
SELECT
|
|
||||||
id, entityId
|
|
||||||
FROM
|
|
||||||
sync
|
|
||||||
LEFT JOIN ${entityName} ON entityId = ${key}
|
|
||||||
WHERE
|
|
||||||
sync.entityName = '${entityName}'
|
|
||||||
AND ${key} IS NULL`,
|
|
||||||
async ({id, entityId}) => {
|
|
||||||
|
|
||||||
await sql.execute("DELETE FROM sync WHERE entityName = ? AND entityId = ?", [entityName, entityId]);
|
|
||||||
|
|
||||||
logFix(`Deleted extra sync record id=${id}, entityName=${entityName}, entityId=${entityId}`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function findBrokenReferenceIssues() {
|
async function findBrokenReferenceIssues() {
|
||||||
await findIssues(`
|
await findIssues(`
|
||||||
SELECT branchId, branches.noteId
|
SELECT branchId, branches.noteId
|
||||||
@ -165,7 +133,7 @@ async function findBrokenReferenceIssues() {
|
|||||||
({noteRevisionId, noteId}) => `Note revision ${noteRevisionId} references missing note ${noteId}`);
|
({noteRevisionId, noteId}) => `Note revision ${noteRevisionId} references missing note ${noteId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function findAndFixExistencyIssues() {
|
async function findExistencyIssues() {
|
||||||
// principle for fixing inconsistencies is that if the note itself is deleted (isDeleted=true) then all related entities should be also deleted (branches, links, attributes)
|
// principle for fixing inconsistencies is that if the note itself is deleted (isDeleted=true) then all related entities should be also deleted (branches, links, attributes)
|
||||||
// but if note is not deleted, then at least one branch should exist.
|
// but if note is not deleted, then at least one branch should exist.
|
||||||
|
|
||||||
@ -233,13 +201,7 @@ async function findAndFixExistencyIssues() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runAllChecks() {
|
async function findLogicIssues() {
|
||||||
outstandingConsistencyErrors = false;
|
|
||||||
|
|
||||||
await findBrokenReferenceIssues();
|
|
||||||
|
|
||||||
await findAndFixExistencyIssues();
|
|
||||||
|
|
||||||
await findIssues( `
|
await findIssues( `
|
||||||
SELECT noteId, type
|
SELECT noteId, type
|
||||||
FROM notes
|
FROM notes
|
||||||
@ -270,13 +232,13 @@ async function runAllChecks() {
|
|||||||
isDeleted = 0
|
isDeleted = 0
|
||||||
AND type = 'relation'
|
AND type = 'relation'
|
||||||
AND value = ''`,
|
AND value = ''`,
|
||||||
async ({attributeId}) => {
|
async ({attributeId}) => {
|
||||||
const relation = await repository.getAttribute(attributeId);
|
const relation = await repository.getAttribute(attributeId);
|
||||||
relation.isDeleted = true;
|
relation.isDeleted = true;
|
||||||
await relation.save();
|
await relation.save();
|
||||||
|
|
||||||
logFix(`Removed relation ${relation.attributeId} of name "${relation.name} with empty target.`);
|
logFix(`Removed relation ${relation.attributeId} of name "${relation.name} with empty target.`);
|
||||||
});
|
});
|
||||||
|
|
||||||
await findIssues(`
|
await findIssues(`
|
||||||
SELECT
|
SELECT
|
||||||
@ -374,13 +336,47 @@ async function runAllChecks() {
|
|||||||
links.isDeleted = 0
|
links.isDeleted = 0
|
||||||
AND targetNote.isDeleted = 1`,
|
AND targetNote.isDeleted = 1`,
|
||||||
async ({linkId, targetNoteId}) => {
|
async ({linkId, targetNoteId}) => {
|
||||||
const link = await repository.getLink(linkId);
|
const link = await repository.getLink(linkId);
|
||||||
link.isDeleted = true;
|
link.isDeleted = true;
|
||||||
await link.save();
|
await link.save();
|
||||||
|
|
||||||
logFix(`Removed link ${linkId} because target note ${targetNoteId} is also deleted.`);
|
logFix(`Removed link ${linkId} because target note ${targetNoteId} is also deleted.`);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function runSyncRowChecks(entityName, key) {
|
||||||
|
await findAndFixIssues(`
|
||||||
|
SELECT
|
||||||
|
${key} as entityId
|
||||||
|
FROM
|
||||||
|
${entityName}
|
||||||
|
LEFT JOIN sync ON sync.entityName = '${entityName}' AND entityId = ${key}
|
||||||
|
WHERE
|
||||||
|
sync.id IS NULL AND ` + (entityName === 'options' ? 'isSynced = 1' : '1'),
|
||||||
|
async ({entityId}) => {
|
||||||
|
await syncTableService.addEntitySync(entityName, entityId);
|
||||||
|
|
||||||
|
logFix(`Created missing sync record entityName=${entityName}, entityId=${entityId}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
await findAndFixIssues(`
|
||||||
|
SELECT
|
||||||
|
id, entityId
|
||||||
|
FROM
|
||||||
|
sync
|
||||||
|
LEFT JOIN ${entityName} ON entityId = ${key}
|
||||||
|
WHERE
|
||||||
|
sync.entityName = '${entityName}'
|
||||||
|
AND ${key} IS NULL`,
|
||||||
|
async ({id, entityId}) => {
|
||||||
|
|
||||||
|
await sql.execute("DELETE FROM sync WHERE entityName = ? AND entityId = ?", [entityName, entityId]);
|
||||||
|
|
||||||
|
logFix(`Deleted extra sync record id=${id}, entityName=${entityName}, entityId=${entityId}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function findSyncRowsIssues() {
|
||||||
await runSyncRowChecks("notes", "noteId");
|
await runSyncRowChecks("notes", "noteId");
|
||||||
await runSyncRowChecks("note_revisions", "noteRevisionId");
|
await runSyncRowChecks("note_revisions", "noteRevisionId");
|
||||||
await runSyncRowChecks("branches", "branchId");
|
await runSyncRowChecks("branches", "branchId");
|
||||||
@ -388,6 +384,18 @@ async function runAllChecks() {
|
|||||||
await runSyncRowChecks("attributes", "attributeId");
|
await runSyncRowChecks("attributes", "attributeId");
|
||||||
await runSyncRowChecks("api_tokens", "apiTokenId");
|
await runSyncRowChecks("api_tokens", "apiTokenId");
|
||||||
await runSyncRowChecks("options", "name");
|
await runSyncRowChecks("options", "name");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function runAllChecks() {
|
||||||
|
outstandingConsistencyErrors = false;
|
||||||
|
|
||||||
|
await findBrokenReferenceIssues();
|
||||||
|
|
||||||
|
await findExistencyIssues();
|
||||||
|
|
||||||
|
await findLogicIssues();
|
||||||
|
|
||||||
|
await findSyncRowsIssues();
|
||||||
|
|
||||||
if (outstandingConsistencyErrors) {
|
if (outstandingConsistencyErrors) {
|
||||||
// we run this only if basic checks passed since this assumes basic data consistency
|
// we run this only if basic checks passed since this assumes basic data consistency
|
||||||
|
Loading…
x
Reference in New Issue
Block a user