salix/db/routines/vn2008/procedures/nest_move.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 ;