Торговец знаниями
Уважаемые, подскажите.
Дано: таблица, содержит в себе дерево (дерево сделано на основе nested sets aka вложенные множества).
Требуется: пример кода для перемещения произвольного узла (возможно, вместе с поддеревом) в произвольную позицию дерева.
С остальными операциями разобрался, а вот с перемещением — не получается.
Есть прекрасная статья, но вот конкретно момент с перемещением узлов там крайне мутно написан.
Дано: таблица, содержит в себе дерево (дерево сделано на основе nested sets aka вложенные множества).
Требуется: пример кода для перемещения произвольного узла (возможно, вместе с поддеревом) в произвольную позицию дерева.
С остальными операциями разобрался, а вот с перемещением — не получается.
Есть прекрасная статья, но вот конкретно момент с перемещением узлов там крайне мутно написан.
function MoveNode($nodeId, $parentId) {
global $db;
$row = $db->selectRow("SELECT id FROM tbl WHERE id = ?d", $nodeId);
$targetRow = $db->selectRow("SELECT id FROM tbl WHERE id = ?d", $parentId);
//фиксируем узел и поддерево, а заобно получаем количство дочерних узлов
$countChilds = $db->query("UPDATE tbl SET fix = 1 WHERE left_id >= ?d AND right_id <= ?d",
$row['left_id'], $row['right_id']);
//обновляем записи
$db->query("UPDATE tbl SET left_id = left_id - ?d WHERE left_id > ?d AND fix = 0",
$countChilds * 2, $row['left_id']);
$db->query("UPDATE tbl SET right_id = right_id - ?d WHERE right_id > ?d AND fix = 0",
$countChilds * 2, $row['left_id']);
//обновляем записи правее вставляемого узла
$db->query("UPDATE tbl SET left_id = left_id + ?d WHERE left_id > ?d AND fix = 0",
$countChilds * 2, $targetRow['left_id']);
$db->query("UPDATE tbl SET right_id = right_id + ?d WHERE right_id > ?d AND fix = 0",
$countChilds * 2, $targetRow['left_id']);
//вставляем узел и обновляем элементы поддерва перемещаемого узла
$db->query("UPDATE tbl SET parent_id = ?d WHERE id = ?d", $parentId, $nodeId);
$db->query("UPDATE tbl SET left_id = left_id + ?d, right_id = right_id + ?d, level = level + ?d WHERE fix = 1",
$targetRow['left_id'] - $row['left_id'] + 1, $targetRow['level'] - $row['level'] +
1);
//снимаем фиксацию
$db->query("UPDATE tbl SET fix = 0 WHERE fix = 1");
}
?>
PS: работа с БД идет через класс DBSimple, Дмитрия Котерова.
PPS: функцию не тестировал =)
В чём, собственно, разница: я не хочу ставить перемещаемый узел первым потомком, а наоборот, есть желание поставить его последним. Соответственно изменяются вычисления на обновлении узлов, относящихся к поддереву перемещаемого узла.