Jump to content

I-AM-OBODO

Members
  • Posts

    442
  • Joined

  • Last visited

Everything posted by I-AM-OBODO

  1. But should i want to assign point for each referral, where should i assign it eg once your downline is 1, you earn £1 and when 2 you earn 5cents, 3 you earn 2cents.
  2. Thank you so very much. you are a life saver. Will find a way of solving the undefined index issue. But i think at the long run, i'll settle with the query instead of the recursive cos i can format the output of that of sql query (join) than the recursive function, but both are very useful. thanks
  3. I tried the recursion method you sent earlier but It's giving "undefined index" here. getRef($data, $data[$id][' refer_id'] ,$startid);
  4. Thank you so very much for your time and help. Maybe i'm not makingmyself clearer enough. Everything is working just fine but the problem is that i do not know how to all the people on my downline. Fot instance in the example table, John is the parent, how to select everyone that comes from John (directly or indirectly). To attempt this i created another colunm called parent_id. On the first level, it easy to insert a value to John as parent. If frank refer tommy, frank becomes tommy's parent. If tommy refers someone, he becomes parent as well. The problem is if i do an insert to table_name, the parent is the new parent. How co-relate the parents together. //if no one referred you, you become the parent of yourself else your referrer is your parent $parent_id = "J123"; //since john referred frank, franks refer_id is john's ref_id which is J123 $refer_id = $ref_id; $stmt=$pdo->prepare("INSERT INTO table(parent_id, acct_num, ref_id, refer_id) VALUES(:parent_id, :acct_num, :ref_id, :refer_id"); $stmt->bindValue(':parent_id', $parent_id, PDO::PARAM_STR); $stmt->bindValue(':acct_num', $acct_num, PDO::PARAM_STR); $stmt->bindValue(':ref_id', $ref_id, PDO::PARAM_STR); $stmt->bindValue(':refer_id', $refer_id, PDO::PARAM_STR); $stmt->execute(); the problem now is that if frank becomes the parent, frank's ref_id will be in the parent_id colunm, i need something to distinguish between john and other children and grand children so that when doing a select, I will say where username = john and the_relationship = relationship so that every person on the downline will display Thanks
  5. Hi. I didn't say It's not working. I said when I use it with a username it's not displaying my indirect down-stream eg if I refer someone and the person refers another, all I see is referral without seeing my referral's referral. if I could get the logic right, it'll work. Thanks
  6. I tried implementing this on my program, it worked perfectly. I even added more joins but the problem is relating the table to a user. The problem i am having is trying to co-relate the third person to the first. Assuming i invited paul and paul invited peter. On my account, i could see just paul and can't see peter. I've been trying this for days now but to no avail. Truth is i was hoping to get this done before the new year. I couldnt figure out the logic to make them co-relate, so that even when peter should invite someone else, i could still see the person on my downline. $sql = "SELECT r.id , r.acct_name , r.ref_id , r1.acct_name as first , r2.acct_name as second, r3.acct_name as third, r4.acct_name as fourth FROM ca_categories r LEFT JOIN ca_categories r1 ON r.refer_id = r1.ref_id LEFT JOIN ca_categories r2 ON r1.refer_id = r2.ref_id LEFT JOIN ca_categories r3 ON r2.refer_id = r3.ref_id LEFT JOIN ca_categories r4 ON r3.refer_id = r4.ref_id WHERE r.referrer_uname = '$_SESSION[username]' ORDER by id"; Please and thanks
  7. Thanks. But when i tried the above code it's giving undefined index somewhere here: getRef($data, $data[$id]['refer_id'] ,$startid);
  8. Hello guys, I want to get the values of 3rd level of my referral but it did not echo any value but if i put the ref id directly on the code, it will echo the values. why is it so? or am i doing it the wrong way? in my database i have a table test_referral id acct_name ref_id refer_id 1 john J1234 0 2 bull B3456 J1234 3 doe D5567 J1234 4 frank F7788 J1234 5 jimmy J9990 J1234 6 tommy T6784 F7788 7 tom T9988 F7788 8 girly G8866 D5567 9 fred F0099 J9990 10 ronaldo R7722 B3456 thanks $stmt= $pdo->query("SELECT * FROM test_referral WHERE acct_name='Chidi Okafor'"); $parent = $stmt->fetch(PDO::FETCH_LAZY); echo "<ul><li>"; echo $parent['acct_name']; $ref_id = $parent['ref_id']; echo "</li><ul>"; $stmt= $pdo->query("SELECT * FROM test_referral WHERE refer_id='$ref_id'"); $child_count = $stmt->rowCount(); while($child = $stmt->fetch(PDO::FETCH_LAZY)){ echo "<li>"; echo $child['acct_name']; $ref_ids = $child['ref_id']; echo "</li>"; } //$reff = "F7788"; //$stmt= $pdo->query("SELECT * FROM test_referral WHERE refer_id='$F7788'"); $stmt= $pdo->query("SELECT * FROM test_referral WHERE refer_id='$ref_ids'"); $child_count2 = $stmt->rowCount(); while($children = $stmt->fetch(PDO::FETCH_LAZY)){ echo "<ul><li>"; echo $children['acct_name']; echo "</li></ul>"; }
  9. Hmmmm. Thanks
  10. But how can the invalid dates for intervals be handled, like the case you sighted with feb 29th?
  11. Thanks kicken and berand you both got my best answer both unfortunately only one has to be chosen. thanks a thrillion dozen time. some day i know i'll give back to this wonderful forum. cheers
  12. Oops! I'd rather you laugh than cry. lolz. I did that on the top of my query if you checked. Maybe I'd do it along with other query? was thinking it wouldnt work. Will give it a shot. But a point to the right direction wouldnt do any harm! Thanks
  13. I noticed that the problem is with my code but i can't figure out where the problem is from or if something is wrong with my code. Maybe there's a better way of re-writting my code. Thanks, here's my code: $table_name = "Chidi"; $stmt2 = $pdo->query("SELECT recurring, due_date, CASE recurring WHEN 'weekly' THEN due_date + INTERVAL 7 DAY WHEN 'bi-weekly' THEN due_date + INTERVAL 14 DAY WHEN 'monthly' THEN due_date + INTERVAL 1 MONTH WHEN 'quarterly' THEN due_date + INTERVAL 3 MONTH WHEN 'half-yearly' THEN due_date + INTERVAL 6 MONTH WHEN 'yearly' THEN due_date + INTERVAL 1 YEAR END as next_due FROM $table_name"); while($row2 = $stmt2->fetch(PDO::FETCH_ASSOC)){ $next_due = $row2['next_due']; } $stmt = $pdo->prepare("SELECT * FROM $tbl_name ORDER BY trans_id DESC LIMIT $start, $limit"); $stmt->execute(); echo "<table width='100%' border='1' bordercolor='#0cc' cellspacing='0' cellpadding='2'>"; echo "<tr> <th bgcolor='#444444' align='center'><font color='#fff'>Trans Ref</th> <th bgcolor='#444444' align='center'><font color='#fff'>Subscriber's A/C No</font></th> <th bgcolor='#444444' align='center'><font color='#fff'>Subscriber's Name</font></th> <th bgcolor='#444444' align='center'><font color='#fff'>Services Provider</font></th> <th bgcolor='#444444' align='center'><font color='#fff'>Provider's A/C No</font></th> <th bgcolor='#444444' align='center'><font color='#fff'>Amount</font></th> <th bgcolor='#444444' align='center'><font color='#fff'>Service</font></th> <th bgcolor='#444444' align='center'><font color='#fff'>Recurring</font></th> <th bgcolor='#444444' align='center'><font color='#fff'>Due Date</font></th> <th bgcolor='#444444' align='center'><font color='#fff'>Next Due Date</font></th> <th bgcolor='#444444' align='center'><font color='#fff'>Status</font></th> <th bgcolor='#444444' align='center'><font color='#fff'>Payment Status</font></th> </tr>"; // keeps getting the next row until there are no more to get while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { // Print out the contents of each row into a table echo "<tr><td>"; echo $row['trans_ref']; echo "</td><td>"; echo $row['acct_num']; echo "</td><td>"; echo ucwords($row['payee']); echo "</td><td>"; echo ucwords($row['company']); echo "</td><td>"; echo $row['acct_no']; echo "</td><td>"; echo number_format($row['amt'],2); echo "</td><td>"; echo $row['purpose']; echo "</td><td>"; echo $row['recurring']; echo "</td><td>"; echo $row['due_date']; echo "</td><td>"; echo $next_due; echo "</td><td>"; echo "<strong>".$row['status']."</strong>"; echo "</td><td>"; echo "<strong>".$row['pay_status']."</strong>"; } echo "</table>";
  14. thanks but what you did is a better and simpler way of doing what i did but it still did not solve my problem. The problem is that it calculates the next due for a single row and gives the result to all the rows in the table even when they are different dates. I need something that will give me the values of different rows/dates eg 2014-12-25 ------ 2015-01-25 (Monthly) 2014-12-10 ------ 2014-12-24 (Bi-Weekly) thanks
  15. I finally know why it giving me the error. It's an issue of variable scope http://php.net/manual/en/language.variables.scope.php
  16. Hi all. In my database, i have a column recurring which is derived from a multiple option form field with values: Weekly, Bi-Monthly, Monthly, Quarterly, Half Yearly and Yearly. I want to have as next due the current date plus the recurring value. eg current date = 2014-11-24 recurring = monthly next due = current date + recurring (in the next due will be 2014-12-24) so i did: $stmt = $pdo->query("SELECT recurring, due_date FROM $table"); while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $recur = $row['recurring']; $date_due = $row['due_date']; } $weekly = "Weekly"; $bi_monthly = "Bi-Monthly"; $monthly = "Monthly"; $quarterly = "Quarterly"; $half_yearly = "Half Yearly"; $yearly = "Yearly"; if(strcmp($recur, $weekly) == 0){ $recurs = "7 DAY"; }elseif(strcmp($recur, $bi_monthly) == 0){ $recurs = "14 DAY"; }elseif(strcmp($recur, $monthly) == 0){ $recurs = "1 MONTH"; }elseif(strcmp($recur, $quarterly) == 0){ $recurs = "3 MONTH"; }elseif(strcmp($recur, $half_yearly) == 0){ $recurs = "6 MONTH"; }elseif(strcmp($recur, $yearly) == 0){ $recurs = "1 YEAR"; } $stmt = $pdo->query("SELECT ADDDATE('$date_due', INTERVAL $recurs) as nex_due FROM $table"); $row = $stmt->fetch(PDO::FETCH_ASSOC); $nex_due = $row['nex_due']; $stmt = $pdo->prepare("SELECT * FROM $table ORDER BY trans_id DESC"); $stmt->execute(); $num_rows = $stmt->rowCount(); while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { // Print out the contents of each row into a table echo "<tr><td>"; echo $row['trans_ref']; echo "</td><td>"; echo $row['acct_num']; echo "</td><td>"; echo ucwords($row['payee']); echo "</td><td>"; echo ucwords($row['company']); echo "</td><td>"; echo $row['acct_no']; echo "</td><td>"; echo number_format($row['amt'],2); echo "</td><td>"; echo $row['purpose']; echo "</td><td>"; echo $row['recurring']; echo "</td><td>"; echo $row['due_date']; echo "</td><td>"; echo $nex_due; echo "</td><td>"; echo "<strong>".$row['status']."</strong>"; echo "</td><td>"; echo "<strong>".$row['pay_status']."</strong>"; echo "</td><td>"; } The problem is that it's giving me as next due the value of the first row even when the recurring is different!
  17. Hi guys. why is my function error: undefined varable pdo? Thanks function referralCount($uid,$reflvl) { $stmt= $pdo->query("SELECT * FROM scraffiliateusr WHERE usrinvby='$uid'"); $nusrref1 = $stmt->rowCount(); //$arrusrref1 = $stmt->fetch(PDO::FETCH_LAZY); $reflvl1=$nusrref1; $ttlreflvl2="0"; $ttlreflvl3="0"; for ($i=0; $i<$nusrref1; $i++) { $arrusrref1 = $stmt->fetch(PDO::FETCH_LAZY); $stmt= $pdo->query("SELECT * FROM scraffiliateusr WHERE usrinvby='$arrusrref1[0]'"); $nusrref2 = $stmt->rowCount(); //$arrusrref2 = $stmt->fetch(PDO::FETCH_LAZY); $ttlreflvl2=$ttlreflvl2+$nusrref2; for ($j=0; $j<$nusrref2; $j++) { $arrusrref2 = $stmt->fetch(PDO::FETCH_LAZY); $stmt= $pdo->query("SELECT * FROM scraffiliateusr WHERE usrinvby='$arrusrref2[0]'"); $nusrref3 = $stmt->rowCount(); //$arrusrref3 = $stmt->fetch(PDO::FETCH_LAZY); $ttlreflvl3=$ttlreflvl3+$nusrref3; } } $reflvl2=$ttlreflvl2; $reflvl3=$ttlreflvl3; if($reflvl=='1') { return($reflvl1); } elseif($reflvl=='2') { return($reflvl2); } elseif($reflvl=='3') { return($reflvl3); } }
  18. mysql version is 5.6.17
  19. Hi guys, I am having a hard time trying to figure out why this gives me an error? #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 10 /** * Baobab (an implementation of Nested Set Model) * * Copyright 2010 Riccardo Attilio Galli <[email protected]> [http://www.sideralis.org] * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * .. note:: * Each occurrence of the word "GENERIC" across this file is meant to be * replaced with the name of the tree (which must be a valid string to use * as SQL table name). */ /* ############################### */ /* ###### TABLES AND VIEWS ####### */ /* ############################### */ CREATE TABLE IF NOT EXISTS GENERIC ( tree_id INTEGER UNSIGNED NOT NULL, id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, lft INTEGER NOT NULL CHECK (lft > 0), rgt INTEGER NOT NULL CHECK (rgt > 1), INDEX(tree_id), INDEX(lft), CONSTRAINT order_okay CHECK (lft < rgt) ) ENGINE INNODB; DROP VIEW IF EXISTS GENERIC_AdjTree; CREATE VIEW GENERIC_AdjTree (tree_id,parent,child,lft) AS SELECT E.tree_id,B.id, E.id, E.lft FROM GENERIC AS E LEFT OUTER JOIN GENERIC AS B ON B.lft = ( SELECT MAX(lft) FROM GENERIC AS S WHERE E.lft > S.lft AND E.lft < S.rgt AND E.tree_id=S.tree_id) AND B.tree_id=E.tree_id ORDER BY lft ASC; /* ##### LIST OF TREE NAMES IN USE ##### */ CREATE TABLE IF NOT EXISTS Baobab_ForestsNames ( name VARCHAR(200) PRIMARY KEY ) ENGINE INNODB DEFAULT CHARSET=utf8; INSERT INTO Baobab_ForestsNames(name) VALUES ('GENERIC') ON DUPLICATE KEY UPDATE name=name; /* ##################################### */ /* ########################### */ /* ###### ERRORS CONTROL ##### */ /* ########################### */ CREATE TABLE IF NOT EXISTS Baobab_Errors ( code INTEGER UNSIGNED NOT NULL PRIMARY KEY, name VARCHAR(50) NOT NULL, msg TINYTEXT NOT NULL, CONSTRAINT unique_codename UNIQUE (name) ) ENGINE INNODB; INSERT INTO Baobab_Errors(code,name,msg) VALUES (1000,'VERSION','1.3.1'), (1100,'ROOT_ERROR','Cannot add or move a node next to root'), (1200,'CHILD_OF_YOURSELF_ERROR','Cannot move a node inside his own subtree'), (1300,'INDEX_OUT_OF_RANGE','The index is out of range'), (1400,'NODE_DOES_NOT_EXIST',"Node doesn't exist"), (1500,'VERSION_NOT_MATCH',"The library and the sql schema have different versions") ON DUPLICATE KEY UPDATE code=code,name=name,msg=msg; DROP FUNCTION IF EXISTS Baobab_getErrCode; CREATE FUNCTION Baobab_getErrCode(x TINYTEXT) RETURNS INT DETERMINISTIC RETURN (SELECT code from Baobab_Errors WHERE name=x); /* ########################## */ /* ######## DROP TREE ####### */ /* ########################## */ DROP PROCEDURE IF EXISTS Baobab_GENERIC_DropTree; CREATE PROCEDURE Baobab_GENERIC_DropTree ( IN node INTEGER UNSIGNED, IN update_numbers INTEGER) LANGUAGE SQL DETERMINISTIC MODIFIES SQL DATA BEGIN DECLARE drop_tree_id INTEGER UNSIGNED; DECLARE drop_id INTEGER UNSIGNED; DECLARE drop_lft INTEGER UNSIGNED; DECLARE drop_rgt INTEGER UNSIGNED; /* declare exit handler for not found rollback; declare exit handler for sqlexception rollback; declare exit handler for sqlwarning rollback; */ /* save the dropped subtree data with a singleton SELECT */ START TRANSACTION; /* save the dropped subtree data with a singleton SELECT */ SELECT tree_id, id, lft, rgt INTO drop_tree_id, drop_id, drop_lft, drop_rgt FROM GENERIC WHERE id = node; /* subtree deletion is easy */ DELETE FROM GENERIC WHERE tree_id=drop_tree_id AND lft BETWEEN drop_lft and drop_rgt; IF update_numbers = 1 THEN /* close up the gap left by the subtree */ UPDATE GENERIC SET lft = CASE WHEN lft > drop_lft THEN lft - (drop_rgt - drop_lft + 1) ELSE lft END, rgt = CASE WHEN rgt > drop_lft THEN rgt - (drop_rgt - drop_lft + 1) ELSE rgt END WHERE tree_id=drop_tree_id AND (lft > drop_lft OR rgt > drop_lft); END IF; COMMIT; END; /* ########################## */ /* ###### APPEND CHILD ###### */ /* ########################## */ /* Add a new child to a parent as last sibling If parent_id is 0, insert a new root node, moving the previous root (if any) as his child. If choosen_tree is 0, use the first available integer as id. If choosen_tree is not present as tree_id in the table, it is used. */ DROP PROCEDURE IF EXISTS Baobab_GENERIC_AppendChild; CREATE PROCEDURE Baobab_GENERIC_AppendChild( IN choosen_tree INTEGER UNSIGNED, IN parent_id INTEGER UNSIGNED, OUT new_id INTEGER UNSIGNED, OUT cur_tree_id INTEGER UNSIGNED) LANGUAGE SQL DETERMINISTIC BEGIN DECLARE num INTEGER UNSIGNED; START TRANSACTION; SET cur_tree_id = IF(choosen_tree > 0, choosen_tree, IFNULL((SELECT MAX(tree_id)+1 FROM GENERIC),1) ); IF parent_id = 0 THEN /* inserting a new root node*/ UPDATE GENERIC SET lft = lft+1, rgt = rgt+1 WHERE tree_id=cur_tree_id; SET num = IFNULL((SELECT MAX(rgt)+1 FROM GENERIC WHERE tree_id=cur_tree_id),2); INSERT INTO GENERIC(tree_id, id, lft, rgt) VALUES (cur_tree_id, NULL, 1, num); ELSE /* append a new node as last right child of his parent */ SET num = (SELECT rgt FROM GENERIC WHERE id = parent_id ); UPDATE GENERIC SET lft = CASE WHEN lft > num THEN lft + 2 ELSE lft END, rgt = CASE WHEN rgt >= num THEN rgt + 2 ELSE rgt END WHERE tree_id=cur_tree_id AND rgt >= num; INSERT INTO GENERIC(tree_id, id, lft, rgt) VALUES (cur_tree_id,NULL, num, (num + 1)); END IF; SELECT LAST_INSERT_ID() INTO new_id; COMMIT; END; /* ############################### */ /* ###### INSERT NODE AFTER ###### */ /* ############################### */ DROP PROCEDURE IF EXISTS Baobab_GENERIC_insertAfter; CREATE PROCEDURE Baobab_GENERIC_insertAfter( IN sibling_id INTEGER UNSIGNED, OUT new_id INTEGER UNSIGNED, OUT error_code INTEGER UNSIGNED) LANGUAGE SQL DETERMINISTIC main:BEGIN IF 1 = (SELECT lft FROM GENERIC WHERE id = sibling_id) THEN BEGIN SELECT Baobab_getErrCode('ROOT_ERROR') INTO error_code; LEAVE main; END; ELSE BEGIN DECLARE lft_sibling INTEGER UNSIGNED; DECLARE choosen_tree INTEGER UNSIGNED; START TRANSACTION; SELECT tree_id,rgt INTO choosen_tree,lft_sibling FROM GENERIC WHERE id = sibling_id; IF ISNULL(lft_sibling) THEN BEGIN SELECT Baobab_getErrCode('NODE_DOES_NOT_EXIST') INTO error_code; LEAVE main; END; END IF; UPDATE GENERIC SET lft = CASE WHEN lft < lft_sibling THEN lft ELSE lft + 2 END, rgt = CASE WHEN rgt < lft_sibling THEN rgt ELSE rgt + 2 END WHERE tree_id=choosen_tree AND rgt > lft_sibling; INSERT INTO GENERIC(tree_id,id,lft,rgt) VALUES (choosen_tree,NULL, (lft_sibling + 1),(lft_sibling + 2)); SELECT LAST_INSERT_ID() INTO new_id; COMMIT; END; END IF; END; /* ################################ */ /* ###### INSERT NODE BEFORE ###### */ /* ################################ */ DROP PROCEDURE IF EXISTS Baobab_GENERIC_insertBefore; CREATE PROCEDURE Baobab_GENERIC_insertBefore( IN sibling_id INTEGER UNSIGNED, OUT new_id INTEGER UNSIGNED, OUT error_code INTEGER UNSIGNED) LANGUAGE SQL DETERMINISTIC main:BEGIN IF 1 = (SELECT lft FROM GENERIC WHERE id = sibling_id) THEN BEGIN SELECT Baobab_getErrCode('ROOT_ERROR') INTO error_code; LEAVE main; END; ELSE BEGIN DECLARE rgt_sibling INTEGER UNSIGNED; DECLARE choosen_tree INTEGER UNSIGNED; START TRANSACTION; SELECT tree_id,lft INTO choosen_tree,rgt_sibling FROM GENERIC WHERE id = sibling_id; IF ISNULL(rgt_sibling) THEN BEGIN SELECT Baobab_getErrCode('NODE_DOES_NOT_EXIST') INTO error_code; LEAVE main; END; END IF; UPDATE IGNORE GENERIC SET lft = CASE WHEN lft < rgt_sibling THEN lft ELSE lft + 2 END, rgt = CASE WHEN rgt < rgt_sibling THEN rgt ELSE rgt + 2 END WHERE tree_id=choosen_tree AND rgt >= rgt_sibling ORDER BY lft DESC; /* order by is meant to avoid uniqueness violation on update */ INSERT INTO GENERIC(tree_id,id,lft,rgt) VALUES (choosen_tree,NULL, rgt_sibling, rgt_sibling + 1); SELECT LAST_INSERT_ID() INTO new_id; COMMIT; END; END IF; END; /* ################################### */ /* ###### INSERT CHILD AT INDEX ###### */ /* ################################### */ /* Add a new child to parent 'parent_id' at index 'index'. index is the new child position, 0 will put the new node as first. index can be negative, where -1 will put the new node before the last one */ DROP PROCEDURE IF EXISTS Baobab_GENERIC_InsertChildAtIndex; CREATE PROCEDURE Baobab_GENERIC_InsertChildAtIndex( IN parent_id INTEGER UNSIGNED, IN idx INTEGER, OUT new_id INTEGER UNSIGNED, OUT error_code INTEGER UNSIGNED) LANGUAGE SQL DETERMINISTIC BEGIN DECLARE nth_child INTEGER UNSIGNED; DECLARE cur_tree_id INTEGER UNSIGNED; SET error_code=0; SET new_id=0; CALL Baobab_GENERIC_getNthChild(parent_id,idx,nth_child,error_code); IF NOT error_code THEN CALL Baobab_GENERIC_insertBefore(nth_child,new_id,error_code); ELSE IF idx = 0 AND error_code = (SELECT Baobab_getErrCode('INDEX_OUT_OF_RANGE')) THEN BEGIN SET error_code = 0; CALL Baobab_GENERIC_AppendChild((SELECT tree_id FROM GENERIC WHERE id = parent_id), parent_id, new_id, cur_tree_id); END; END IF; END IF; END; /* ########################### */ /* ###### GET NTH CHILD ###### */ /* ########################### */ DROP PROCEDURE IF EXISTS Baobab_GENERIC_getNthChild; CREATE PROCEDURE Baobab_GENERIC_getNthChild( IN parent_id INTEGER UNSIGNED, IN idx INTEGER, OUT nth_child INTEGER UNSIGNED, OUT error_code INTEGER UNSIGNED) LANGUAGE SQL DETERMINISTIC main:BEGIN DECLARE num_children INTEGER; SET error_code=0; SELECT COUNT(*) INTO num_children FROM GENERIC_AdjTree WHERE parent = parent_id; IF num_children = 0 OR IF(idx<0,(-idx)-1,idx) >= num_children THEN /* idx is out of range */ BEGIN SELECT Baobab_getErrCode('INDEX_OUT_OF_RANGE') INTO error_code; LEAVE main; END; ELSE SELECT child INTO nth_child FROM GENERIC_AdjTree as t1 WHERE (SELECT count(*) FROM GENERIC_AdjTree as t2 WHERE parent = parent_id AND t2.lft<=t1.lft AND t1.tree_id=t2.tree_id ) = (CASE WHEN idx >= 0 THEN idx+1 ELSE num_children+1+idx END ) LIMIT 1; END IF; END; /* ###################################### */ /* ###### MOVE SUBTREE BEFORE NODE ###### */ /* ###################################### */ DROP PROCEDURE IF EXISTS Baobab_GENERIC_MoveSubtreeBefore; CREATE PROCEDURE Baobab_GENERIC_MoveSubtreeBefore( IN node_id_to_move INTEGER UNSIGNED, IN reference_node INTEGER UNSIGNED, OUT error_code INTEGER UNSIGNED) LANGUAGE SQL DETERMINISTIC main:BEGIN DECLARE node_revised INTEGER UNSIGNED; DECLARE move_as_first_sibling BOOLEAN; DECLARE ref_left INTEGER UNSIGNED; DECLARE ref_node_tree INTEGER UNSIGNED; SET error_code=0; /* 0 means no error */ SET move_as_first_sibling = TRUE; SELECT tree_id,lft INTO ref_node_tree,ref_left FROM GENERIC WHERE id = reference_node; IF ref_left = 1 THEN BEGIN /* cannot move a parent node before or after root */ SELECT Baobab_getErrCode('ROOT_ERROR') INTO error_code; LEAVE main; END; END IF; /* if reference_node is the first child of his parent, set node_revised to the parent id, else set node_revised to NULL */ SET node_revised = ( SELECT id FROM GENERIC WHERE tree_id=ref_node_tree AND lft = -1+ ref_left); IF ISNULL(node_revised) THEN /* if node_revised is NULL we must find the previous sibling */ BEGIN SET node_revised= (SELECT id FROM GENERIC WHERE tree_id=ref_node_tree AND rgt = -1 + ref_left); SET move_as_first_sibling = FALSE; END; END IF; CALL Baobab_GENERIC_MoveSubtree_real( node_id_to_move, node_revised , move_as_first_sibling, error_code ); END; /* ##################################### */ /* ###### MOVE SUBTREE AFTER NODE ###### */ /* ##################################### */ DROP PROCEDURE IF EXISTS Baobab_GENERIC_MoveSubtreeAfter; CREATE PROCEDURE Baobab_GENERIC_MoveSubtreeAfter( IN node_id_to_move INTEGER UNSIGNED, IN reference_node INTEGER UNSIGNED, OUT error_code INTEGER UNSIGNED) LANGUAGE SQL DETERMINISTIC BEGIN SELECT 0 INTO error_code; /* 0 means no error */ CALL Baobab_GENERIC_MoveSubtree_real( node_id_to_move,reference_node,FALSE,error_code ); END; /* ##################################### */ /* ####### MOVE SUBTREE AT INDEX ####### */ /* ##################################### */ DROP PROCEDURE IF EXISTS Baobab_GENERIC_MoveSubtreeAtIndex; CREATE PROCEDURE Baobab_GENERIC_MoveSubtreeAtIndex( IN node_id_to_move INTEGER UNSIGNED, IN parent_id INTEGER UNSIGNED, IN idx INTEGER, OUT error_code INTEGER) LANGUAGE SQL DETERMINISTIC main:BEGIN DECLARE nth_child INTEGER UNSIGNED; DECLARE num_children INTEGER; DECLARE parent_of_node_to_move INTEGER UNSIGNED; DECLARE s_lft INTEGER UNSIGNED; DECLARE current_idx INTEGER; SET error_code=0; SELECT COUNT(*) INTO num_children FROM GENERIC_AdjTree WHERE parent = parent_id; IF idx < 0 THEN SET idx = num_children + idx; ELSEIF idx > 0 THEN BEGIN SELECT parent, lft INTO parent_of_node_to_move, s_lft FROM GENERIC_AdjTree WHERE child = node_id_to_move; IF parent_of_node_to_move = parent_id THEN BEGIN SELECT count(*) INTO current_idx FROM GENERIC_AdjTree WHERE parent = parent_id AND lft < s_lft; IF idx > current_idx THEN SET idx = idx + 1; END IF; END; END IF; END; END IF; SET idx = IF(idx<0,num_children+idx,idx); IF idx = 0 THEN /* moving as first child, special case */ CALL Baobab_GENERIC_MoveSubtree_real(node_id_to_move,parent_id,TRUE,error_code); ELSE BEGIN /* search the node before idx, and we wil move our node after that */ CALL Baobab_GENERIC_getNthChild(parent_id,idx-1,nth_child,error_code); IF NOT error_code THEN CALL Baobab_GENERIC_MoveSubtree_real(node_id_to_move,nth_child,FALSE,error_code); END IF; END; END IF; END; /* ####################################### */ /* ####### MOVE SUBTREE REAL LOGIC #######*/ /* ####################################### */ /* If move_as_first_sibling is FALSE, move node_id_to_move after reference_node, else reference_node is the new father of node_id_to_move */ SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_UNSIGNED_SUBTRACTION'; DROP PROCEDURE IF EXISTS Baobab_GENERIC_MoveSubtree_real; CREATE PROCEDURE Baobab_GENERIC_MoveSubtree_real( IN node_id_to_move INTEGER UNSIGNED, IN reference_node INTEGER UNSIGNED, IN move_as_first_sibling BOOLEAN, OUT error_code INTEGER ) LANGUAGE SQL DETERMINISTIC main:BEGIN DECLARE s_lft INTEGER UNSIGNED; DECLARE s_rgt INTEGER UNSIGNED; DECLARE ref_lft INTEGER UNSIGNED; DECLARE ref_rgt INTEGER UNSIGNED; DECLARE source_node_tree INTEGER UNSIGNED; DECLARE ref_node_tree INTEGER UNSIGNED; DECLARE diff_when_inside_sourcetree BIGINT SIGNED; DECLARE diff_when_next_sourcetree BIGINT SIGNED; DECLARE ext_bound_1 INTEGER UNSIGNED; DECLARE ext_bound_2 INTEGER UNSIGNED; SET error_code=0; START TRANSACTION; /* select tree, left and right of the node to move */ SELECT tree_id,lft, rgt INTO source_node_tree, s_lft, s_rgt FROM GENERIC WHERE id = node_id_to_move; /* select left and right of the reference node If moving as first sibling, ref_lft will become the new lft value of node_id_to_move, (and ref_rgt is unused), else we're saving left and right value of soon to be previous sibling */ SELECT tree_id, IF(move_as_first_sibling,lft+1,lft), rgt INTO ref_node_tree, ref_lft, ref_rgt FROM GENERIC WHERE id = reference_node; IF move_as_first_sibling = TRUE THEN IF s_lft <= ref_lft AND s_rgt >= ref_rgt AND source_node_tree=ref_node_tree THEN /* cannot move a parent node inside his own subtree */ BEGIN SELECT Baobab_getErrCode('CHILD_OF_YOURSELF_ERROR') INTO error_code; LEAVE main; END; ELSE IF s_lft > ref_lft THEN BEGIN SET diff_when_inside_sourcetree = -(s_lft-ref_lft); SET diff_when_next_sourcetree = s_rgt-s_lft+1; SET ext_bound_1 = ref_lft; SET ext_bound_2 = s_lft-1; END; ELSEIF s_lft = ref_lft and source_node_tree = ref_node_tree THEN BEGIN /* we have been asked to move a node to his same position */ LEAVE main; END; ELSE BEGIN SET diff_when_inside_sourcetree = ref_lft-s_rgt-1; SET diff_when_next_sourcetree = -(s_rgt-s_lft+1); SET ext_bound_1 = s_rgt+1; SET ext_bound_2 = ref_lft-1; END; END IF; END IF; ELSE /* moving after an existing child */ IF ref_lft = 1 THEN /* cannot move a node before or after root */ BEGIN SELECT Baobab_getErrCode('ROOT_ERROR') INTO error_code; LEAVE main; END; ELSEIF s_lft < ref_lft AND s_rgt > ref_rgt AND source_node_tree=ref_node_tree THEN /* cannot move a parent node inside his own subtree */ BEGIN SELECT Baobab_getErrCode('CHILD_OF_YOURSELF_ERROR') INTO error_code; LEAVE main; END; ELSE IF s_lft > ref_rgt THEN BEGIN SET diff_when_inside_sourcetree = -(s_lft-ref_rgt-1); SET diff_when_next_sourcetree = s_rgt-s_lft+1; SET ext_bound_1 = ref_rgt+1; SET ext_bound_2 = s_lft-1; END; ELSE BEGIN SET diff_when_inside_sourcetree = ref_rgt-s_rgt; SET diff_when_next_sourcetree = -(s_rgt-s_lft+1); SET ext_bound_1 = s_rgt+1; SET ext_bound_2 = ref_rgt; END; END IF; END IF; END IF; IF source_node_tree <> ref_node_tree THEN BEGIN CALL Baobab_GENERIC_MoveSubtree_Different_Trees( node_id_to_move,reference_node,move_as_first_sibling); LEAVE main; END; END IF; UPDATE GENERIC SET lft = lft + CASE WHEN lft BETWEEN s_lft AND s_rgt THEN diff_when_inside_sourcetree WHEN lft BETWEEN ext_bound_1 AND ext_bound_2 THEN diff_when_next_sourcetree ELSE 0 END , rgt = rgt + CASE WHEN rgt BETWEEN s_lft AND s_rgt THEN diff_when_inside_sourcetree WHEN rgt BETWEEN ext_bound_1 AND ext_bound_2 THEN diff_when_next_sourcetree ELSE 0 END WHERE tree_id=source_node_tree; COMMIT; END; SET sql_mode=@OLD_SQL_MODE; DROP PROCEDURE IF EXISTS Baobab_GENERIC_MoveSubtree_Different_Trees; CREATE PROCEDURE Baobab_GENERIC_MoveSubtree_Different_Trees( IN node_id_to_move INTEGER UNSIGNED, IN reference_node INTEGER UNSIGNED, IN move_as_first_sibling BOOLEAN ) LANGUAGE SQL DETERMINISTIC main:BEGIN DECLARE s_lft INTEGER UNSIGNED; DECLARE s_rgt INTEGER UNSIGNED; DECLARE ref_lft INTEGER UNSIGNED; DECLARE ref_rgt INTEGER UNSIGNED; DECLARE source_node_tree INTEGER UNSIGNED; DECLARE ref_node_tree INTEGER UNSIGNED; START TRANSACTION; /* select tree, left and right of the node to move */ SELECT tree_id,lft, rgt INTO source_node_tree, s_lft, s_rgt FROM GENERIC WHERE id = node_id_to_move; /* The current select will behave differently whether we're moving the node as first sibling or not. If move_as_first_sibling, ref_lft will have the value of the "lft" field of node_id_to_move at end of move (ref_rgt here is discarded) else ref_lft and ref_rgt will have the values of the node before node_id_to_move at end of move */ SELECT tree_id, IF(move_as_first_sibling,lft+1,lft), rgt INTO ref_node_tree, ref_lft, ref_rgt FROM GENERIC WHERE id = reference_node; IF (move_as_first_sibling) THEN BEGIN /* create a gap in the destination tree to hold the subtree */ UPDATE GENERIC SET lft = CASE WHEN lft < ref_lft THEN lft ELSE lft + s_rgt-s_lft+1 END, rgt = CASE WHEN rgt < ref_lft THEN rgt ELSE rgt + s_rgt-s_lft+1 END WHERE tree_id=ref_node_tree AND rgt >= ref_lft; /* move the subtree to the new tree */ UPDATE GENERIC SET lft = ref_lft + (lft-s_lft), rgt = ref_lft + (rgt-s_lft), tree_id = ref_node_tree WHERE tree_id = source_node_tree AND lft >= s_lft AND rgt <= s_rgt; END; ELSE BEGIN /* create a gap in the destination tree to hold the subtree */ UPDATE GENERIC SET lft = CASE WHEN lft < ref_rgt THEN lft ELSE lft + s_rgt-s_lft+1 END, rgt = CASE WHEN rgt <= ref_rgt THEN rgt ELSE rgt + s_rgt-s_lft+1 END WHERE tree_id=ref_node_tree AND rgt > ref_rgt; /* move the subtree to the new tree */ UPDATE GENERIC SET lft = ref_rgt+1 + (lft-s_lft), rgt = ref_rgt+1 + (rgt-s_lft), tree_id = ref_node_tree WHERE tree_id = source_node_tree AND lft >= s_lft AND rgt <= s_rgt; END; END IF; /* close the gap in the source tree */ CALL Baobab_GENERIC_Close_Gaps(source_node_tree); COMMIT; END; /* ########################## */ /* ####### CLOSE GAPS ####### */ /* ########################## */ DROP PROCEDURE IF EXISTS Baobab_GENERIC_Close_Gaps; CREATE PROCEDURE Baobab_GENERIC_Close_Gaps( IN choosen_tree INTEGER UNSIGNED) LANGUAGE SQL DETERMINISTIC BEGIN UPDATE GENERIC SET lft = (SELECT COUNT(*) FROM ( SELECT lft as seq_nbr FROM GENERIC WHERE tree_id=choosen_tree UNION ALL SELECT rgt FROM GENERIC WHERE tree_id=choosen_tree ) AS LftRgt WHERE tree_id=choosen_tree AND seq_nbr <= lft ), rgt = (SELECT COUNT(*) FROM ( SELECT lft as seq_nbr FROM GENERIC WHERE tree_id=choosen_tree UNION ALL SELECT rgt FROM GENERIC WHERE tree_id=choosen_tree ) AS LftRgt WHERE tree_id=choosen_tree AND seq_nbr <= rgt ) WHERE tree_id=choosen_tree; END
  20. Hello. The problem I'm having with the link you sent me is, how do they determine the left and right values? since i cannot just insert any value to them. thanks
  21. Hi kicken. I've read the link you sent, i think changing to a nested set model will do the job, but how can i switch my database to a nested set model with my given fields or any other better way. Thanks
  22. for instance I give 4 points on first tree and 3points on second tree, 2points on third tree and above.
  23. hi guys. i want to implement a referral system. a member can only refer using a form in the memebers area. on the referral form, i have a hidden field which is his referral id and a unique code (md5 generated link) and a field for the email address he wants to refer. once he sends the mail, a referal link (md5 generated, for uniqueness and to curb cheating) is sent to the email so that once he clicks, it takes him/her to the registration area. on my database table referrer_uid - the unique id of person referring someone referred_uid - the unique id of person being referred ref_code - the md5 generated code which is used on the link sent referred_email - the email address of the person being referred status - once a member sends a refer link, status is set to Referal sent date_referred - the date the refering took place date_accepted - the day the referred was accepted (i dont want this to change on clicking a referal link or registration cos not everyone gets accepted to avoid spurious referals) my question is how do i create a traversal tree with this. i read about traversal tree on sitepoint but when i tried to implement the examples, it didnt work for me and i noticed it was an old post. note: i intend giving points based on the child/tree and it could be as deep as possible. also if my method is wrong, ideas are higly appreciated. thanks
  24. I f you could represent what you saying with example codes, it'll be better
  25. thanks all. I managed to get it working, mightn't be the best of approaches but it solved my problem. I'm replying via my mobile so sending the code on how I did it will be later. but basically, I created another table for it with the columns I need and did an insert if the table is empty and a while to check if it is not. I assigned a value of 0 to point if the variable exists and 1 if not. thanks all. topic should be marked solved for best answer, emmm. I guess all are useful
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.