Мне уже стало интересно и таки добил. Полный пример - https://gist.github.com/knutov/9959392
Вопросы: 1) как и можно ли обойтись без временной переменной $t? Читал документацию, не придумал. 2) как бы вы это улучшили? 3) Этот конструктор не очень хорошо позволяет работать с уловиями IN () в where и совсем не позволяет сделать опциональный вложенный селект со своими параметрами в where. Может кто-нибудь придумает как это сделать? ps: Нашел SQL::OOP - https://metacpan.org/pod/distribution/SQL-OOP/README.pod - который почти идеально мне подходит, кроме того, что много букв. Но интереснее сделать своё ) pps: Главный кусок кода из гиста: sub query2 (@) { my ($in, $p, $o, $l) = @_; my @aa = map {my $t = $_; map { $_ .' '. $t->{$_}[0] . ' ? '} keys %$t} @$p; my @bb = map {my $t = $_; map { $t->{$_}[1] } keys %$t} @$p; (join' ', $in, map @$_, grep $_->[1], $p ? [where => join ' AND ', @aa] : (), $o ? ['ORDER BY' => join ',', @$o] : (), $l ? [limit => join ',', ('?') x @$l] : ()), $p ? @bb : (), $l ? @$l : () } say Dumper query2 'SELECT i FROM t', [{'x' => ['=',99]}, {'a' => ['=',1]},{'b' => ['>',3]}], ['id DESC','a ASC'], [0,1]; } 03.04.2014 8:11, Nick Knutov пишет: > > Спасибо, я наконец проникся. > > Но при таком конструкторе не учитывается порядок следования полей в > условии AND, который иногда очень даже следует учитывать в случае с > MySQL. Пример: > > query 'select i from t', {qw(x 99 a 1 b 3)}, ['id desc','a asc'], [0,1]; > даст > where a = ? and b = ? and x = ? > > И, может быть у вас есть готовый код, позволяющий сделать > > query 'select i from t', {'a' => ['=',1],'b' => ['>',3]}, ['id desc','a > asc'], [0,1]; > > или чего-то такого по условиям, можно с другим входным форматом (надо > задавать не только =, но и <,>,IS, IS NOT, IN и т.д.)? > > У меня получилось: > > (join' ', $in, map @$_, grep $_->[1], > $p ? [where => join ' and ', map $_.' '.$p->{$_}[0].' ?', keys%$p] : > (), > $o ? ['order by' => join ',', @$o] : (), > $l ? [limit => join ',', ('?') x @$l] : ()), > $p ? map($_->[1], values $p) : (), $l ? @$l : () > > Но оно стало еще менее читабельным. И если добавить поддержку {'a' => > [1], ...}, считая, что если элемент один, то значение - единственный > элемент, а действие по умолчанию - "=", то код получается еще мене красивым. > > > upd: А если делать массив для соблюдения порядка, то для конструкции > [ > {'x' => ['=',99]}, > {'a' => ['=',1]}, > {'b' => ['>',3]} > ] > слишком многоэтажные конструкции получаются. > > > 18.12.2013 14:07, vividsnow пишет: >> как вариант что-то вроде: >> https://gist.github.com/vividsnow/8d294801959975730fc3 >> (возможно более специфичное к вашей задаче) >> >> On 12/18/2013 03:44 AM, Nick Knutov wrote: >>> Не вижу, чем мне это может помочь. >>> >>> В данном примере posts_sql_view() возвращает нечто очень большое и >>> сложное, например селект с джойнами по куче таблиц из селекта с джойнами. >>> >>> Как минимум, конструировать запрос мне надо начиная с того места, где >>> может быть WHERE. И, например, как тут - наличие LIMIT и его количество >>> зависит от других параметров. >>> >>> >>> 18.12.2013 5:34, vividsnow пишет: >>>> https://metacpan.org/pod/SQL::Abstract >>>> >>>> >>>> 2013/12/18 Nick Knutov <[email protected] <mailto:[email protected]>> >>>> >>>> У меня в коде в некоторых функциях, в зависимости от входных >>>> параметров, >>>> конструируются разные sql запросы. Пример: >>>> >>>> my $sql = posts_sql_view(); >>>> $sql .= ' WHERE ' if $type or $id or $main; >>>> do { $sql .= ' ty.id =? '; push @params, $type;} if $type; >>>> do { $sql .= ' AND p.id =? LIMIT 1'; push @params, $id >>>> } if $id; >>>> $sql .= ' ORDER BY id DESC ' unless $id; >>>> do { $sql .= ' LIMIT ? ' ; push @params, $limit } if $limit and not >>>> $id; >>>> >>>> Мне не нравится как это визуально выглядит. Как бы вы это переписали, >>>> чтобы было понятнее и читабельнее? >>>> >>>> ps: в некоторых других случаях можно было бы использовать && вместо >>>> do{}, но не тут. >>>> >>>> pps: ORM предлагать и обсуждать не надо. Как минимум потому, что >>>> запросы >>>> сложные и сложность/стоимость проверки того, что генерирует ORM >>>> многократно выше любого профита от ORM в данной ситуации. >>>> >>>> -- >>>> Best Regards, >>>> Nick Knutov >>>> http://knutov.com >>>> ICQ: 272873706 >>>> Voice: +7-904-84-23-130 <tel:%2B7-904-84-23-130> >>>> -- >>>> Moscow.pm mailing list >>>> [email protected] <mailto:[email protected]> | http://moscow.pm.org >>>> >>>> >>>> >>>> >>> > -- Best Regards, Nick Knutov http://knutov.com ICQ: 272873706 Voice: +7-904-84-23-130 -- Moscow.pm mailing list [email protected] | http://moscow.pm.org
