Показ дописів із міткою NestedSet. Показати всі дописи
Показ дописів із міткою NestedSet. Показати всі дописи

четвер, березня 26, 2009

Nested Set Symfony или CodeIgniter

symfonyО проблемах хранения деревьев в SQL базах данных вопрос можно не поднимать, просто сказать, что они есть. Теорию, посвященную описанию этих деревьев и как организована структура в базе данных, можно найти на сайте Wikipedia. В данном же посте я опишу свой класс, который я разработал для манипулирования Nested Set в Doctrine для CodeIgniter или Symfony. При помощи этого класса, можно не задумываясь вставлять, удалять, перемещать ноды дерева. Класс писался с прицелом, на то, что его можно будет легко заменить другим классом, не работающим с Nested Set, но предоставляющим такой же API. Также важная поправка, класс писался используя плагин к Doctrine Nested Set.
Первое, что я создал для класса вложенных множеств это его интерфейс:
interface Hierarchical
{
public function build($object);
public function _getTree();
public function _getBranch($branch = 0);
public function _add($parent);
public function _delete($id);
public function _replace($parent,$id);
}
Благодаря интерфейсу, иной класс, наследуя его может с легкостью заменить класс вложенных множеств.

Сам класс выглядит так:
class NestedSet extends Doctrine_Record implements Hierarchical
{
public function build($object)
{
$this->iObject = $object;
$this->Object = Doctrine::getTable($this->TABLE_NAME)->getTree();
$this->hasManyRoots = $this->Object->getAttribute('hasManyRoots');
}

public function _getTree()
private function getChildren($item)
public function _getBranch($branch = 0)
public function _add($parent)
public function _delete($id)
public function _replace($parent,$id)
}
Зная, о том, что деревья могут содержать несколько рутовых веток или одну рут-ветку некоторые функции учитывают эту особенность.

Функция получения Дерева в Nested set:
public function _getTree()
{
$this->TreeArray = array();

if ($this->hasManyRoots)
{
$rootColumnName = $this->Object->getAttribute('rootColumnName');
foreach ($this->Object->fetchRoots() as $root)
{
$options = array('root_id'=>$root->$rootColumnName);
foreach($this->Object->fetchTree($options)->toArray() as $node)
{
$this->TreeArray[$root->$rootColumnName][] = $node;
}
}
}
else
{
foreach ($this->Object->fetchTree()->toArray() as $node)
{
$this->TreeArray[$node['level']][] = $node;
}
}
return $this->TreeArray;
}
Как видно из кода все ясно и понятно.

Особенности создания правильной структуры Nested Set, и как создавать Many Roots деревья используя Doctrine yaml в схемах, я опишу немного позже.

Вот основная функция, которая работают с деревом Nested Set в Symfony и в CodeIgniter используя PHP ORM Doctrine плагин. Сам класс получился довольно простым и дееспособным. Остальные функции, выложить не удалось из-за нечитабельного их расположения на страницах блога (код вылазит за границы страницы и надо его вручную подгонять, а мне лень).
Весь код класса я могу выложить сюда же в блог, по первому требованию девелоперов, для того, что бы сократить время затраченное на разработку тех или иных задач, в которых используется NestedSet.

Основную информацию по легкому созданию и управлению деревьями вы можете взять отсюда и написать свой собственный класс.

В дальнейшем я планирую написать легкое и доступное овервью как создавать деревья посредством Doctrine yaml схем, и как использовать SimpleTest в Doctrine для методики TDD.
Также хочу насторожить тех девелоперов, которые впервые работают с Nested Set. Переход от структуры смежных вершин к вложенному множеству влечет за собой некий дискомфорт ))).

середу, березня 25, 2009

PHP ORM Doctrine и почему ее надо использовать.

DoctrineСклоняетесь или интересуетесь ORM?
Знаете PHP, но не работали с ORM?
Слышали про Doctrine, но толком не вкурите в чем соль?
Тогда Вам сюда. Здесь я постараюсь описать свое впечатление от работы с системой, а вы возьмете на заметку. Ведь в конечном итоге Вам решать работать с ней или нет.

Что такое ORM?
Ну вообще ORM простыми словами, это система, которая позволяет абстрагироваться от БД и работать на уровне обьектов. В чем соль?
Вся соль в том, что я могу сказать обьекту:
$обьект->сохранись();
И он сохранился, а sql я не пишу. Жииииррррр.....

Итак:
Я переключился на Doctrine после двугодичной разработки самописных систем. Что такое самописная система надеюсь все знают, это когда все написано от руки и это все модифицируется и со временем выростает в громадную кучу кода. С которой уже не хочется работать.
Doctrine
Так вот после этих двух лет, я открыл для себя новый горизонт. Первое, что мне понравилось в Доктрине, это:
  1. То, что написание sql запросов в разы улучшается, с точки зрения подхода! Именно с точки зрения подхода, а это важно. Важно, потому что это огромная экономия времени на написании и на дебаге sql запросов. Вообще Doctrine абстрагируется от базы данных и работать с ней, становится одним удовольствием.
  2. Doctrine позволяет подходить к разработке посредством сущности - СУПЕР КЛАССНО. Объявив один раз сущность "Новость", я могу вертеть ей как мне захочется, это также громадная экономия времени. Я могу связать эту сущность с сущностью "Категория" и с легкостью выбирать все новости по категории.
  3. Doctrine использует innoDB таблицы MySQL сервера. А innoDB в свою очередь тянет за собой весь свой потенциал. Особенно мне нравятся каскадные удаления. А раньше я писал проверки и удалял руками из одной таблицы, потом из другой.
  4. Я в восторге от подхода Доктрины к формированию БД и обьектов посредством фикстур и схем. Описав их один раз, я могу с легкостью разворачивать проект где мне угодно и не заботиться о дампах баз данных.
  5. Мне очень нравится плагин к Доктрине Nested Set (вложенное множество), который я сразу же начал использовать в новом проекте.
И еще мне много чего в ней нравится, но главное это наверное одно: "Простота и быстрота решения поставленных задач".

Есть в ней конечно и минусы и иногда даже нужно лезть в код и править саму Doctrine. Есть некоторые недоразумения в объявлении yaml схем, также в составных ключах и использование праймери ключа в таблицах. Также минус для новичка, это довольно скудная и сложная для чтения документация API. Но эти минусы можно виртуозно обходить используя другие подходы к решению задач.
Doctrine предоставляет свой репозиторий, откуда можно высосать последнюю версию. Еще у нее есть открытый для пользователя Trac. Сама она написана тоже достаточно не сложно. Так что вам и карты в руки.

Использование Doctrine вместе с Symfony или CodeIgniter позволяет юзать классный OOP PHP5, что есть очень хорошим опытом и развитием для программиста. Но я пошел дальше, я прикрутил SimpleTest и стал использовать методику TDD.

Как итог могу подвести следующее: PHP ORM Doctrine включает в себя немалый потенциал, есть конечно и минусы и плюсы, но в целом мне нравится их подход, если первый проект отрекомендует себя довольно неплохо, вряд ли я откажусь от Доктрины.

Класс посвященный управлению Nested Set в Symfony с использованием Doctrine.

Що таке база данних?

База данних — це спеціальна система зберігання, організації та пошуку інформації. Вона містить дані у вигляді таблиць, записів та інших стру...