subtree duplication with becca

This commit is contained in:
zadam 2021-04-25 22:02:32 +02:00
parent a5ee590544
commit 93cae44ba0
6 changed files with 50 additions and 16 deletions

View file

@ -9,6 +9,7 @@ const log = require('../../services/log');
const TaskContext = require('../../services/task_context'); const TaskContext = require('../../services/task_context');
const fs = require('fs'); const fs = require('fs');
const noteRevisionService = require("../../services/note_revisions.js"); const noteRevisionService = require("../../services/note_revisions.js");
const becca = require("../../services/becca/becca.js");
function getNote(req) { function getNote(req) {
const noteId = req.params.noteId; const noteId = req.params.noteId;
@ -107,7 +108,7 @@ function sortChildNotes(req) {
function protectNote(req) { function protectNote(req) {
const noteId = req.params.noteId; const noteId = req.params.noteId;
const note = repository.getNote(noteId); const note = becca.notes[noteId];
const protect = !!parseInt(req.params.isProtected); const protect = !!parseInt(req.params.isProtected);
const includingSubTree = !!parseInt(req.query.subtree); const includingSubTree = !!parseInt(req.query.subtree);

View file

@ -26,7 +26,8 @@ class AbstractEntity {
} }
getUtcDateChanged() { getUtcDateChanged() {
return this.utcDateModified || this.utcDateCreated; // FIXME
return this.utcDateModified || this.utcDateCreated || "FAKE";
} }
get repository() { get repository() {

View file

@ -121,7 +121,9 @@ class Attribute extends AbstractEntity {
name: this.name, name: this.name,
position: this.position, position: this.position,
value: this.value, value: this.value,
isInheritable: this.isInheritable isInheritable: this.isInheritable,
utcDateModified: dateUtils.utcNowDateTime(),
isDeleted: false
}; };
} }
@ -148,8 +150,6 @@ class Attribute extends AbstractEntity {
} }
super.beforeSaving(); super.beforeSaving();
this.utcDateModified = dateUtils.utcNowDateTime();
} }
createClone(type, name, value, isInheritable) { createClone(type, name, value, isInheritable) {

View file

@ -55,6 +55,10 @@ class Branch extends AbstractEntity {
return this.becca.notes[this.noteId]; return this.becca.notes[this.noteId];
} }
getNote() {
return this.childNote;
}
/** @return {Note} */ /** @return {Note} */
get parentNote() { get parentNote() {
if (!(this.parentNoteId in this.becca.notes)) { if (!(this.parentNoteId in this.becca.notes)) {

View file

@ -93,14 +93,22 @@ class Note extends AbstractEntity {
return this.parentBranches; return this.parentBranches;
} }
getBranches() {
return this.parentBranches;
}
getParentNotes() { getParentNotes() {
return this.parents; return this.parents;
} }
getChildrenNotes() { getChildNotes() {
return this.children; return this.children;
} }
getChildBranches() {
return this.children.map(childNote => this.becca.getBranch(childNote.noteId, this.noteId));
}
/* /*
* Note content has quite special handling - it's not a separate entity, but a lazily loaded * 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: * part of Note entity with it's own sync. Reasons behind this hybrid design has been:
@ -525,6 +533,26 @@ class Note extends AbstractEntity {
return this.getOwnedAttributes(RELATION, name); return this.getOwnedAttributes(RELATION, name);
} }
/**
* @param {string} [type] - (optional) attribute type to filter
* @param {string} [name] - (optional) attribute name to filter
* @returns {Attribute[]} note's "owned" attributes - excluding inherited ones
*/
getOwnedAttributes(type, name) {
if (type && name) {
return this.ownedAttributes.filter(attr => attr.type === type && attr.name === name);
}
else if (type) {
return this.ownedAttributes.filter(attr => attr.type === type);
}
else if (name) {
return this.ownedAttributes.filter(attr => attr.name === name);
}
else {
return this.ownedAttributes.slice();
}
}
get isArchived() { get isArchived() {
return this.hasAttribute('label', 'archived'); return this.hasAttribute('label', 'archived');
} }
@ -672,6 +700,10 @@ class Note extends AbstractEntity {
return this.subtreeNotes.map(note => note.noteId); return this.subtreeNotes.map(note => note.noteId);
} }
getDescendantNoteIds() {
return this.subtreeNoteIds;
}
get parentCount() { get parentCount() {
return this.parents.length; return this.parents.length;
} }
@ -775,10 +807,6 @@ class Note extends AbstractEntity {
return minDistance; return minDistance;
} }
getChildBranches() {
return this.children.map(childNote => this.becca.getBranch(childNote.noteId, this.noteId));
}
decrypt() { decrypt() {
if (this.isProtected && !this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) { if (this.isProtected && !this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) {
try { try {

View file

@ -762,7 +762,7 @@ function duplicateSubtree(origNoteId, newParentNoteId) {
log.info(`Duplicating ${origNoteId} subtree into ${newParentNoteId}`); log.info(`Duplicating ${origNoteId} subtree into ${newParentNoteId}`);
const origNote = repository.getNote(origNoteId); const origNote = becca.notes[origNoteId];
// might be null if orig note is not in the target newParentNoteId // might be null if orig note is not in the target newParentNoteId
const origBranch = origNote.getBranches().find(branch => branch.parentNoteId === newParentNoteId); const origBranch = origNote.getBranches().find(branch => branch.parentNoteId === newParentNoteId);
@ -799,16 +799,16 @@ function duplicateSubtreeInner(origNote, origBranch, newParentNoteId, noteIdMapp
const newNoteId = noteIdMapping[origNote.noteId]; const newNoteId = noteIdMapping[origNote.noteId];
const newBranch = new Branch({ const newBranch = new BeccaBranch(becca,{
noteId: newNoteId, noteId: newNoteId,
parentNoteId: newParentNoteId, parentNoteId: newParentNoteId,
// here increasing just by 1 to make sure it's directly after original // here increasing just by 1 to make sure it's directly after original
notePosition: origBranch ? origBranch.notePosition + 1 : null notePosition: origBranch ? origBranch.notePosition + 1 : null
}).save(); }).save();
const existingNote = repository.getNote(newNoteId); const existingNote = becca.notes[newNoteId];
if (existingNote) { if (existingNote.title !== undefined) { // checking that it's not just note's skeleton created because of Branch above
// note has multiple clones and was already created from another placement in the tree // note has multiple clones and was already created from another placement in the tree
// so a branch is all we need for this clone // so a branch is all we need for this clone
return { return {
@ -817,7 +817,7 @@ function duplicateSubtreeInner(origNote, origBranch, newParentNoteId, noteIdMapp
} }
} }
const newNote = new Note(origNote); const newNote = new BeccaNote(becca, origNote);
newNote.noteId = newNoteId; newNote.noteId = newNoteId;
newNote.dateCreated = dateUtils.localNowDateTime(); newNote.dateCreated = dateUtils.localNowDateTime();
newNote.utcDateCreated = dateUtils.utcNowDateTime(); newNote.utcDateCreated = dateUtils.utcNowDateTime();
@ -833,7 +833,7 @@ function duplicateSubtreeInner(origNote, origBranch, newParentNoteId, noteIdMapp
newNote.setContent(content); newNote.setContent(content);
for (const attribute of origNote.getOwnedAttributes()) { for (const attribute of origNote.getOwnedAttributes()) {
const attr = new Attribute(attribute); const attr = new BeccaAttribute(becca, attribute);
attr.attributeId = undefined; // force creation of new attribute attr.attributeId = undefined; // force creation of new attribute
attr.noteId = newNote.noteId; attr.noteId = newNote.noteId;