Advertisement
Guest User

Untitled

a guest
Jan 6th, 2014
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.60 KB | None | 0 0
  1.  
  2. i have this error :
  3.  
  4. ###################################################################
  5. # Your query produced 14 warnings.
  6. # Warnings from last query:
  7. # Note: PROCEDURE Baobab_GENERIC_Close_Gaps does not exist
  8. ###################################################################
  9. Please advice
  10.  
  11. /*---------------------------------------------------------*/
  12. /* ############################### */
  13. /* ###### TABLES AND VIEWS ####### */
  14. /* ############################### */
  15.  
  16. CREATE TABLE IF NOT EXISTS GENERIC (
  17. tree_id INTEGER UNSIGNED NOT NULL,
  18. id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  19. lft INTEGER NOT NULL CHECK (lft > 0),
  20. rgt INTEGER NOT NULL CHECK (rgt > 1),
  21. INDEX(tree_id),
  22. INDEX(lft),
  23. CONSTRAINT order_okay CHECK (lft < rgt)
  24. ) ENGINE INNODB;
  25.  
  26. DROP VIEW IF EXISTS GENERIC_AdjTree;
  27. CREATE VIEW GENERIC_AdjTree (tree_id,parent,child,lft)
  28. AS
  29. SELECT E.tree_id,B.id, E.id, E.lft
  30. FROM GENERIC AS E
  31. LEFT OUTER JOIN GENERIC AS B
  32. ON B.lft = ( SELECT MAX(lft)
  33. FROM GENERIC AS S
  34. WHERE E.lft > S.lft
  35. AND E.lft < S.rgt
  36. AND E.tree_id=S.tree_id)
  37. AND B.tree_id=E.tree_id
  38. ORDER BY lft ASC;
  39.  
  40. /* ##### LIST OF TREE NAMES IN USE ##### */
  41.  
  42. CREATE TABLE IF NOT EXISTS Baobab_ForestsNames (
  43. name VARCHAR(200) PRIMARY KEY
  44. ) ENGINE INNODB DEFAULT CHARSET=utf8;
  45.  
  46. INSERT INTO Baobab_ForestsNames(name) VALUES ('GENERIC')
  47. ON DUPLICATE KEY UPDATE name=name;
  48.  
  49. /* ##################################### */
  50.  
  51.  
  52. /* ########################### */
  53. /* ###### ERRORS CONTROL ##### */
  54. /* ########################### */
  55.  
  56. CREATE TABLE IF NOT EXISTS Baobab_Errors (
  57. code INTEGER UNSIGNED NOT NULL PRIMARY KEY,
  58. name VARCHAR(50) NOT NULL,
  59. msg TINYTEXT NOT NULL,
  60. CONSTRAINT unique_codename UNIQUE (name)
  61. ) ENGINE INNODB;
  62.  
  63. INSERT INTO Baobab_Errors(code,name,msg)
  64. VALUES
  65. (1000,'VERSION','1.0'),
  66. (1100,'ROOT_ERROR','Cannot add or move a node next to root'),
  67. (1200,'CHILD_OF_YOURSELF_ERROR','Cannot move a node inside his own subtree'),
  68. (1300,'INDEX_OUT_OF_RANGE','The index is out of range'),
  69. (1400,'NODE_DOES_NOT_EXIST',"Node doesn't exist"),
  70. (1500,'VERSION_NOT_MATCH',"The library and the sql schema have different versions")
  71. ON DUPLICATE KEY UPDATE code=code,name=name,msg=msg;
  72.  
  73. DROP FUNCTION IF EXISTS Baobab_getErrCode;
  74. CREATE FUNCTION Baobab_getErrCode(x TINYTEXT) RETURNS INT
  75. DETERMINISTIC
  76. RETURN (SELECT code from Baobab_Errors WHERE name=x);
  77.  
  78.  
  79.  
  80. /* ########################## */
  81. /* ######## DROP TREE ####### */
  82. /* ########################## */
  83.  
  84. DROP PROCEDURE IF EXISTS Baobab_GENERIC_DropTree;
  85. DELIMITER //
  86. CREATE PROCEDURE Baobab_GENERIC_DropTree (
  87. IN node INTEGER UNSIGNED,
  88. IN update_numbers INTEGER)
  89. LANGUAGE SQL
  90. DETERMINISTIC
  91. MODIFIES SQL DATA
  92.  
  93. BEGIN
  94.  
  95. DECLARE drop_tree_id INTEGER UNSIGNED;
  96. DECLARE drop_id INTEGER UNSIGNED;
  97. DECLARE drop_lft INTEGER UNSIGNED;
  98. DECLARE drop_rgt INTEGER UNSIGNED;
  99.  
  100.  
  101. /*
  102. declare exit handler for not found rollback;
  103. declare exit handler for sqlexception rollback;
  104. declare exit handler for sqlwarning rollback;
  105. */
  106.  
  107. /* save the dropped subtree data with a singleton SELECT */
  108.  
  109. START TRANSACTION;
  110.  
  111. /* save the dropped subtree data with a singleton SELECT */
  112.  
  113. SELECT tree_id, id, lft, rgt
  114. INTO drop_tree_id, drop_id, drop_lft, drop_rgt
  115. FROM GENERIC
  116. WHERE id = node;
  117.  
  118. /* subtree deletion is easy */
  119.  
  120. DELETE FROM GENERIC
  121. WHERE tree_id=drop_tree_id AND lft BETWEEN drop_lft and drop_rgt;
  122.  
  123. IF update_numbers = 1 THEN
  124. /* close up the gap left by the subtree */
  125.  
  126. UPDATE GENERIC
  127. SET lft = CASE WHEN lft > drop_lft
  128. THEN lft - (drop_rgt - drop_lft + 1)
  129. ELSE lft END,
  130. rgt = CASE WHEN rgt > drop_lft
  131. THEN rgt - (drop_rgt - drop_lft + 1)
  132. ELSE rgt END
  133. WHERE tree_id=drop_tree_id AND lft > drop_lft OR rgt > drop_lft;
  134.  
  135. END IF;
  136.  
  137. COMMIT;
  138.  
  139. END//
  140.  
  141. DELIMITER ;
  142. /* ########################## */
  143. /* ###### APPEND CHILD ###### */
  144. /* ########################## */
  145.  
  146. /* Add a new child to a parent as last sibling
  147. If parent_id is 0, insert a new root node, moving the
  148. previous root (if any) as his child.
  149. If choosen_tree is 0, use the first available integer as id.
  150. If choosen_tree is not present as tree_id in the table, it is used.
  151. */
  152. DROP PROCEDURE IF EXISTS Baobab_GENERIC_AppendChild;
  153. DELIMITER //
  154. CREATE PROCEDURE Baobab_GENERIC_AppendChild(
  155. IN choosen_tree INTEGER UNSIGNED,
  156. IN parent_id INTEGER UNSIGNED,
  157. OUT new_id INTEGER UNSIGNED,
  158. OUT cur_tree_id INTEGER UNSIGNED)
  159. LANGUAGE SQL
  160. DETERMINISTIC
  161.  
  162. BEGIN
  163.  
  164. DECLARE num INTEGER UNSIGNED;
  165.  
  166. START TRANSACTION;
  167.  
  168. SET cur_tree_id = IF(choosen_tree > 0,
  169. choosen_tree,
  170. IFNULL((SELECT MAX(tree_id)+1 FROM GENERIC),1)
  171. );
  172.  
  173. IF parent_id = 0 THEN /* inserting a new root node*/
  174.  
  175. UPDATE GENERIC
  176. SET lft = lft+1, rgt = rgt+1
  177. WHERE tree_id=cur_tree_id;
  178.  
  179. SET num = IFNULL((SELECT MAX(rgt)+1 FROM GENERIC WHERE tree_id=cur_tree_id),2);
  180.  
  181. INSERT INTO GENERIC(tree_id, id, lft, rgt)
  182. VALUES (cur_tree_id, NULL, 1, num);
  183.  
  184. ELSE /* append a new node as last right child of his parent */
  185.  
  186. SET num = (SELECT rgt
  187. FROM GENERIC
  188. WHERE id = parent_id
  189. );
  190.  
  191. UPDATE GENERIC
  192. SET lft = CASE WHEN lft > num
  193. THEN lft + 2
  194. ELSE lft END,
  195. rgt = CASE WHEN rgt >= num
  196. THEN rgt + 2
  197. ELSE rgt END
  198. WHERE tree_id=cur_tree_id AND rgt >= num;
  199.  
  200. INSERT INTO GENERIC(tree_id, id, lft, rgt)
  201. VALUES (cur_tree_id,NULL, num, (num + 1));
  202.  
  203. END IF;
  204.  
  205. SELECT LAST_INSERT_ID() INTO new_id;
  206.  
  207. COMMIT;
  208.  
  209. END//
  210. DELIMITER ;
  211. /* ############################### */
  212. /* ###### INSERT NODE AFTER ###### */
  213. /* ############################### */
  214.  
  215. DROP PROCEDURE IF EXISTS Baobab_GENERIC_insertAfter;
  216. DELIMITER //
  217. CREATE PROCEDURE Baobab_GENERIC_insertAfter(
  218. IN sibling_id INTEGER UNSIGNED,
  219. OUT new_id INTEGER UNSIGNED,
  220. OUT error_code INTEGER UNSIGNED)
  221. LANGUAGE SQL
  222. DETERMINISTIC
  223.  
  224. main:BEGIN
  225.  
  226. IF 1 = (SELECT lft FROM GENERIC WHERE id = sibling_id) THEN
  227. BEGIN
  228. SELECT Baobab_getErrCode('ROOT_ERROR') INTO error_code;
  229. LEAVE main;
  230. END;
  231. ELSE
  232. BEGIN
  233.  
  234. DECLARE lft_sibling INTEGER UNSIGNED;
  235. DECLARE choosen_tree INTEGER UNSIGNED;
  236.  
  237. START TRANSACTION;
  238.  
  239. SELECT tree_id,rgt
  240. INTO choosen_tree,lft_sibling
  241. FROM GENERIC
  242. WHERE id = sibling_id;
  243.  
  244. IF ISNULL(lft_sibling) THEN
  245. BEGIN
  246. SELECT Baobab_getErrCode('NODE_DOES_NOT_EXIST') INTO error_code;
  247. LEAVE main;
  248. END;
  249. END IF;
  250.  
  251. UPDATE GENERIC
  252. SET lft = CASE WHEN lft < lft_sibling
  253. THEN lft
  254. ELSE lft + 2 END,
  255. rgt = CASE WHEN rgt < lft_sibling
  256. THEN rgt
  257. ELSE rgt + 2 END
  258. WHERE tree_id=choosen_tree AND rgt > lft_sibling;
  259.  
  260. INSERT INTO GENERIC(tree_id,id,lft,rgt)
  261. VALUES (choosen_tree,NULL, (lft_sibling + 1),(lft_sibling + 2));
  262.  
  263. SELECT LAST_INSERT_ID() INTO new_id;
  264.  
  265. COMMIT;
  266.  
  267. END;
  268. END IF;
  269.  
  270. END//
  271. DELIMITER ;
  272.  
  273. /* ################################ */
  274. /* ###### INSERT NODE BEFORE ###### */
  275. /* ################################ */
  276.  
  277. DROP PROCEDURE IF EXISTS Baobab_GENERIC_insertBefore;
  278. DELIMITER //
  279. CREATE PROCEDURE Baobab_GENERIC_insertBefore(
  280. IN sibling_id INTEGER UNSIGNED,
  281. OUT new_id INTEGER UNSIGNED,
  282. OUT error_code INTEGER UNSIGNED)
  283. LANGUAGE SQL
  284. DETERMINISTIC
  285. main:BEGIN
  286.  
  287. IF 1 = (SELECT lft FROM GENERIC WHERE id = sibling_id) THEN
  288. BEGIN
  289. SELECT Baobab_getErrCode('ROOT_ERROR') INTO error_code;
  290. LEAVE main;
  291. END;
  292. ELSE
  293. BEGIN
  294.  
  295. DECLARE rgt_sibling INTEGER UNSIGNED;
  296. DECLARE choosen_tree INTEGER UNSIGNED;
  297.  
  298. START TRANSACTION;
  299.  
  300. SELECT tree_id,lft
  301. INTO choosen_tree,rgt_sibling
  302. FROM GENERIC
  303. WHERE id = sibling_id;
  304.  
  305. IF ISNULL(rgt_sibling) THEN
  306. BEGIN
  307. SELECT Baobab_getErrCode('NODE_DOES_NOT_EXIST') INTO error_code;
  308. LEAVE main;
  309. END;
  310. END IF;
  311.  
  312. UPDATE IGNORE GENERIC
  313. SET lft = CASE WHEN lft < rgt_sibling
  314. THEN lft
  315. ELSE lft + 2 END,
  316. rgt = CASE WHEN rgt < rgt_sibling
  317. THEN rgt
  318. ELSE rgt + 2 END
  319. WHERE tree_id=choosen_tree AND rgt >= rgt_sibling
  320. ORDER BY lft DESC; /* order by is meant to avoid uniqueness violation on update */
  321.  
  322. INSERT INTO GENERIC(tree_id,id,lft,rgt)
  323. VALUES (choosen_tree,NULL, rgt_sibling, rgt_sibling + 1);
  324.  
  325. SELECT LAST_INSERT_ID() INTO new_id;
  326.  
  327. COMMIT;
  328.  
  329. END;
  330. END IF;
  331.  
  332. END//
  333.  
  334. DELIMITER ;
  335. /* ################################### */
  336. /* ###### INSERT CHILD AT INDEX ###### */
  337. /* ################################### */
  338.  
  339. /* Add a new child to parent 'parent_id' at index 'index'.
  340. index is the new child position, 0 will put the new node as first.
  341. index can be negative, where -1 will put the new node before the last one
  342. */
  343.  
  344. DROP PROCEDURE IF EXISTS Baobab_GENERIC_InsertChildAtIndex;
  345. DELIMITER //
  346. CREATE PROCEDURE Baobab_GENERIC_InsertChildAtIndex(
  347. IN parent_id INTEGER UNSIGNED,
  348. IN idx INTEGER,
  349. OUT new_id INTEGER UNSIGNED,
  350. OUT error_code INTEGER UNSIGNED)
  351. LANGUAGE SQL
  352. DETERMINISTIC
  353.  
  354. BEGIN
  355.  
  356. DECLARE nth_child INTEGER UNSIGNED;
  357.  
  358. SET error_code=0;
  359. SET new_id=0;
  360.  
  361. CALL Baobab_GENERIC_getNthChild(parent_id,idx,nth_child,error_code);
  362.  
  363. IF NOT error_code THEN
  364. CALL Baobab_GENERIC_insertBefore(nth_child,new_id,error_code);
  365. END IF;
  366.  
  367. END//
  368.  
  369. /* ########################### */
  370. /* ###### GET NTH CHILD ###### */
  371. /* ########################### */
  372. DELIMITER ;
  373. DROP PROCEDURE IF EXISTS Baobab_GENERIC_getNthChild;
  374. DELIMITER //
  375. CREATE PROCEDURE Baobab_GENERIC_getNthChild(
  376. IN parent_id INTEGER UNSIGNED,
  377. IN idx INTEGER,
  378. OUT nth_child INTEGER UNSIGNED,
  379. OUT error_code INTEGER UNSIGNED)
  380. LANGUAGE SQL
  381. DETERMINISTIC
  382.  
  383. main:BEGIN
  384.  
  385. DECLARE num_children INTEGER;
  386.  
  387. SET error_code=0;
  388.  
  389. SELECT COUNT(*)
  390. INTO num_children
  391. FROM GENERIC_AdjTree WHERE parent = parent_id;
  392.  
  393. IF num_children = 0 OR IF(idx<0,(-idx)-1,idx) >= num_children THEN
  394. /* idx is out of range */
  395. BEGIN
  396. SELECT Baobab_getErrCode('INDEX_OUT_OF_RANGE') INTO error_code;
  397. LEAVE main;
  398. END;
  399. ELSE
  400.  
  401. SELECT child
  402. INTO nth_child
  403. FROM GENERIC_AdjTree as t1
  404. WHERE (SELECT count(*) FROM GENERIC_AdjTree as t2
  405. WHERE parent = parent_id AND t2.lft<=t1.lft AND t1.tree_id=t2.tree_id
  406. )
  407. = (CASE
  408. WHEN idx >= 0
  409. THEN idx+1
  410. ELSE num_children+1+idx
  411. END
  412. )
  413. LIMIT 1;
  414.  
  415. END IF;
  416.  
  417. END//
  418.  
  419. DELIMITER ;
  420.  
  421. /* ###################################### */
  422. /* ###### MOVE SUBTREE BEFORE NODE ###### */
  423. /* ###################################### */
  424.  
  425. DROP PROCEDURE IF EXISTS Baobab_GENERIC_MoveSubtreeBefore;
  426. DELIMITER //
  427. CREATE PROCEDURE Baobab_GENERIC_MoveSubtreeBefore(
  428. IN node_id_to_move INTEGER UNSIGNED,
  429. IN reference_node INTEGER UNSIGNED,
  430. OUT error_code INTEGER UNSIGNED)
  431. LANGUAGE SQL
  432. DETERMINISTIC
  433.  
  434. main:BEGIN
  435.  
  436. DECLARE node_revised INTEGER UNSIGNED;
  437. DECLARE move_as_first_sibling BOOLEAN;
  438. DECLARE ref_left INTEGER UNSIGNED;
  439. DECLARE ref_node_tree INTEGER UNSIGNED;
  440.  
  441. SET error_code=0; /* 0 means no error */
  442. SET move_as_first_sibling = TRUE;
  443.  
  444. SELECT tree_id,lft
  445. INTO ref_node_tree,ref_left
  446. FROM GENERIC WHERE id = reference_node;
  447.  
  448. IF ref_left = 1 THEN
  449. BEGIN
  450. /* cannot move a parent node before or after root */
  451. SELECT Baobab_getErrCode('ROOT_ERROR') INTO error_code;
  452. LEAVE main;
  453. END;
  454. END IF;
  455.  
  456. /* if reference_node is the first child of his parent, set node_revised
  457. to the parent id, else set node_revised to NULL */
  458. SET node_revised = ( SELECT id FROM GENERIC WHERE tree_id=ref_node_tree AND lft = -1+ ref_left);
  459.  
  460. IF ISNULL(node_revised) THEN /* if node_revised is NULL we must find the previous sibling */
  461. BEGIN
  462. SET node_revised= (SELECT id FROM GENERIC
  463. WHERE tree_id=ref_node_tree AND rgt = -1 + ref_left);
  464. SET move_as_first_sibling = FALSE;
  465. END;
  466. END IF;
  467.  
  468. CALL Baobab_GENERIC_MoveSubtree_real(
  469. node_id_to_move, node_revised , move_as_first_sibling, error_code
  470. );
  471.  
  472. END//
  473.  
  474. DELIMITER ;
  475.  
  476. /* ##################################### */
  477. /* ###### MOVE SUBTREE AFTER NODE ###### */
  478. /* ##################################### */
  479.  
  480. DROP PROCEDURE IF EXISTS Baobab_GENERIC_MoveSubtreeAfter;
  481. DELIMITER //
  482. CREATE PROCEDURE Baobab_GENERIC_MoveSubtreeAfter(
  483. IN node_id_to_move INTEGER UNSIGNED,
  484. IN reference_node INTEGER UNSIGNED,
  485. OUT error_code INTEGER UNSIGNED)
  486. LANGUAGE SQL
  487. DETERMINISTIC
  488.  
  489. BEGIN
  490.  
  491. SELECT 0 INTO error_code; /* 0 means no error */
  492.  
  493. CALL Baobab_GENERIC_MoveSubtree_real(
  494. node_id_to_move,reference_node,FALSE,error_code
  495. );
  496.  
  497. END//
  498.  
  499. DELIMITER ;
  500.  
  501. /* ##################################### */
  502. /* ####### MOVE SUBTREE AT INDEX ####### */
  503. /* ##################################### */
  504.  
  505. DROP PROCEDURE IF EXISTS Baobab_GENERIC_MoveSubtreeAtIndex;
  506. DELIMITER //
  507. CREATE PROCEDURE Baobab_GENERIC_MoveSubtreeAtIndex(
  508. IN node_id_to_move INTEGER UNSIGNED,
  509. IN parent_id INTEGER UNSIGNED,
  510. IN idx INTEGER,
  511. OUT error_code INTEGER)
  512. LANGUAGE SQL
  513. DETERMINISTIC
  514.  
  515. main:BEGIN
  516.  
  517. DECLARE nth_child INTEGER UNSIGNED;
  518. DECLARE num_children INTEGER;
  519.  
  520. SET error_code=0;
  521.  
  522. SELECT COUNT(*)
  523. INTO num_children
  524. FROM GENERIC_AdjTree WHERE parent = parent_id;
  525.  
  526. IF num_children = 0 THEN
  527. BEGIN
  528. SELECT Baobab_getErrCode('INDEX_OUT_OF_RANGE') INTO error_code;
  529. LEAVE main;
  530. END;
  531. END IF;
  532.  
  533. SET idx = IF(idx<0,num_children+idx,idx);
  534.  
  535. IF idx = 0 THEN /* moving as first child, special case */
  536. CALL Baobab_GENERIC_MoveSubtree_real(node_id_to_move,parent_id,TRUE,error_code);
  537. ELSE
  538. BEGIN
  539. /* search the node before idx, and we wil move our node after that */
  540. CALL Baobab_GENERIC_getNthChild(parent_id,idx-1,nth_child,error_code);
  541.  
  542. IF NOT error_code THEN
  543. CALL Baobab_GENERIC_MoveSubtree_real(node_id_to_move,nth_child,FALSE,error_code);
  544. END IF;
  545. END;
  546. END IF;
  547.  
  548. END//
  549.  
  550. DELIMITER ;
  551. /* ####################################### */
  552. /* ####### MOVE SUBTREE REAL LOGIC #######*/
  553. /* ####################################### */
  554.  
  555. /* If move_as_first_sibling is FALSE, move node_id_to_move after reference_node,
  556. else reference_node is the new father of node_id_to_move */
  557.  
  558. SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_UNSIGNED_SUBTRACTION';
  559.  
  560. DROP PROCEDURE IF EXISTS Baobab_GENERIC_MoveSubtree_real;
  561. DELIMITER //
  562. CREATE PROCEDURE Baobab_GENERIC_MoveSubtree_real(
  563. IN node_id_to_move INTEGER UNSIGNED,
  564. IN reference_node INTEGER UNSIGNED,
  565. IN move_as_first_sibling BOOLEAN,
  566. OUT error_code INTEGER
  567. )
  568. LANGUAGE SQL
  569. DETERMINISTIC
  570.  
  571. main:BEGIN
  572.  
  573. DECLARE s_lft INTEGER UNSIGNED;
  574. DECLARE s_rgt INTEGER UNSIGNED;
  575. DECLARE ref_lft INTEGER UNSIGNED;
  576. DECLARE ref_rgt INTEGER UNSIGNED;
  577.  
  578. DECLARE source_node_tree INTEGER UNSIGNED;
  579. DECLARE ref_node_tree INTEGER UNSIGNED;
  580.  
  581. DECLARE diff_when_inside_sourcetree BIGINT SIGNED;
  582. DECLARE diff_when_next_sourcetree BIGINT SIGNED;
  583. DECLARE ext_bound_1 INTEGER UNSIGNED;
  584. DECLARE ext_bound_2 INTEGER UNSIGNED;
  585.  
  586. SET error_code=0;
  587.  
  588. START TRANSACTION;
  589.  
  590. /* select tree, left and right of the node to move */
  591. SELECT tree_id,lft, rgt
  592. INTO source_node_tree, s_lft, s_rgt
  593. FROM GENERIC
  594. WHERE id = node_id_to_move;
  595.  
  596. /* select left and right of the reference node
  597.  
  598. If moving as first sibling, ref_lft will become the new lft value of node_id_to_move,
  599. (and ref_rgt is unused), else we're saving left and right value of soon to be
  600. previous sibling
  601.  
  602. */
  603. SELECT tree_id, IF(move_as_first_sibling,lft+1,lft), rgt
  604. INTO ref_node_tree, ref_lft, ref_rgt
  605. FROM GENERIC
  606. WHERE id = reference_node;
  607.  
  608.  
  609. IF move_as_first_sibling = TRUE THEN
  610.  
  611. IF s_lft <= ref_lft AND s_rgt >= ref_rgt AND source_node_tree=ref_node_tree THEN
  612. /* cannot move a parent node inside his own subtree */
  613. BEGIN
  614. SELECT Baobab_getErrCode('CHILD_OF_YOURSELF_ERROR') INTO error_code;
  615. LEAVE main;
  616. END;
  617. ELSE
  618.  
  619. IF s_lft > ref_lft THEN BEGIN
  620. SET diff_when_inside_sourcetree = -(s_lft-ref_lft);
  621. SET diff_when_next_sourcetree = s_rgt-s_lft+1;
  622. SET ext_bound_1 = ref_lft;
  623. SET ext_bound_2 = s_lft-1;
  624.  
  625. END;
  626. ELSE BEGIN
  627. SET diff_when_inside_sourcetree = ref_lft-s_rgt-1;
  628. SET diff_when_next_sourcetree = -(s_rgt-s_lft+1);
  629. SET ext_bound_1 = s_rgt+1;
  630. SET ext_bound_2 = ref_lft-1;
  631.  
  632. END;
  633. END IF;
  634.  
  635. END IF;
  636. ELSE /* moving after an existing child */
  637.  
  638. IF ref_lft = 1 THEN /* cannot move a node before or after root */
  639. BEGIN
  640. SELECT Baobab_getErrCode('ROOT_ERROR') INTO error_code;
  641. LEAVE main;
  642. END;
  643. ELSEIF s_lft < ref_lft AND s_rgt > ref_rgt AND source_node_tree=ref_node_tree THEN
  644. /* cannot move a parent node inside his own subtree */
  645. BEGIN
  646. SELECT Baobab_getErrCode('CHILD_OF_YOURSELF_ERROR') INTO error_code;
  647. LEAVE main;
  648. END;
  649. ELSE
  650.  
  651. IF s_lft > ref_rgt THEN BEGIN
  652. SET diff_when_inside_sourcetree = -(s_lft-ref_rgt-1);
  653. SET diff_when_next_sourcetree = s_rgt-s_lft+1;
  654. SET ext_bound_1 = ref_rgt+1;
  655. SET ext_bound_2 = s_lft-1;
  656.  
  657. END;
  658. ELSE BEGIN
  659. SET diff_when_inside_sourcetree = ref_rgt-s_rgt;
  660. SET diff_when_next_sourcetree = -(s_rgt-s_lft+1);
  661. SET ext_bound_1 = s_rgt+1;
  662. SET ext_bound_2 = ref_rgt;
  663.  
  664. END;
  665. END IF;
  666.  
  667. END IF;
  668.  
  669. END IF;
  670.  
  671.  
  672. IF source_node_tree <> ref_node_tree THEN
  673. BEGIN
  674. CALL Baobab_GENERIC_MoveSubtree_Different_Trees(
  675. node_id_to_move,reference_node,move_as_first_sibling);
  676. LEAVE main;
  677. END;
  678. END IF;
  679.  
  680. UPDATE GENERIC
  681. SET lft =
  682. lft + CASE
  683. WHEN lft BETWEEN s_lft AND s_rgt
  684. THEN diff_when_inside_sourcetree
  685. WHEN lft BETWEEN ext_bound_1 AND ext_bound_2
  686. THEN diff_when_next_sourcetree
  687. ELSE 0 END
  688. ,
  689. rgt =
  690. rgt + CASE
  691.  
  692. WHEN rgt BETWEEN s_lft AND s_rgt
  693. THEN diff_when_inside_sourcetree
  694. WHEN rgt BETWEEN ext_bound_1 AND ext_bound_2
  695. THEN diff_when_next_sourcetree
  696. ELSE 0 END
  697. WHERE tree_id=source_node_tree;
  698.  
  699. COMMIT;
  700.  
  701. END//
  702. DELIMITER ;
  703. SET sql_mode=@OLD_SQL_MODE;
  704.  
  705. DROP PROCEDURE IF EXISTS Baobab_GENERIC_MoveSubtree_Different_Trees;
  706. DELIMITER //
  707. CREATE PROCEDURE Baobab_GENERIC_MoveSubtree_Different_Trees(
  708. IN node_id_to_move INTEGER UNSIGNED,
  709. IN reference_node INTEGER UNSIGNED,
  710. IN move_as_first_sibling BOOLEAN
  711. )
  712. LANGUAGE SQL
  713. DETERMINISTIC
  714.  
  715. main:BEGIN
  716.  
  717. DECLARE s_lft INTEGER UNSIGNED;
  718. DECLARE s_rgt INTEGER UNSIGNED;
  719. DECLARE ref_lft INTEGER UNSIGNED;
  720. DECLARE ref_rgt INTEGER UNSIGNED;
  721.  
  722. DECLARE source_node_tree INTEGER UNSIGNED;
  723. DECLARE ref_node_tree INTEGER UNSIGNED;
  724.  
  725. START TRANSACTION;
  726.  
  727. /* select tree, left and right of the node to move */
  728. SELECT tree_id,lft, rgt
  729. INTO source_node_tree, s_lft, s_rgt
  730. FROM GENERIC
  731. WHERE id = node_id_to_move;
  732.  
  733. /* The current select will behave differently whether we're moving
  734. the node as first sibling or not.
  735.  
  736. If move_as_first_sibling,
  737. ref_lft will have the value of the "lft" field of node_id_to_move at end
  738. of move (ref_rgt here is discarded)
  739. else
  740. ref_lft and ref_rgt will have the values of the node before node_id_to_move
  741. at end of move
  742. */
  743. SELECT tree_id, IF(move_as_first_sibling,lft+1,lft), rgt
  744. INTO ref_node_tree, ref_lft, ref_rgt
  745. FROM GENERIC
  746. WHERE id = reference_node;
  747.  
  748. IF (move_as_first_sibling) THEN BEGIN
  749.  
  750. /* create a gap in the destination tree to hold the subtree */
  751. UPDATE GENERIC
  752. SET lft = CASE WHEN lft < ref_lft
  753. THEN lft
  754. ELSE lft + s_rgt-s_lft+1 END,
  755. rgt = CASE WHEN rgt < ref_lft
  756. THEN rgt
  757. ELSE rgt + s_rgt-s_lft+1 END
  758. WHERE tree_id=ref_node_tree AND rgt >= ref_lft;
  759.  
  760. /* move the subtree to the new tree */
  761. UPDATE GENERIC
  762. SET lft = ref_lft + (lft-s_lft),
  763. rgt = ref_lft + (rgt-s_lft),
  764. tree_id = ref_node_tree
  765. WHERE tree_id = source_node_tree AND lft >= s_lft AND rgt <= s_rgt;
  766.  
  767. END;
  768. ELSE BEGIN
  769.  
  770. /* create a gap in the destination tree to hold the subtree */
  771. UPDATE GENERIC
  772. SET lft = CASE WHEN lft < ref_rgt
  773. THEN lft
  774. ELSE lft + s_rgt-s_lft+1 END,
  775. rgt = CASE WHEN rgt <= ref_rgt
  776. THEN rgt
  777. ELSE rgt + s_rgt-s_lft+1 END
  778. WHERE tree_id=ref_node_tree AND rgt > ref_rgt;
  779.  
  780. /* move the subtree to the new tree */
  781. UPDATE GENERIC
  782. SET lft = ref_rgt+1 + (lft-s_lft),
  783. rgt = ref_rgt+1 + (rgt-s_lft),
  784. tree_id = ref_node_tree
  785. WHERE tree_id = source_node_tree AND lft >= s_lft AND rgt <= s_rgt;
  786.  
  787. END;
  788.  
  789. END IF;
  790.  
  791. /* close the gap in the source tree */
  792. CALL Baobab_GENERIC_Close_Gaps(source_node_tree);
  793.  
  794. COMMIT;
  795.  
  796. END//
  797. DELIMITER ;
  798. /* ########################## */
  799. /* ####### CLOSE GAPS ####### */
  800. /* ########################## */
  801.  
  802. DROP PROCEDURE IF EXISTS Baobab_GENERIC_Close_Gaps;
  803. DELIMITER //
  804. CREATE PROCEDURE Baobab_GENERIC_Close_Gaps(
  805. IN choosen_tree INTEGER UNSIGNED)
  806. LANGUAGE SQL
  807. DETERMINISTIC
  808.  
  809. BEGIN
  810.  
  811. UPDATE GENERIC
  812. SET lft = (SELECT COUNT(*)
  813. FROM (
  814. SELECT lft as seq_nbr FROM GENERIC WHERE tree_id=choosen_tree
  815. UNION ALL
  816. SELECT rgt FROM GENERIC WHERE tree_id=choosen_tree
  817. ) AS LftRgt
  818. WHERE tree_id=choosen_tree AND seq_nbr <= lft
  819. ),
  820. rgt = (SELECT COUNT(*)
  821. FROM (
  822. SELECT lft as seq_nbr FROM GENERIC WHERE tree_id=choosen_tree
  823. UNION ALL
  824. SELECT rgt FROM GENERIC WHERE tree_id=choosen_tree
  825. ) AS LftRgt
  826. WHERE tree_id=choosen_tree AND seq_nbr <= rgt
  827. )
  828. WHERE tree_id=choosen_tree;
  829. END//
  830. delimiter ;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement