1. Требуются разработчики и тестеры для проекта codebyOS. Требования для участия в проекте: Знание принципов работы ОС на базе Linux; Знание Bash; Крайне желательное знание CPP, Python, Lua; Навыки системного администрирования. Подробнее ...

    Скрыть объявление

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

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

  1. artkl

    artkl Гость

    Репутация:
    0
    Здравствуйте уважаемые программисты.
    Обращаюсь к вам, так как сам дурак и не могу понять суть формирования 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 Гость

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

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

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

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