diff --git a/docs/backend_api/services_backend_script_api.js.html b/docs/backend_api/services_backend_script_api.js.html index cb310abc5..8f44ab816 100644 --- a/docs/backend_api/services_backend_script_api.js.html +++ b/docs/backend_api/services_backend_script_api.js.html @@ -138,7 +138,7 @@ function BackendScriptApi(currentNote, apiParams) { searchParams.ignoreHoistedNote = true; } - const noteIds = searchService.findNotesWithQuery(query, new SearchContext(searchParams)) + const noteIds = searchService.findResultsWithQuery(query, new SearchContext(searchParams)) .map(sr => sr.noteId); return repository.getNotes(noteIds); diff --git a/spec/search/search.spec.js b/spec/search/search.spec.js index 26079e4a6..68a5a2171 100644 --- a/spec/search/search.spec.js +++ b/spec/search/search.spec.js @@ -23,7 +23,7 @@ describe("Search", () => { ); const searchContext = new SearchContext(); - const searchResults = searchService.findNotesWithQuery('europe austria', searchContext); + const searchResults = searchService.findResultsWithQuery('europe austria', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy(); @@ -40,12 +40,12 @@ describe("Search", () => { .label('inhabitants', '1888776')); const searchContext = new SearchContext(); - let searchResults = searchService.findNotesWithQuery('capital', searchContext); + let searchResults = searchService.findResultsWithQuery('capital', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy(); - searchResults = searchService.findNotesWithQuery('inhabitants', searchContext); + searchResults = searchService.findResultsWithQuery('inhabitants', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Vienna")).toBeTruthy(); @@ -57,17 +57,17 @@ describe("Search", () => { .child(note("Hello World.java", {type: 'code', mime: 'text/x-java'})); const searchContext = new SearchContext(); - let searchResults = searchService.findNotesWithQuery('book', searchContext); + let searchResults = searchService.findResultsWithQuery('book', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Effective Java")).toBeTruthy(); - searchResults = searchService.findNotesWithQuery('text', searchContext); // should match mime + searchResults = searchService.findResultsWithQuery('text', searchContext); // should match mime expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Hello World.java")).toBeTruthy(); - searchResults = searchService.findNotesWithQuery('java', searchContext); + searchResults = searchService.findResultsWithQuery('java', searchContext); expect(searchResults.length).toEqual(2); }); @@ -79,7 +79,7 @@ describe("Search", () => { ); const searchContext = new SearchContext(); - const searchResults = searchService.findNotesWithQuery('europe', searchContext); + const searchResults = searchService.findResultsWithQuery('europe', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Europe")).toBeTruthy(); @@ -94,7 +94,7 @@ describe("Search", () => { const searchContext = new SearchContext(); - const searchResults = searchService.findNotesWithQuery('Vienna', searchContext); + const searchResults = searchService.findResultsWithQuery('Vienna', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy(); }); @@ -110,16 +110,16 @@ describe("Search", () => { const searchContext = new SearchContext(); - let searchResults = searchService.findNotesWithQuery('#capital=Vienna', searchContext); + let searchResults = searchService.findResultsWithQuery('#capital=Vienna', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy(); // case sensitivity: - searchResults = searchService.findNotesWithQuery('#CAPITAL=VIENNA', searchContext); + searchResults = searchService.findResultsWithQuery('#CAPITAL=VIENNA', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy(); - searchResults = searchService.findNotesWithQuery('#caPItal=vienNa', searchContext); + searchResults = searchService.findResultsWithQuery('#caPItal=vienNa', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy(); }); @@ -135,7 +135,7 @@ describe("Search", () => { const searchContext = new SearchContext(); - let searchResults = searchService.findNotesWithQuery('# note.labels.capital=Prague', searchContext); + let searchResults = searchService.findResultsWithQuery('# note.labels.capital=Prague', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Czech Republic")).toBeTruthy(); }); @@ -152,7 +152,7 @@ describe("Search", () => { const searchContext = new SearchContext(); - const searchResults = searchService.findNotesWithQuery('#country #population >= 10000000', searchContext); + const searchResults = searchService.findResultsWithQuery('#country #population >= 10000000', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Czech Republic")).toBeTruthy(); }); @@ -173,11 +173,11 @@ describe("Search", () => { const searchContext = new SearchContext(); - let searchResults = searchService.findNotesWithQuery('#established <= "1955-01-01"', searchContext); + let searchResults = searchService.findResultsWithQuery('#established <= "1955-01-01"', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Hungary")).toBeTruthy(); - searchResults = searchService.findNotesWithQuery('#established > "1955-01-01"', searchContext); + searchResults = searchService.findResultsWithQuery('#established > "1955-01-01"', searchContext); expect(searchResults.length).toEqual(2); expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy(); expect(findNoteByTitle(searchResults, "Czech Republic")).toBeTruthy(); @@ -197,7 +197,7 @@ describe("Search", () => { const searchContext = new SearchContext(); function test(query, expectedResultCount) { - const searchResults = searchService.findNotesWithQuery(query, searchContext); + const searchResults = searchService.findResultsWithQuery(query, searchContext); expect(searchResults.length).toEqual(expectedResultCount); if (expectedResultCount === 1) { @@ -251,7 +251,7 @@ describe("Search", () => { const searchContext = new SearchContext(); - const searchResults = searchService.findNotesWithQuery('#languageFamily = slavic OR #languageFamily = germanic', searchContext); + const searchResults = searchService.findResultsWithQuery('#languageFamily = slavic OR #languageFamily = germanic', searchContext); expect(searchResults.length).toEqual(2); expect(findNoteByTitle(searchResults, "Czech Republic")).toBeTruthy(); expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy(); @@ -268,18 +268,18 @@ describe("Search", () => { let searchContext = new SearchContext({fuzzyAttributeSearch: false}); - let searchResults = searchService.findNotesWithQuery('#language', searchContext); + let searchResults = searchService.findResultsWithQuery('#language', searchContext); expect(searchResults.length).toEqual(0); - searchResults = searchService.findNotesWithQuery('#languageFamily=ger', searchContext); + searchResults = searchService.findResultsWithQuery('#languageFamily=ger', searchContext); expect(searchResults.length).toEqual(0); searchContext = new SearchContext({fuzzyAttributeSearch: true}); - searchResults = searchService.findNotesWithQuery('#language', searchContext); + searchResults = searchService.findResultsWithQuery('#language', searchContext); expect(searchResults.length).toEqual(2); - searchResults = searchService.findNotesWithQuery('#languageFamily=ger', searchContext); + searchResults = searchService.findResultsWithQuery('#languageFamily=ger', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy(); }); @@ -292,7 +292,7 @@ describe("Search", () => { const searchContext = new SearchContext(); - const searchResults = searchService.findNotesWithQuery('# note.title =* czech', searchContext); + const searchResults = searchService.findResultsWithQuery('# note.title =* czech', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Czech Republic")).toBeTruthy(); }); @@ -309,16 +309,16 @@ describe("Search", () => { const searchContext = new SearchContext(); - let searchResults = searchService.findNotesWithQuery('# note.parents.title = Europe', searchContext); + let searchResults = searchService.findResultsWithQuery('# note.parents.title = Europe', searchContext); expect(searchResults.length).toEqual(2); expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy(); expect(findNoteByTitle(searchResults, "Czech Republic")).toBeTruthy(); - searchResults = searchService.findNotesWithQuery('# note.parents.title = Asia', searchContext); + searchResults = searchService.findResultsWithQuery('# note.parents.title = Asia', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Taiwan")).toBeTruthy(); - searchResults = searchService.findNotesWithQuery('# note.parents.parents.title = Europe', searchContext); + searchResults = searchService.findResultsWithQuery('# note.parents.parents.title = Europe', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Prague")).toBeTruthy(); }); @@ -337,11 +337,11 @@ describe("Search", () => { const searchContext = new SearchContext(); - let searchResults = searchService.findNotesWithQuery('#city AND note.ancestors.title = Europe', searchContext); + let searchResults = searchService.findResultsWithQuery('#city AND note.ancestors.title = Europe', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Prague")).toBeTruthy(); - searchResults = searchService.findNotesWithQuery('#city AND note.ancestors.title = Asia', searchContext); + searchResults = searchService.findResultsWithQuery('#city AND note.ancestors.title = Asia', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Taipei")).toBeTruthy(); }); @@ -358,16 +358,16 @@ describe("Search", () => { const searchContext = new SearchContext(); - let searchResults = searchService.findNotesWithQuery('# note.children.title =* Aust', searchContext); + let searchResults = searchService.findResultsWithQuery('# note.children.title =* Aust', searchContext); expect(searchResults.length).toEqual(2); expect(findNoteByTitle(searchResults, "Europe")).toBeTruthy(); expect(findNoteByTitle(searchResults, "Oceania")).toBeTruthy(); - searchResults = searchService.findNotesWithQuery('# note.children.title =* Aust AND note.children.title *= republic', searchContext); + searchResults = searchService.findResultsWithQuery('# note.children.title =* Aust AND note.children.title *= republic', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Europe")).toBeTruthy(); - searchResults = searchService.findNotesWithQuery('# note.children.children.title = Prague', searchContext); + searchResults = searchService.findResultsWithQuery('# note.children.children.title = Prague', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Europe")).toBeTruthy(); }); @@ -388,11 +388,11 @@ describe("Search", () => { const searchContext = new SearchContext(); - let searchResults = searchService.findNotesWithQuery('# ~neighbor.title = Austria', searchContext); + let searchResults = searchService.findResultsWithQuery('# ~neighbor.title = Austria', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Czech Republic")).toBeTruthy(); - searchResults = searchService.findNotesWithQuery('# ~neighbor.title = Portugal', searchContext); + searchResults = searchService.findResultsWithQuery('# ~neighbor.title = Portugal', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Spain")).toBeTruthy(); }); @@ -413,7 +413,7 @@ describe("Search", () => { const searchContext = new SearchContext(); - const searchResults = searchService.findNotesWithQuery('# note.relations.neighbor.title = Austria', searchContext); + const searchResults = searchService.findResultsWithQuery('# note.relations.neighbor.title = Austria', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Czech Republic")).toBeTruthy(); }); @@ -439,11 +439,11 @@ describe("Search", () => { const searchContext = new SearchContext(); - let searchResults = searchService.findNotesWithQuery('# note.relations.neighbor.relations.neighbor.title = Italy', searchContext); + let searchResults = searchService.findResultsWithQuery('# note.relations.neighbor.relations.neighbor.title = Italy', searchContext); expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Czech Republic")).toBeTruthy(); - searchResults = searchService.findNotesWithQuery('# note.relations.neighbor.relations.neighbor.title = Ukraine', searchContext); + searchResults = searchService.findResultsWithQuery('# note.relations.neighbor.relations.neighbor.title = Ukraine', searchContext); expect(searchResults.length).toEqual(2); expect(findNoteByTitle(searchResults, "Czech Republic")).toBeTruthy(); expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy(); @@ -477,7 +477,7 @@ describe("Search", () => { const searchContext = new SearchContext(); function test(propertyName, value, expectedResultCount) { - const searchResults = searchService.findNotesWithQuery(`# note.${propertyName} = ${value}`, searchContext); + const searchResults = searchService.findResultsWithQuery(`# note.${propertyName} = ${value}`, searchContext); expect(searchResults.length).toEqual(expectedResultCount); } @@ -536,36 +536,36 @@ describe("Search", () => { const searchContext = new SearchContext(); - let searchResults = searchService.findNotesWithQuery('# note.parents.title = Europe orderBy note.title', searchContext); + let searchResults = searchService.findResultsWithQuery('# note.parents.title = Europe orderBy note.title', searchContext); expect(searchResults.length).toEqual(4); expect(becca.notes[searchResults[0].noteId].title).toEqual("Austria"); expect(becca.notes[searchResults[1].noteId].title).toEqual("Italy"); expect(becca.notes[searchResults[2].noteId].title).toEqual("Slovakia"); expect(becca.notes[searchResults[3].noteId].title).toEqual("Ukraine"); - searchResults = searchService.findNotesWithQuery('# note.parents.title = Europe orderBy note.labels.capital', searchContext); + searchResults = searchService.findResultsWithQuery('# note.parents.title = Europe orderBy note.labels.capital', searchContext); expect(searchResults.length).toEqual(4); expect(becca.notes[searchResults[0].noteId].title).toEqual("Slovakia"); expect(becca.notes[searchResults[1].noteId].title).toEqual("Ukraine"); expect(becca.notes[searchResults[2].noteId].title).toEqual("Italy"); expect(becca.notes[searchResults[3].noteId].title).toEqual("Austria"); - searchResults = searchService.findNotesWithQuery('# note.parents.title = Europe orderBy note.labels.capital DESC', searchContext); + searchResults = searchService.findResultsWithQuery('# note.parents.title = Europe orderBy note.labels.capital DESC', searchContext); expect(searchResults.length).toEqual(4); expect(becca.notes[searchResults[0].noteId].title).toEqual("Austria"); expect(becca.notes[searchResults[1].noteId].title).toEqual("Italy"); expect(becca.notes[searchResults[2].noteId].title).toEqual("Ukraine"); expect(becca.notes[searchResults[3].noteId].title).toEqual("Slovakia"); - searchResults = searchService.findNotesWithQuery('# note.parents.title = Europe orderBy note.labels.capital DESC limit 2', searchContext); + searchResults = searchService.findResultsWithQuery('# note.parents.title = Europe orderBy note.labels.capital DESC limit 2', searchContext); expect(searchResults.length).toEqual(2); expect(becca.notes[searchResults[0].noteId].title).toEqual("Austria"); expect(becca.notes[searchResults[1].noteId].title).toEqual("Italy"); - searchResults = searchService.findNotesWithQuery('# note.parents.title = Europe orderBy #capital DESC limit 1', searchContext); + searchResults = searchService.findResultsWithQuery('# note.parents.title = Europe orderBy #capital DESC limit 1', searchContext); expect(searchResults.length).toEqual(1); - searchResults = searchService.findNotesWithQuery('# note.parents.title = Europe orderBy #capital DESC limit 1000', searchContext); + searchResults = searchService.findResultsWithQuery('# note.parents.title = Europe orderBy #capital DESC limit 1000', searchContext); expect(searchResults.length).toEqual(4); }); @@ -580,11 +580,11 @@ describe("Search", () => { const searchContext = new SearchContext(); - let searchResults = searchService.findNotesWithQuery('# not(#capital) and note.noteId != root', searchContext); + let searchResults = searchService.findResultsWithQuery('# not(#capital) and note.noteId != root', searchContext); expect(searchResults.length).toEqual(1); expect(becca.notes[searchResults[0].noteId].title).toEqual("Europe"); - searchResults = searchService.findNotesWithQuery('#!capital and note.noteId != root', searchContext); + searchResults = searchService.findResultsWithQuery('#!capital and note.noteId != root', searchContext); expect(searchResults.length).toEqual(1); expect(becca.notes[searchResults[0].noteId].title).toEqual("Europe"); }); @@ -600,7 +600,7 @@ describe("Search", () => { const searchContext = new SearchContext(); - let searchResults = searchService.findNotesWithQuery('# note.text *=* vaki and note.noteId != root', searchContext); + let searchResults = searchService.findResultsWithQuery('# note.text *=* vaki and note.noteId != root', searchContext); expect(searchResults.length).toEqual(1); expect(becca.notes[searchResults[0].noteId].title).toEqual("Slovakia"); }); @@ -617,7 +617,7 @@ describe("Search", () => { const searchContext = new SearchContext({excludeArchived: true}); - let searchResults = searchService.findNotesWithQuery('reddit', searchContext); + let searchResults = searchService.findResultsWithQuery('reddit', searchContext); expect(searchResults.length).toEqual(1); expect(becca.notes[searchResults[0].noteId].title).toEqual("Reddit is bad"); }); @@ -640,7 +640,7 @@ describe("Search", () => { // // const searchContext = new SearchContext(); // - // const searchResults = searchService.findNotesWithQuery('#capital = #largestCity', searchContext); + // const searchResults = searchService.findResultsWithQuery('#capital = #largestCity', searchContext); // expect(searchResults.length).toEqual(2); // expect(findNoteByTitle(searchResults, "Czech Republic")).toBeTruthy(); // expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy(); diff --git a/src/public/app/services/glob.js b/src/public/app/services/glob.js index 2e444af3d..8e8c5e750 100644 --- a/src/public/app/services/glob.js +++ b/src/public/app/services/glob.js @@ -21,6 +21,7 @@ function setupGlobs() { window.glob.ESLINT = libraryLoader.ESLINT; window.glob.appContext = appContext; // for debugging window.glob.froca = froca; + window.glob.treeCache = froca; // compatibility for CKEditor builds for a while // for CKEditor integration (button on block toolbar) window.glob.importMarkdownInline = async () => { diff --git a/src/routes/api/options.js b/src/routes/api/options.js index 4928adcce..0b27f97ea 100644 --- a/src/routes/api/options.js +++ b/src/routes/api/options.js @@ -3,6 +3,7 @@ const optionService = require('../../services/options'); const log = require('../../services/log'); const attributes = require('../../services/attributes'); +const searchService = require('../../services/search/services/search'); // options allowed to be updated directly in options dialog const ALLOWED_OPTIONS = new Set([ @@ -91,8 +92,7 @@ function update(name, value) { } function getUserThemes() { - const notes = attributes.getNotesWithLabel('appTheme'); - + const notes = searchService.findNotes("#appTheme"); const ret = []; for (const note of notes) { diff --git a/src/routes/api/search.js b/src/routes/api/search.js index 39f77139f..7b6cd333c 100644 --- a/src/routes/api/search.js +++ b/src/routes/api/search.js @@ -28,7 +28,7 @@ async function searchFromNoteInt(note) { fuzzyAttributeSearch: false }); - searchResultNoteIds = searchService.findNotesWithQuery(searchString, searchContext) + searchResultNoteIds = searchService.findResultsWithQuery(searchString, searchContext) .map(sr => sr.noteId); } @@ -215,7 +215,7 @@ function quickSearch(req) { fuzzyAttributeSearch: false }); - return searchService.findNotesWithQuery(searchString, searchContext) + return searchService.findResultsWithQuery(searchString, searchContext) .map(sr => sr.noteId); } @@ -229,7 +229,7 @@ function search(req) { ignoreHoistedNote: true }); - return searchService.findNotesWithQuery(searchString, searchContext) + return searchService.findResultsWithQuery(searchString, searchContext) .map(sr => sr.noteId); } @@ -242,8 +242,8 @@ function getRelatedNotes(req) { fuzzyAttributeSearch: false }; - const matchingNameAndValue = searchService.findNotesWithQuery(formatAttrForSearch(attr, true), new SearchContext(searchSettings)); - const matchingName = searchService.findNotesWithQuery(formatAttrForSearch(attr, false), new SearchContext(searchSettings)); + const matchingNameAndValue = searchService.findResultsWithQuery(formatAttrForSearch(attr, true), new SearchContext(searchSettings)); + const matchingName = searchService.findResultsWithQuery(formatAttrForSearch(attr, false), new SearchContext(searchSettings)); const results = []; diff --git a/src/services/attributes.js b/src/services/attributes.js index 7faa0ab52..bfd207c3c 100644 --- a/src/services/attributes.js +++ b/src/services/attributes.js @@ -67,7 +67,7 @@ function getNotesWithLabel(name, value) { params.push(value); } - return repository.getEntities(`SELECT notes.* FROM notes JOIN attributes USING(noteId) + return repository.getEntities(`SELECT notes.* FROM notes JOIN attributes USING(noteId) WHERE notes.isDeleted = 0 AND attributes.isDeleted = 0 AND attributes.name = ? ${valueCondition} ORDER BY position`, params); } diff --git a/src/services/backend_script_api.js b/src/services/backend_script_api.js index 527b5d98f..a6a118781 100644 --- a/src/services/backend_script_api.js +++ b/src/services/backend_script_api.js @@ -110,7 +110,7 @@ function BackendScriptApi(currentNote, apiParams) { searchParams.ignoreHoistedNote = true; } - const noteIds = searchService.findNotesWithQuery(query, new SearchContext(searchParams)) + const noteIds = searchService.findResultsWithQuery(query, new SearchContext(searchParams)) .map(sr => sr.noteId); return repository.getNotes(noteIds); diff --git a/src/services/becca/becca_loader.js b/src/services/becca/becca_loader.js index 05076e699..7d2e29882 100644 --- a/src/services/becca/becca_loader.js +++ b/src/services/becca/becca_loader.js @@ -22,7 +22,7 @@ function load() { } for (const row of sql.iterateRows(`SELECT branchId, noteId, parentNoteId, prefix, notePosition, isExpanded FROM branches WHERE isDeleted = 0`, [])) { - const branch = new Branch(becca, row); + new Branch(becca, row); } for (const row of sql.iterateRows(`SELECT attributeId, noteId, type, name, value, isInheritable, position FROM attributes WHERE isDeleted = 0`, [])) { @@ -66,7 +66,7 @@ eventService.subscribe([eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED childNote.parentBranches = childNote.parentBranches.filter(branch => branch.branchId !== branchId); if (childNote.parents.length > 0) { - childNote.invalidateSubfrocas(); + childNote.invalidateSubTree(); } } @@ -105,7 +105,7 @@ eventService.subscribe([eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED if (note && attr) { // first invalidate and only then remove the attribute (otherwise invalidation wouldn't be complete) if (attr.isAffectingSubtree || note.isTemplate) { - note.invalidateSubfrocas(); + note.invalidateSubTree(); } else { note.invalidateThisCache(); } @@ -147,7 +147,7 @@ eventService.subscribe([eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED if (note) { if (attr.isAffectingSubtree || note.isTemplate) { - note.invalidateSubfrocas(); + note.invalidateSubTree(); } else { note.invalidateThisCache(); diff --git a/src/services/becca/entities/note.js b/src/services/becca/entities/note.js index 7d5f63c5e..9ca720350 100644 --- a/src/services/becca/entities/note.js +++ b/src/services/becca/entities/note.js @@ -3,6 +3,9 @@ const protectedSessionService = require('../../protected_session'); const log = require('../../log'); +const LABEL = 'label'; +const RELATION = 'relation'; + class Note { constructor(becca, row) { /** @param {Becca} */ @@ -153,26 +156,126 @@ class Note { && (!value || attr.value.toLowerCase() === value)); } - hasLabel(name) { - return this.hasAttribute('label', name); - } - - hasRelation(name) { - return this.hasAttribute('relation', name); - } - - getLabelValue(name) { - const label = this.attributes.find(attr => attr.type === 'label' && attr.name === name); - - return label ? label.value : null; - } - getRelationTarget(name) { const relation = this.attributes.find(attr => attr.type === 'relation' && attr.name === name); return relation ? relation.targetNote : null; } + /** + * @param {string} name - label name + * @returns {boolean} true if label exists (including inherited) + */ + hasLabel(name) { return this.hasAttribute(LABEL, name); } + + /** + * @param {string} name - label name + * @returns {boolean} true if label exists (excluding inherited) + */ + hasOwnedLabel(name) { return this.hasOwnedAttribute(LABEL, name); } + + /** + * @param {string} name - relation name + * @returns {boolean} true if relation exists (including inherited) + */ + hasRelation(name) { return this.hasAttribute(RELATION, name); } + + /** + * @param {string} name - relation name + * @returns {boolean} true if relation exists (excluding inherited) + */ + hasOwnedRelation(name) { return this.hasOwnedAttribute(RELATION, name); } + + /** + * @param {string} name - label name + * @returns {Attribute|null} label if it exists, null otherwise + */ + getLabel(name) { return this.getAttribute(LABEL, name); } + + /** + * @param {string} name - label name + * @returns {Attribute|null} label if it exists, null otherwise + */ + getOwnedLabel(name) { return this.getOwnedAttribute(LABEL, name); } + + /** + * @param {string} name - relation name + * @returns {Attribute|null} relation if it exists, null otherwise + */ + getRelation(name) { return this.getAttribute(RELATION, name); } + + /** + * @param {string} name - relation name + * @returns {Attribute|null} relation if it exists, null otherwise + */ + getOwnedRelation(name) { return this.getOwnedAttribute(RELATION, name); } + + /** + * @param {string} name - label name + * @returns {string|null} label value if label exists, null otherwise + */ + getLabelValue(name) { return this.getAttributeValue(LABEL, name); } + + /** + * @param {string} name - label name + * @returns {string|null} label value if label exists, null otherwise + */ + getOwnedLabelValue(name) { return this.getOwnedAttributeValue(LABEL, name); } + + /** + * @param {string} name - relation name + * @returns {string|null} relation value if relation exists, null otherwise + */ + getRelationValue(name) { return this.getAttributeValue(RELATION, name); } + + /** + * @param {string} name - relation name + * @returns {string|null} relation value if relation exists, null otherwise + */ + getOwnedRelationValue(name) { return this.getOwnedAttributeValue(RELATION, name); } + + /** + * @param {string} type - attribute type (label, relation, etc.) + * @param {string} name - attribute name + * @returns {boolean} true if note has an attribute with given type and name (excluding inherited) + */ + hasOwnedAttribute(type, name) { + return !!this.getOwnedAttribute(type, name); + } + + /** + * @param {string} type - attribute type (label, relation, etc.) + * @param {string} name - attribute name + * @returns {Attribute} attribute of given type and name. If there's more such attributes, first is returned. Returns null if there's no such attribute belonging to this note. + */ + getAttribute(type, name) { + const attributes = this.getAttributes(); + + return attributes.find(attr => attr.type === type && attr.name === name); + } + + /** + * @param {string} type - attribute type (label, relation, etc.) + * @param {string} name - attribute name + * @returns {string|null} attribute value of given type and name or null if no such attribute exists. + */ + getAttributeValue(type, name) { + const attr = this.getAttribute(type, name); + + return attr ? attr.value : null; + } + + /** + * @param {string} type - attribute type (label, relation, etc.) + * @param {string} name - attribute name + * @returns {string|null} attribute value of given type and name or null if no such attribute exists. + */ + getOwnedAttributeValue(type, name) { + const attr = this.getOwnedAttribute(type, name); + + return attr ? attr.value : null; + } + get isArchived() { return this.hasAttribute('label', 'archived'); } @@ -235,7 +338,7 @@ class Note { this.ancestorCache = null; } - invalidateSubfrocas(path = []) { + invalidateSubTree(path = []) { if (path.includes(this.noteId)) { return; } @@ -247,7 +350,7 @@ class Note { } for (const childNote of this.children) { - childNote.invalidateSubfrocas(path); + childNote.invalidateSubTree(path); } for (const targetRelation of this.targetRelations) { @@ -255,7 +358,7 @@ class Note { const note = targetRelation.note; if (note) { - note.invalidateSubfrocas(path); + note.invalidateSubTree(path); } } } @@ -423,6 +526,10 @@ class Note { return minDistance; } + getChildBranches() { + return this.children.map(childNote => this.becca.getBranch(childNote.noteId, this.noteId)); + } + decrypt() { if (this.isProtected && !this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) { try { diff --git a/src/services/notes.js b/src/services/notes.js index 49138cf2c..5469fb0a4 100644 --- a/src/services/notes.js +++ b/src/services/notes.js @@ -17,15 +17,19 @@ const attributeService = require('../services/attributes'); const request = require('./request'); const path = require('path'); const url = require('url'); +const becca = require('../services/becca/becca'); function getNewNotePosition(parentNoteId) { - const maxNotePos = sql.getValue(` - SELECT MAX(notePosition) - FROM branches - WHERE parentNoteId = ? - AND isDeleted = 0`, [parentNoteId]); + const note = becca.notes[parentNoteId]; - return maxNotePos === null ? 0 : maxNotePos + 10; + if (!note) { + throw new Error(`Can't find note ${parentNoteId}`); + } + + const maxNotePos = note.getChildBranches() + .reduce((max, note) => Math.max(max, note.notePosition), 0); + + return maxNotePos + 10; } function triggerChildNoteCreated(childNote, parentNote) { @@ -151,7 +155,7 @@ function createNewNoteWithTarget(target, targetBranchId, params) { return createNewNote(params); } else if (target === 'after') { - const afterNote = sql.getRow('SELECT notePosition FROM branches WHERE branchId = ?', [targetBranchId]); + const afterNote = becca.branches[targetBranchId].notePosition; // not updating utcDateModified to avoig having to sync whole rows sql.execute('UPDATE branches SET notePosition = notePosition + 10 WHERE parentNoteId = ? AND notePosition > ? AND isDeleted = 0', diff --git a/src/services/search/services/search.js b/src/services/search/services/search.js index 85fdf8cb2..99039b5c5 100644 --- a/src/services/search/services/search.js +++ b/src/services/search/services/search.js @@ -63,7 +63,7 @@ function loadNeededInfoFromDatabase() { * @param {SearchContext} searchContext * @return {SearchResult[]} */ -function findNotesWithExpression(expression, searchContext) { +function findResultsWithExpression(expression, searchContext) { let allNotes = Object.values(becca.notes); if (searchContext.dbLoadNeeded) { @@ -132,12 +132,22 @@ function parseQueryToExpression(query, searchContext) { return expression; } +/** + * @param {string} query + * @return {Note[]} + */ +function findNotes(query) { + const searchResults = findResultsWithQuery(query, new SearchContext()); + + return searchResults.map(sr => becca.notes[sr.noteId]); +} + /** * @param {string} query * @param {SearchContext} searchContext * @return {SearchResult[]} */ -function findNotesWithQuery(query, searchContext) { +function findResultsWithQuery(query, searchContext) { query = query || ""; searchContext.originalQuery = query; @@ -147,11 +157,11 @@ function findNotesWithQuery(query, searchContext) { return []; } - return findNotesWithExpression(expression, searchContext); + return findResultsWithExpression(expression, searchContext); } function searchTrimmedNotes(query, searchContext) { - const allSearchResults = findNotesWithQuery(query, searchContext); + const allSearchResults = findResultsWithQuery(query, searchContext); const trimmedSearchResults = allSearchResults.slice(0, 200); return { @@ -252,5 +262,6 @@ function formatAttribute(attr) { module.exports = { searchTrimmedNotes, searchNotesForAutocomplete, - findNotesWithQuery + findResultsWithQuery, + findNotes };