From 63ebb46049063588a9e3e137ae755f2292c54051 Mon Sep 17 00:00:00 2001 From: zadam Date: Sat, 12 Sep 2020 22:21:44 +0200 Subject: [PATCH] fix inverse relation detection in relation maps --- src/entities/attribute.js | 16 +++++++++ src/entities/note.js | 16 +++++++-- src/routes/api/notes.js | 8 +++-- .../promoted_attribute_definition_parser.js | 35 +++++++++++++++++++ 4 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 src/services/promoted_attribute_definition_parser.js diff --git a/src/entities/attribute.js b/src/entities/attribute.js index 79c71f9f2..857531ffe 100644 --- a/src/entities/attribute.js +++ b/src/entities/attribute.js @@ -1,8 +1,10 @@ "use strict"; + const Entity = require('./entity'); const dateUtils = require('../services/date_utils'); const sql = require('../services/sql'); +const promotedAttributeDefinitionParser = require("../services/promoted_attribute_definition_parser"); /** * Attribute is key value pair owned by a note. @@ -61,6 +63,20 @@ class Attribute extends Entity { 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') { diff --git a/src/entities/note.js b/src/entities/note.js index 59bfc4480..1db0e8abb 100644 --- a/src/entities/note.js +++ b/src/entities/note.js @@ -380,15 +380,15 @@ class Note extends Entity { return firstDefinitionIndex === index; } else { - const definitionAttr = attributes.find(el => el.type === attr.type + '-definition' && el.name === attr.name); + const definitionAttr = attributes.find(el => el.type === 'label' && el.name === attr.type + ':' + attr.name); if (!definitionAttr) { return true; } - const definition = definitionAttr.value; + const definition = definitionAttr.getDefinition(); - if (definition.multiplicityType === 'multi') { + if (definition.multiplicity === 'multi') { return true; } else { @@ -868,6 +868,16 @@ class Note extends Entity { return notePaths; } + getRelationDefinitions() { + return this.getLabels() + .filter(l => l.name.startsWith("relation:")); + } + + getLabelDefinitions() { + return this.getLabels() + .filter(l => l.name.startsWith("relation:")); + } + /** * @param ancestorNoteId * @return {boolean} - true if ancestorNoteId occurs in at least one of the note's paths diff --git a/src/routes/api/notes.js b/src/routes/api/notes.js index 616bce2bc..1220bda31 100644 --- a/src/routes/api/notes.js +++ b/src/routes/api/notes.js @@ -139,7 +139,7 @@ function getRelationMap(req) { for (const note of notes) { resp.noteTitles[note.noteId] = note.title; - resp.relations = resp.relations.concat((note.getRelations()) + resp.relations = resp.relations.concat(note.getRelations() .filter(relation => noteIds.includes(relation.value)) .map(relation => ({ attributeId: relation.attributeId, @@ -149,8 +149,10 @@ function getRelationMap(req) { }))); for (const relationDefinition of note.getRelationDefinitions()) { - if (relationDefinition.value.inverseRelation) { - resp.inverseRelations[relationDefinition.name] = relationDefinition.value.inverseRelation; + const def = relationDefinition.getDefinition(); + + if (def.inverseRelation) { + resp.inverseRelations[relationDefinition.getDefinedName()] = def.inverseRelation; } } } diff --git a/src/services/promoted_attribute_definition_parser.js b/src/services/promoted_attribute_definition_parser.js new file mode 100644 index 000000000..d7f611cb9 --- /dev/null +++ b/src/services/promoted_attribute_definition_parser.js @@ -0,0 +1,35 @@ +function parse(value) { + const tokens = value.split(',').map(t => t.trim()); + const defObj = {}; + + for (const token of tokens) { + if (token === 'promoted') { + defObj.isPromoted = true; + } + else if (['text', 'number', 'boolean', 'date', 'url'].includes(token)) { + defObj.labelType = token; + } + else if (['single', 'multi'].includes(token)) { + defObj.multiplicity = token; + } + else if (token.startsWith('precision')) { + const chunks = token.split('='); + + defObj.numberPrecision = parseInt(chunks[1]); + } + else if (token.startsWith('inverse')) { + const chunks = token.split('='); + + defObj.inverseRelation = chunks[1]; + } + else { + console.log("Unrecognized attribute definition token:", token); + } + } + + return defObj; +} + +module.exports = { + parse +};