Перемещение узлов Nested Sets. Формирование Sql запроса

Тема в разделе "SQL", создана пользователем artkl, 30 июн 2010.

  1. artkl

    artkl Гость

    Здравствуйте уважаемые программисты.
    Обращаюсь к вам, так как сам дурак и не могу понять суть формирования sql запроса в БД (MySql), для перемещения узлов дерева, упакованных по методу nested sets.
    Вообщем есть класс управления деревьями, часть которого я и выкладываю:

    Код (PHP):
    <?php
    /**
    * Класс обработки иерархии в БД (nested sets)
    */

    Class Tree
    {
    var $CI; //Глобальный объект ядра CI
    //Основные поля используемые в таблице
    var $t_id           = 't_id'; //уникальный индетификатор каждого узла
    var $right_key      = 'right_key'; //правый ключ
    var $left_key        = 'left_key'; //левый ключ
    var $level           = 'level';
    var $name            = 'name'; //имя узла
    var $description    = 'description'; //описание узла

    var $table_name = 'taxonomy';

    var $return         = array(); // Сообщения возвращаемые после выполнения

    function __construct()
    {
    $this->CI =& get_instance();

    $this->CI->load->database();
    }
    /*********************************************************************
    * Возвращает информацию о узле.
    * Уровень, правый и левый ключ
    */

    private function get_info_node($t_id)
    {
    $t_id = (int)$t_id;

    $get = 'SELECT '.$this->left_key.','.$this->right_key.','.$this->level.' FROM `'.$this->table_name.'` WHERE `'.$this->t_id.'`='.$t_id;
    $get = $this->CI->db->query($get);
    $get = $get->result_array();

    //Если делаем перемещение в корень, то возвращаем уровень = 0, максимальный правый и минимальный левый ключи
    if($t_id==0)
    {
    $get = 'SELECT max('.$this->right_key.'), min('.$this->left_key.') FROM `'.$this->table_name.'`';
    $get = $this->CI->db->query($get);
    $get = $get->result_array();

    return array(0,$get['0']['right_key'],$get['0']['left_key']);
    }

    if(count($get)>0) return array($get['0']['level'],$get['0']['right_key'],$get['0']['left_key']);
    //else return false;
    else echo 'count <= 0';
    die;
    }
    /*********************************************************************
    * Перемещение узла.
    * $t_id : id перемещаемого узла
    * $parrent_t_id : id нового родителя
    */

    function move($t_id,$parrent_t_id)
    {
    list($level,$right_key,$left_key) = $this->get_info_node($t_id);
    list($level_near,$right_key_near,$left_key_near) = $this->get_info_node($parrent_t_id);

    $skew_level = $level_near - $level + 1;
    $skew_tree = $right_key - $left_key;

    if($right_key_near > $right_key)
    {
    $skew_edit = $right_key_near - $left_key + 1;
    $get = 'UPDATE '.$this->table_name.'
    SET
    '
    .$this->right_key.' = CASE WHEN '.$this->left_key.' >= '.$left_key.'
    THEN '
    .$this->right_key.' + '.$skew_edit.'
    ELSE CASE WHEN '
    .$this->right_key.' < '.$left_key.'
    THEN '
    .$this->right_key.' + '.$skew_tree.'
    ELSE '
    .$this->right_key.'
    END
    END,
    '
    .$this->level.' = CASE WHEN '.$this->left_key.' >= '.$left_key.'
    THEN '
    .$this->left_key.' + '.$skew_level.'
    ELSE '
    .$this->left_key.'
    END,
    '
    .$this->left_key.' = CASE WHEN '.$this->left_key.' >= '.$left_key.'
    THEN '
    .$this->left_key.' + '.$skew_edit.'
    ELSE CASE WHEN '
    .$this->left_key.' > '.$right_key_near.'
    THEN '
    .$this->left_key.' + '.$skew_tree.'
    ELSE '
    .$this->left_key.'
    END
    END
    WHERE
    '
    .$this->right_key.' > '.$right_key_near.' AND
    '
    .$this->left_key.' < '.$right_key;
    echo $this->CI->db->query($get);
    } else
    {
    echo "else. debug! :) #156 in libraries/Tree.php";
    }
    }
    Метод move() полностью не дописан, пока что только реализован вариант перемещения в "область вышестоящих узлов"
    При написании, пользовался этой статьей.

    Так вот, при выполнении запроса в БД меняется только значение level у корневого узла (+1,+3)(!!! :KillMe: ), а остальные значения остаются неизменными.
    По всякому пробовал извращаться над кодом, не помогло. Пробовал выполнять запрос ко всем типам таблиц (MyISAM,InnoDB и т.д.)

    Извините за наглость, но наведите на верный путь в плане формирования sql-запроса на перемещение, пожалуйста. Самому в голову уже ничего не приходит.

    PS В данный момент работаю с фрейворком Codeiginter.
    PSS Если возможно, без закидывания тухлыми помидорами, я только учусь..
     
  2. artkl

    artkl Гость

    Проблема решена путем заимствования sql-запроса из готовой библиотеки для работы с nested sets :KillMe:

    Хотя суть составления запроса все равно не понятна. Думаю следует прикупить литературу по sql.

    Тему можно закрывать.
     
Загрузка...

Поделиться этой страницей