[Moscow.pm] v2 просьба о ревью модуля DBIx::Struct

Warstone@list.ru warstone на list.ru
Чт Янв 15 13:16:40 PST 2015


 В моём варианте можно унаследовать класс DBC::User и сделать то же самое. 
>Пользовался подобным несколько раз, но, в основном, "всё иначе" и объекты БД 
>не привожу к ООП (смеси данных из БД и произвольных методов), а определяю 
>отдельный API работы с ядром, а что вернёт хендлер метода API уже дело 
>хендлера. Согласен, неудачный пример. Ну да, надеюсь простите, если не буду более удачного показывать... Под рукой ничего такого не находится с ходу. Хотя-я-я... Да вот пожалуйста: поле active_status - является-ли пользователь активным или нет. Раньше было поле, которое должно было апдейтиться  по крону и на его основе перебирались таблички на быструю и медленную (для Пг это разумно, чтобы больше вероятность попадания была). Рассчитывали запилить такой подход, потом оказалось что понятие активности для бизнеса и для базы - разные вещи. active_status стал геттером, который проверяет конфиг и last_visit. Приложения (которых много и разрабатываются несколькими командами) не заметили этого и продолжили жить, как есть. Таких примеров... не то, чтобы много, но они есть. Это конечно, не панацея, но в некоторых случаях помогает.
>Ни разу не наблюдал особой проблемы с количеством модулей. Ах, да, я ж, 
>наверное, "не писал сложных проекто никогда". Возможно.
Хватит прибедняться... Я вот тут недавно заметил, что на текущей архитектуре мне надо создать 4 или 5 файлов, чтобы реализовать ту или иную фичу... Сейчас с этим боремся.
>Да ничем, кроме некоторой негибкости кода, по моему мнению. Первое что приходит в голову - вы теряете возможность кастомных типов данных. Допустим у нас есть специальный тип, который сериализуется в JSON. В схеме я ему пишу тип: MyCoolSpecialType, а во время создания объекта прописываю inflate и deflate процедуры. После чего ...->single->cool_column->make_cool_method_on_my_cool_type. Наверняка еще 100500 маленьких приятностей, которые называются сахаром.
>Ой. И никакой ORM? 
Подколка засчитана... Свой ORM из 15-20 строчек не считая сервисной рутины.
>
>> В SQL::Abstract думали еще и о том, что это должно
>> выполняться на как можно большем количестве диалектов, допустим.
>
>Ну да, поэтому работу с offset/limit решили не делать. SQL::Abstract. как ни 
>странно, ничего не хочет знать про БД, он именно абстрактный "вычислитель 
>запросов". SQL::Abstract::More , если вам надо больше. ))
>Зависит от ситуации. Хранимки выполняют две функции: поддержание некоторого 
>API БД и исключение лишнего трафика клиент-сервер. Если сам запрос достаточно 
>тяжёлый и лишнего трафика сервер-клиент нет, то хранимка особого выигрыша в 
>производительности не даст, но некоторые алгоритмы там всё-таки разумнее 
>реализовывать. Но, собственно, кому я рассказываю.
У нас философия такая:
Все что надо сделать с базой, чтобы база работала быстрее - делается внутри базы... То есть теоретически можно и RULE на VIEW навесить и сказать что это таблица и прочее. Но только до тех пор, пока это надо и потому что по другому никак, но надо. Остальное - в приложении.
>Нет, так как раз запутаннее. Сначала надо всё-таки полную структуру 
>подразумеваемого приложения понять. Фронт запрашивает ядро. Ядро обращается к 
>бекенду. Бекенд обращается к базе. При этом объекты ORM выступают в роли 
>бекенда (или ядра?). Я запутался. Front-end(браузер) запрашивает страницу, nginx через proxy-pass отдает запрос на один из back-end'ов, которое есть наше приложение. Ядро - это набор библиотек, подключенных туда-же.
>Я признаюсь, ни разу не писал, когда бекендов много. Или когда баз данных 
>много. У меня были проекты, когда несколько фронтов<->ядро+база, а проблема 
>производительности базы решалась ростом RAM и переходом на SSD. Но, я 
>чувствую, что это просто мелочь в сравнении с настоящим хайлоадом.
Не совсем... Просто настоящий, как вы говорите, хайлоад начинается тогда, когда больше RAM и больше SSD не дают эффекта или не выгодны, так как нагрузка может кратно превысить сервер... Тут есть несколько вариантов, они, в общем-то, описаны в интернете (но по задворками и равномерным слоем) и никакого ноу-хау там нету. Просто подходы меняются и все.
>
>> Посмотрите в сторону DBIx::Simple в связке с SQL::Abstract я думаю вас это
>> удовлетворит, так как это оно и есть.
>
>Смотрел когда-то давно. Ну, допустим, я повторил даже чью-то функциональность. 
>Но, как мне кажется, я сделал это удобнее. И зачем мне отказываться от того, 
>что я написал в пользу других модулей? Например, в моём модуле есть следующий 
>сахар (цитата из документации)
>
>Допустим, у нас есть следующие таблицы:
>
>employer:
>    id_employer,
>    name
>
> employee:
>    id_employee,
>    id_employer references employer (id_employer),
>    id_employee_invited_by
>    name
>
> alter table employee add constraint fk_employee_employee 
>     foreign key (id_employee_invited_by) references employee (id_employee);
>
>Тогда можно использовать следующие выражения:
>
> my $employee = one_row("employee", {name => 'John'});
> my $employer = $employee->Employer;
>
>Последняя строка автоматически по ссылке из объекта $employee выберет объект 
>$employer.
>
>my $referenced_by = $employee->refEmployeeInvitedBys;
>
>Эта строка выберет всех "employee", которые были рекомндованы конкретным 
>$employee.
>
>my $robert_associates = $employee->Employer->refEmployees(name => 'Robert');
>
>А эта строка выберет коллег этого $employee, у кого имя 'Robert'.
>
>Личто мне этот сахар удобен и экономит код. На счёт эффективности не вижу тут 
>проблем так же. refEmployeeInvitedBys и refEmployees из коробки в том-же DBIx::Class'е нету, но... Как вы не видите, что пишете свой DBIx::Class, который в последствии разрастется хуже оригинального?.. Если видите, так может сразу взять лучшее оттуда и добавить недостающие фишки... Причем DBIx::Class тот-же прекрасно сабклассится (если понимать идеологию mro::c3)

Ну хорошо... вы хотели некоторых отзывов...
Открываем DBIx::Struct.pm:
%driver_pk_insert - и там код как строка... Зачем?..
Идем дальше...
sub make_object_new - Бешеная кодогенерация . Вы про наследование слышали? Делаете класс-аксессоры, а потом тупо:

sub create_new_package {
  my ($self, $class_name, $config) = @_;
  my $isa = \@{"${class_name}::ISA"};
  push(@$isa, "DBIx::Struct::Base");
  $class_name->_initialize($config); # Или не делаете, если инициализировать нечего или сами забивайте руками эти аксессоры.
}

Нет, все... Я на куче кодогенерации выпал в осадок.
----------- следущая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mail.pm.org/pipermail/moscow-pm/attachments/20150116/e366a674/attachment-0001.html>


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