Посоветуйте SQL Query Builder

AmdY

Пью пиво
Команда форума
Хочу набросать абстракцию к базе данных, прошлый мой велосипед утонул в багах из-за костыльного Query Builder-а, решил переписать, но хочется эту часть взять готовой. Насобирал пачку решений, но закладки где-то затерялись при синхронизации хрома. Пока ищу, может кто посоветует интересные решения. Желательно тупо под Mysqli, не хочу DBAL и PDO.
 

Absinthe

жожо
Doctrine DBAL вроде работает нормально, но мне кажется, что ее код пахнет.
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
А вот кстати про квери билдер. Я тут планирую писать свой велосипед, но вдруг кто видел готовый на нужных мне треугольных колёсах.

Есть ли билдер, позволяющий не писать хрень типа
PHP:
$select->from('blah')->join('blergh')->on('blah.blergh_id', '=', 'blergh.id')->where('blah.id', '=', 1);
а собирать запросы из более крупных кусков написанного вручную SQL'я?
 

deepslam

Новичок
А вот кстати про квери билдер. Я тут планирую писать свой велосипед, но вдруг кто видел готовый на нужных мне треугольных колёсах.

Есть ли билдер, позволяющий не писать хрень типа
PHP:
$select->from('blah')->join('blergh')->on('blah.blergh_id', '=', 'blergh.id')->where('blah.id', '=', 1);
а собирать запросы из более крупных кусков написанного вручную SQL'я?
Никогда не понимал, чем такая запись проще обычного SQL запроса :)


интересный проектик www.redbeanphp.com не использовал, но многообещающий..
Спасибо большое за ссылку! Судя по описанию ВЕЩЬ! :)
 

Фанат

oncle terrible
Команда форума
deepslam
Отличие тут ровно одно.
"сборка запросов из более крупных кусков написанного вручную SQL'я" обеспечивает последовательный доступ к структуре запроса. "только вперед".
А запрос как объект обеспечивает произвольный доступ, что в некоторых случаях может оказаться удобнее.

мне уже давно пришел в голову мысленный пример типа

PHP:
$count = $select('count(*)')->from('blah')->where('blah.id', '=', 1);
$data = $count->select('*')->limit(5,10);
но никто, правда, не подтверждает случаев такого использования. Хотя мне кажется очень логичным
 

deepslam

Новичок
deepslam
Отличие тут ровно одно.
"сборка запросов из более крупных кусков написанного вручную SQL'я" обеспечивает последовательный доступ к структуре запроса. "только вперед".
А запрос как объект обеспечивает произвольный доступ, что в некоторых случаях может оказаться удобнее.

мне уже давно пришел в голову мысленный пример типа

PHP:
$count = $select('count(*)')->from('blah')->where('blah.id', '=', 1);
$data = $count->select('*')->limit(5,10);
но никто, правда, не подтверждает случаев такого использования. Хотя мне кажется очень логичным
Да, очень здравая идея :)
 

флоппик

promotor fidei
Команда форума
Партнер клуба
но никто, правда, не подтверждает случаев такого использования. Хотя мне кажется очень логичным
Ну, у меня пагинация, завязанная на кохановский квери-билдер/орм работает почти так.
 

AmdY

Пью пиво
Команда форума
Sad Spirit
Тебе нужно совместить билдер с sql парсером типа https://code.google.com/p/php-sql-parser/
В doctrine так же есть разборщик DQL
В любом случае внизу должен лежать билдер, который дёргается парсером. Без билдера задалбёшся писать и отлаживать.
интересный проектик www.redbeanphp.com не использовал, но многообещающий..
Очень странный проект.
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Sad Spirit
Тебе нужно совместить билдер с sql парсером типа https://code.google.com/p/php-sql-parser/
В doctrine так же есть разборщик DQL
В любом случае внизу должен лежать билдер, который дёргается парсером. Без билдера задалбёшся писать и отлаживать.
Ну кстати, да, разумно. С одной стороны тогда можно будет прямо куски sql в запрос хреначить
PHP:
$query->addFrom(<<<SQL
(
  select ...
  from foo, bar, blah
  where ...
) as an_alias
SQL
);
А с другой можно будет делать предложенную Фанат'ом замену count(*) на * и обратно.
 

fixxxer

К.О.
Партнер клуба
Уже сейчас видно, что всё это будет глючить и тормозить :D
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Будет, куда денется. Главное, чтобы работало! А отваливающиеся куски изолентой примотаем...
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
deepslam
PHP:
$count = $select('count(*)')->from('blah')->where('blah.id', '=', 1);
$data = $count->select('*')->limit(5,10);
но никто, правда, не подтверждает случаев такого использования. Хотя мне кажется очень логичным
напомни завтра в чате, покажем ;)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
такой билдер на парсере - это только для cron-скриптов и админок; а как же всякие расширения SQL вида WITH RECURSIVE, FROM ONLY ?
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
такой билдер на парсере - это только для cron-скриптов и админок; а как же всякие расширения SQL вида WITH RECURSIVE, FROM ONLY ?
Если речь про то, что тупить будет, то надо кэшировать результат извращений, есессно. Запросы меняются редко, меняются обычно только их параметры.

Ну и полноценный парсер по большому счёту не очень нужен, из кусков SQL'я вытащить надо
* Названия / алиасы выбираемых колонок,
* Названия / алиасы элементов во FROM,
* Именованные placeholder'ы. Если собирать запрос из кусочков, то понятное дело, позиционными постгресовскими $1, $2, $3 пользоваться будет нереально.

Билдер да, либо допиливать готовый, чтобы позволял всякое, либо свой писать.
 

WMix

герр M:)ller
Партнер клуба
или я не понимаю о чем вы или этот трехколесный велосипед обсуждаете
PHP:
$sql = $db->select()
    ->from(array('b' => 'blah'), array(
        'counter' => new Zend_Db_Expr('count(*)'),
        'another'
    ))
    ->where('b.id = ?', 1);
$sql->limit(5,10);
$sql->columns('*')
// echo $sql->assemble();
return $db->fetchRow($sql);
Zend_Db_Select или на втором
Очень странный проект.
а что не понравилось?
 

fixxxer

К.О.
Партнер клуба
все эти зенддыбы позволяют писать в основном только запросы вида "вчера прочитал книжку по sql"

вот что-нибудь из этого тредика без сведения всего к банальной конкатенации ручками написанного sql-я эти зенддыбы осилят?

я знаю только один билдер, который осилит, и тот на питоне написан (sqlalchemy)
 

WMix

герр M:)ller
Партнер клуба
я уверен что можно, разложить селекты на переменные. те внутри не вижу ни единой трудности.
это я правда не знаю, но можно кусочки с текстом складывать.

PHP:
 //субселест
$subSelect = $db->select()->from('aktualne', array('n' => 'name'));
$select = $db->select()
                        ->from( array('akt' => $subSelect), array('n'))
                        ->where('akt.n = ?', 2008);
// union all
$select = $db->select()->union($select1, $select2, Zend_Db_Select::SQL_UNION_ALL);
// голый запрос
$stmt = $db->query(
            'SELECT * FROM bugs WHERE reported_by = ? AND bug_status = ?',
            array('goofy', 'FIXED')
        );
что еще вызывает трудности?
 

WMix

герр M:)ller
Партнер клуба
PHP:
$stmt = $db->query('with recursive overs as ( ? )', array( $select ) );
ну так то можно написать?
на край (эскейпинг)
PHP:
$stmt = $db->query('with recursive overs as ( ? )', array( new Zend_Db_Expr($select) ) );
 
Сверху