Постановка задачи: требуется составить Criteria для Propel, который позволяет выполнить запрос с использованием CASE WHEN и при этом не потерять выбираемые колонки и гидрацию объектов.
Собственно казалось бы, используем конструкцию $criteria->addAsColumn(…) и все. Но не тут то было, при использовании этого запроса теряются все колонки, выбираемые по-умолчанию Propel’ом.
Итак, вот, пример запроса который нам нужно выполнить:
SELECT `table`.`id`, `table`.`field1`, `table`.`field2`, CASE WHEN `table`.`photo_count` > 0 THEN 1 WHEN `table`.`photo_count` = 0 THEN 0 END as has_photo FROM `table` WHERE `table`.`status_id` = 2 AND `table`.`type_id` = 1 ... ORDER BY has_photo DESC, `table`.`created_at` DESC
Ключевые особенности – дополнительное “поле” photo_count принимает значение 0 или 1 и по нему осуществляется сортировка. При этом на выходе мы хотим получить Propel-объекты.
На самом деле решение очень простое:
PropertyPeer::addSelectColumns( $criteria ); $criteria->addAsColumn( "has_photo" , "CASE WHEN " . TablePeer::PHOTO_COUNT . " > 0 THEN 1 " . "WHEN " . TablePeer::PHOTO_COUNT . " = 0 THEN 0 END" ); $criteria->addDescendingOrderByColumn( "has_photo" );
Ключевой особенностью этого решения является первая строка. Просто, не так ли? Тем не менее чтобы найти решение проблемы потребовался не один час, куча нервов. Собственно ответ был найден в trac’е propel – http://propel.phpdb.org/trac/ticket/643
с уважением, отдел по борьбе с propel )))