Powiedzmy, ze jest sobie tabela z forum, ktorej struktura przedstawia sie nastepujaco:
forum_id
forum_parent
forum_subject
left_id
right_id
forum_parent przechowuje ID galezi - rodzica. Czyli mamy np. taka strukture forum:
Kategoria 1
Forum 1
Forum 2
Kategoria 2
W tabeli takie dane prezentuja sie nastepujaco:
forum_id | forum_parent | forum_subject | left_id | right_id
---------------------------------------------------------------------
1 | 0 | Kategoria 1 | 1 | 6
----------------------------------------------------------------------
2 | 1 | Forum 1 | 2 | 5
----------------------------------------------------------------------
3 | 2 | Forum 2 | 3 | 4
----------------------------------------------------------------------
4 | 0 | Kategoria 2 | 7 | 8
Teraz chodzi mi o to, aby przeniesc galaz Forum 1 wraz z galeziami - potomkami. Czyli, zeby to wygladalo tak:
Kategoria 1
Kategoria 2
Forum 1
Forum 2
Procedura dodawania:
CREATE DEFINER=`root`@`localhost` FUNCTION `FORUM_ADD`(forumParentId SMALLINT) RETURNS smallint(6)
BEGIN
DECLARE leftId SMALLINT DEFAULT 0;
DECLARE rightId SMALLINT DEFAULT 1;
DECLARE forumOrder SMALLINT DEFAULT 0;
IF NOT forumParentId THEN
SELECT MAX(right_id) + 1 AS right_id INTO rightId FROM coyote_forum;
IF rightId IS NULL THEN
SET rightId = 1;
END IF;
ELSE
SELECT left_id, right_id INTO leftId, rightId FROM coyote_forum WHERE forum_id = forumParentId;
UPDATE coyote_forum SET right_id = right_id + 2 WHERE right_id >= rightId;
UPDATE coyote_forum SET left_id = left_id + 2 WHERE left_id > rightId;
END IF;
SET leftId = rightId;
SET rightId = rightId + 1;
SELECT MAX(forum_order) AS forum_order INTO forumOrder FROM coyote_forum WHERE forum_parent = forumParentId;
IF forumOrder IS NULL THEN
SET forumOrder = 0;
END IF;
SET forumOrder = forumOrder + 1;
INSERT INTO coyote_forum(forum_parent, left_id, right_id, forum_order) VALUES(forumParentId, leftId, rightId, forumOrder);
RETURN LAST_INSERT_ID();
END
Procedura usuwania:
CREATE DEFINER=`root`@`localhost` PROCEDURE `FORUM_DELETE`(forumId SMALLINT)
BEGIN
DECLARE leftId SMALLINT DEFAULT 0;
DECLARE rightId SMALLINT DEFAULT 0;
SELECT left_id, right_id INTO leftId, rightId FROM coyote_forum WHERE forum_id = forumId;
IF leftId > 0 and rightId > 0 THEN
UPDATE coyote_forum SET right_id = right_id - 2 WHERE left_id < rightId AND right_id > rightId;
UPDATE coyote_forum SET left_id = left_id - 2, right_id = right_id - 2 WHERE left_id > rightId;
CALL FORUM_ORDER(forumId);
DELETE FROM coyote_forum WHERE forum_id = forumId;
END IF;
END
Ale kurde nie moge sobie poradzic z przenoszeniem galezi wraz z potomkami :/ Gdzies mam luki w algorytmie. Zaznaczam, ze usuwanie i wstawianie od nowa nie wchodzi w gre! forum_id musi zostac zachowane!
Mam procedure, ktora radzi sobie z przenoszeniem, ale jedynie pojedynczych galezi - bez potomkow:
CREATE DEFINER=`root`@`localhost` PROCEDURE `FORUM_MOVE`(forumId SMALLINT, forumParentId SMALLINT)
BEGIN
DECLARE leftId SMALLINT DEFAULT 0;
DECLARE rightId SMALLINT DEFAULT 0;
DECLARE parentId SMALLINT DEFAULT 0;
DECLARE forumOrder SMALLINT DEFAULT 0;
SELECT forum_parent, left_id, right_id INTO parentId, leftId, rightId FROM coyote_forum WHERE forum_id = forumId;
IF leftId > 0 and rightId > 0 THEN
UPDATE coyote_forum SET right_id = right_id - 2 WHERE left_id < rightId AND right_id > rightId;
UPDATE coyote_forum SET left_id = left_id - 2, right_id = right_id - 2 WHERE left_id > rightId;
IF NOT forumParentId THEN
SELECT MAX(right_id) + 1 AS right_id INTO rightId FROM coyote_forum;
ELSE
SELECT left_id, right_id INTO leftId, rightId FROM coyote_forum WHERE forum_id = forumParentId;
UPDATE coyote_forum SET right_id = right_id + 2 WHERE right_id >= rightId;
UPDATE coyote_forum SET left_id = left_id + 2 WHERE left_id > rightId;
END IF;
SET leftId = rightId;
SET rightId = rightId + 1;
CALL FORUM_ORDER(forumId);
SELECT MAX(forum_order) + 1 INTO forumOrder FROM coyote_forum WHERE forum_parent = forumParentId;
IF forumOrder IS NULL THEN
SET forumOrder = 1;
END IF;
UPDATE coyote_forum SET forum_parent = forumParentId, left_id = leftId, right_id = rightId, forum_order = forumOrder WHERE forum_id = forumId;
END IF;
END
Czy ktos ma moze pomysl na algorytm umozliwiajacy przenoszenie wraz z potomkami?