From 1687ed7e0b9411e739c1a0610b37c63917002df2 Mon Sep 17 00:00:00 2001 From: azivner Date: Mon, 16 Apr 2018 16:26:47 -0400 Subject: [PATCH] load only expanded tree with the rest being lazy loaded, WIP --- .../a2c75661-f9e2-478f-a69f-6a9409e69997.xml | 4 ++ db/main_branches.sql | 1 + db/migrations/0089__add_root_branch.sql | 5 ++ db/migrations/0090__branch_index.sql | 1 + db/migrations/0091__drop_isDeleted_index.sql | 2 + src/public/javascripts/services/link.js | 2 +- src/routes/api/tree.js | 68 ++++++++----------- src/services/app_info.js | 2 +- src/services/consistency_checks.js | 10 +-- src/tools/generate_document.js | 2 +- 10 files changed, 50 insertions(+), 47 deletions(-) create mode 100644 db/migrations/0089__add_root_branch.sql create mode 100644 db/migrations/0090__branch_index.sql create mode 100644 db/migrations/0091__drop_isDeleted_index.sql diff --git a/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml b/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml index 6c23a85af..7d07bfbef 100644 --- a/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml +++ b/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml @@ -388,10 +388,14 @@ imageId 2 TEXT|0s + 1 + "unnamed" 3 TEXT|0s + 1 + "" 4 diff --git a/db/main_branches.sql b/db/main_branches.sql index ca48ff98b..5b32f5a4d 100644 --- a/db/main_branches.sql +++ b/db/main_branches.sql @@ -1,3 +1,4 @@ +INSERT INTO branches (branchId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('root', 'root', 'none', 0, null, 1, 0, '2018-01-01T00:00:00.000Z'); INSERT INTO branches (branchId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('dLgtLUFn3GoN', '1Heh2acXfPNt', 'root', 21, null, 1, 0, '2017-12-23T00:46:39.304Z'); INSERT INTO branches (branchId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('QLfS835GSfIh', '3RkyK9LI18dO', '1Heh2acXfPNt', 1, null, 1, 0, '2017-12-23T01:20:04.181Z'); INSERT INTO branches (branchId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('QJAcYJ1gGUh9', 'L1Ox40M1aEyy', '3RkyK9LI18dO', 0, null, 0, 0, '2017-12-23T01:20:45.365Z'); diff --git a/db/migrations/0089__add_root_branch.sql b/db/migrations/0089__add_root_branch.sql new file mode 100644 index 000000000..0c88be74a --- /dev/null +++ b/db/migrations/0089__add_root_branch.sql @@ -0,0 +1,5 @@ +INSERT INTO branches (branchId, noteId, parentNoteId, notePosition, prefix, isExpanded, dateModified) + VALUES ('root', 'root', 'none', 0, null, 1, '2018-01-01T00:00:00.000Z'); + +INSERT INTO sync (entityName, entityId, sourceId, syncDate) + VALUES ('branches' ,'root', 'SYNC_FILL', '2018-01-01T00:00:00.000Z'); \ No newline at end of file diff --git a/db/migrations/0090__branch_index.sql b/db/migrations/0090__branch_index.sql new file mode 100644 index 000000000..88d396a74 --- /dev/null +++ b/db/migrations/0090__branch_index.sql @@ -0,0 +1 @@ +CREATE INDEX IDX_branches_parentNoteId ON branches (parentNoteId); \ No newline at end of file diff --git a/db/migrations/0091__drop_isDeleted_index.sql b/db/migrations/0091__drop_isDeleted_index.sql new file mode 100644 index 000000000..4d547394b --- /dev/null +++ b/db/migrations/0091__drop_isDeleted_index.sql @@ -0,0 +1,2 @@ +-- index confuses planner and is mostly useless anyway since we're mostly used in non-deleted notes (which are presumably majority) +DROP INDEX IDX_notes_isDeleted; \ No newline at end of file diff --git a/src/public/javascripts/services/link.js b/src/public/javascripts/services/link.js index 7fa74cb34..89d37bdc4 100644 --- a/src/public/javascripts/services/link.js +++ b/src/public/javascripts/services/link.js @@ -75,7 +75,7 @@ function goToLink(e) { } function addLinkToEditor(linkTitle, linkHref) { - const editor = noteDetailText.getEditor(); + const editor = noteDetailText.getEditor();Rum editor.model.change( writer => { const insertPosition = editor.model.document.selection.getFirstPosition(); diff --git a/src/routes/api/tree.js b/src/routes/api/tree.js index 0bd0372d4..7322e0b40 100644 --- a/src/routes/api/tree.js +++ b/src/routes/api/tree.js @@ -3,56 +3,46 @@ const sql = require('../../services/sql'); const optionService = require('../../services/options'); const protectedSessionService = require('../../services/protected_session'); +const utils = require('../../services/utils'); async function getTree() { const branches = await sql.getRows(` - SELECT - branchId, - noteId, - parentNoteId, - notePosition, - prefix, - isExpanded - FROM - branches - WHERE - isDeleted = 0 - ORDER BY - notePosition`); + WITH RECURSIVE + tree(branchId, noteId, isExpanded) AS ( + SELECT branchId, noteId, isExpanded FROM branches WHERE branchId = 'root' + UNION ALL + SELECT branches.branchId, branches.noteId, branches.isExpanded FROM branches + JOIN tree ON branches.parentNoteId = tree.noteId + WHERE tree.isExpanded = 1 AND branches.isDeleted = 0 + ) + SELECT branches.* FROM tree JOIN branches USING(branchId);`); - const notes = [{ - noteId: 'root', - title: 'root', - isProtected: false, - type: 'none', - mime: 'none' - }].concat(await sql.getRows(` - SELECT - notes.noteId, - notes.title, - notes.isProtected, - notes.type, - notes.mime, - hideInAutocomplete.labelId AS 'hideInAutocomplete' - FROM - notes - LEFT JOIN labels AS hideInAutocomplete ON hideInAutocomplete.noteId = notes.noteId - AND hideInAutocomplete.name = 'hideInAutocomplete' - AND hideInAutocomplete.isDeleted = 0 - WHERE - notes.isDeleted = 0`)); + const noteIds = branches.map(b => b.noteId); + const questionMarks = branches.map(() => "?").join(","); + + const notes = await sql.getRows(` + SELECT noteId, title, isProtected, type, mime + FROM notes WHERE isDeleted = 0 AND noteId IN (${questionMarks})`, noteIds); protectedSessionService.decryptNotes(notes); - notes.forEach(note => { - note.hideInAutocomplete = !!note.hideInAutocomplete; - note.isProtected = !!note.isProtected; - }); + notes.forEach(note => note.isProtected = !!note.isProtected); + + const relationships = await sql.getRows(`SELECT noteId, parentNoteId FROM branches WHERE isDeleted = 0 + AND parentNoteId IN (${questionMarks})`, noteIds); + + const parentToChild = {}; + + for (const rel of relationships) { + parentToChild[rel.parentNoteId] = parentToChild[rel.parentNoteId] || []; + parentToChild[rel.parentNoteId].push(rel.noteId); + } return { startNotePath: await optionService.getOption('startNotePath'), branches: branches, - notes: notes + notes: notes, + parentToChild }; } diff --git a/src/services/app_info.js b/src/services/app_info.js index 3c2a5cd6b..c8433345f 100644 --- a/src/services/app_info.js +++ b/src/services/app_info.js @@ -3,7 +3,7 @@ const build = require('./build'); const packageJson = require('../../package'); -const APP_DB_VERSION = 88; +const APP_DB_VERSION = 91; module.exports = { appVersion: packageJson.version, diff --git a/src/services/consistency_checks.js b/src/services/consistency_checks.js index bc764db3f..d8b0921c3 100644 --- a/src/services/consistency_checks.js +++ b/src/services/consistency_checks.js @@ -116,7 +116,7 @@ async function runAllChecks() { WHERE notes.isDeleted = 1 AND branches.isDeleted = 0`, - "Note tree is not deleted even though main note is deleted for following branch IDs", errorList); + "Branch is not deleted even though main note is deleted for following branch IDs", errorList); await runCheck(` SELECT @@ -125,12 +125,12 @@ async function runAllChecks() { branches AS child WHERE child.isDeleted = 0 - AND child.parentNoteId != 'root' + AND child.parentNoteId != 'none' AND (SELECT COUNT(*) FROM branches AS parent WHERE parent.noteId = child.parentNoteId AND parent.isDeleted = 0) = 0`, - "All parent branches are deleted but child note tree is not for these child note tree IDs", errorList); + "All parent branches are deleted but child branch is not for these child branch IDs", errorList); - // we do extra JOIN to eliminate orphan notes without note tree (which are reported separately) + // we do extra JOIN to eliminate orphan notes without branches (which are reported separately) await runCheck(` SELECT DISTINCT noteId @@ -150,7 +150,7 @@ async function runAllChecks() { LEFT JOIN branches AS parent ON parent.noteId = child.parentNoteId WHERE parent.noteId IS NULL - AND child.parentNoteId != 'root'`, + AND child.parentNoteId != 'none'`, "Not existing parent in the following parent > child relations", errorList); await runCheck(` diff --git a/src/tools/generate_document.js b/src/tools/generate_document.js index 7933615c8..ab58d9fde 100644 --- a/src/tools/generate_document.js +++ b/src/tools/generate_document.js @@ -58,7 +58,7 @@ async function start() { } // we'll create clones for 20% of notes - for (let i = 0; i < (noteCount / 5); i++) { + for (let i = 0; i < (noteCount / 50); i++) { const noteIdToClone = getRandomParentNoteId(); const parentNoteId = getRandomParentNoteId(); const prefix = Math.random() > 0.8 ? "prefix" : null;