From 1a87190f43b28425406919312bd02990c3d2a7f5 Mon Sep 17 00:00:00 2001 From: zadam Date: Sun, 17 Nov 2019 09:07:35 +0100 Subject: [PATCH] added IN operator to search, closes #534 --- src/services/build_search_query.js | 2 +- src/services/note_cache.js | 20 ++++++++++++++++++++ src/services/search.js | 14 ++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/services/build_search_query.js b/src/services/build_search_query.js index efd549140..2f54afb76 100644 --- a/src/services/build_search_query.js +++ b/src/services/build_search_query.js @@ -67,7 +67,7 @@ module.exports = function(filters, selectedColumns = 'notes.*') { const params = []; for (const filter of filters) { - if (['isarchived', 'orderby', 'limit'].includes(filter.name.toLowerCase())) { + if (['isarchived', 'in', 'orderby', 'limit'].includes(filter.name.toLowerCase())) { continue; // these are not real filters } diff --git a/src/services/note_cache.js b/src/services/note_cache.js index c8c93cb3a..dfdc2ae35 100644 --- a/src/services/note_cache.js +++ b/src/services/note_cache.js @@ -255,6 +255,25 @@ function isArchived(noteId) { return isNotePathArchived(notePath); } +/** + * @param {string} noteId + * @param {string} ancestorNoteId + * @return {boolean} - true if given noteId has ancestorNoteId in any of its paths (even archived) + */ +function isInAncestor(noteId, ancestorNoteId) { + if (ancestorNoteId === noteId) { // special case + return true; + } + + for (const parentNoteId of childToParent[noteId] || []) { + if (isInAncestor(parentNoteId, ancestorNoteId)) { + return true; + } + } + + return false; +} + function getNoteTitleFromPath(notePath) { const pathArr = notePath.split("/"); @@ -529,6 +548,7 @@ module.exports = { getNoteTitleFromPath, isAvailable, isArchived, + isInAncestor, load, findSimilarNotes }; \ No newline at end of file diff --git a/src/services/search.js b/src/services/search.js index 70436827d..472e66e6f 100644 --- a/src/services/search.js +++ b/src/services/search.js @@ -35,6 +35,20 @@ async function searchForNoteIds(searchString) { } } + const isInFilter = filters.find(filter => filter.name.toLowerCase() === 'in'); + + if (isInFilter) { + if (isInFilter.operator === '=') { + noteIds = noteIds.filter(noteId => noteCacheService.isInAncestor(noteId, isInFilter.value)); + } + else if (isInFilter.operator === '!=') { + noteIds = noteIds.filter(noteId => !noteCacheService.isInAncestor(noteId, isInFilter.value)); + } + else { + throw new Error(`Unrecognized isIn operator ${isInFilter.operator}`); + } + } + const limitFilter = filters.find(filter => filter.name.toLowerCase() === 'limit'); if (limitFilter) {