fix creating tree cycle by moving clone into another clone, closes #4442

This commit is contained in:
zadam 2023-11-16 23:31:33 +01:00
parent 999cf0d9e3
commit 426a8f75aa
3 changed files with 22 additions and 16 deletions

View File

@ -19,14 +19,14 @@ const ValidationError = require("../../errors/validation_error");
function moveBranchToParent(req) {
const {branchId, parentBranchId} = req.params;
const parentBranch = becca.getBranch(parentBranchId);
const branchToMove = becca.getBranch(branchId);
const targetParentBranch = becca.getBranch(parentBranchId);
if (!parentBranch || !branchToMove) {
if (!branchToMove || !targetParentBranch) {
throw new ValidationError(`One or both branches '${branchId}', '${parentBranchId}' have not been found`);
}
return branchService.moveBranchToBranch(branchToMove, parentBranch, branchId);
return branchService.moveBranchToBranch(branchToMove, targetParentBranch, branchId);
}
function moveBranchBeforeNote(req) {

View File

@ -1,12 +1,12 @@
const treeService = require("./tree");
const sql = require("./sql");
function moveBranchToNote(sourceBranch, targetParentNoteId) {
if (sourceBranch.parentNoteId === targetParentNoteId) {
function moveBranchToNote(branchToMove, targetParentNoteId) {
if (branchToMove.parentNoteId === targetParentNoteId) {
return {success: true}; // no-op
}
const validationResult = treeService.validateParentChild(targetParentNoteId, sourceBranch.noteId, sourceBranch.branchId);
const validationResult = treeService.validateParentChild(targetParentNoteId, branchToMove.noteId, branchToMove.branchId);
if (!validationResult.success) {
return [200, validationResult];
@ -15,10 +15,10 @@ function moveBranchToNote(sourceBranch, targetParentNoteId) {
const maxNotePos = sql.getValue('SELECT MAX(notePosition) FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [targetParentNoteId]);
const newNotePos = maxNotePos === null ? 0 : maxNotePos + 10;
const newBranch = sourceBranch.createClone(targetParentNoteId, newNotePos);
const newBranch = branchToMove.createClone(targetParentNoteId, newNotePos);
newBranch.save();
sourceBranch.markAsDeleted();
branchToMove.markAsDeleted();
return {
success: true,
@ -26,16 +26,18 @@ function moveBranchToNote(sourceBranch, targetParentNoteId) {
};
}
function moveBranchToBranch(sourceBranch, targetParentBranch) {
const res = moveBranchToNote(sourceBranch, targetParentBranch.noteId);
function moveBranchToBranch(branchToMove, targetParentBranch) {
const res = moveBranchToNote(branchToMove, targetParentBranch.noteId);
if (!res.success) {
return res;
}
// expanding so that the new placement of the branch is immediately visible
targetParentBranch.isExpanded = true;
targetParentBranch.save();
if (!targetParentBranch.isExpanded) {
targetParentBranch.isExpanded = true;
targetParentBranch.save();
}
return res;
}

View File

@ -8,7 +8,7 @@ const becca = require('../becca/becca');
function validateParentChild(parentNoteId, childNoteId, branchId = null) {
if (['root', '_hidden', '_share', '_lbRoot', '_lbAvailableLaunchers', '_lbVisibleLaunchers'].includes(childNoteId)) {
return { branch: null, success: false, message: `Cannot change this note's location.`};
return { branch: null, success: false, message: `Cannot change this note's location.` };
}
if (parentNoteId === 'none') {
@ -16,14 +16,14 @@ function validateParentChild(parentNoteId, childNoteId, branchId = null) {
return { branch: null, success: false, message: `Cannot move anything into 'none' parent.` };
}
const existing = becca.getBranchFromChildAndParent(childNoteId, parentNoteId);
const existingBranch = becca.getBranchFromChildAndParent(childNoteId, parentNoteId);
if (existing && (branchId === null || existing.branchId !== branchId)) {
if (existingBranch && existingBranch.branchId !== branchId) {
const parentNote = becca.getNote(parentNoteId);
const childNote = becca.getNote(childNoteId);
return {
branch: existing,
branch: existingBranch,
success: false,
message: `Note "${childNote.title}" note already exists in the "${parentNote.title}".`
};
@ -52,6 +52,10 @@ function validateParentChild(parentNoteId, childNoteId, branchId = null) {
* Tree cycle can be created when cloning or when moving existing clone. This method should detect both cases.
*/
function wouldAddingBranchCreateCycle(parentNoteId, childNoteId) {
if (parentNoteId === childNoteId) {
return true;
}
const childNote = becca.getNote(childNoteId);
const parentNote = becca.getNote(parentNoteId);