[Moscow.pm] аналог SQL View в DBIx

Eugene Toropov jt на aaanet.ru
Сб Июл 19 13:25:57 PDT 2008


Предупреждаю, что с DBIx вообще не работал, но посмотрите вот сюда, мож 
поможет: http://www.perlmonks.org/?node_id=675917

Еще оказывается есть сообщество http://community.livejournal.com/ru_dbic , 
правда ощущение, что почти сыграло в ящик :)

Евгений,
jt на aaanet.ru

> Привет всем,
>
> как корректно сделать аналог SQL-вского View в DBIx ?
>
> Т.е. оператор SQL
>
> SELECT cms_menus.id,cms_menus.name,
>    CASE cms_page_menus.id WHEN cms_page_menus.id THEN 1 ELSE 0 END 
> is_enable FROM cms_menus LEFT JOIN cms_page_menus ON 
> cms_page_menus.cms_menu_id=cms_menus.id AND 
> cms_page_menus.cms_page_id=XXXX
>
>
> должен выдавать:
>
> +----+----------+-----------+
> | id | name     | is_enable |
> +----+----------+-----------+
> |  2 | Sub Menu |         0 |
> |  1 | Top Menu |         1 |
> +----+----------+-----------+
>
>
>
> и этот оператор хочеться оформить в виде объекта DBIx и вызывать примерно 
> так:
>
> my $menu_items =  [$c->model('DB::CmsSomeView')->search(
>                                                         undef , )];
>
>
> Пока нашел такое решение:
> package DB::CmsView1;
>
> use strict;
> use warnings;
>
> use base 'DBIx::Class::Core';
>
> __PACKAGE__->table("DUMMY");
> __PACKAGE__->add_columns(qw/id name is_enable /);
> __PACKAGE__->result_source_instance->name(\'(SELECT 
> cms_menus.id,cms_menus.name,CASE cms_page_menus.id WHEN cms_page_menus.id 
> THEN 1 ELSE 0 END is_enable FROM cms_menus  LEFT JOIN cms_page_menus ON 
> cms_page_menus.cms_menu_id=cms_menus.id     AND 
> cms_page_menus.cms_page_id=?)');
>
> 1;
> ------------------
> непосредcтвенно в контроллере (Catalyst) вызываю:
>
> my $menu_items = [$c->model('CmsView1')->search( {} , {bind => 
> [$page_id]})];
>
>
> Все работает, нужные поля возвращаются.
>
> Но, как в том анекдтоте - "есть нюанс"...
> в MySql выстреливается запрос:
> SELECT me.id, me.name, me.is_enable FROM (SELECT 
> cms_menus.id,cms_menus.name,CASE cms_page_menus.id WHEN cms_page_menus.id 
> THEN 1 ELSE 0 END is_enable FROM cms_menus  LEFT JOIN cms_page_menus ON 
> cms_page_menus.cms_menu_id=cms_menus.id     AND 
> cms_page_menus.cms_page_id=?) me: '2'
>
> Что ни разу не кошерно. Цель использования "вьюхи" - оптимизация скорости 
> работы приложения, а какая тут нафиг оптимизация если идет вложенный 
> SELECT.
>
>
> Есть еще вариант "опустится" до использования DBi без всякой там ORM 
> фигни для критичных по скорости запросов, но во первых тут появится 
> дополнительное соединение с базой данных, а во вторых хочеться остаться в 
> рамках DBIx.
>
>
> Гдето в обзоре я читал что DBIx  позволяет выполнять нативные SQL запросы. 
> Интересно как это можно сделать почеловечески?
>
>
> Уйти от возможности выдать нативный SQL запрос в сторону  "истинного ORM" 
> не предлагать, ибо оптимизировать тяжело нагруженную БД через
> DBIx::Class::Relationship 
> <http://search.cpan.org/%7Eash/DBIx-Class-0.08007/lib/DBIx/Class/Relationship.pm> 
> это все равно что наклеивать обои через щель почтового ящика. А я все таки 
> не на конкурсе гинекологов.
>
>
> С уважением
> Alex Ivin
>
> --
> Moscow.pm mailing list
> moscow-pm на pm.org | http://moscow.pm.org
> 



Подробная информация о списке рассылки Moscow-pm