diff --git a/src/public/app/services/entrypoints.js b/src/public/app/services/entrypoints.js index 073150d52..42e4f79ee 100644 --- a/src/public/app/services/entrypoints.js +++ b/src/public/app/services/entrypoints.js @@ -213,9 +213,13 @@ export default class Entrypoints extends Component { } else if (note.mime.endsWith("env=backend")) { await server.post('script/run/' + note.noteId); } else if (note.mime === 'text/x-sqlite;schema=trilium') { - const {results} = await server.post("sql/execute/" + note.noteId); + const resp = await server.post("sql/execute/" + note.noteId); - await appContext.triggerEvent('sqlQueryResults', {ntxId: ntxId, results: results}); + if (!resp.success) { + alert("Error occurred while executing SQL query: " + resp.message); + } + + await appContext.triggerEvent('sqlQueryResults', {ntxId: ntxId, results: resp.results}); } toastService.showMessage("Note executed"); diff --git a/src/services/consistency_checks.js b/src/services/consistency_checks.js index f12f930e3..76debe2db 100644 --- a/src/services/consistency_checks.js +++ b/src/services/consistency_checks.js @@ -258,7 +258,8 @@ class ConsistencyChecks { FROM branches WHERE noteId = ? and parentNoteId = ? - and isDeleted = 0`, [noteId, parentNoteId]); + and isDeleted = 0 + ORDER BY utcDateCreated`, [noteId, parentNoteId]); const branches = branchIds.map(branchId => becca.getBranch(branchId)); @@ -537,6 +538,27 @@ class ConsistencyChecks { logError(`Unrecognized entity change id=${id}, entityName=${entityName}, entityId=${entityId}`); } }); + + this.findAndFixIssues(` + SELECT + id, entityId + FROM + entity_changes + JOIN ${entityName} ON entityId = ${key} + WHERE + entity_changes.isErased = 1 + AND entity_changes.entityName = '${entityName}'`, + ({id, entityId}) => { + if (this.autoFix) { + sql.execute(`DELETE FROM ${entityName} WHERE ${key} = ?`, [entityId]); + + this.reloadNeeded = true; + + logFix(`Erasing entityName=${entityName}, entityId=${entityId} since entity change id=${id} has it as erased.`); + } else { + logError(`Entity change id=${id} has entityName=${entityName}, entityId=${entityId} as erased, but it's not.`); + } + }); } findEntityChangeIssues() { @@ -603,14 +625,14 @@ class ConsistencyChecks { this.fixedIssues = false; this.reloadNeeded = false; + this.findEntityChangeIssues(); + this.findBrokenReferenceIssues(); this.findExistencyIssues(); this.findLogicIssues(); - this.findEntityChangeIssues(); - this.findWronglyNamedAttributes(); this.findSyncIssues(); diff --git a/src/services/notes.js b/src/services/notes.js index dffe24318..eee18cb16 100644 --- a/src/services/notes.js +++ b/src/services/notes.js @@ -733,23 +733,26 @@ function eraseAttributes(attributeIdsToErase) { } function eraseDeletedEntities(eraseEntitiesAfterTimeInSeconds = null) { - if (eraseEntitiesAfterTimeInSeconds === null) { - eraseEntitiesAfterTimeInSeconds = optionService.getOptionInt('eraseEntitiesAfterTimeInSeconds'); - } + // this is important also so that the erased entity changes are sent to the connected clients + sql.transactional(() => { + if (eraseEntitiesAfterTimeInSeconds === null) { + eraseEntitiesAfterTimeInSeconds = optionService.getOptionInt('eraseEntitiesAfterTimeInSeconds'); + } - const cutoffDate = new Date(Date.now() - eraseEntitiesAfterTimeInSeconds * 1000); + const cutoffDate = new Date(Date.now() - eraseEntitiesAfterTimeInSeconds * 1000); - const noteIdsToErase = sql.getColumn("SELECT noteId FROM notes WHERE isDeleted = 1 AND utcDateModified <= ?", [dateUtils.utcDateTimeStr(cutoffDate)]); + const noteIdsToErase = sql.getColumn("SELECT noteId FROM notes WHERE isDeleted = 1 AND utcDateModified <= ?", [dateUtils.utcDateTimeStr(cutoffDate)]); - eraseNotes(noteIdsToErase); + eraseNotes(noteIdsToErase); - const branchIdsToErase = sql.getColumn("SELECT branchId FROM branches WHERE isDeleted = 1 AND utcDateModified <= ?", [dateUtils.utcDateTimeStr(cutoffDate)]); + const branchIdsToErase = sql.getColumn("SELECT branchId FROM branches WHERE isDeleted = 1 AND utcDateModified <= ?", [dateUtils.utcDateTimeStr(cutoffDate)]); - eraseBranches(branchIdsToErase); + eraseBranches(branchIdsToErase); - const attributeIdsToErase = sql.getColumn("SELECT attributeId FROM attributes WHERE isDeleted = 1 AND utcDateModified <= ?", [dateUtils.utcDateTimeStr(cutoffDate)]); + const attributeIdsToErase = sql.getColumn("SELECT attributeId FROM attributes WHERE isDeleted = 1 AND utcDateModified <= ?", [dateUtils.utcDateTimeStr(cutoffDate)]); - eraseAttributes(attributeIdsToErase); + eraseAttributes(attributeIdsToErase); + }); } function eraseNotesWithDeleteId(deleteId) { diff --git a/src/services/special_notes.js b/src/services/special_notes.js index bfdac7b8e..2c572072d 100644 --- a/src/services/special_notes.js +++ b/src/services/special_notes.js @@ -34,6 +34,7 @@ function getHiddenRoot() { if (!hidden) { hidden = noteService.createNewNote({ + branchId: 'hidden', noteId: 'hidden', title: 'hidden', type: 'text',