Traverzování kolem stromu #3
Traverzování kolem stromu je jeden ze způsobů, jak ukládat stromovou strukturu dat v relační databázi. V tomto třetím díle dokončíme přesouvání uzlů a navíc doplníme naši třídu o velice jednoduchou metodu pro přejmenování uzlů.
Článek opět volně navazuje na předchozí články o Traverzování kolem stromu ( #1, #2 ). V minulém článku jsme se začali věnovat přesouvání jednotlivých uzlů ve stromu.
Při traverzování nám vzniká strom dost složitý pro editaci uzlů, protože si musíme neustále hlídat indexy. U přesouvání uzlů je to o to obtížnější, že musíme přečíslování většinou rozdělit do několika částí.
V minulém článku jsme si řekli, že nám může vznikat několik případů při přesouvání:
První z nich nastane v případě že jsou dva uzly hned vedle sebe a neobsahují další vnořené uzly. Tento případ je nejjednodušší a stačí pouze přehodit indexy u těchto uzlů.
Další případ nastane v případě, že dva uzly jsou vedle sebe, ale mají v sobě vnořené další uzly. V tomto případě musíme navíc změnit indexy i na uzlech, které jsou uvnitř uzlů, které přesouváme. Je to logické, protože pravý a levý uzel nemusí obsahovat stejný počet vnořených uzlů a tím pádem musí být změněny všechny indexy.
Nejsložitější případ nastane v situaci, kdy oba uzly které přesouváme obsahují další uzly a navíc jsou další uzly mezi nimi. V tomto případě musíme změnit indexy ve všech poduzlech pravého uzlu, ve všech poduzlech levého uzlu a nakonec ještě změnit indexy ve všech uzlech, které jsou mezi těmito dvěma uzly.
Toto jsou tří základní případy a pokud všechny ošetříme, nebude problém ve stromu přesouvat.
Přesouvání uzlů ve stromu
Dost bylo teorie a nyní se podíváme na praxi. Nebudeme se zabývat jednotlivými případy přesouvání ale vytvoříme si univerzální metody, které nám ošetří automaticky všechny tři případy bez ohledu na to, zda jsou uzly hned vedle sebe, nebo nikoli.
Metodu pro přesun pojmenujeme changeTree a jako vstupní parametry budou levé indexy mezi sebou přesouvaných uzlů. Tato metoda nebude zatím nic přesouvat, ale pouze připraví proměnné pomocí dalších metod, které jsme si vytvořili minule:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
function changeTree($left1, $left2){ if( ($svalues = self::_checkingTree($left1, $left2)) == 0 ) return 0; $this->parametrs[ 'parent' ] = $svalues[0]; $this->parametrs[ 'left1' ] = ( $left1 < $left2 ? $left1 : $left2 ); $this->parametrs[ 'right1' ] = ( $svalues[2] < $svalues[3] ? $svalues[2] : $svalues[3] ); $this->parametrs[ 'left2' ] = ( $left1 < $left2 ? $left2 : $left1 ); $this->parametrs[ 'right2' ] = ( $svalues[2] < $svalues[3] ? $svalues[3] : $svalues[2] ); switch( self::_edit_TREE()){ case 0 : return 0; break; case -1 : return -1; break; default: return 1; } } |
Metoda vytvoří pole $parametrs, které bude obsahovat levé a pravé indexy uzlů pro přesun. Pro zjištění indexů použijeme metodu _checkingTree, která zároveň kontroluje, zda mají oba uzly stejnou úroveň vnoření ve stromu
Na konci je volána metoda _edit_TREE, která už bude přesouvat uzly. Než si ji napíšeme budeme potřebovat další metodu, která nám zjistí ID uzlů, které leží v prvním přesouvaném podstromu a mezi oběma přesouvanými stromy, pokud takové existují. Vždy musí existovat minimálně jeden takový uzel:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
function _select_ids($left, $left2){ $select = "SELECT id_traverz, traverz_left FROM " . $this->table_name . " WHERE traverz_left > '" . ( $left - 1 ) . "' AND traverz_right < '" . $left2 . "' ORDER BY traverz_left"; $data = mysql_query($select, $this->link); if( mysql_num_rows($data) == 0 ) return 0; while( $row = mysql_fetch_object($data) ){ $this->ids[$row->traverz_left] = $row->id_traverz; } return ( sizeof($this->ids) > 0 ? 1 : 0 ); } |
Všimněte si, že pokud se některá operace nepodaří, metoda vždy vrací hodnotu „nula“ a nic dalšího se nestane.
Tím máme hotový základ a můžeme se vrhnout na metodu pro přesun.
Meodta _edit_TREE nejprve přečísluje pravý podstrom, který leží více vpravo ( má větší pravý index ) na místo levého podstromu, potom zjistí, zda existují mezi těmito dvěma podstromy další uzly a v případě že ano, přečísluje je.
Nakonec přečísluje i levý strom na místo pravého.
Žádné další uzly přečíslovávat nemusí (tím myslím uzly které jsou před levým podstromem nebo za pravým podstromem), protože tyto uzly musí i dále souhlasit tak jako byli před přesouváním.
Funkce _edit_TREE:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
function _edit_TREE(){ if( self::_select_ids($this->parametrs['left1'], $this->parametrs['left2']) == 0 ) return 0; $right_tree = $this->parametrs['left2'] - $this->parametrs['left1']; $update = "UPDATE " . $this->table_name . " SET traverz_left = traverz_left - '" . $right_tree . "', traverz_right = traverz_right - '" . $right_tree . "' WHERE traverz_left > '" . ( $this->parametrs['left2'] - 1 ) . "' AND traverz_right < '" . ( $this->parametrs['right2'] + 1 ) . "'"; mysql_query($update, $this->link); if( ( $mysql_affected_rows = mysql_affected_rows($this->link)) < 1 ) return 0; $left_array = ( $this->parametrs['right1'] - $this->parametrs['left1'] - 1 ) / 2 ; $right_array = ( $this->parametrs['right2'] - $this->parametrs['left2'] - 1 ) / 2 ; if( $left_array != $right_array ){ if( ($num_rows = self::_edit_bettwen( $mysql_affected_rows)) < 0 ) return -1; } else $num_rows = 0; //$num_rows = $num_rows - 1; $p_a = (abs( $mysql_affected_rows ) + abs( $num_rows )) * 2; reset($this->ids); $ids = array(); foreach( $this->ids as $id => $value ) if( ($id <= $this->parametrs['right1']) && ($id >= $this->parametrs['left1']) ) $ids[] = $value; $update = "UPDATE " . $this->table_name . " SET traverz_left = (traverz_left + " . $p_a . "), traverz_right = traverz_right + " . $p_a . " WHERE id_traverz IN( "; foreach( $ids as $value ) $update .= $value . ','; $update = substr($update, 0, -1) . ') LIMIT ' . sizeof($ids) . ';'; mysql_query($update, $this->link); if( mysql_error() != NULL ){ return -1; } else return 1; } |
Všimněte si, že metoda volá další metodu, _edit_bettwen. Tato metoda bude právě přečíslovávat uzly mezi dvěma stromu a musíme ji nyní dopsat:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
function _edit_bettwen($affected_rows){ if( ($this->parametrs['right1'] + 1 ) == $this->parametrs['left2'] ) return 0; $p_a = ( ($this->parametrs['left1']) + (2 * $affected_rows)) - ($this->parametrs['right1'] + 1 ); if( $p_a == 0 ) return 0; reset($this->ids); foreach($this->ids as $id => $value) if( ($id > $this->parametrs['right1']) && ($id < $this->parametrs['left2']) ) $ids[] = $value; $update_value = ( $p_a > 0 ? ' + ' : ' - ') . "'" . abs($p_a) . "'"; $update = "UPDATE " . $this->table_name . " SET traverz_left = (traverz_left " . $update_value . "), traverz_right = traverz_right " . $update_value . " WHERE id_traverz IN( "; foreach( $ids as $value ) $update .= $value . ','; $update = substr($update, 0, -1) . ') LIMIT ' . sizeof($ids) . ';'; mysql_query($update, $this->link); return mysql_affected_rows($this->link); } |
Volána by nebyla, kdyby dva podstromy, které přesouváme měli stejný počet poduzlů. V takovém případě by indexy mezi stromy souhlasily. Bohužel toto nemusí být vždy pravda. Metoda _edit_bettwen nám tento případ zabezpečí.
Posun nahoru || dolů
Pro případ, že bychom chtěli přesouvat uzly jenom o jeden uzel vedle si můžeme vytvořit dvě jednoduché metody, které budou využívat hotovou metodu _edit_TREE, ovšem nikdy se nebude volat metoda _edit_bettwen.
Abychom si zjednodušili práci s uživatelským prostředím, tak si vytvoříme ještě jednu metodu, která bude mít první vstupní parametr levý index přesouvaného uzlu a druhý bude směr, kam se bude přesouvat.
V metodě jsou použity výrazy nahoru a dolů, toto je myšleno podle velikosti levého indexu:
1 2 3 4 5 6 7 8 9 |
function moveTree( $left, $shift ){ switch( $shift ){ case 'up' : return self::_moveUpTree( $left ); break; case 'down' : return self::_moveDownTree( $left ); break; default: return 0; } return 1; } |
Volány jsou dvě metody, které si budou velmi podobné. Nejprve se zjistí levý index uzlu na který chceme přesouvat a v případě že takový uzel existuje a vyhovuje, volá se metoda changeTree:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
function _moveUpTree($left){ $parent = self::select_parent( $left ); $select = "SELECT MAX(traverz_left) FROM " . $this->table_name . " WHERE( traverz_left < '" . $left . "') AND ( traverz_parent = '" . ( $parent - 1 ) . "')"; $data = mysql_query( $select, $this->link ); if( mysql_num_rows( $data ) == 0 ) return 0; $left2 = mysql_result( $data, 0, 0 ); return self::changeTree( $left2, $left); } function _moveDownTree( $left ){ $parent = self::select_parent( $left ); $select = "SELECT MIN( traverz_left) FROM " . $this->table_name . " WHERE( traverz_left > '" . $left . "') AND( traverz_parent = '" . ( $parent - 1 ) . "')"; $data = mysql_query( $select, $this->link ); if( mysql_num_rows( $data ) == 0 ) return 0; $left2 = mysql_result( $data, 0, 0 ); return self::changeTree( $left2, $left); } |
Tím máme hotovu celou operaci přesouvání uzlů. Na závěr si ještě doplníme naši třídu o jednoduché přejmenování uzlu.
Přejmenování uzlu
Metoda pro přejmenování je v naší třídě jenom jako takové doplnění, protože tuto funkci můžete v budoucnu potřebovat:
1 2 3 4 5 6 7 8 9 10 11 12 |
function renameCell($new_name, $left){ $update = "UPDATE " . $this->table_name . " SET traverz_name = '" . trim(htmlspecialchars( $new_name )) . "', url = '" . $_REQUEST['url'] . "' WHERE traverz_left = '" . intval( $left ) . "' AND lang = '" . $_SESSION['lang_prefix'] . "' LIMIT 1;"; mysql_query($update, $this->link); return ( mysql_affected_rows( $this->link ) == 1 ? 1 : 0 ); } |
V příští části se podíváme na ovládání celé třídy. Vytvoříme si funkce pro vypsání stromu a vytvoříme si jednoduchý kód pro snadné ovládání přesunu a podobně.
Na závěr se zase můžeme podívat co máme hotové:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 |
class traverz extends connect{ public $traverz_right = NULL; public $id_traverz = NULL; public $parametrs = array(); public $ids = array(); public $table = NULL; function __construct( $table_name ){ $this->table_name = $table_name; parent::__construct(); self::_check_num_of_rows(); } function _check_num_of_rows(){ $select = "SELECT COUNT(*) FROM " . $this->table_name . ""; if( mysql_result( mysql_query( $select, $this->link ), 0, 0) == 0 ){ self::_insert_first(); return 0; } else{ return 0; } } function _insert_first(){ $insert = "INSERT INTO " . $this->table_name . "( traverz_name, traverz_parent, traverz_left, traverz_right ) VALUES( 'HOME', '0', '1', '2' )"; mysql_query($insert, $this->link); return ( mysql_affected_rows($this->link) == 1 ? 1 : 0); } function _update_tree($id, $left){ $sql[] = "UPDATE " . $this->table_name . " SET traverz_left = (traverz_left + 2) WHERE ( traverz_left > '" . $left . "' ) AND id_traverz != '" . $id . "'"; $sql[] = "UPDATE " . $this->table_name . " SET traverz_right = (traverz_right + 2) WHERE ( traverz_right > '" . ($left - 1) . "' ) AND id_traverz != '" . $id . "'"; foreach($sql as $value){ mysql_query($value, $this->link); } if(mysql_affected_rows($this->link) == 0 ) return 0; } function select_parent($left, $info = 0){ $select = "SELECT traverz_parent, traverz_right, id_traverz FROM " . $this->table_name . " WHERE traverz_left = '" . $left . "' LIMIT 1;"; $data = mysql_query($select, $this->link); if( $info == 1 ){ $this->traverz_right = @mysql_result($data, 0, 1); $this->id_traverz = @mysql_result( $data, 0, 2 ); } return ( @mysql_result($data, 0, 0) + 1 ); } function _setup_position( $position ){ switch( $position ){ case 'h' : return 0; break; case 'e' : return 1; break; default: return 0; } } function addTree ( $name, $left, $position = 0 ){ if( gettype( $position ) == 'string' ) $position = self::_setup_position( $position ); $position = abs( intval( $position) ); if( $position > 2 ) return 0; $parent = self::select_parent($left, 1); switch( $position ){ case 0 : { if( self::_addTree_h( $name, $left, $parent ) == 1 ) return 1; else return 0; break; } case 1 :{ if( self::_addTree_e( $name, $left, $parent, ( $this->traverz_right - 1 ) ) == 1 ) return 1; else return 0; break; } } return 1; } function _addTree_h( $name, $left, $parent ){ $insert = "INSERT INTO " . $this->table_name . "( traverz_name, traverz_parent, traverz_left, traverz_right ) VALUES( '" . trim( htmlspecialchars($name) ) . "', '" . intval( $parent ) . "', '" . ( intval( $left ) + 1 ) . "', '" . ( intval( $left ) + 2 ) . "' );"; mysql_query($insert, $this->link); if( mysql_affected_rows($this->link) == 1 ) return (self::_update_tree(mysql_insert_id(), $left) == 1 ? 1 : 0 ); else return 0; } function _addTree_e( $name, $left, $parent ){ $insert = "INSERT INTO " . $this->table_name . "( traverz_name, traverz_parent, traverz_left, traverz_right ) VALUES( '" . trim( htmlspecialchars( $name ) ) . "', '" . intval( $parent ) . "', '" . intval( $this->traverz_right ) . "', '" . ( intval( $this->traverz_right ) + 1 ) . "' );"; mysql_query($insert, $this->link); if( mysql_affected_rows($this->link) == 1 ) return (self::_update_tree(mysql_insert_id(), $this->traverz_right) == 1 ? 1 : 0 ); else return 0; } function _renumberTree($left){ $update[] = "UPDATE " . $this->table_name . " SET traverz_left = (traverz_left - 2) WHERE ( traverz_left > '" . intval( $left ) . "')"; $update[] = "UPDATE " . $this->table_name . " SET traverz_right = (traverz_right - 2) WHERE ( traverz_right > '" . intval( $left + 1 ) . "')"; foreach($update as $value){ mysql_query( $value, $this->link ); if( mysql_affected_rows( $this->link ) < 0 ) return 0; } return 1; } function _checkTree( $left, $parent ){ $select = "SELECT COUNT(*) FROM " . $this->table_name . " WHERE ( traverz_left BETWEEN '" . $left . "' AND '" . $this->traverz_right . "' ) "; $num = intval( @mysql_result(mysql_query($select, $this->link), 0, 0) - 1 ); return ( $num == 0 ? 1 : 0 ); } function deleteTree( $left, $id ){ $left = intval( $left ); $id = intval( $id ); $parent = self::select_parent($left, 1); if(self::_checkTree($left, $parent) == 0) return -1; if( self::_renumberTree($left) == 0 ) return 0; $delete = "DELETE FROM " . $this->table_name . " WHERE id_traverz = '" . $id . "' LIMIT 1;"; mysql_query($delete, $this->link); return ( mysql_affected_rows( $this->link ) == 0 ? 0 : 1 ); } function _select_parent_check($left1, $left2){ $select = "SELECT traverz_parent, traverz_right FROM " . $this->table_name . " WHERE traverz_left IN ('" . $left1 . "', '" . $left2 . "') ORDER BY traverz_left;"; if( ( $data = mysql_query($select, $this->link) ) == FALSE ){ return 0; } return array( @mysql_result($data, 0, 0), @mysql_result($data, 1, 0), @mysql_result($data, 0, 1), @mysql_result($data, 1, 1) ); } function _checkingTree($left1, $left2){ $parents = self::_select_parent_check($left1, $left2); if( sizeof($parents) != 4 ) return 0; else if( $parents[0] != $parents[1] ) return 0; $select = "SELECT traverz_parent, traverz_left, traverz_right FROM " . $this->table_name . " WHERE traverz_left < '" . ( $left1 < $left2 ? $left1 : $left2) . "' AND traverz_parent = '" . ($parents[0] - 1) . "' ORDER BY traverz_left DESC LIMIT 1;"; $data = mysql_query($select, $this->link); if( mysql_error() != NULL ) return 0; $h1 = @mysql_result($data, 0, 1); $h2 = @mysql_result($data, 0, 2); //test left1 if( !(($h1 < $left1) && ($h2 > $left2)) ){ return 0; } //test left2 else if( !(($h1 < $left2) && ($h2 > $left2)) ){ return 0; } else { return $parents; } } function changeTree($left1, $left2){ if( ($svalues = self::_checkingTree($left1, $left2)) == 0 ) return 0; $this->parametrs[ 'parent' ] = $svalues[0]; $this->parametrs[ 'left1' ] = ( $left1 < $left2 ? $left1 : $left2 ); $this->parametrs[ 'right1' ] = ( $svalues[2] < $svalues[3] ? $svalues[2] : $svalues[3] ); $this->parametrs[ 'left2' ] = ( $left1 < $left2 ? $left2 : $left1 ); $this->parametrs[ 'right2' ] = ( $svalues[2] < $svalues[3] ? $svalues[3] : $svalues[2] ); switch( self::_edit_TREE()){ case 0 : return 0; break; case -1 : return -1; break; default: return 1; } } function _select_ids($left, $left2){ $select = "SELECT id_traverz, traverz_left FROM " . $this->table_name . " WHERE traverz_left > '" . ( $left - 1 ) . "' AND traverz_right < '" . $left2 . "' ORDER BY traverz_left"; $data = mysql_query($select, $this->link); if( mysql_num_rows($data) == 0 ) return 0; while( $row = mysql_fetch_object($data) ){ $this->ids[$row->traverz_left] = $row->id_traverz; } return ( sizeof($this->ids) > 0 ? 1 : 0 ); } function _edit_TREE(){ if( self::_select_ids($this->parametrs['left1'], $this->parametrs['left2']) == 0 ) return 0; $right_tree = $this->parametrs['left2'] - $this->parametrs['left1']; $update = "UPDATE " . $this->table_name . " SET traverz_left = traverz_left - '" . $right_tree . "', traverz_right = traverz_right - '" . $right_tree . "' WHERE traverz_left > '" . ( $this->parametrs['left2'] - 1 ) . "' AND traverz_right < '" . ( $this->parametrs['right2'] + 1 ) . "' "; mysql_query($update, $this->link); if( ( $mysql_affected_rows = mysql_affected_rows($this->link)) < 1 ) return 0; $left_array = ( $this->parametrs['right1'] - $this->parametrs['left1'] - 1 ) / 2 ; $right_array = ( $this->parametrs['right2'] - $this->parametrs['left2'] - 1 ) / 2 ; if( $left_array != $right_array ){ if( ($num_rows = self::_edit_bettwen( $mysql_affected_rows)) < 0 ) return -1; } else $num_rows = 0; //$num_rows = $num_rows - 1; $p_a = (abs( $mysql_affected_rows ) + abs( $num_rows )) * 2; reset($this->ids); $ids = array(); foreach( $this->ids as $id => $value ) if( ($id <= $this->parametrs['right1']) && ($id >= $this->parametrs['left1']) ) $ids[] = $value; $update = "UPDATE " . $this->table_name . " SET traverz_left = (traverz_left + " . $p_a . "), traverz_right = traverz_right + " . $p_a . " WHERE id_traverz IN( "; foreach( $ids as $value ) $update .= $value . ','; $update = substr($update, 0, -1) . ') LIMIT ' . sizeof($ids) . ';'; mysql_query($update, $this->link); if( mysql_error() != NULL ){ return -1; } else return 1; } function _edit_bettwen($affected_rows){ if( ($this->parametrs['right1'] + 1 ) == $this->parametrs['left2'] ) return 0; $p_a = ( ($this->parametrs['left1']) + (2 * $affected_rows)) - ($this->parametrs['right1'] + 1 ); if( $p_a == 0 ) return 0; reset($this->ids); foreach($this->ids as $id => $value) if( ($id > $this->parametrs['right1']) && ($id < $this->parametrs['left2']) ) $ids[] = $value; $update_value = ( $p_a > 0 ? ' + ' : ' - ') . "'" . abs($p_a) . "'"; $update = "UPDATE " . $this->table_name . " SET traverz_left = (traverz_left " . $update_value . "), traverz_right = traverz_right " . $update_value . " WHERE id_traverz IN( "; foreach( $ids as $value ) $update .= $value . ','; $update = substr($update, 0, -1) . ') LIMIT ' . sizeof($ids) . ';'; mysql_query($update, $this->link); return mysql_affected_rows($this->link); } function moveTree( $left, $shift ){ switch( $shift ){ case 'up' : return self::_moveUpTree( $left ); break; case 'down' : return self::_moveDownTree( $left ); break; default: return 0; } return 1; } function _moveUpTree($left){ $parent = self::select_parent( $left ); $select = "SELECT MAX(traverz_left) FROM " . $this->table_name . " WHERE( traverz_left < '" . $left . "') AND ( traverz_parent = '" . ( $parent - 1 ) . "')"; $data = mysql_query( $select, $this->link ); if( mysql_num_rows( $data ) == 0 ) return 0; $left2 = mysql_result( $data, 0, 0 ); return self::changeTree( $left2, $left); } function _moveDownTree( $left ){ $parent = self::select_parent( $left ); $select = "SELECT MIN( traverz_left) FROM " . $this->table_name . " WHERE( traverz_left > '" . $left . "') AND( traverz_parent = '" . ( $parent - 1 ) . "')"; $data = mysql_query( $select, $this->link ); if( mysql_num_rows( $data ) == 0 ) return 0; $left2 = mysql_result( $data, 0, 0 ); return self::changeTree( $left2, $left); } function renameCell($new_name, $left){ $update = "UPDATE " . $this->table_name . " SET traverz_name = '" . trim(htmlspecialchars( $new_name )) . "', url = '" . $_REQUEST['url'] . "' WHERE traverz_left = '" . intval( $left ) . "' AND lang = '" . $_SESSION['lang_prefix'] . "' LIMIT 1;"; mysql_query($update, $this->link); return ( mysql_affected_rows( $this->link ) == 1 ? 1 : 0 ); } } |
He, a co takhle stored procedures v databazi ;). Nebylo by to praktickejsi nez ta spousta PHP kodu…
Dobry den,
uz v prvnim dile jsem psal ze vsechno bude optimalizovane pro MySQL 4.x, kde stored procedures jeste nejsou.
Ovsem o co se snazim je nastinit jak cely algoritmus funguje. Kazdy si jej muze upravit dle vlastniho uvazeni.
Tento kod bude kompatibilni jak s MySQL 4.x tak s MySQL 5.x a pokud nekdo bude chtit pouzit stored procedures tak prosim 🙂
Samozrejme by to bylo mnohem jednoduzsi a mozna i vice prehledne.
Zdravim. Velmi zaujimavy clanok, ktory mi rozsiril obzor co sa tyka ukladania dat do DB. Chcem sa opytat, kedy sa chysta dalsi diel. Vopred dik.
Dobry den, vše zálezí na volném čase, kterého se mi v poslední době nedostává. Ovšem pokusím se jej napsat co nejdříve.