2020-05-17 09:48:24 +02:00
|
|
|
"use strict";
|
|
|
|
|
2020-08-27 23:54:02 +02:00
|
|
|
const Note = require('./note.js');
|
2021-04-25 20:00:42 +02:00
|
|
|
const AbstractEntity = require("./abstract_entity.js");
|
|
|
|
const sql = require("../../sql.js");
|
|
|
|
const dateUtils = require("../../date_utils.js");
|
|
|
|
const promotedAttributeDefinitionParser = require("../../promoted_attribute_definition_parser");
|
|
|
|
|
|
|
|
class Attribute extends AbstractEntity {
|
|
|
|
static get entityName() { return "attributes"; }
|
|
|
|
static get primaryKeyName() { return "attributeId"; }
|
|
|
|
static get hashedProperties() { return ["attributeId", "noteId", "type", "name", "value", "isInheritable"]; }
|
2020-08-27 22:37:57 +02:00
|
|
|
|
2021-04-30 22:13:13 +02:00
|
|
|
constructor(row) {
|
2021-04-25 20:00:42 +02:00
|
|
|
super();
|
|
|
|
|
2020-05-16 23:12:29 +02:00
|
|
|
/** @param {string} */
|
|
|
|
this.attributeId = row.attributeId;
|
|
|
|
/** @param {string} */
|
|
|
|
this.noteId = row.noteId;
|
|
|
|
/** @param {string} */
|
|
|
|
this.type = row.type;
|
|
|
|
/** @param {string} */
|
2020-12-12 12:07:15 +01:00
|
|
|
this.name = row.name;
|
2020-12-11 22:06:12 +01:00
|
|
|
/** @param {int} */
|
|
|
|
this.position = row.position;
|
2020-05-16 23:12:29 +02:00
|
|
|
/** @param {string} */
|
2020-12-13 23:27:42 +01:00
|
|
|
this.value = row.value;
|
2020-05-16 23:12:29 +02:00
|
|
|
/** @param {boolean} */
|
|
|
|
this.isInheritable = !!row.isInheritable;
|
|
|
|
|
2021-04-16 23:00:08 +02:00
|
|
|
this.becca.attributes[this.attributeId] = this;
|
2020-08-27 22:37:57 +02:00
|
|
|
|
2021-04-16 23:00:08 +02:00
|
|
|
if (!(this.noteId in this.becca.notes)) {
|
2020-08-27 22:37:57 +02:00
|
|
|
// entities can come out of order in sync, create skeleton which will be filled later
|
2021-05-02 21:34:57 +02:00
|
|
|
this.becca.notes[this.noteId] = new Note({noteId: this.noteId});
|
2020-08-27 22:37:57 +02:00
|
|
|
}
|
|
|
|
|
2021-04-16 23:00:08 +02:00
|
|
|
this.becca.notes[this.noteId].ownedAttributes.push(this);
|
2020-05-16 23:12:29 +02:00
|
|
|
|
2020-12-14 22:12:26 +01:00
|
|
|
const key = `${this.type}-${this.name.toLowerCase()}`;
|
2021-04-16 23:00:08 +02:00
|
|
|
this.becca.attributeIndex[key] = this.becca.attributeIndex[key] || [];
|
|
|
|
this.becca.attributeIndex[key].push(this);
|
2020-05-16 23:12:29 +02:00
|
|
|
|
|
|
|
const targetNote = this.targetNote;
|
|
|
|
|
|
|
|
if (targetNote) {
|
|
|
|
targetNote.targetRelations.push(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
get isAffectingSubtree() {
|
|
|
|
return this.isInheritable
|
|
|
|
|| (this.type === 'relation' && this.name === 'template');
|
|
|
|
}
|
|
|
|
|
2021-02-19 20:42:34 +01:00
|
|
|
isAutoLink() {
|
|
|
|
return this.type === 'relation' && ['internalLink', 'imageLink', 'relationMapLink', 'includeNoteLink'].includes(this.name);
|
|
|
|
}
|
|
|
|
|
2020-05-16 23:12:29 +02:00
|
|
|
get note() {
|
2021-04-16 23:00:08 +02:00
|
|
|
return this.becca.notes[this.noteId];
|
2020-05-16 23:12:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
get targetNote() {
|
|
|
|
if (this.type === 'relation') {
|
2021-04-16 23:00:08 +02:00
|
|
|
return this.becca.notes[this.value];
|
2020-05-16 23:12:29 +02:00
|
|
|
}
|
|
|
|
}
|
2021-02-10 22:56:23 +01:00
|
|
|
|
2021-04-25 20:00:42 +02:00
|
|
|
/**
|
|
|
|
* @returns {Note|null}
|
|
|
|
*/
|
|
|
|
getNote() {
|
2021-04-30 22:13:13 +02:00
|
|
|
return this.becca.getNote(this.noteId);
|
2021-04-25 20:00:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @returns {Note|null}
|
|
|
|
*/
|
|
|
|
getTargetNote() {
|
|
|
|
if (this.type !== 'relation') {
|
|
|
|
throw new Error(`Attribute ${this.attributeId} is not relation`);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.value) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2021-04-30 22:13:13 +02:00
|
|
|
return this.becca.getNote(this.value);
|
2021-04-25 20:00:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return {boolean}
|
|
|
|
*/
|
|
|
|
isDefinition() {
|
|
|
|
return this.type === 'label' && (this.name.startsWith('label:') || this.name.startsWith('relation:'));
|
|
|
|
}
|
|
|
|
|
|
|
|
getDefinition() {
|
|
|
|
return promotedAttributeDefinitionParser.parse(this.value);
|
|
|
|
}
|
|
|
|
|
|
|
|
getDefinedName() {
|
|
|
|
if (this.type === 'label' && this.name.startsWith('label:')) {
|
|
|
|
return this.name.substr(6);
|
|
|
|
} else if (this.type === 'label' && this.name.startsWith('relation:')) {
|
|
|
|
return this.name.substr(9);
|
|
|
|
} else {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
beforeSaving() {
|
|
|
|
if (!this.value) {
|
|
|
|
if (this.type === 'relation') {
|
|
|
|
throw new Error(`Cannot save relation ${this.name} since it does not target any note.`);
|
|
|
|
}
|
|
|
|
|
|
|
|
// null value isn't allowed
|
|
|
|
this.value = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.position === undefined) {
|
2021-05-08 21:10:58 +02:00
|
|
|
// TODO: can be calculated from becca
|
2021-04-25 20:00:42 +02:00
|
|
|
this.position = 1 + sql.getValue(`SELECT COALESCE(MAX(position), 0) FROM attributes WHERE noteId = ?`, [this.noteId]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.isInheritable) {
|
|
|
|
this.isInheritable = false;
|
|
|
|
}
|
2021-02-10 22:56:23 +01:00
|
|
|
|
2021-04-25 20:00:42 +02:00
|
|
|
super.beforeSaving();
|
|
|
|
}
|
2021-02-10 22:56:23 +01:00
|
|
|
|
2021-05-08 21:10:58 +02:00
|
|
|
getPojo() {
|
|
|
|
return {
|
|
|
|
attributeId: this.attributeId,
|
|
|
|
noteId: this.noteId,
|
|
|
|
type: this.type,
|
|
|
|
name: this.name,
|
|
|
|
position: this.position,
|
|
|
|
value: this.value,
|
|
|
|
isInheritable: this.isInheritable,
|
|
|
|
utcDateModified: dateUtils.utcNowDateTime(),
|
|
|
|
isDeleted: false
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-04-25 20:00:42 +02:00
|
|
|
createClone(type, name, value, isInheritable) {
|
|
|
|
return new Attribute({
|
|
|
|
noteId: this.noteId,
|
|
|
|
type: type,
|
|
|
|
name: name,
|
|
|
|
value: value,
|
|
|
|
position: this.position,
|
|
|
|
isInheritable: isInheritable,
|
|
|
|
utcDateModified: this.utcDateModified
|
|
|
|
});
|
2021-02-10 22:56:23 +01:00
|
|
|
}
|
2020-05-16 23:12:29 +02:00
|
|
|
}
|
2020-05-17 09:48:24 +02:00
|
|
|
|
|
|
|
module.exports = Attribute;
|