26 октября 2011 г. 21:26 пользователь Ivan Petrov <[email protected]> написал: > сделали мы тут цельный проект на DBIx::Class. С точки зрения > попробовать последний. До этого всегда использовали DBI, который > использовала модель в системе MVC. > > Впечатления плохие, однако появились мысли куда надо двигаться чтобы > было хорошо. Я их тут изложу, а вы покритикуйте. > > В первую очередь зачем как бы нужен был этот DBIC. > - конструирование SQL-запросов > - уход от смешивания кода Perl с кодом SQL > - выборка объектов, а не хешей из БД, которые можно расширять своими > методами > - упрощение кода моделей с точки зрения что в простых случаях вообще > не делать выделенную модель > > Ничего не забыл? > > По результатам проекта (проект был довольно большой и дальше еще будет > долго) я понял следующее: > > 1. даже в простых случаях DBIC на роль модели не годится. То есть в > любом случае нужно делать выделенную модель, пусть даже там один > resultset('Name')->find. Ибо тесты. При их написании мы применяем > способ "подменить модель на стадии тестирования". > > 2. DBIC не предоставляет хорошей абстракции над БД. Все равно > JOIN'ы, SELECT'ы торчат местами (например join_type => 'left' в has'ах > итп). То есть оперировать хранилищем как некоей абстракцией в реальном > случае не получается. > > 3. Конструктор SQL-запросов крайне страшен. Работали мы с постоянно > включенной отладкой (выводом всех делающихся запросов в лог). С одной > стороны есть множество вещей которые на DBIC сделать крайне непросто > (например многие аггрегаторные вещи), с другой стороны когда > начинается работа с более чем двумя таблицами он зачастую мутит такие > страшные вложенные SQL-запросы что волосы дыбом становятся, а с > третьей стороны использование фич конкретной БД становится затруднено. > > В итоге пришли к тому, что в сложных случаях приходится делать в БД > view'ы только из за того что от DBIC добиться генерации нормального > запроса очень и очень сложно или невозможно. Набор опций при выборке > может быть больше самого SQL-запроса, если его просто написать. > > Ну вот и в свете того, что код работы с DBIC все равно располагается в > моделях, конструировать эффективные SQL-запросы он все равно не умеет, > то из плюсов его использования остаются только: > - выборка в объекты и итераторы по ним > - уход от смешивания Perl и SQL > > Соответственно размышляя над всем этим мы пришли к тому, что > > 1. построить качественный автогенератор SQL запросов на все случаи > жизни (или по кр. мере на большинство) невозможно, поэтому его не > стоит и пытаться сделать > > 2. из за п.1 бОльшая часть DBIC становится не нужна, а надо делать > некоего помощника, который бы человеку просто помогал удобно работать > с БД. > > то есть надо > > 1. написать свой итератор, работающий поверх массива или > хеша - выборки из БД. > 2. написать базовую обертку над одной строкой выборки (доступ в виде > методов) > 3. Используя 1 и 2 написать над DBI класс, который выборки блессает в > итераторы и объекты > 4. решить вопрос с выносом SQL-кода из перловых модулей. То есть > обертка 3 должна уметь работать с SQL, располагающимися в файлах. > > > Вынос SQL в файлы очень плохо соотносится с дефолтными плейсхолдерами > DBI. поскольку они позиционные. > > Вывод: > 5. надо реализовывать именованные плейсхолдеры > > ну и попутно > 5.1 реализовать плейсхолдерные (темплейтные) выражения для типовых > вещей, как-то > INSERT ... VALUES (?,?,?),(?,?,?),(?,?,?),... > > или > SELECT ... WHERE id IN (?,?,?) > > то есть подстановки массивов. > > Соответственно исходя из этого родился набор модулей, который в > ближайшее время, если кому-то будет интересно, мы можем выложить на > CPAN (там еще работы на неск. дней осталось), который все это делает: > > 1. по дефолту блесает строки-выборки в объект, у которого три > предопределенных метода: new, is_changed, iterator. Плюс методы > совпадающие с именами выбранных столбиков. > > 2. блесает наборы-выборки в объект позволяющий делать проходы по > выборкам итп (совместимо с DBIC'шными ->all, while(...->next) итп > > 3. в п. 1 и 2 позволяет указывать свои классы для итераторов и выборок > > 4. позволяет вместо SQL использовать имена файлов SQL в предзаданной > директории (по аналогии с темлейтами любого вебпроекта) > > 5. реализует следующий набор подстановок в SQL > > ?{путь} - просто подставляет переменную > ?@{путь} - подставляет массив переменных (через запятую) > ?%{путь}{поле,поле,...} - подставляет массив переменных (через > запятую) из массива хешей > > ну и на вс случай сделали > ?sub{перловый код} > > > А так же набор условных подстановок вроде > > ?if[de]?{путь}{ блок который вставится }{else-блок} > > условия - if - истина > ifd - определен > ife - имеется > > Блоки можно вкладывать друг в друга. > > пути - по сути путь к переменной во входном хеше, то есть > > $dbh->do($sql, values => { ids => [1, 3, 5] }, abc => 'def'); > > путями являются > 'values' > 'abc' > 'values.ids' > > и так далее. > > поддерживаются в путях и объекты > > path.to:method - будет вызван метод объекта, а значение им > возвращенное будет вставлено в SQL. > > > В итоге что получили: > > 1. SQL вынесен в отдельный каталог (отдельные каталоги) примерно так > же как вынесены темплейты в любом вебпроекте > 2. типичные SQL-вещи делаются просто. Сложные тоже можно делать. > 3. Поскольку итератор по именам методов постарались сделать > совместимым с DBIC то замена одного на другое не вызывает больших > трудностей. > > ну и возьмем пример: > > скажем приходит от пользователя форма > > $filters = { region => 'Москва', street => '' }; > > То есть он фильтр по региону заполнил, а фильтр по улице нет > > запрос может выглядеть так > > SELECT > * > FROM > tbl1 > LEFT JOIN tbl2 ... > > WHERE > something = .. > > ?if{filters.region}{ AND region = ?{filters.region} } > ?if{filters.street}{ AND street = ?{filters.street} } > > и так далее. > > Получается SQL перестраивается в зависимости от того что там вводит > пользователь. > > Осталось нерешенными некоторые типовые вопросы, но мы их планируем > порешать в ближайшее время (например подставновки частей в > like-секции) > > соответственно вопросы: > > 1. кому-нибудь интересна подобная система, стоит класть на CPAN?
Безусловно стоит.При множестве глаз баги выплывают на поверхность > 2. может на эту тему есть что-то готовое да мы велик очередной ваяем? > тогда ткните указкой:) > -- > Moscow.pm mailing list > [email protected] | http://moscow.pm.org > -- Moscow.pm mailing list [email protected] | http://moscow.pm.org
