mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-04 13:39:01 +01:00 
			
		
		
		
	basic note creation with becca
This commit is contained in:
		
							parent
							
								
									8d8d654fe8
								
							
						
					
					
						commit
						6c5b1420d2
					
				@ -1,5 +1,9 @@
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const utils = require('../../utils');
 | 
			
		||||
 | 
			
		||||
let repo = null;
 | 
			
		||||
 | 
			
		||||
class AbstractEntity {
 | 
			
		||||
    beforeSaving() {
 | 
			
		||||
        this.generateIdIfNecessary();
 | 
			
		||||
@ -27,7 +31,7 @@ class AbstractEntity {
 | 
			
		||||
 | 
			
		||||
    get repository() {
 | 
			
		||||
        if (!repo) {
 | 
			
		||||
            repo = require('../services/repository');
 | 
			
		||||
            repo = require('../../repository');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return repo;
 | 
			
		||||
 | 
			
		||||
@ -113,7 +113,7 @@ class Attribute extends AbstractEntity {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get pojo() {
 | 
			
		||||
    getPojo() {
 | 
			
		||||
        return {
 | 
			
		||||
            attributeId: this.attributeId,
 | 
			
		||||
            noteId: this.noteId,
 | 
			
		||||
 | 
			
		||||
@ -65,15 +65,25 @@ class Branch extends AbstractEntity {
 | 
			
		||||
        return this.becca.notes[this.parentNoteId];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get pojo() {
 | 
			
		||||
        return {
 | 
			
		||||
    getPojo() {
 | 
			
		||||
        const pojo = {
 | 
			
		||||
            branchId: this.branchId,
 | 
			
		||||
            noteId: this.noteId,
 | 
			
		||||
            parentNoteId: this.parentNoteId,
 | 
			
		||||
            prefix: this.prefix,
 | 
			
		||||
            notePosition: this.notePosition,
 | 
			
		||||
            isExpanded: this.isExpanded
 | 
			
		||||
            isExpanded: this.isExpanded,
 | 
			
		||||
            utcDateModified: dateUtils.utcNowDateTime()
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // FIXME
 | 
			
		||||
        if (true || !pojo.branchId) {
 | 
			
		||||
            pojo.utcDateCreated = dateUtils.utcNowDateTime();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.utcDateModified = dateUtils.utcNowDateTime();
 | 
			
		||||
 | 
			
		||||
        return pojo;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    createClone(parentNoteId, notePosition) {
 | 
			
		||||
@ -96,13 +106,7 @@ class Branch extends AbstractEntity {
 | 
			
		||||
            this.isExpanded = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!this.branchId) {
 | 
			
		||||
            this.utcDateCreated = dateUtils.utcNowDateTime();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        super.beforeSaving();
 | 
			
		||||
 | 
			
		||||
        this.utcDateModified = dateUtils.utcNowDateTime();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -34,7 +34,7 @@ class Note extends AbstractEntity {
 | 
			
		||||
        this.ownedAttributes = [];
 | 
			
		||||
 | 
			
		||||
        /** @param {Attribute[]|null} */
 | 
			
		||||
        this.attributeCache = null;
 | 
			
		||||
        this.__attributeCache = null;
 | 
			
		||||
        /** @param {Attribute[]|null} */
 | 
			
		||||
        this.inheritableAttributeCache = null;
 | 
			
		||||
 | 
			
		||||
@ -89,6 +89,18 @@ class Note extends AbstractEntity {
 | 
			
		||||
        this.flatTextCache = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getParentBranches() {
 | 
			
		||||
        return this.parentBranches;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getParentNotes() {
 | 
			
		||||
        return this.parents;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getChildrenNotes() {
 | 
			
		||||
        return this.children;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Note content has quite special handling - it's not a separate entity, but a lazily loaded
 | 
			
		||||
     * part of Note entity with it's own sync. Reasons behind this hybrid design has been:
 | 
			
		||||
@ -245,9 +257,26 @@ class Note extends AbstractEntity {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @return {Attribute[]} */
 | 
			
		||||
    get attributes() {
 | 
			
		||||
        return this.__getAttributes([]);
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} [type] - (optional) attribute type to filter
 | 
			
		||||
     * @param {string} [name] - (optional) attribute name to filter
 | 
			
		||||
     * @returns {Attribute[]} all note's attributes, including inherited ones
 | 
			
		||||
     */
 | 
			
		||||
    getAttributes(type, name) {
 | 
			
		||||
        this.__getAttributes([]);
 | 
			
		||||
 | 
			
		||||
        if (type && name) {
 | 
			
		||||
            return this.__attributeCache.filter(attr => attr.type === type && attr.name === name);
 | 
			
		||||
        }
 | 
			
		||||
        else if (type) {
 | 
			
		||||
            return this.__attributeCache.filter(attr => attr.type === type);
 | 
			
		||||
        }
 | 
			
		||||
        else if (name) {
 | 
			
		||||
            return this.__attributeCache.filter(attr => attr.name === name);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            return this.__attributeCache.slice();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    __getAttributes(path) {
 | 
			
		||||
@ -255,7 +284,7 @@ class Note extends AbstractEntity {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!this.attributeCache) {
 | 
			
		||||
        if (!this.__attributeCache) {
 | 
			
		||||
            const parentAttributes = this.ownedAttributes.slice();
 | 
			
		||||
            const newPath = [...path, this.noteId];
 | 
			
		||||
 | 
			
		||||
@ -277,7 +306,7 @@ class Note extends AbstractEntity {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.attributeCache = [];
 | 
			
		||||
            this.__attributeCache = [];
 | 
			
		||||
 | 
			
		||||
            const addedAttributeIds = new Set();
 | 
			
		||||
 | 
			
		||||
@ -285,20 +314,20 @@ class Note extends AbstractEntity {
 | 
			
		||||
                if (!addedAttributeIds.has(attr.attributeId)) {
 | 
			
		||||
                    addedAttributeIds.add(attr.attributeId);
 | 
			
		||||
 | 
			
		||||
                    this.attributeCache.push(attr);
 | 
			
		||||
                    this.__attributeCache.push(attr);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.inheritableAttributeCache = [];
 | 
			
		||||
 | 
			
		||||
            for (const attr of this.attributeCache) {
 | 
			
		||||
            for (const attr of this.__attributeCache) {
 | 
			
		||||
                if (attr.isInheritable) {
 | 
			
		||||
                    this.inheritableAttributeCache.push(attr);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return this.attributeCache;
 | 
			
		||||
        return this.__attributeCache;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @return {Attribute[]} */
 | 
			
		||||
@ -315,21 +344,21 @@ class Note extends AbstractEntity {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    hasAttribute(type, name) {
 | 
			
		||||
        return !!this.attributes.find(attr => attr.type === type && attr.name === name);
 | 
			
		||||
        return !!this.getAttributes().find(attr => attr.type === type && attr.name === name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getAttributeCaseInsensitive(type, name, value) {
 | 
			
		||||
        name = name.toLowerCase();
 | 
			
		||||
        value = value ? value.toLowerCase() : null;
 | 
			
		||||
 | 
			
		||||
        return this.attributes.find(
 | 
			
		||||
        return this.getAttributes().find(
 | 
			
		||||
            attr => attr.type === type
 | 
			
		||||
            && attr.name.toLowerCase() === name
 | 
			
		||||
            && (!value || attr.value.toLowerCase() === value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getRelationTarget(name) {
 | 
			
		||||
        const relation = this.attributes.find(attr => attr.type === 'relation' && attr.name === name);
 | 
			
		||||
        const relation = this.getAttributes().find(attr => attr.type === 'relation' && attr.name === name);
 | 
			
		||||
 | 
			
		||||
        return relation ? relation.targetNote : null;
 | 
			
		||||
    }
 | 
			
		||||
@ -448,6 +477,54 @@ class Note extends AbstractEntity {
 | 
			
		||||
        return attr ? attr.value : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} [name] - label name to filter
 | 
			
		||||
     * @returns {Attribute[]} all note's labels (attributes with type label), including inherited ones
 | 
			
		||||
     */
 | 
			
		||||
    getLabels(name) {
 | 
			
		||||
        return this.getAttributes(LABEL, name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} [name] - label name to filter
 | 
			
		||||
     * @returns {string[]} all note's label values, including inherited ones
 | 
			
		||||
     */
 | 
			
		||||
    getLabelValues(name) {
 | 
			
		||||
        return this.getLabels(name).map(l => l.value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} [name] - label name to filter
 | 
			
		||||
     * @returns {Attribute[]} all note's labels (attributes with type label), excluding inherited ones
 | 
			
		||||
     */
 | 
			
		||||
    getOwnedLabels(name) {
 | 
			
		||||
        return this.getOwnedAttributes(LABEL, name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} [name] - label name to filter
 | 
			
		||||
     * @returns {string[]} all note's label values, excluding inherited ones
 | 
			
		||||
     */
 | 
			
		||||
    getOwnedLabelValues(name) {
 | 
			
		||||
        return this.getOwnedAttributes(LABEL, name).map(l => l.value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} [name] - relation name to filter
 | 
			
		||||
     * @returns {Attribute[]} all note's relations (attributes with type relation), including inherited ones
 | 
			
		||||
     */
 | 
			
		||||
    getRelations(name) {
 | 
			
		||||
        return this.getAttributes(RELATION, name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} [name] - relation name to filter
 | 
			
		||||
     * @returns {Attribute[]} all note's relations (attributes with type relation), excluding inherited ones
 | 
			
		||||
     */
 | 
			
		||||
    getOwnedRelations(name) {
 | 
			
		||||
        return this.getOwnedAttributes(RELATION, name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get isArchived() {
 | 
			
		||||
        return this.hasAttribute('label', 'archived');
 | 
			
		||||
    }
 | 
			
		||||
@ -485,7 +562,7 @@ class Note extends AbstractEntity {
 | 
			
		||||
 | 
			
		||||
            this.flatTextCache += this.title + ' ';
 | 
			
		||||
 | 
			
		||||
            for (const attr of this.attributes) {
 | 
			
		||||
            for (const attr of this.getAttributes()) {
 | 
			
		||||
                // it's best to use space as separator since spaces are filtered from the search string by the tokenization into words
 | 
			
		||||
                this.flatTextCache += (attr.type === 'label' ? '#' : '~') + attr.name;
 | 
			
		||||
 | 
			
		||||
@ -505,7 +582,7 @@ class Note extends AbstractEntity {
 | 
			
		||||
    invalidateThisCache() {
 | 
			
		||||
        this.flatTextCache = null;
 | 
			
		||||
 | 
			
		||||
        this.attributeCache = null;
 | 
			
		||||
        this.__attributeCache = null;
 | 
			
		||||
        this.inheritableAttributeCache = null;
 | 
			
		||||
        this.ancestorCache = null;
 | 
			
		||||
    }
 | 
			
		||||
@ -604,7 +681,7 @@ class Note extends AbstractEntity {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get labelCount() {
 | 
			
		||||
        return this.attributes.filter(attr => attr.type === 'label').length;
 | 
			
		||||
        return this.getAttributes().filter(attr => attr.type === 'label').length;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get ownedLabelCount() {
 | 
			
		||||
@ -612,11 +689,11 @@ class Note extends AbstractEntity {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get relationCount() {
 | 
			
		||||
        return this.attributes.filter(attr => attr.type === 'relation' && !attr.isAutoLink()).length;
 | 
			
		||||
        return this.getAttributes().filter(attr => attr.type === 'relation' && !attr.isAutoLink()).length;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get relationCountIncludingLinks() {
 | 
			
		||||
        return this.attributes.filter(attr => attr.type === 'relation').length;
 | 
			
		||||
        return this.getAttributes().filter(attr => attr.type === 'relation').length;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get ownedRelationCount() {
 | 
			
		||||
@ -636,11 +713,11 @@ class Note extends AbstractEntity {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get attributeCount() {
 | 
			
		||||
        return this.attributes.length;
 | 
			
		||||
        return this.getAttributes().length;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get ownedAttributeCount() {
 | 
			
		||||
        return this.attributes.length;
 | 
			
		||||
        return this.getAttributes().length;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get ancestors() {
 | 
			
		||||
@ -715,8 +792,8 @@ class Note extends AbstractEntity {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get pojo() {
 | 
			
		||||
        return {
 | 
			
		||||
    getPojo() {
 | 
			
		||||
        const pojo = {
 | 
			
		||||
            noteId: this.noteId,
 | 
			
		||||
            title: this.title,
 | 
			
		||||
            isProtected: this.isProtected,
 | 
			
		||||
@ -727,6 +804,18 @@ class Note extends AbstractEntity {
 | 
			
		||||
            utcDateCreated: this.utcDateCreated,
 | 
			
		||||
            utcDateModified: this.utcDateModified
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if (pojo.isProtected) {
 | 
			
		||||
            if (this.isDecrypted) {
 | 
			
		||||
                pojo.title = protectedSessionService.encrypt(pojo.title);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                // updating protected note outside of protected session means we will keep original ciphertexts
 | 
			
		||||
                delete pojo.title;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return pojo;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    beforeSaving() {
 | 
			
		||||
@ -744,16 +833,8 @@ class Note extends AbstractEntity {
 | 
			
		||||
        this.utcDateModified = dateUtils.utcNowDateTime();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    updatePojo(pojo) {
 | 
			
		||||
        if (pojo.isProtected) {
 | 
			
		||||
            if (this.isDecrypted) {
 | 
			
		||||
                pojo.title = protectedSessionService.encrypt(pojo.title);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                // updating protected note outside of protected session means we will keep original ciphertexts
 | 
			
		||||
                delete pojo.title;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    markAsDeleted() {
 | 
			
		||||
        sql.execute("UPDATE notes SET isDeleted = 1 WHERE noteId = ?", [this.noteId]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,7 @@ function buildRewardMap(note) {
 | 
			
		||||
            addToRewardMap(ancestorNote.title, 0.3);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (const branch of ancestorNote.parentBranches) {
 | 
			
		||||
        for (const branch of ancestorNote.getParentBranches()) {
 | 
			
		||||
            addToRewardMap(branch.prefix, 0.3);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -84,11 +84,11 @@ function buildRewardMap(note) {
 | 
			
		||||
        addToRewardMap(note.title, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (const branch of note.parentBranches) {
 | 
			
		||||
    for (const branch of note.getParentBranches()) {
 | 
			
		||||
        addToRewardMap(branch.prefix, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (const attr of note.attributes) {
 | 
			
		||||
    for (const attr of note.getAttributes()) {
 | 
			
		||||
        if (attr.name.startsWith('child:')
 | 
			
		||||
            || attr.name.startsWith('relation:')
 | 
			
		||||
            || attr.name.startsWith('label:')) {
 | 
			
		||||
@ -222,7 +222,7 @@ function splitToWords(text) {
 | 
			
		||||
 * that it doesn't actually need to be shown to the user.
 | 
			
		||||
 */
 | 
			
		||||
function hasConnectingRelation(sourceNote, targetNote) {
 | 
			
		||||
    return sourceNote.attributes.find(attr => attr.type === 'relation'
 | 
			
		||||
    return sourceNote.getAttributes().find(attr => attr.type === 'relation'
 | 
			
		||||
                                           && ['includenotelink', 'imagelink'].includes(attr.name)
 | 
			
		||||
                                           && attr.value === targetNote.noteId);
 | 
			
		||||
}
 | 
			
		||||
@ -243,7 +243,7 @@ async function findSimilarNotes(noteId) {
 | 
			
		||||
        dateLimits = buildDateLimits(baseNote);
 | 
			
		||||
    }
 | 
			
		||||
    catch (e) {
 | 
			
		||||
        throw new Error(`Date limits failed with ${e.message}, entity: ${JSON.stringify(baseNote.pojo)}`);
 | 
			
		||||
        throw new Error(`Date limits failed with ${e.message}, entity: ${JSON.stringify(baseNote.getPojo())}`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const rewardMap = buildRewardMap(baseNote);
 | 
			
		||||
@ -298,7 +298,7 @@ async function findSimilarNotes(noteId) {
 | 
			
		||||
                        score += gatherRewards(parentNote.title, 0.3);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    for (const branch of parentNote.parentBranches) {
 | 
			
		||||
                    for (const branch of parentNote.getParentBranches()) {
 | 
			
		||||
                        score += gatherRewards(branch.prefix, 0.3)
 | 
			
		||||
                               + gatherAncestorRewards(branch.parentNote);
 | 
			
		||||
                    }
 | 
			
		||||
@ -319,11 +319,11 @@ async function findSimilarNotes(noteId) {
 | 
			
		||||
            score += gatherRewards(candidateNote.title);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (const branch of candidateNote.parentBranches) {
 | 
			
		||||
        for (const branch of candidateNote.getParentBranches()) {
 | 
			
		||||
            score += gatherRewards(branch.prefix);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (const attr of candidateNote.attributes) {
 | 
			
		||||
        for (const attr of candidateNote.getAttributes()) {
 | 
			
		||||
            if (attr.name.startsWith('child:')
 | 
			
		||||
                || attr.name.startsWith('relation:')
 | 
			
		||||
                || attr.name.startsWith('label:')) {
 | 
			
		||||
@ -342,7 +342,7 @@ async function findSimilarNotes(noteId) {
 | 
			
		||||
            let factor = 1;
 | 
			
		||||
 | 
			
		||||
            if (!value.startsWith) {
 | 
			
		||||
                log.info(`Unexpected falsy value for attribute ${JSON.stringify(attr.pojo)}`);
 | 
			
		||||
                log.info(`Unexpected falsy value for attribute ${JSON.stringify(attr.getPojo())}`);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            else if (value.startsWith('http')) {
 | 
			
		||||
@ -434,8 +434,6 @@ async function findSimilarNotes(noteId) {
 | 
			
		||||
            for (const {noteId} of results) {
 | 
			
		||||
                const note = becca.notes[noteId];
 | 
			
		||||
 | 
			
		||||
                console.log("NOTE", note.pojo);
 | 
			
		||||
 | 
			
		||||
                displayRewards = true;
 | 
			
		||||
                ancestorRewardCache = {}; // reset cache
 | 
			
		||||
                const totalReward = computeScore(note);
 | 
			
		||||
 | 
			
		||||
@ -7,8 +7,11 @@ const eventService = require('./events');
 | 
			
		||||
const repository = require('./repository');
 | 
			
		||||
const cls = require('../services/cls');
 | 
			
		||||
const Note = require('../entities/note');
 | 
			
		||||
const BeccaNote = require('../services/becca/entities/note.js');
 | 
			
		||||
const Branch = require('../entities/branch');
 | 
			
		||||
const BeccaBranch = require('../services/becca/entities/branch.js');
 | 
			
		||||
const Attribute = require('../entities/attribute');
 | 
			
		||||
const BeccaAttribute = require('../services/becca/entities/attribute.js');
 | 
			
		||||
const protectedSessionService = require('../services/protected_session');
 | 
			
		||||
const log = require('../services/log');
 | 
			
		||||
const utils = require('../services/utils');
 | 
			
		||||
@ -67,7 +70,7 @@ function deriveMime(type, mime) {
 | 
			
		||||
function copyChildAttributes(parentNote, childNote) {
 | 
			
		||||
    for (const attr of parentNote.getAttributes()) {
 | 
			
		||||
        if (attr.name.startsWith("child:")) {
 | 
			
		||||
            new Attribute({
 | 
			
		||||
            new BeccaAttribute({
 | 
			
		||||
                noteId: childNote.noteId,
 | 
			
		||||
                type: attr.type,
 | 
			
		||||
                name: attr.name.substr(6),
 | 
			
		||||
@ -75,8 +78,6 @@ function copyChildAttributes(parentNote, childNote) {
 | 
			
		||||
                position: attr.position,
 | 
			
		||||
                isInheritable: attr.isInheritable
 | 
			
		||||
            }).save();
 | 
			
		||||
 | 
			
		||||
            childNote.invalidateAttributeCache();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -99,7 +100,7 @@ function copyChildAttributes(parentNote, childNote) {
 | 
			
		||||
 * @return {{note: Note, branch: Branch}}
 | 
			
		||||
 */
 | 
			
		||||
function createNewNote(params) {
 | 
			
		||||
    const parentNote = repository.getNote(params.parentNoteId);
 | 
			
		||||
    const parentNote = becca.notes[params.parentNoteId];
 | 
			
		||||
 | 
			
		||||
    if (!parentNote) {
 | 
			
		||||
        throw new Error(`Parent note "${params.parentNoteId}" not found.`);
 | 
			
		||||
@ -110,7 +111,7 @@ function createNewNote(params) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return sql.transactional(() => {
 | 
			
		||||
        const note = new Note({
 | 
			
		||||
        const note = new BeccaNote(becca,{
 | 
			
		||||
            noteId: params.noteId, // optionally can force specific noteId
 | 
			
		||||
            title: params.title,
 | 
			
		||||
            isProtected: !!params.isProtected,
 | 
			
		||||
@ -120,7 +121,7 @@ function createNewNote(params) {
 | 
			
		||||
 | 
			
		||||
        note.setContent(params.content);
 | 
			
		||||
 | 
			
		||||
        const branch = new Branch({
 | 
			
		||||
        const branch = new BeccaBranch(becca,{
 | 
			
		||||
            noteId: note.noteId,
 | 
			
		||||
            parentNoteId: params.parentNoteId,
 | 
			
		||||
            notePosition: params.notePosition !== undefined ? params.notePosition : getNewNotePosition(params.parentNoteId),
 | 
			
		||||
@ -416,11 +417,12 @@ function saveLinks(note, content) {
 | 
			
		||||
        throw new Error("Unrecognized type " + note.type);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const existingLinks = note.getLinks();
 | 
			
		||||
    const existingLinks = note.getRelations().filter(rel =>
 | 
			
		||||
        ['internalLink', 'imageLink', 'relationMapLink', 'includeNoteLink'].includes(rel.name));
 | 
			
		||||
 | 
			
		||||
    for (const foundLink of foundLinks) {
 | 
			
		||||
        const targetNote = repository.getNote(foundLink.value);
 | 
			
		||||
        if (!targetNote || targetNote.isDeleted) {
 | 
			
		||||
        const targetNote = becca.notes[foundLink.value];
 | 
			
		||||
        if (!targetNote) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -429,7 +431,7 @@ function saveLinks(note, content) {
 | 
			
		||||
            && existingLink.name === foundLink.name);
 | 
			
		||||
 | 
			
		||||
        if (!existingLink) {
 | 
			
		||||
            const newLink = new Attribute({
 | 
			
		||||
            const newLink = new BeccaAttribute({
 | 
			
		||||
                noteId: note.noteId,
 | 
			
		||||
                type: 'relation',
 | 
			
		||||
                name: foundLink.name,
 | 
			
		||||
@ -438,10 +440,6 @@ function saveLinks(note, content) {
 | 
			
		||||
 | 
			
		||||
            existingLinks.push(newLink);
 | 
			
		||||
        }
 | 
			
		||||
        else if (existingLink.isDeleted) {
 | 
			
		||||
            existingLink.isDeleted = false;
 | 
			
		||||
            existingLink.save();
 | 
			
		||||
        }
 | 
			
		||||
        // else the link exists so we don't need to do anything
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -451,8 +449,7 @@ function saveLinks(note, content) {
 | 
			
		||||
                                    && existingLink.name === foundLink.name));
 | 
			
		||||
 | 
			
		||||
    for (const unusedLink of unusedLinks) {
 | 
			
		||||
        unusedLink.isDeleted = true;
 | 
			
		||||
        unusedLink.save();
 | 
			
		||||
        unusedLink.markAsDeleted();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return content;
 | 
			
		||||
 | 
			
		||||
@ -94,11 +94,19 @@ function updateEntity(entity) {
 | 
			
		||||
        entity.beforeSaving();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const clone = Object.assign({}, entity);
 | 
			
		||||
    let clone;
 | 
			
		||||
 | 
			
		||||
    // this check requires that updatePojo is not static
 | 
			
		||||
    if (entity.updatePojo) {
 | 
			
		||||
        entity.updatePojo(clone);
 | 
			
		||||
    if (entity.getPojo) {
 | 
			
		||||
        clone = entity.getPojo();
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        // FIXME: delete this branch after migration to becca
 | 
			
		||||
        clone = Object.assign({}, entity);
 | 
			
		||||
 | 
			
		||||
        // this check requires that updatePojo is not static
 | 
			
		||||
        if (entity.updatePojo) {
 | 
			
		||||
            entity.updatePojo(clone);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (const key in clone) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user