класс CDBTree баг в работе метода moveAll

PhpGuest

Guest
класс CDBTree баг в работе метода moveAll

класс CDBTree баг в работе метода moveAll

Хранение древовидных структур в Базах данных в статьях - багнутый метод move All при попытке переместить ветку к тому же самому родителю - свя структура рассыпается

phpDBTree 1.3

PHP:
function moveAll($ID, $newParentId) { 
      if(!(list($leftId, $rightId, $level) = $this->getNodeInfo($ID))) die("phpDbTree error: ".$this->db->error()); 
      if(!(list($leftIdP, $rightIdP, $levelP) = $this->getNodeInfo($newParentId))) die("phpDbTree error: ".$this->db->error()); 
      if($ID == $newParentId || $leftId == $leftIdP || ($leftIdP >= $leftId && $leftIdP <= $rightId)) return false; 

      // если происходит перемещение вверх по родительской оси 
      if ($leftIdP < $leftId && $rightIdP > $rightId && $levelP < $level - 1 ) { 
         $this->sql = 'UPDATE '.$this->table.' SET ' 
            . $this->level.'=IF('.$this->left.' BETWEEN '.$leftId.' AND '.$rightId.', '.$this->level.sprintf('%+d', -($level-1)+$levelP).', '.$this->level.'), ' 
            . $this->right.'=IF('.$this->right.' BETWEEN '.($rightId+1).' AND '.($rightIdP-1).', '.$this->right.'-'.($rightId-$leftId+1).', ' 
                           .'IF('.$this->left.' BETWEEN '.($leftId).' AND '.($rightId).', '.$this->right.'+'.((($rightIdP-$rightId-$level+$levelP)/2)*2 + $level - $levelP - 1).', '.$this->right.')),  ' 
            . $this->left.'=IF('.$this->left.' BETWEEN '.($rightId+1).' AND '.($rightIdP-1).', '.$this->left.'-'.($rightId-$leftId+1).', ' 
                           .'IF('.$this->left.' BETWEEN '.$leftId.' AND '.($rightId).', '.$this->left.'+'.((($rightIdP-$rightId-$level+$levelP)/2)*2 + $level - $levelP - 1).', '.$this->left. ')) ' 
            . 'WHERE '.$this->left.' BETWEEN '.($leftIdP+1).' AND '.($rightIdP-1) 
         ; 
      } elseif($leftIdP < $leftId) { 
         $this->sql = 'UPDATE '.$this->table.' SET ' 
            . $this->level.'=IF('.$this->left.' BETWEEN '.$leftId.' AND '.$rightId.', '.$this->level.sprintf('%+d', -($level-1)+$levelP).', '.$this->level.'), ' 
            . $this->left.'=IF('.$this->left.' BETWEEN '.$rightIdP.' AND '.($leftId-1).', '.$this->left.'+'.($rightId-$leftId+1).', ' 
               . 'IF('.$this->left.' BETWEEN '.$leftId.' AND '.$rightId.', '.$this->left.'-'.($leftId-$rightIdP).', '.$this->left.') ' 
            . '), ' 
            . $this->right.'=IF('.$this->right.' BETWEEN '.$rightIdP.' AND '.$leftId.', '.$this->right.'+'.($rightId-$leftId+1).', ' 
               . 'IF('.$this->right.' BETWEEN '.$leftId.' AND '.$rightId.', '.$this->right.'-'.($leftId-$rightIdP).', '.$this->right.') ' 
            . ') ' 
            . 'WHERE '.$this->left.' BETWEEN '.$leftIdP.' AND '.$rightId 
            // !!! added this line (Maxim Matyukhin) 
            .' OR '.$this->right.' BETWEEN '.$leftIdP.' AND '.$rightId 
         ; 
      } else { 
         $this->sql = 'UPDATE '.$this->table.' SET ' 
            . $this->level.'=IF('.$this->left.' BETWEEN '.$leftId.' AND '.$rightId.', '.$this->level.sprintf('%+d', -($level-1)+$levelP).', '.$this->level.'), ' 
            . $this->left.'=IF('.$this->left.' BETWEEN '.$rightId.' AND '.$rightIdP.', '.$this->left.'-'.($rightId-$leftId+1).', ' 
               . 'IF('.$this->left.' BETWEEN '.$leftId.' AND '.$rightId.', '.$this->left.'+'.($rightIdP-1-$rightId).', '.$this->left.')' 
            . '), ' 
            . $this->right.'=IF('.$this->right.' BETWEEN '.($rightId+1).' AND '.($rightIdP-1).', '.$this->right.'-'.($rightId-$leftId+1).', ' 
               . 'IF('.$this->right.' BETWEEN '.$leftId.' AND '.$rightId.', '.$this->right.'+'.($rightIdP-1-$rightId).', '.$this->right.') ' 
            . ') ' 
            . 'WHERE '.$this->left.' BETWEEN '.$leftId.' AND '.$rightIdP 
            // !!! added this line (Maxim Matyukhin) 
            . ' OR '.$this->right.' BETWEEN '.$leftId.' AND '.$rightIdP 
         ; 
      } 
      return $this->db->query($this->sql) or die("phpDbTree error: ".$this->db->error()); 
   } // func
 

Макс

Старожил PHPClub
ветку к тому же самому родителю - свя структура рассыпается
то есть если $newParentId равен старому родителю ?
Если да, то такое можешь и сам исправить :
делаешь запрос для получения родителя и сравниваешь его id с $newParentId.
 

PhpGuest

Guest
Автор оригинала: Макс
то есть если $newParentId равен старому родителю ?
Если да, то такое можешь и сам исправить :
делаешь запрос для получения родителя и сравниваешь его id с $newParentId.
именно.
исправиьт я могу только запретом подобного переноса.
 

Макс

Старожил PHPClub
ИМХО если в условый оператор :
PHP:
if($ID == $newParentId || $leftId == $leftIdP || ($leftIdP >= $leftId && $leftIdP <= $rightId)) return false;
добавить еще одно условие:
PHP:
if($ID == $newParentId || $leftId == $leftIdP || $leftId == $leftIdP+1 || ($leftIdP >= $leftId && $leftIdP <= $rightId)) return false;
то должно работать (проверять лень :))
 

PhpGuest

Guest
ща проверю у мня редкатор каталога на етой dbtree построен

-~{}~ 12.10.04 18:54:

нифига - тот же эффект

-~{}~ 12.10.04 18:56:

$leftId == $leftIdP+1 ? эт тока для крайних левых узлов по моему годиться
 

Макс

Старожил PHPClub
PHP:
if(
     $ID == $newParentId || 
     $leftId == $leftIdP ||
     ($leftIdP >= $leftId && $leftIdP <= $rightId) ||
      ($level == $levelP+1 && $leftId > $leftIdP && $rightId < $rightIdP)

) return false;
а так ?

-~{}~ 12.10.04 19:01:

$leftId == $leftIdP+1 ? эт тока для крайних левых узлов по моему годиться
угу, я уже понял
 

PhpGuest

Guest
гуд :)


работаеть, thx

-~{}~ 12.10.04 19:07:

надо бы новый пакет собрать этого cdbtree со всеми изменениями и с дополнениями (в особенности включить метод изменения порядка следования узлов в уровне ) и можно продавать )
 
Сверху