diff --git a/src/becca/becca.js b/src/becca/becca.js index 3c712ddae..2cae47e0e 100644 --- a/src/becca/becca.js +++ b/src/becca/becca.js @@ -163,6 +163,10 @@ class Becca { .replace('_', '') ); + if (!(camelCaseEntityName in this)) { + throw new Error(`Unknown entity name '${camelCaseEntityName}' (original argument '${entityName}')`); + } + return this[camelCaseEntityName][entityId]; } diff --git a/src/public/app/widgets/type_widgets/image.js b/src/public/app/widgets/type_widgets/image.js index deffe5c7a..467f9b1cd 100644 --- a/src/public/app/widgets/type_widgets/image.js +++ b/src/public/app/widgets/type_widgets/image.js @@ -90,7 +90,7 @@ class ImageTypeWidget extends TypeWidget { } async doRefresh(note) { - this.$imageView.prop("src", `api/images/${note.noteId}/${note.title}`); + this.$imageView.prop("src", `api/images/${note.noteId}/${encodeURIComponent(note.title)}`); } copyImageReferenceToClipboardEvent({ntxId}) { diff --git a/src/services/consistency_checks.js b/src/services/consistency_checks.js index c31640b15..6bb6e066d 100644 --- a/src/services/consistency_checks.js +++ b/src/services/consistency_checks.js @@ -148,13 +148,28 @@ class ConsistencyChecks { AND notes.noteId IS NULL`, ({branchId, parentNoteId}) => { if (this.autoFix) { - const branch = becca.getBranch(branchId); - branch.parentNoteId = 'root'; - branch.save(); + // Delete the old branch and recreate it with root as parent. + const oldBranch = becca.getBranch(branchId); + const noteId = oldBranch.noteId; + oldBranch.markAsDeleted("missing-parent"); + + let message = `Branch '${branchId}' was was missing parent note '${parentNoteId}', so it was deleted. `; + + if (becca.getNote(noteId).getParentBranches().length === 0) { + const newBranch = new Branch({ + parentNoteId: 'root', + noteId: noteId, + prefix: 'recovered' + }).save(); + + message += `${newBranch.branchId} was created in the root instead.`; + } else { + message += `There is one or more valid branches, so no new one will be created as a replacement.`; + } this.reloadNeeded = true; - logFix(`Branch '${branchId}' was set to root parent since it was referencing missing parent note '${parentNoteId}'`); + logFix(message); } else { logError(`Branch '${branchId}' references missing parent note '${parentNoteId}'`); } @@ -467,10 +482,17 @@ class ConsistencyChecks { const branches = branchIds.map(branchId => becca.getBranch(branchId)); for (const branch of branches) { - branch.parentNoteId = 'root'; - branch.save(); + // delete the old wrong branch + branch.markAsDeleted("parent-is-search"); - logFix(`Child branch '${branch.branchId}' has been moved to root since it was a child of a search note '${parentNoteId}'`) + // create a replacement branch in root parent + new Branch({ + parentNoteId: 'root', + noteId: branch.noteId, + prefix: 'recovered' + }).save(); + + logFix(`Note '${branch.noteId}' has been moved to root since it was a child of a search note '${parentNoteId}'`) } this.reloadNeeded = true; diff --git a/src/services/entity_changes.js b/src/services/entity_changes.js index f4cfe8a5f..2c3991d81 100644 --- a/src/services/entity_changes.js +++ b/src/services/entity_changes.js @@ -100,15 +100,38 @@ function fillEntityChanges(entityName, entityPrimaryKey, condition = '') { if (existingRows === 0) { createdCount++; - const entity = becca.getEntity(entityName, entityId); + let hash; + let utcDateChanged; + let isSynced; + + if (entityName.endsWith("_contents")) { + // FIXME: hacky, not sure if it might cause some problems + hash = "fake value"; + utcDateChanged = dateUtils.utcNowDateTime(); + isSynced = true; // contents are always synced + } else { + const entity = becca.getEntity(entityName, entityId); + + if (entity) { + hash = entity?.generateHash() || "|deleted"; + utcDateChanged = entity?.getUtcDateChanged() || dateUtils.utcNowDateTime(); + isSynced = entityName !== 'options' || !!entity?.isSynced; + } else { + // entity might be null (not present in becca) when it's deleted + // FIXME: hacky, not sure if it might cause some problems + hash = "deleted"; + utcDateChanged = dateUtils.utcNowDateTime(); + isSynced = true; // deletable (the ones with isDeleted) entities are synced + } + } addEntityChange({ entityName, entityId, - hash: entity.generateHash(), + hash: hash, isErased: false, - utcDateChanged: entity.getUtcDateChanged(), - isSynced: entityName !== 'options' || !!entity.isSynced + utcDateChanged: utcDateChanged, + isSynced: isSynced }); } }