покритикуйте метод!

Духовность™

Продвинутый новичок
покритикуйте метод!

Очень часто приходится делать массу методов типа findById, findByUrl и пр. Т.е. логика SQL во всех методах разная, но сортировка, where и limit зачастую необходимо изменять. Например, когда получаем список комментариев, то метод должен уметь сортировать и так и эдак, и находить только определенные комменты и пр. условия.

Решил во всех базовых классах, там, где нужно, реализовать всё через массив параметров:

PHP:
    // вытаскивает список комментариев
    public function selectList($params = array())
    {
        $params = self::makeSqlFromParams($params);

        // в самом SQL метода - никаких явных WHERE, ORDER, LIMIT!  
        $res = $this->db->query('SELECT  * FROM table '.$params['where'].$params['order'].$params['limit']);

        // далее что-то делаем с $res..........
    }

    /*
    * Служебная функция формирования SQL запросов из массива параметров params.
    */
    protected static function makeSqlFromParams($params)
    {
        $params['where'] = !empty($params['where']) ? ' WHERE '.$params['where'].' ' : '';

        $params['limit'] = isset($params['start']) && is_numeric($params['start'])
                           ? ' LIMIT '.$params['start'].
                           (isset($params['stop']) && is_numeric($params['stop']) 
                            ? ', '.$params['stop']
                            : ''
                           )
                           : '';

        $order = '';

        if (isset($params['order']))
        {
            foreach ($params['order'] as $field => $method)
            {
                $order .= ' ORDER BY '.$field.' '.$method.', ';
            }

            $order = rtrim($order, ', ');
        }

        $params['order'] = $order;

        return $params;
    }
Вызывается так:

PHP:
$comments->selectList(array('where' => 'id_record ='.$post->getId(),
                            'order'=>array('id_comment'=>'DESC'),
                            'start'=>$startLimit,
                            'stop'=>$stopLimit
                           )
                     );
 

Ravanger

Новичок
я бы where тоже передавал бы как массив типа
PHP:
array('field' => 'value'[,...]);
 

Wicked

Новичок
имхо, еще один наколеночный конструктор запросов, который, работу с запросами не упрощает, а усложняет.

при этом, классически, чтобы сделать join'ы, подзапросы, group by, select for update, и т.д. - придется либо все делать с нуля, либо проводить через хаки а-ля
PHP:
'where' => 'id_record = '.$post->getId().' group by ...',
 

Ravanger

Новичок
Wicked
делать массу методов типа findById, findByUrl
весьма частный случай, для него можно и конструктор написать, он же не сказал, что это SQL билдер для всех запросов которые могут использоваться в работе
 

Wicked

Новичок
тем не менее, даже для поставленной задачи такое решение - жесть. Про это и была первая часть моего сообщения.
 

Духовность™

Продвинутый новичок
Wicked
метод selectList() должен возвращать список записей. при этом мы должны предусмотреть выборку по полям, сортировку, лимит. как ты это иначе сделаешь?
 

Wicked

Новичок
как-как :)
PHP:
$c = new Criteria();
$c->addDescendingOrderByColumn(CommentPeer::id_comment)
->addOffset($startLimit)
->addLimit($stopLimit - $startLimit);
$post->getComments($c);
 
triumvirat
Для простых, часто используемых запросов к одной таблице я использую несколько простых методов. Для запросов к нескольким таблицам, искользую JOIN-ы и т.д, приходится писать запросы вручную - другого вменяемого решения пока не нашел...

PHP:
    /**
     * ...
     *
     * @param string $sTable
     * @param string $sWhere
     * @return bool
     */
    public function simpleDelete($sTable, $sWhere = '') {
		//...
    }
    
    /**
     * ...
     *
     * @param string $sTable
     * @param string $sWhere
     * @param array $aColumns
     * @param string $sOrder
     * @return array
     */
    public function simpleSelect($sTable, $sWhere = '', $aColumns = array(), $sOrder = '') {
		//...
	}
    
    
    /**
     * ...
     *
     * @param string $sTable
     * @param array  $aUpdates
     * @param string $sWhere
     * @return integer
     */
    public function simpleUpdate($sTable, $aUpdates = array(), $sWhere = null) {
		//...
    }

    
    /**
     * ...
     *
     * @param string $sTable
     * @param array $aValues
     * @return integer
     */
    public function simpleInsert($sTable, $aValues = array()) {
		//...
    }
    
    
    /**
     * ...
     *
     * @param string $sTable
     * @return integer
     */
    public function simpleTruncate($sTable) {
		//...
    }
 

HraKK

Мудак
Команда форума
Переезжаем.
triumvirat
Пожалуйста, задавай свои философские вопросы в оффтопике, спасибо.
 

DYPA

Настоящая dypa (c)
лучше уж так
PHP:
function php(array $Array = array())
{
extract($Array);
echo $php.$net;
}
php(array('php'=>1,'net'=>2));
 

AmdY

Пью пиво
Команда форума
Автор оригинала: triumvirat
Wicked
хрен редьки не слаще :Р
:D
слаще. в случае с критерией легче отслеживать правильность запроса, а то в случае очепятки в ключе, можно незаметно потерять часть запроса.

-~{}~ 25.11.08 23:09:

и биндинга нету
 

newARTix

Новичок
Я вот тоже применяю функции наподобии предложений triumvirat и Loshadka. Конечно со своими особенностями, но принцип такой же.
Помоему, для _простых_ (по логике) запросов такие функции значительно сокращают код, повышают и читабельность и, как ни странно, безопасность.

Если передавать в функцию информацию о таблице, можно не просто формировать запрос, но и фильтровать данные в зависимости от типа столбца. (Хотя тут конечно вопрос спорный, о прозрачности этого момента). А если эти простенькие функции подключить к классу абстракции БД, дать им возможность автоматически получать информацию о таблице, кэшировать ее, кэшировать сформированные запросы по хэшу переданных параметров...
Тут главное вовремя остановиться. Все-таки такие функции это _хелперы_, а не мини-ORM.

Сложные же запросы, чаще всего ориентируются на особенности движка конкретной БД и особенности задачи, и делать для них абстракции и универсалии, помоему - абсурд.
 

Angerslave

Новичок
newARTix
Плюсадын. Сам себе сделал что-то подобное и не заморачиваюсь, что она сама связи не обрабатывает, JOIN'ы с UNION'ами не делает и т.п.
 
Сверху