[Moscow.pm] SQL + \%hash -> SQL

Akzhan Abdulin akzhan.abdulin на gmail.com
Вт Апр 18 07:11:06 PDT 2017


А чем не понравился  ВИШчЖЖСдфы  или другие ORM, которые используют
SQL::Abstract?

Как минимум, они берут на себя и такие вещи, как join/prefetch/having etc..

18 апреля 2017 г., 15:28 пользователь Konstantin S. Uvarin via Moscow-pm <
moscow-pm на pm.org> написал:

> Приветствую!
>
>   Очередная безумная идея, рождённая вследствие просмотра SQL::Abstract и
> всяких прочих LINQ. Периодически возникает ситуация, когда мы что-то
> выбираем из базы, но конкретные критерии неизвестны заранее (date < ? или
> date > ? или оба). Тут мне известны варианты:
>
> * сделать нужный запрос руками ($sql .= (defined $x ? " foo = ?" : " foo
> IS NULL");
> * прогенерить из DSL;
> * написать один раз функцию, которая генерит селект_заданного_типа для
> данной конкретной модели;
> * использовать ORM.
>
> (Что я пропустил?..)
>
> Ну и вот, собственно, идея: в большинстве случаев "каждый раз другие"
> критерии - это на самом деле просто группа отношений, которые надо
> применить к заранее известной таблице. Поэтому пишем шаблон запроса (как с
> плейсхолдерами (foo =?)) + добавляем хеши условий вместо одиночных
> значений. Т.е. используем SQL как DSL для описания SQL.
>
> Что-то вроде
>
>     my $template_query = "SELECT * FROM foobar f WHERE f.??? ORDER BY
> created LIMIT ?";
>     my %criteria = ( foo => 42, bar => undef );
>     my ($normal_query, @param_list) = decorate_query( $template_query,
> \%criteria, 12 );
>
>     на выходе вместо трёх вопросов - "f.foo = ? AND f.bar IS NULL" и потом
> два параметра (42, 12).
>
> ??? выбрано потому, что вряд ли кто-то в здравом уме напишет три
> плейсхолдера подряд без пробелов. А префикс f. мы требуем, ибо может быть
> более 1 таблицы (да и скорее всего будет много таблиц - типа пришёл DBA с
> листочком - "я вам тут запросы соптимизировал, ннннадо?..").
>
> И вторая часть - а как нам покороче записать foo < 5? SQL::Abstract
> предлагает foo => { "<" => 5 }, но мне кажется, что можно сделать через
> прототипы + overload (точнее, я уже сделал, но там такой код, что его
> показывать стыдно):
>
>     {
>         foo => (value < 5) & (value != 3),
>         bar => value->in("дыр", "бул", "щыл")),
>     }
>
> 1. Чего не хватает в списке вариантов?
> 2. Есть ли уже что-то подобное?
> 3. Достаточно ли выразителен синтаксис t.???, или надо что-то
> поинтереснее? А если мы хотим заранее определить поля? У меня была идея
> "t.???[city cost created]", но, может, что-то получше можно?
>
> Всем хорошего (остатка) дня!
>
> --
> Konstantin S. Uvarin
> jabber: see <from>
> skype: kuvarin
> http://github.com/dallaylaen
>
> --
> Moscow.pm mailing list
> moscow-pm на pm.org | http://moscow.pm.org
>
>
----------- следущая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mail.pm.org/pipermail/moscow-pm/attachments/20170418/d0e22a6a/attachment-0001.html>


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