ВыходВход

Меню сайта

Категории статей
Теория [1]
Древовидные структуры данных. Методология, описание
Использование в SQL DB [0]
Решения используемые в SQL DB
Использование в Perl [7]
Применение технологии Nested Sets в Perl программировании
Использование в PHP [2]
Применение технологии Nested Sets в PHP программировании

Меню пользователя

Поиск по статьям

Друзья сайта

Класс PHP или гонки слепых котят - 2. Управление (часть первая)
» Каталог статей » Использование в PHP
Класс PHP или гонки слепых котят - 2. Управление (часть первая)

Класс PHP или гонки слепых котят - 2. Управление (часть первая)

4. Управление деревом

И вот, наконец, можно заняться управлением дерева. По структуре и принципу класс такой же как и модуль Perl, единственные отличия в операторах и специфицеских особенностях языка. Итак, функции, которые мы включим в класс:

  • InsertUnit - создание узла;
  • DeleteUnit - удаление узла и подчиненных;
  • SetUnitUnder - перемещение узла в подчинение другому;
  • SetUnitNear - перемещение узла рядом с другим;
  • SetUnitLevel - изменение уровня узла (одни уровень вверх(вниз));
  • SetUnitOrder - изменение порядка узла в пределах подчинения;
  • _move_unit - внутренняя процедура перемещения узла и подчиненных;

Схемы и принципы описаны в предыдущих статьях,  поэтому можно смело начинать писать код...

4.1. Создание (вставка) узла

function InsertUnit ($under = 'root', $tree = 1, $order) {
    if (!is_numeric($under)) {$under = 'root';}
    if (!is_numeric($tree)) {$tree = 1;}
    if ($under == 'root') {
        $level = 1;
        if ((isset($order) && $order == 'top') || $this->order == 'T') {
            $key = 1;
        } else {
            $sql = 'SELECT MAX('.$this->right.') + 1 AS nums
            FROM '
.$this->table.
            ($this->type == 'M' ? ' WHERE '.$this->multi.' = '.$tree : '');
            if (($query = mysql_query($sql)) &&
                (mysql_num_rows($query) == 1) &&
                ($Data = mysql_fetch_array($query))) {$key = $Data['nums'];}
            else {$key = 1;}
        }
    } else {
        $sql = 'SELECT '.$this->left.' AS lk, '.
                         $this->right.' AS rk, '.
                         $this->level.'AS lv'.
                        ($this->type == 'M' ? ', '.$this->multi.' AS cl ' : '').
              ' FROM '.$this->table.' WHERE '.$this->id.' = '.$under;
        if (($mysql_query = mysql_query($sql)) &&
            (mysql_num_rows($mysql_query) == 1) &&
            ($Data = mysql_fetch_array($mysql_query))) {
                $level = $Data['lv'] + 1;
                if ($this->type == 'M') {$tree = $Data['cl'];}
                if ((isset($order) && $order == 'top') || $this->order == 'T') {
                    $key = $Data['cl'];
                }
        } else {trigger_error('ERR! Неправильный ID родительского узла!');}
    }
    $update = 'UPDATE '.$this->table.' SET '.
                    $this->right.' = '.$this->right.' + 2, '.
                    $this->left.' = CASE WHEN '.$this->left.' >= '.$key.
                                       ' THEN '.$this->left.' + 2
                                         ELSE '
.$this->left.' END
               WHERE '
.$this->right.' >= '.$key.
                   ($this->type == 'M' ? ' AND '.$this->multi.' = '.$tree : '');
    mysql_query($update);
// Список полей
    $update = 'INSERT INTO '.$this->table.
                ' ('.$this->left.', '.
                     $this->right.', '.
                     $this->level.
                    ($this->type == 'M' ? ', '.$this->multi : '').
             ') VAUES ('.$key.', '.($key + 1).', '.$level.
                    ($this->type == 'M' ? ', '.$tree.')' : ')');
// Выполняем запрос
    mysql_query($update);
// Получаем идентификатор вставленного узла
    $sql = 'SELECT MAX('.$this->id.') FROM '.$this->table;
    $mysql_query = mysql_query($sql);
    $id = mysql_fetch_array($mysql_query);
    return $id[0];
}

4.2. Удаление узла

// Удаление узла
function DeleteUnit ($unit) {
    if (isset($unit)) {$this->SelectUnit($unit);}
    $skew_tree = $this->unit['right'] - $this->unit['left'] + 1;
    $update = 'DELETE FROM '.$this->table.'
               WHERE '
.$this->left.'>='.$this->unit['left'].' AND '.
                       $this->right.'<='.$this->unit['right'].
                       ($this->type == 'M' ? ' AND '.$this->multi.'='.$this->unit['multi'] : '');
    mysql_query($update);
    $update = 'UPDATE '.$this->table.'
               SET '
.$this->left.'= CASE WHEN '.$this->left.'>'.$this->unit['left'].'
                                         THEN '
.$this->left.'-'.$skew_tree.'
                                         ELSE '
.$this->left.' END, '.
                     $this->right.'='.$this->right.'-'.$skew_tree.
             ' WHERE '.$this->right.'>'.$this->unit['right'].
                      ($this->type == 'M' ? ' AND '.$this->multi.'='.$this->unit['multi'] : '');
    mysql_query($update);
    return 1;
}

4.3. Перемещение узла

Процедуры перемещения узла начнем со стандартной, точнее, универсальной, которая, собственно, узлы и перемещает остальные процедуры просто определяют координаты перемещения. По сути, в процедуре всего два запроса, но довольно сложных.

// Внутренняя процедура перемещения узла
function _move_unit ($data = array()) {
    if ($data['near'] >= $this->unit['left'] && $data['near'] <= $this->unit['right']) {return 'ERR';}
    $skew_tree = $this->unit['right'] - $this->unit['left'] + 1;
    $skew_level = $data['level_new'] - $this->unit['level'];
// Перемещение вверх по дереву
    if ($this->unit['right'] < $data['near']) {
        $skew_edit = $data['near'] - $this->unit['left'] + 1 - $skew_tree;
        $sql = 'UPDATE '.$this->table.'
                SET '
.
                  $this->left.' = CASE WHEN '.$this->right.'<='.$this->unit['right'].' THEN '.
                    $this->left.'+'.$skew_edit.' ELSE CASE WHEN '.$this->left.'>'.$this->unit['right'].' THEN '.
                     $this->left.'-'.$skew_tree.' ELSE '.$this->left.' END END, '.
                  $this->level.' = CASE WHEN '.$this->right.'<='.$this->unit['right'].' THEN '.
                    $this->level.'+'.$skew_level.' ELSE '.$this->level.' END, '.
                  $this->right.' = CASE WHEN '.$this->right.'<='.$this->unit['right'].' THEN '.
                    $this->right.'+'.$skew_edit.' ELSE CASE WHEN '.$this->right.'<='.$data['near'].' THEN '.
                      $this->right.'-'.$skew_tree.' ELSE '.$this->right.' END END
                WHERE '
.
                  $this->right.'>'.$this->unit['left'].' AND '.
                  $this->left.'<='.$data['near'].
                ($this->type == 'M' ? ' AND '.$this->multi.'='.$this->unit['multi'] : '');
        $mysql_query = mysql_query($sql);
    } else {
// Перемещение вниз по дереву
        $skew_edit = $data['near'] - $this->unit['left'] + 1;
        $sql = 'UPDATE '.$this->table.'
                SET '
.
                  $this->right.' = CASE WHEN '.$this->left.'>='.$this->unit['left'].' THEN '.
                    $this->right.'+'.$skew_edit.' ELSE CASE WHEN '.$this->right.'<'.$this->unit['left'].' THEN '.
                      $this->right.'+'.$skew_tree.' ELSE '.$this->right.' END END, '.
                  $this->level.' = CASE WHEN '.$this->left.'>='.$this->unit['left'].' THEN '.
                    $this->level.'+'.$skew_level.' ELSE '.$this->level.' END, '.
                  $this->left.' = CASE WHEN '.$this->left.'>='.$this->unit['left'].' THEN '.
                    $this->left.'+'.$skew_edit.' ELSE CASE WHEN '.$this->left.'>'.$data['near'].' THEN '.
                      $this->left.'+'.$skew_tree.' ELSE '.$this->left.' END END
                WHERE '
.
                  $this->right.'>'.$data['near'].' AND '.
                  $this->left.'<'.$this->unit['right'].
                  ($this->type == 'M' ? ' AND '.$this->multi.'='.$this->unit['multi'] : '');
        $mysql_query = mysql_query($sql);
    }
    return 'OK';
}


Другие статьи по теме
Категория: Использование в PHP | Добавил: phoinix (2005-12-18) | Автор: Сергей Томулевич (aka Phoinix)
Просмотров: 3117 | Рейтинг: 3.3 |

Комментарии

 

Бесплатный конструктор сайтов - uCoz