diff --git a/bin/build-server.sh b/bin/build-server.sh index 2b5d512f2..514c262b9 100755 --- a/bin/build-server.sh +++ b/bin/build-server.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash PKG_DIR=dist/trilium-linux-x64-server -NODE_VERSION=12.16.3 +NODE_VERSION=12.18.3 if [ "$1" != "DONTCOPY" ] then diff --git a/spec/search/parser.spec.js b/spec/search/parser.spec.js index c3223cdff..a49b07db9 100644 --- a/spec/search/parser.spec.js +++ b/spec/search/parser.spec.js @@ -27,8 +27,9 @@ describe("Parser", () => { parsingContext: new ParsingContext({includeNoteContent: false}) }); - expect(rootExp.constructor.name).toEqual("NoteCacheFlatTextExp"); - expect(rootExp.tokens).toEqual(["hello", "hi"]); + expect(rootExp.constructor.name).toEqual("AndExp"); + expect(rootExp.subExpressions[0].constructor.name).toEqual("NoteCacheFlatTextExp"); + expect(rootExp.subExpressions[0].tokens).toEqual(["hello", "hi"]); }); it("fulltext parser with content", () => { @@ -38,8 +39,11 @@ describe("Parser", () => { parsingContext: new ParsingContext({includeNoteContent: true}) }); - expect(rootExp.constructor.name).toEqual("OrExp"); - const subs = rootExp.subExpressions; + expect(rootExp.constructor.name).toEqual("AndExp"); + expect(rootExp.subExpressions[0].constructor.name).toEqual("OrExp"); + expect(rootExp.subExpressions[1].constructor.name).toEqual("PropertyComparisonExp"); + + const subs = rootExp.subExpressions[0].subExpressions; expect(subs[0].constructor.name).toEqual("NoteCacheFlatTextExp"); expect(subs[0].tokens).toEqual(["hello", "hi"]); @@ -149,8 +153,9 @@ describe("Parser", () => { expect(rootExp.constructor.name).toEqual("AndExp"); const [firstSub, secondSub] = rootExp.subExpressions; - expect(firstSub.constructor.name).toEqual("NoteCacheFlatTextExp"); - expect(firstSub.tokens).toEqual(["hello"]); + expect(firstSub.constructor.name).toEqual("AndExp"); + expect(firstSub.subExpressions[0].constructor.name).toEqual("NoteCacheFlatTextExp"); + expect(firstSub.subExpressions[0].tokens).toEqual(["hello"]); expect(secondSub.constructor.name).toEqual("LabelComparisonExp"); expect(secondSub.attributeName).toEqual("mylabel"); diff --git a/spec/search/search.spec.js b/spec/search/search.spec.js index a26617921..26e238157 100644 --- a/spec/search/search.spec.js +++ b/spec/search/search.spec.js @@ -544,6 +544,23 @@ describe("Search", () => { expect(noteCache.notes[searchResults[0].noteId].title).toEqual("Slovakia"); }); + it("test that fulltext does not match archived notes", () => { + const italy = note("Italy").label("capital", "Rome"); + const slovakia = note("Slovakia").label("capital", "Bratislava"); + + rootNote + .child(note("Reddit").label('archived', '', true) + .child(note('Post X')) + .child(note('Post Y'))) + .child(note ('Reddit is bad')); + + const parsingContext = new ParsingContext(); + + let searchResults = searchService.findNotesWithQuery('reddit', parsingContext); + expect(searchResults.length).toEqual(1); + expect(noteCache.notes[searchResults[0].noteId].title).toEqual("Reddit is bad"); + }); + // FIXME: test what happens when we order without any filter criteria // it("comparison between labels", () => { diff --git a/src/services/note_cache/entities/note.js b/src/services/note_cache/entities/note.js index 693afe7df..a00682b29 100644 --- a/src/services/note_cache/entities/note.js +++ b/src/services/note_cache/entities/note.js @@ -115,7 +115,7 @@ class Note { } hasAttribute(type, name) { - return this.attributes.find(attr => attr.type === type && attr.name === name); + return !!this.attributes.find(attr => attr.type === type && attr.name === name); } getLabelValue(name) { diff --git a/src/services/search/expressions/note_cache_flat_text.js b/src/services/search/expressions/note_cache_flat_text.js index c17f79218..c503d7653 100644 --- a/src/services/search/expressions/note_cache_flat_text.js +++ b/src/services/search/expressions/note_cache_flat_text.js @@ -75,11 +75,6 @@ class NoteCacheFlatTextExp extends Expression { continue; } - // for leaf note it doesn't matter if "archived" label is inheritable or not - if (note.isArchived) { - continue; - } - const foundAttrTokens = []; for (const attribute of note.ownedAttributes) { diff --git a/src/services/search/expressions/property_comparison.js b/src/services/search/expressions/property_comparison.js index 3f37987a2..6ee7ce63e 100644 --- a/src/services/search/expressions/property_comparison.js +++ b/src/services/search/expressions/property_comparison.js @@ -13,7 +13,7 @@ const PROP_MAPPING = { "type": "type", "mime": "mime", "isprotected": "isProtected", - "isarhived": "isArchived", + "isarchived": "isArchived", "datecreated": "dateCreated", "datemodified": "dateModified", "utcdatecreated": "utcDateCreated", diff --git a/src/services/search/services/parse.js b/src/services/search/services/parse.js index 9e6eb1ffd..abc908441 100644 --- a/src/services/search/services/parse.js +++ b/src/services/search/services/parse.js @@ -25,16 +25,24 @@ function getFulltext(tokens, parsingContext) { if (tokens.length === 0) { return null; } - else if (parsingContext.includeNoteContent) { - return new OrExp([ + + let textSearchExpression; + + if (parsingContext.includeNoteContent) { + textSearchExpression = new OrExp([ new NoteCacheFulltextExp(tokens), new NoteContentProtectedFulltextExp('*=*', tokens), new NoteContentUnprotectedFulltextExp('*=*', tokens) ]); } else { - return new NoteCacheFulltextExp(tokens); + textSearchExpression = new NoteCacheFulltextExp(tokens); } + + return new AndExp([ + textSearchExpression, + new PropertyComparisonExp("isarchived", comparatorBuilder("=", "false")) + ]); } function isOperator(str) {