cleanup of isErased obsolete usage

This commit is contained in:
zadam 2020-12-16 15:01:20 +01:00
parent d0578971f7
commit c5ec57e08e
4 changed files with 24 additions and 157 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;
} }

View File

@ -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() {