refactoring

This commit is contained in:
zadam
2021-04-17 20:52:46 +02:00
parent 42510fda5c
commit 1fdf889ccf
11 changed files with 213 additions and 90 deletions

View File

@@ -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 () => {

View File

@@ -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) {

View File

@@ -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 = [];

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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();

View File

@@ -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 {

View File

@@ -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',

View File

@@ -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
};