109 lines
2.4 KiB
SQL
109 lines
2.4 KiB
SQL
DELIMITER $$
|
|
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`nest_move`(
|
|
vTable VARCHAR(45)
|
|
,idNODE INT
|
|
,idFATHER INT
|
|
)
|
|
BEGIN
|
|
DECLARE myRight INT;
|
|
DECLARE myLeft INT;
|
|
DECLARE myWidth INT;
|
|
DECLARE fatherRight INT;
|
|
DECLARE fatherLeft INT;
|
|
DECLARE gap INT;
|
|
|
|
SET vTable = util.quoteIdentifier(vTable);
|
|
|
|
DROP TEMPORARY TABLE IF EXISTS aux;
|
|
CREATE TEMPORARY TABLE aux
|
|
SELECT 0 as rgt, 0 as lft, 0 as wdt, 0 as frg, 0 as flf;
|
|
|
|
-- Averiguamos el ancho de la rama
|
|
EXECUTE IMMEDIATE CONCAT(
|
|
'UPDATE aux a
|
|
JOIN ', vTable, ' t
|
|
SET a.wdt = t.rgt - t.lft + 1
|
|
WHERE t.id = ?')
|
|
USING idNODE;
|
|
|
|
-- Averiguamos la posicion del nuevo padre
|
|
EXECUTE IMMEDIATE CONCAT(
|
|
'UPDATE aux a
|
|
JOIN ', vTable, ' t
|
|
SET a.frg = t.rgt,
|
|
a.flf = t.lft
|
|
WHERE t.id = ?')
|
|
USING idFATHER;
|
|
|
|
SELECT wdt, frg, flf INTO myWidth, fatherRight, fatherLeft
|
|
FROM aux;
|
|
|
|
-- 1º Incrementamos los valores de todos los nodos a la derecha del punto de inserción (fatherRight) , para hacer sitio
|
|
EXECUTE IMMEDIATE CONCAT(
|
|
'UPDATE ', vTable,
|
|
'SET rgt = rgt + ?
|
|
WHERE rgt >= ?
|
|
ORDER BY rgt DESC')
|
|
USING myWidth,
|
|
fatherRight;
|
|
|
|
EXECUTE IMMEDIATE CONCAT(
|
|
'UPDATE ', vTable,
|
|
'SET lft = lft + ?
|
|
WHERE lft >= ?
|
|
ORDER BY lft DESC')
|
|
USING myWidth,
|
|
fatherRight;
|
|
|
|
-- Es preciso recalcular los valores del nodo en el caso de que estuviera a la derecha del nuevo padre
|
|
EXECUTE IMMEDIATE CONCAT(
|
|
'UPDATE aux a
|
|
JOIN ', vTable, ' t
|
|
SET a.rgt = t.rgt,
|
|
a.lft = t.lft
|
|
WHERE t.id = ?')
|
|
USING idNODE;
|
|
|
|
SELECT lft, rgt, frg - lft INTO myLeft, myRight, gap
|
|
FROM aux;
|
|
|
|
-- 2º Incrementamos el valor de todos los nodos a trasladar hasta alcanzar su nueva posicion
|
|
EXECUTE IMMEDIATE CONCAT(
|
|
'UPDATE ', vTable,
|
|
'SET lft = lft + ?
|
|
WHERE lft BETWEEN ? AND ?
|
|
ORDER BY lft DESC')
|
|
USING gap,
|
|
myLeft,
|
|
myRight;
|
|
|
|
EXECUTE IMMEDIATE CONCAT(
|
|
'UPDATE ', vTable,
|
|
'SET rgt = rgt + ?
|
|
WHERE rgt BETWEEN ? AND ?
|
|
ORDER BY rgt DESC')
|
|
USING gap,
|
|
myLeft,
|
|
myRight;
|
|
|
|
-- 3º Restaremos a todos los nodos resultantes, a la derecha de la posicion arrancada el ancho de la rama escindida
|
|
EXECUTE IMMEDIATE CONCAT(
|
|
'UPDATE ', vTable,
|
|
'SET lft = lft - ?
|
|
WHERE lft > ?
|
|
ORDER BY lft')
|
|
USING myWidth,
|
|
myLeft;
|
|
|
|
EXECUTE IMMEDIATE CONCAT(
|
|
'UPDATE ', vTable,
|
|
'SET rgt = rgt - ?
|
|
WHERE rgt > ?
|
|
ORDER BY rgt')
|
|
USING myWidth,
|
|
myRight;
|
|
|
|
DROP TEMPORARY TABLE aux;
|
|
END$$
|
|
DELIMITER ;
|