[Moscow.pm] SQL + \%hash -> SQL
Konstantin S. Uvarin
khedin на gmail.com
Вт Апр 18 05:28:02 PDT 2017
Приветствую!
Очередная безумная идея, рождённая вследствие просмотра 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
----------- следущая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mail.pm.org/pipermail/moscow-pm/attachments/20170418/26261b6a/attachment.html>
Подробная информация о списке рассылки Moscow-pm