среда, 2 декабря 2009 г.

Nuxeo Digital Assets Management (DAM)

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

ИМХО, довольно интересный продукт. Судя по Быстрому Старту использует целый стек других довольно известных открытых продуктов:

пятница, 13 ноября 2009 г.

Новая книга по BPM

Наткнулся сегодня в блоге Intalio на новую книгу по BPM от Александра Самарина. Можно посмотреть содержание и купить. Также на сайте есть масса публикаций по теме.

пятница, 30 октября 2009 г.

Переводим Adjency List в Nested Set

Ох уж эти деревья ... В Spree .9.2 изменили дерево таксонов (иерархию групп продуктов) по сравнению с .9.0 со своей модификации atcs_as_tree на acts_as_nested_sets, и моя выгрузка данных из 1С на этом переходе обломилась. Естественно пошел в интернет искать информацию о том как сделать из списка смежности (дерево: объект, родитель, ...) вложенные множества (объект, родитель, левое, правое, ...). В русском сегменте встретил только теоретическую информацию об устройстве nested sets, выгодах получаемых при выборке и тормозах при обновлении (при переносе вершины нужно пересчитать все дерево).

SQL ответ нашелся в древней статье 97 года самого автора такой модели вложенных множеств - Деревья в SQL, ... а Ruby ответ нашелся в папке с миграциями и был быстро преобразован в Rake Task. И если первый сможете прочесть у автора - второй опубликую (кстати он гораздо короче SQL-варианта)


desc "update taxons to nestedset"
task :upd_taxons => :environment do
Taxon.class_eval do
# adapted from awesome nested set to use "position" information
indices = {}

left_column_name = "lft"
right_column_name = "rgt"
quoted_parent_column_name = "parent_id"
scope = lambda{|node|}

set_left_and_rights = lambda do |node|
# set left
node[left_column_name] = indices[scope.call(node)] += 1
# find
find(:all, :conditions => ["#{quoted_parent_column_name} = ?", node], :order => "position ASC").each{|n| set_left_and_rights.call(n) }
# set right
node[right_column_name] = indices[scope.call(node)] += 1
node.save!
end

# Find root node(s)
find(:all, :conditions => "#{quoted_parent_column_name} IS NULL", :order => "position ASC").each do |root_node|
# setup index for this scope
indices[scope.call(root_node)] ||= 0
set_left_and_rights.call(root_node)
end
end
end


ЗЫ

Design Patterns исполнилось 15 лет - читайте посвященное этому событию интервью с авторами книги