А чем не понравился ВИШчЖЖСдфы или другие ORM, которые используют SQL::Abstract?
Как минимум, они берут на себя и такие вещи, как join/prefetch/having etc.. 18 апреля 2017 г., 15:28 пользователь Konstantin S. Uvarin via Moscow-pm < [email protected]> написал: > Приветствую! > > Очередная безумная идея, рождённая вследствие просмотра 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 > [email protected] | http://moscow.pm.org > >
-- Moscow.pm mailing list [email protected] | http://moscow.pm.org
