mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	cleanup of isErased obsolete usage
This commit is contained in:
		| @@ -15,7 +15,6 @@ const entityChangesService = require('../services/entity_changes.js'); | |||||||
|  * @property {string} type |  * @property {string} type | ||||||
|  * @property {string} mime |  * @property {string} mime | ||||||
|  * @property {string} title |  * @property {string} title | ||||||
|  * @property {boolean} isErased |  | ||||||
|  * @property {boolean} isProtected |  * @property {boolean} isProtected | ||||||
|  * @property {string} dateLastEdited |  * @property {string} dateLastEdited | ||||||
|  * @property {string} dateCreated |  * @property {string} dateCreated | ||||||
|   | |||||||
| @@ -80,8 +80,7 @@ function downloadNoteRevision(req, res) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function eraseAllNoteRevisions(req) { | function eraseAllNoteRevisions(req) { | ||||||
|     const noteRevisionIdsToErase = sql.getColumn( |     const noteRevisionIdsToErase = sql.getColumn('SELECT noteRevisionId FROM note_revisions WHERE noteId = ?', | ||||||
|         'SELECT noteRevisionId FROM note_revisions WHERE isErased = 0 AND noteId = ?', |  | ||||||
|         [req.params.noteId]); |         [req.params.noteId]); | ||||||
|  |  | ||||||
|     noteRevisionService.eraseNoteRevisions(noteRevisionIdsToErase); |     noteRevisionService.eraseNoteRevisions(noteRevisionIdsToErase); | ||||||
| @@ -94,7 +93,7 @@ function eraseNoteRevision(req) { | |||||||
| function restoreNoteRevision(req) { | function restoreNoteRevision(req) { | ||||||
|     const noteRevision = repository.getNoteRevision(req.params.noteRevisionId); |     const noteRevision = repository.getNoteRevision(req.params.noteRevisionId); | ||||||
|  |  | ||||||
|     if (noteRevision && !noteRevision.isErased) { |     if (noteRevision) { | ||||||
|         const note = noteRevision.getNote(); |         const note = noteRevision.getNote(); | ||||||
|  |  | ||||||
|         noteRevisionService.createNoteRevision(note); |         noteRevisionService.createNoteRevision(note); | ||||||
|   | |||||||
| @@ -15,7 +15,6 @@ function getRecentChanges(req) { | |||||||
|             notes.noteId, |             notes.noteId, | ||||||
|             notes.isDeleted AS current_isDeleted, |             notes.isDeleted AS current_isDeleted, | ||||||
|             notes.deleteId AS current_deleteId, |             notes.deleteId AS current_deleteId, | ||||||
|             notes.isErased AS current_isErased, |  | ||||||
|             notes.title AS current_title, |             notes.title AS current_title, | ||||||
|             notes.isProtected AS current_isProtected, |             notes.isProtected AS current_isProtected, | ||||||
|             note_revisions.title, |             note_revisions.title, | ||||||
| @@ -23,8 +22,7 @@ function getRecentChanges(req) { | |||||||
|             note_revisions.dateCreated AS date |             note_revisions.dateCreated AS date | ||||||
|         FROM  |         FROM  | ||||||
|             note_revisions |             note_revisions | ||||||
|             JOIN notes USING(noteId) |             JOIN notes USING(noteId)`); | ||||||
|         WHERE note_revisions.isErased = 0`); |  | ||||||
|  |  | ||||||
|     for (const noteRevision of noteRevisions) { |     for (const noteRevision of noteRevisions) { | ||||||
|         if (noteCacheService.isInAncestor(noteRevision.noteId, ancestorNoteId)) { |         if (noteCacheService.isInAncestor(noteRevision.noteId, ancestorNoteId)) { | ||||||
| @@ -40,28 +38,24 @@ function getRecentChanges(req) { | |||||||
|                 notes.noteId, |                 notes.noteId, | ||||||
|                 notes.isDeleted AS current_isDeleted, |                 notes.isDeleted AS current_isDeleted, | ||||||
|                 notes.deleteId AS current_deleteId, |                 notes.deleteId AS current_deleteId, | ||||||
|                 notes.isErased AS current_isErased, |  | ||||||
|                 notes.title AS current_title, |                 notes.title AS current_title, | ||||||
|                 notes.isProtected AS current_isProtected, |                 notes.isProtected AS current_isProtected, | ||||||
|                 notes.title, |                 notes.title, | ||||||
|                 notes.utcDateCreated AS utcDate, |                 notes.utcDateCreated AS utcDate, | ||||||
|                 notes.dateCreated AS date |                 notes.dateCreated AS date | ||||||
|             FROM |             FROM notes | ||||||
|                 notes |  | ||||||
|         UNION ALL |         UNION ALL | ||||||
|             SELECT |             SELECT | ||||||
|                 notes.noteId, |                 notes.noteId, | ||||||
|                 notes.isDeleted AS current_isDeleted, |                 notes.isDeleted AS current_isDeleted, | ||||||
|                 notes.deleteId AS current_deleteId, |                 notes.deleteId AS current_deleteId, | ||||||
|                 notes.isErased AS current_isErased, |  | ||||||
|                 notes.title AS current_title, |                 notes.title AS current_title, | ||||||
|                 notes.isProtected AS current_isProtected, |                 notes.isProtected AS current_isProtected, | ||||||
|                 notes.title, |                 notes.title, | ||||||
|                 notes.utcDateModified AS utcDate, |                 notes.utcDateModified AS utcDate, | ||||||
|                 notes.dateModified AS date |                 notes.dateModified AS date | ||||||
|             FROM |             FROM notes | ||||||
|                 notes |             WHERE notes.isDeleted = 1`); | ||||||
|             WHERE notes.isDeleted = 1 AND notes.isErased = 0`); |  | ||||||
|  |  | ||||||
|     for (const note of notes) { |     for (const note of notes) { | ||||||
|         if (noteCacheService.isInAncestor(note.noteId, ancestorNoteId)) { |         if (noteCacheService.isInAncestor(note.noteId, ancestorNoteId)) { | ||||||
| @@ -85,10 +79,6 @@ function getRecentChanges(req) { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (change.current_isDeleted) { |         if (change.current_isDeleted) { | ||||||
|             if (change.current_isErased) { |  | ||||||
|                 change.canBeUndeleted = false; |  | ||||||
|             } |  | ||||||
|             else { |  | ||||||
|             const deleteId = change.current_deleteId; |             const deleteId = change.current_deleteId; | ||||||
|  |  | ||||||
|             const undeletedParentBranches = noteService.getUndeletedParentBranches(change.noteId, deleteId); |             const undeletedParentBranches = noteService.getUndeletedParentBranches(change.noteId, deleteId); | ||||||
| @@ -97,7 +87,6 @@ function getRecentChanges(req) { | |||||||
|             change.canBeUndeleted = undeletedParentBranches.length > 0; |             change.canBeUndeleted = undeletedParentBranches.length > 0; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     } |  | ||||||
|  |  | ||||||
|     return recentChanges; |     return recentChanges; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ const optionsService = require('./options'); | |||||||
| const Branch = require('../entities/branch'); | const Branch = require('../entities/branch'); | ||||||
| const dateUtils = require('./date_utils'); | const dateUtils = require('./date_utils'); | ||||||
| const attributeService = require('./attributes'); | const attributeService = require('./attributes'); | ||||||
|  | const noteRevisionService = require('./note_revisions'); | ||||||
|  |  | ||||||
| class ConsistencyChecks { | class ConsistencyChecks { | ||||||
|     constructor(autoFix) { |     constructor(autoFix) { | ||||||
| @@ -304,7 +305,7 @@ class ConsistencyChecks { | |||||||
|                     } |                     } | ||||||
|                     else { |                     else { | ||||||
|                         // empty string might be wrong choice for some note types but it's a best guess |                         // empty string might be wrong choice for some note types but it's a best guess | ||||||
|                         note.setContent(note.isErased ? null : ''); |                         note.setContent(''); | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                     logFix(`Note ${noteId} content was set to empty string since there was no corresponding row`); |                     logFix(`Note ${noteId} content was set to empty string since there was no corresponding row`); | ||||||
| @@ -332,53 +333,6 @@ class ConsistencyChecks { | |||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
|         this.findAndFixIssues(` |  | ||||||
|                     SELECT noteId |  | ||||||
|                     FROM notes |  | ||||||
|                       JOIN note_contents USING (noteId) |  | ||||||
|                     WHERE isErased = 1 |  | ||||||
|                       AND content IS NOT NULL`, |  | ||||||
|             ({noteId}) => { |  | ||||||
|  |  | ||||||
|             // we always fix this issue because there does not seem to be a good way to prevent it. |  | ||||||
|             // Scenario in which this can happen: |  | ||||||
|             // 1. user on instance A deletes the note (sync for notes is created, but not for note_contents) and is later erased |  | ||||||
|             // 2. instance B gets synced from instance A, note is updated because of entity change for notes, |  | ||||||
|             //    but note_contents is not because erasion does not create entity change rows |  | ||||||
|             // 3. therefore note.isErased = true, but note_contents.content remains not updated and not erased. |  | ||||||
|             // |  | ||||||
|             // Considered solutions: |  | ||||||
|             // - don't sync erased notes - this might prevent syncing also of the isDeleted flag and note would continue |  | ||||||
|             //   to exist on the other instance |  | ||||||
|             // - create entity changes for erased event - this would be a problem for undeletion since erasion might happen |  | ||||||
|             //   on one instance after undelete and thus would win even though there's no user action behind it |  | ||||||
|             // |  | ||||||
|             // So instead we just fix such cases afterwards here. |  | ||||||
|  |  | ||||||
|             sql.execute(`UPDATE note_contents SET content = NULL WHERE noteId = ?`, [noteId]); |  | ||||||
|  |  | ||||||
|             logFix(`Note ${noteId} content has been set to null since the note is erased`); |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         this.findAndFixIssues(` |  | ||||||
|                     SELECT noteId, noteRevisionId |  | ||||||
|                     FROM notes |  | ||||||
|                       JOIN note_revisions USING (noteId) |  | ||||||
|                     WHERE notes.isErased = 1 |  | ||||||
|                       AND note_revisions.isErased = 0`, |  | ||||||
|             ({noteId, noteRevisionId}) => { |  | ||||||
|                 if (this.autoFix) { |  | ||||||
|                     const noteRevision = repository.getNoteRevision(noteRevisionId); |  | ||||||
|                     noteRevision.isErased = true; |  | ||||||
|                     noteRevision.setContent(null); |  | ||||||
|                     noteRevision.save(); |  | ||||||
|  |  | ||||||
|                     logFix(`Note revision ${noteRevisionId} has been erased since its note ${noteId} is also erased.`); |  | ||||||
|                 } else { |  | ||||||
|                     logError(`Note revision ${noteRevisionId} is not erased even though note ${noteId} is erased.`); |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|  |  | ||||||
|         this.findAndFixIssues(` |         this.findAndFixIssues(` | ||||||
|                     SELECT note_revisions.noteRevisionId |                     SELECT note_revisions.noteRevisionId | ||||||
|                     FROM note_revisions |                     FROM note_revisions | ||||||
| @@ -387,10 +341,7 @@ class ConsistencyChecks { | |||||||
|                       AND note_revisions.isProtected = 0`, |                       AND note_revisions.isProtected = 0`, | ||||||
|             ({noteRevisionId}) => { |             ({noteRevisionId}) => { | ||||||
|                 if (this.autoFix) { |                 if (this.autoFix) { | ||||||
|                     const noteRevision = repository.getNoteRevision(noteRevisionId); |                     noteRevisionService.eraseNoteRevisions([noteRevisionId]); | ||||||
|                     noteRevision.setContent(null); |  | ||||||
|                     noteRevision.isErased = true; |  | ||||||
|                     noteRevision.save(); |  | ||||||
|  |  | ||||||
|                     logFix(`Note revision content ${noteRevisionId} was created and set to erased since it did not exist.`); |                     logFix(`Note revision content ${noteRevisionId} was created and set to erased since it did not exist.`); | ||||||
|                 } else { |                 } else { | ||||||
| @@ -398,59 +349,6 @@ class ConsistencyChecks { | |||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
|         this.findAndFixIssues(` |  | ||||||
|                     SELECT noteRevisionId |  | ||||||
|                     FROM note_revisions |  | ||||||
|                       JOIN note_revision_contents USING (noteRevisionId) |  | ||||||
|                     WHERE isErased = 0 |  | ||||||
|                       AND content IS NULL`, |  | ||||||
|             ({noteRevisionId}) => { |  | ||||||
|                 if (this.autoFix) { |  | ||||||
|                     const noteRevision = repository.getNoteRevision(noteRevisionId); |  | ||||||
|                     noteRevision.isErased = true; |  | ||||||
|                     noteRevision.save(); |  | ||||||
|  |  | ||||||
|                     logFix(`Note revision ${noteRevisionId} content was set to erased since it was null even though it was not erased`); |  | ||||||
|                 } else { |  | ||||||
|                     logError(`Note revision ${noteRevisionId} content is null even though it is not erased`); |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|  |  | ||||||
|         this.findAndFixIssues(` |  | ||||||
|                     SELECT noteRevisionId |  | ||||||
|                     FROM note_revisions |  | ||||||
|                              JOIN note_revision_contents USING (noteRevisionId) |  | ||||||
|                     WHERE isErased = 1 |  | ||||||
|                       AND content IS NOT NULL`, |  | ||||||
|             ({noteRevisionId}) => { |  | ||||||
|                 if (this.autoFix) { |  | ||||||
|                     sql.execute(`UPDATE note_revision_contents SET content = NULL WHERE noteRevisionId = ?`, [noteRevisionId]); |  | ||||||
|  |  | ||||||
|                     logFix(`Note revision ${noteRevisionId} content was set to null since the note revision is erased`); |  | ||||||
|                 } |  | ||||||
|                 else { |  | ||||||
|                     logError(`Note revision ${noteRevisionId} content is not null even though the note revision is erased`); |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|  |  | ||||||
|         this.findAndFixIssues(` |  | ||||||
|                     SELECT noteId |  | ||||||
|                     FROM notes |  | ||||||
|                     WHERE isErased = 1 |  | ||||||
|                       AND isDeleted = 0`, |  | ||||||
|             ({noteId}) => { |  | ||||||
|                 if (this.autoFix) { |  | ||||||
|                     const note = repository.getNote(noteId); |  | ||||||
|                     note.isDeleted = true; |  | ||||||
|                     note.save(); |  | ||||||
|  |  | ||||||
|                     logFix(`Note ${noteId} was set to deleted since it is erased`); |  | ||||||
|                 } |  | ||||||
|                 else { |  | ||||||
|                     logError(`Note ${noteId} is not deleted even though it is erased`); |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|  |  | ||||||
|         this.findAndFixIssues(` |         this.findAndFixIssues(` | ||||||
|                     SELECT parentNoteId |                     SELECT parentNoteId | ||||||
|                     FROM branches |                     FROM branches | ||||||
| @@ -661,36 +559,18 @@ class ConsistencyChecks { | |||||||
|         return !this.unrecoveredConsistencyErrors; |         return !this.unrecoveredConsistencyErrors; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     showEntityStat(name, query) { |     runDbDiagnostics() { | ||||||
|         const map = sql.getMap(query); |         function showEntityStat(tableName) { | ||||||
|  |             const count = sql.getValue(`SELECT COUNT(1) FROM ${tableName}`); | ||||||
|  |  | ||||||
|         map[0] = map[0] || 0; |             log.info(`${tableName}: ${count}`); | ||||||
|         map[1] = map[1] || 0; |  | ||||||
|  |  | ||||||
|         log.info(`${name} deleted: ${map[1]}, not deleted ${map[0]}`); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     runDbDiagnostics() { |         showEntityStat("notes"); | ||||||
|         this.showEntityStat("Notes", |         showEntityStat("note_revisions"); | ||||||
|                 `SELECT isDeleted, count(1) |         showEntityStat("branches"); | ||||||
|                        FROM notes |         showEntityStat("attributes"); | ||||||
|                        GROUP BY isDeleted`); |         showEntityStat("api_tokens"); | ||||||
|         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() { |     async runChecks() { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user