From 2e58e32112db24713a1ad1215005d3c89166e367 Mon Sep 17 00:00:00 2001 From: zadam Date: Fri, 1 Nov 2019 20:00:56 +0100 Subject: [PATCH] note revision sync and other fixes --- .../a2c75661-f9e2-478f-a69f-6a9409e69997.xml | 206 +++++++++++------- .../0150__note_revision_contents.sql | 3 + db/schema.sql | 44 ++-- src/entities/note_revision.js | 2 +- .../javascripts/services/note_tooltip.js | 4 +- src/routes/api/note_revisions.js | 8 +- src/services/repository.js | 1 + src/services/sync_table.js | 2 + src/services/sync_update.js | 24 +- 9 files changed, 177 insertions(+), 117 deletions(-) diff --git a/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml b/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml index 22d1652a1..fd55d255c 100644 --- a/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml +++ b/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml @@ -13,8 +13,8 @@
-
-
+
+
@@ -57,6 +57,7 @@ 1 apiTokenId + 1 @@ -125,20 +126,25 @@ 1 attributeId + 1 noteId + name value + name + value + attributeId @@ -171,7 +177,9 @@ value 6 - BOOLEAN|0s + INTEGER|0s + 1 + 0 7 @@ -198,52 +206,60 @@ value 1 branchId + 1 noteId parentNoteId + noteId + parentNoteId + branchId 1 sqlite_autoindex_branches_1 - + 1 TEXT|0s 1 - + 2 TEXT|0s + NULL - + 3 TEXT|0s + 1 + "" - + 4 TEXT|0s 1 - + 1 - eventId + noteId + 1 - eventId + noteId 1 - sqlite_autoindex_event_log_1 + sqlite_autoindex_note_contents_1 - + 1 TEXT|0s 1 @@ -251,28 +267,28 @@ parentNoteId 2 TEXT|0s - NULL 3 TEXT|0s 1 - "" + '' 4 TEXT|0s 1 - + 1 - noteId + noteRevisionId + 1 - noteId + noteRevisionId 1 - sqlite_autoindex_note_contents_1 + sqlite_autoindex_note_revision_contents_1 1 @@ -288,9 +304,10 @@ parentNoteId 3 TEXT|0s - + 4 - TEXT|0s + INT|0s + 1 5 @@ -298,291 +315,314 @@ parentNoteId 1 0 - + 6 TEXT|0s 1 - + 7 TEXT|0s 1 - + 8 TEXT|0s 1 - + 9 TEXT|0s 1 - + 10 TEXT|0s 1 - '' - + 11 TEXT|0s 1 '' - + 12 TEXT|0s 1 - "" + '' - + + 13 + TEXT|0s + 1 + '' + + 1 noteRevisionId + 1 - + noteId + - - utcDateModifiedFrom + + utcDateLastEdited + - - utcDateModifiedTo + + utcDateCreated + - + + dateLastEdited + + + + dateCreated + + + noteRevisionId 1 sqlite_autoindex_note_revisions_1 - + 1 TEXT|0s 1 - + 2 TEXT|0s 1 "note" - + 3 INT|0s 1 0 - + 4 TEXT|0s 1 'text' - + 5 TEXT|0s 1 'text/html' - + 6 TEXT|0s 1 "" - + 7 INT|0s 1 0 - + 8 TEXT|0s 1 - + 9 TEXT|0s 1 - + 10 TEXT|0s 1 - + 11 TEXT|0s 1 - + 1 noteId + 1 - + noteId 1 sqlite_autoindex_notes_1 - + 1 TEXT|0s 1 - + 2 TEXT|0s - + 3 INTEGER|0s 1 0 - + 4 TEXT|0s 1 "" - + 5 TEXT|0s 1 - + 6 TEXT|0s 1 - + 1 name + 1 - + name 1 sqlite_autoindex_options_1 - + 1 TEXT|0s 1 - + 2 TEXT|0s 1 - + 3 TEXT|0s 1 "" - + 4 TEXT|0s 1 - + 5 INT|0s - + 1 noteId + 1 - + noteId 1 sqlite_autoindex_recent_notes_1 - + 1 TEXT|0s 1 - + 2 TEXT|0s 1 - + 1 sourceId + 1 - + sourceId 1 sqlite_autoindex_source_ids_1 - + 1 text|0s - + 2 text|0s - + 3 text|0s - + 4 int|0s - + 5 text|0s - + 1 - + 2 - + 1 INTEGER|0s 1 1 - + 2 TEXT|0s 1 - + 3 TEXT|0s 1 - + 4 TEXT|0s 1 - + 5 TEXT|0s 1 - + entityName entityId + 1 - + utcSyncDate + - + id 1 diff --git a/db/migrations/0150__note_revision_contents.sql b/db/migrations/0150__note_revision_contents.sql index 5349f175d..806eb3586 100644 --- a/db/migrations/0150__note_revision_contents.sql +++ b/db/migrations/0150__note_revision_contents.sql @@ -31,3 +31,6 @@ CREATE INDEX `IDX_note_revisions_utcDateCreated` ON `note_revisions` (`utcDateCr CREATE INDEX `IDX_note_revisions_utcDateLastEdited` ON `note_revisions` (`utcDateLastEdited`); CREATE INDEX `IDX_note_revisions_dateCreated` ON `note_revisions` (`dateCreated`); CREATE INDEX `IDX_note_revisions_dateLastEdited` ON `note_revisions` (`dateLastEdited`); + +INSERT INTO sync (entityName, entityId, sourceId, utcSyncDate) +SELECT 'note_revision_contents', entityId, sourceId, utcSyncDate FROM sync WHERE entityName = 'note_revisions'; \ No newline at end of file diff --git a/db/schema.sql b/db/schema.sql index d649a5870..c13e2bae5 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -9,19 +9,6 @@ CREATE TABLE IF NOT EXISTS "source_ids" ( `utcDateCreated` TEXT NOT NULL, PRIMARY KEY(`sourceId`) ); -CREATE TABLE IF NOT EXISTS "note_revisions" ( - `noteRevisionId` TEXT NOT NULL PRIMARY KEY, - `noteId` TEXT NOT NULL, - `title` TEXT, - `content` TEXT, - `isProtected` INT NOT NULL DEFAULT 0, - `utcDateModifiedFrom` TEXT NOT NULL, - `utcDateModifiedTo` TEXT NOT NULL, - `dateModifiedFrom` TEXT NOT NULL, - `dateModifiedTo` TEXT NOT NULL, - type TEXT DEFAULT '' NOT NULL, - mime TEXT DEFAULT '' NOT NULL, - hash TEXT DEFAULT "" NOT NULL); CREATE TABLE IF NOT EXISTS "api_tokens" ( apiTokenId TEXT PRIMARY KEY NOT NULL, @@ -72,15 +59,6 @@ CREATE UNIQUE INDEX `IDX_sync_entityName_entityId` ON `sync` ( CREATE INDEX `IDX_sync_utcSyncDate` ON `sync` ( `utcSyncDate` ); -CREATE INDEX `IDX_note_revisions_noteId` ON `note_revisions` ( - `noteId` - ); -CREATE INDEX `IDX_note_revisions_dateModifiedFrom` ON `note_revisions` ( - `utcDateModifiedFrom` - ); -CREATE INDEX `IDX_note_revisions_dateModifiedTo` ON `note_revisions` ( - `utcDateModifiedTo` - ); CREATE INDEX IDX_attributes_name_value on attributes (name, value); CREATE INDEX IDX_attributes_name_index @@ -119,3 +97,25 @@ CREATE TABLE IF NOT EXISTS "branches" ( CREATE INDEX `IDX_branches_noteId` ON `branches` (`noteId`); CREATE INDEX `IDX_branches_noteId_parentNoteId` ON `branches` (`noteId`,`parentNoteId`); CREATE INDEX IDX_branches_parentNoteId ON branches (parentNoteId); +CREATE TABLE IF NOT EXISTS "note_revisions" (`noteRevisionId` TEXT NOT NULL PRIMARY KEY, + `noteId` TEXT NOT NULL, + `title` TEXT, + `contentLength` INT NOT NULL, + `isProtected` INT NOT NULL DEFAULT 0, + `utcDateLastEdited` TEXT NOT NULL, + `utcDateCreated` TEXT NOT NULL, + `utcDateModified` TEXT NOT NULL, + `dateLastEdited` TEXT NOT NULL, + `dateCreated` TEXT NOT NULL, + type TEXT DEFAULT '' NOT NULL, + mime TEXT DEFAULT '' NOT NULL, + hash TEXT DEFAULT '' NOT NULL); +CREATE TABLE IF NOT EXISTS "note_revision_contents" (`noteRevisionId` TEXT NOT NULL PRIMARY KEY, + `content` TEXT, + hash TEXT DEFAULT '' NOT NULL, + `utcDateModified` TEXT NOT NULL); +CREATE INDEX `IDX_note_revisions_noteId` ON `note_revisions` (`noteId`); +CREATE INDEX `IDX_note_revisions_utcDateCreated` ON `note_revisions` (`utcDateCreated`); +CREATE INDEX `IDX_note_revisions_utcDateLastEdited` ON `note_revisions` (`utcDateLastEdited`); +CREATE INDEX `IDX_note_revisions_dateCreated` ON `note_revisions` (`dateCreated`); +CREATE INDEX `IDX_note_revisions_dateLastEdited` ON `note_revisions` (`dateLastEdited`); diff --git a/src/entities/note_revision.js b/src/entities/note_revision.js index 6cd8853e8..260d74894 100644 --- a/src/entities/note_revision.js +++ b/src/entities/note_revision.js @@ -125,7 +125,7 @@ class NoteRevision extends Entity { await sql.upsert("note_revision_contents", "noteRevisionId", pojo); - await syncTableService.addNoteContentSync(this.noteId); + await syncTableService.addNoteRevisionContentSync(this.noteRevisionId); } // cannot be static! diff --git a/src/public/javascripts/services/note_tooltip.js b/src/public/javascripts/services/note_tooltip.js index ac7da96c5..9edb33b44 100644 --- a/src/public/javascripts/services/note_tooltip.js +++ b/src/public/javascripts/services/note_tooltip.js @@ -19,7 +19,9 @@ function setupElementTooltip($el) { async function mouseEnterHandler() { const $link = $(this); - if ($link.hasClass("no-tooltip-preview") || $link.hasClass("disabled")) { + if ($link.hasClass("no-tooltip-preview") + || $link.hasClass("disabled") + || $link.attr("data-action") === 'note-revision') { return; } diff --git a/src/routes/api/note_revisions.js b/src/routes/api/note_revisions.js index 522242970..464d66cf2 100644 --- a/src/routes/api/note_revisions.js +++ b/src/routes/api/note_revisions.js @@ -14,11 +14,11 @@ async function getNoteRevisions(req) { } async function getNoteRevision(req) { - const {noteRevisionId} = req.params; + const noteRevision = await repository.getNoteRevision(req.params.noteRevisionId); - return await repository.getNote(`SELECT * - FROM note_revisions - WHERE noteRevisionId = ?`, [noteId]); + await noteRevision.getContent(); + + return noteRevision; } async function getEditedNotesOnDate(req) { diff --git a/src/services/repository.js b/src/services/repository.js index 3d6f3a79b..38d835f35 100644 --- a/src/services/repository.js +++ b/src/services/repository.js @@ -141,6 +141,7 @@ module.exports = { getEntity, getNote, getNotes, + getNoteRevision, getBranch, getAttribute, getOption, diff --git a/src/services/sync_table.js b/src/services/sync_table.js index bb3ace759..79a20d7fe 100644 --- a/src/services/sync_table.js +++ b/src/services/sync_table.js @@ -64,6 +64,7 @@ async function fillAllSyncRows() { await fillSyncRows("note_contents", "noteId"); await fillSyncRows("branches", "branchId"); await fillSyncRows("note_revisions", "noteRevisionId"); + await fillSyncRows("note_revision_contents", "noteRevisionId"); await fillSyncRows("recent_notes", "noteId"); await fillSyncRows("attributes", "attributeId"); await fillSyncRows("api_tokens", "apiTokenId"); @@ -76,6 +77,7 @@ module.exports = { addBranchSync: async (branchId, sourceId) => await addEntitySync("branches", branchId, sourceId), addNoteReorderingSync: async (parentNoteId, sourceId) => await addEntitySync("note_reordering", parentNoteId, sourceId), addNoteRevisionSync: async (noteRevisionId, sourceId) => await addEntitySync("note_revisions", noteRevisionId, sourceId), + addNoteRevisionContentSync: async (noteRevisionId, sourceId) => await addEntitySync("note_revision_contents", noteRevisionId, sourceId), addOptionsSync: async (name, sourceId) => await addEntitySync("options", name, sourceId), addRecentNoteSync: async (noteId, sourceId) => await addEntitySync("recent_notes", noteId, sourceId), addAttributeSync: async (attributeId, sourceId) => await addEntitySync("attributes", attributeId, sourceId), diff --git a/src/services/sync_update.js b/src/services/sync_update.js index 1a2366618..283f3628e 100644 --- a/src/services/sync_update.js +++ b/src/services/sync_update.js @@ -39,7 +39,7 @@ async function updateEntity(sync, entity, sourceId) { // currently making exception for protected notes and note revisions because here // the title and content are not available decrypted as listeners would expect - if ((entityName !== 'notes' && entityName !== 'note_revisions') || !entity.isProtected) { + if (!['notes', 'note_contents', 'note_revisions', 'note_revision_contents'].includes(entityName) || !entity.isProtected) { await eventService.emit(eventService.ENTITY_SYNCED, { entityName, entity @@ -101,11 +101,7 @@ async function updateNoteRevision(entity, sourceId) { const orig = await sql.getRowOrNull("SELECT * FROM note_revisions WHERE noteRevisionId = ?", [entity.noteRevisionId]); await sql.transactional(async () => { - // we update note revision even if date modified to is the same because the only thing which might have changed - // is the protected status (and correnspondingly title and content) which doesn't affect the utcDateCreated - if (orig === null || orig.utcDateCreated <= entity.utcDateCreated) { - entity.content = entity.content === null ? null : Buffer.from(entity.content, 'base64'); - + if (orig === null || orig.utcDateModified < entity.utcDateModified) { await sql.replace('note_revisions', entity); await syncTableService.addNoteRevisionSync(entity.noteRevisionId, sourceId); @@ -115,6 +111,22 @@ async function updateNoteRevision(entity, sourceId) { }); } +async function updateNoteRevisionContent(entity, sourceId) { + const orig = await sql.getRowOrNull("SELECT * FROM note_revision_contents WHERE noteRevisionId = ?", [entity.noteRevisionId]); + + await sql.transactional(async () => { + if (orig === null || orig.utcDateModified < entity.utcDateModified) { + entity.content = entity.content === null ? null : Buffer.from(entity.content, 'base64'); + + await sql.replace('note_revision_contents', entity); + + await syncTableService.addNoteRevisionContentSync(entity.noteRevisionId, sourceId); + + log.info("Update/sync note revision content " + entity.noteRevisionId); + } + }); +} + async function updateNoteReordering(entityId, entity, sourceId) { await sql.transactional(async () => { for (const key in entity) {