DbTreeBehavior - вложенные множества

Выкладываем свои наработки
Ответить
Аватара пользователя
Stepan Selyuk
Сообщения: 198
Зарегистрирован: 2010.02.03, 05:51
Откуда: Cyprus, Limassol
Контактная информация:

DbTreeBehavior - вложенные множества

Сообщение Stepan Selyuk »

Сделал поведение для моделей, для работы со вложенными множествами (nested sets). Может кому пригодиться.
Основано на оригинальном классе CDBTree автора Maxim Poltarak, сайт http://dev.e-taller.net/dbtree/

Комментить пытался на английском - так как Zend 7.1.1 не хочет форматировать код с русскими комментариями. Так что не пинайте.
Некоторая функциональность реализована для использования на конечной системе. Но все равно старался сделать универсальной.

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

Код длинный, прикрепляю файл.
Вложения
DbTreeBehavior.zip
(3.88 КБ) 266 скачиваний
Сначала невидимое, затем видимое. И так у всех программистов :)
Аватара пользователя
Stepan Selyuk
Сообщения: 198
Зарегистрирован: 2010.02.03, 05:51
Откуда: Cyprus, Limassol
Контактная информация:

Re: DbTreeBehavior - вложенные множества

Сообщение Stepan Selyuk »

Почитал TODO для скучающих, оказывается есть уже расширение такое! :)
http://www.yiiframework.com/extension/nestedset/
Сначала невидимое, затем видимое. И так у всех программистов :)
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: DbTreeBehavior - вложенные множества

Сообщение samdark »

1) Много кода, который можно не писать.
2) Не решает задачу «вытащить все категории продукты в которых опубликованы и весят больше 40г».
3) Все методы префиксованы dbTree_, что не есть очень хорошо.
4) protected $model можно заменить на $this->getOwner(), выносить в _initDbTree() не стоит.
5) Нет run-time поддержки модификаций дерева.
6) Совершенно не в стиле yii.
7) Не использует транзакции.

В yiiext есть наработка (в очень ранней, но уже рабочей стадии): http://code.google.com/p/yiiext/source/ ... havior.php
Аватара пользователя
Stepan Selyuk
Сообщения: 198
Зарегистрирован: 2010.02.03, 05:51
Откуда: Cyprus, Limassol
Контактная информация:

Re: DbTreeBehavior - вложенные множества

Сообщение Stepan Selyuk »

Видимо дело в том что с Yii я работаю неделю :) принял стратегическое решение и уже на половину разработанный проект на своем фреймворке переписал по Yii.

1. Ну рефакторинг никто не отменял - постепенно. Цель была переписать изначальный CDBTree под Yii Behaviour
2. Это и не планировалось. Поведение может вернуть $criteria для дальшейшей допилки условий. Насчет дальнейшей интеграции в модели можно подумать.
3. На всякий случай, привычка из правильного наименования кода (хотя кто-как привык).
4. Можно конечно. $model внедрил для простоты автодополнения в редакторе.
5. Это что такое?
6. Ну..учится буду ... стиль воспринимать :)
7. Пока в Yii насколько я знаю нет поддержки (без допилки) вложенных транзакций, и поэтому обновление такого дерева произведет commit предыдущей транзакции. Я думаю можно лишь внедрить либо проверку активной транзакции и исполнение кода sql: SAVEPOINT 'name'

Видимо разные инструменты для разных задач.
Сначала невидимое, затем видимое. И так у всех программистов :)
Dreammaker
Сообщения: 139
Зарегистрирован: 2009.09.02, 16:21
Откуда: Черкассы, Украина

Re: DbTreeBehavior - вложенные множества

Сообщение Dreammaker »

2. Это и не планировалось. Поведение может вернуть $criteria для дальшейшей допилки условий. Насчет дальнейшей интеграции в модели можно подумать.
То есть, Вы предлагаете вытянуть, например, 2000 позиций, чтобы потом их средствами пхп разрулить о_О
Аватара пользователя
Stepan Selyuk
Сообщения: 198
Зарегистрирован: 2010.02.03, 05:51
Откуда: Cyprus, Limassol
Контактная информация:

Re: DbTreeBehavior - вложенные множества

Сообщение Stepan Selyuk »

Dreammaker писал(а):
2. Это и не планировалось. Поведение может вернуть $criteria для дальшейшей допилки условий. Насчет дальнейшей интеграции в модели можно подумать.
То есть, Вы предлагаете вытянуть, например, 2000 позиций, чтобы потом их средствами пхп разрулить о_О
Зачем? Ну допустим нужно вернуть детей категории. Поведение сформировало условие и вернуло критерию (если мы об этом попросили).
Дальше делаем

Код: Выделить всё

$criteria->addCondition('products.weight >= 40');
Category::model()->with('products')->findAll($criteria);
 
И в принципе получаем категории продуктов в которых продукты 40 грамм и больше.
Сначала невидимое, затем видимое. И так у всех программистов :)
nagash
Сообщения: 35
Зарегистрирован: 2010.03.30, 14:26
Откуда: Украина, г. Сумы

Re: DbTreeBehavior - вложенные множества

Сообщение nagash »

Sam Dark писал(а): В yiiext есть наработка (в очень ранней, но уже рабочей стадии): http://code.google.com/p/yiiext/source/ ... havior.php
Когда можно будет посмотреть примеры работы, или документацию?
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: DbTreeBehavior - вложенные множества

Сообщение samdark »

Это к creocoder-у, его детище.
plandem
Сообщения: 25
Зарегистрирован: 2009.09.03, 02:34

Re: DbTreeBehavior - вложенные множества

Сообщение plandem »

Sam Dark писал(а):1) Много кода, который можно не писать.
2) Не решает задачу «вытащить все категории продукты в которых опубликованы и весят больше 40г».
3) Все методы префиксованы dbTree_, что не есть очень хорошо.
4) protected $model можно заменить на $this->getOwner(), выносить в _initDbTree() не стоит.
5) Нет run-time поддержки модификаций дерева.
6) Совершенно не в стиле yii.
7) Не использует транзакции.

В yiiext есть наработка (в очень ранней, но уже рабочей стадии): http://code.google.com/p/yiiext/source/ ... havior.php
посмотрел бегло код (сам сейчас изучаю вопрос, чтобы определиться самому писать все или же использовать готовое расширение) и нашел вот такую штуку:

Код: Выделить всё

public function remove()
        {
                $owner=$this->getOwner();

                $transaction=$owner->getDbConnection()->beginTransaction();


                try
                {
                        $condition=$this->left.'>='.$owner->getAttribute($this->left).' AND '.
                                $this->right.'<='.$owner->getAttribute($this->right);

                        $root=$this->hasManyRoots ? $owner->getAttribute($this->root) : null;

                        if($root!==null)
                                $condition.=' AND '.$this->root.'='.$root;

                        $owner->deleteAll($condition);

                        $first=$owner->getAttribute($this->right)+1;
                        $delta=$owner->getAttribute($this->left)-$owner->getAttribute($this->right)-1;
                        $this->shiftLeftRight($first,$delta,$root);

                        $transaction->commit();

                        return true;
                }
                catch(Exception $e)
                {
                        $transaction->rollBack();

                        return false;
                }
        }
 
Уверен, что:

Код: Выделить всё

$owner->deleteAll($condition); 
Очень плохая идея, т.к. не будут вызваны events для удаленных моделей. А там может быть логика при удалении категории (удаление привязанных товаров, как один из примеров)!
plandem
Сообщения: 25
Зарегистрирован: 2009.09.03, 02:34

Re: DbTreeBehavior - вложенные множества

Сообщение plandem »

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