Помните, в Kohana v2.3.4 был такой метод объекта Database? Если нет, то напомню — данный метод возвращал общее количество записей для предыдущего запроса. Например, выбрали 10 первых записей из выборки, а потом вызвали $this->db->count_last_query()
и узнали, что всего записей 35. Стоп, скажете Вы! Ведь есть метод count_records()
, который занимается тем же самым. Да, count_records()
считает все записи, но count_last_query()
учитывает все примененные условия последнего запроса (WHERE, HAVING и т.д.). Зачем это нужно? В первую очередь для модуля Pagination, ведь надо как-то вычислять общее количество страниц, а оно зависит именно от числа записей.
Так вот, в Ko3 такого метода нет. Почему — непонятно, хотя сделать его несложно. По сути просто берется текст последнего запроса и вырезаются модификаторы LIMIT и OFFSET. Вспоминаем лозунг «спасение утопающих — дело рук самих утопающих», и переносим метод count_last_query()
из 2.3.4 в 3.0. У меня получилось вот так:
/** * Count the number of records in the last query, without LIMIT or OFFSET applied. * * @return integer */ public function count_last_query() { if ($sql = $this->last_query) { $sql = trim($sql); if (stripos($sql, 'SELECT') !== 0) { return FALSE; } if (stripos($sql, 'LIMIT') !== FALSE) { // Remove LIMIT from the SQL $sql = preg_replace('/sLIMITs+[^a-z]+/i', ' ', $sql); } if (stripos($sql, 'OFFSET') !== FALSE) { // Remove OFFSET from the SQL $sql = preg_replace('/sOFFSETs+d+/i', '', $sql); } // Get the total rows from the last query executed $result = $this->query ( Database::SELECT, 'SELECT COUNT(*) AS '.$this->quote_identifier('total_rows').' '. 'FROM ('.$sql.') AS '.$this->quote_table('counted_results'), TRUE ); // Return the total number of rows from the query return (int) $result->current()->total_rows; } return FALSE; } |
Закидываем это в файл APPPATH/classes/database.php, чтобы не редактировать системный класс Kohana_Database. Проверяем — должно работать. Если хочется, чтобы заработало и в ORM (обычно с Pagination используют именно ORM), надо создать в нем метод count_last_query()
, где прописать вызов $this->_db->count_last_query()
. Естественно, править надо не сам системный файл MODPATH/orm/classes/kohana/orm.php, а создать свой — APPPATH/classes/orm.php.
Вот и все. Пользуйтесь на здоровье
Кхм странно что его нет в третей линейке. А я сижу себе в 2.3.4 и радуюсь
Господи, почему нельзя просто использовать SQL_CALC_FOUND_ROWS()/FOUND_ROWS()
@Werewolf
Это решение специфично для MySQL. Кроме того, требуется заранее модифицировать свой запрос (добавить SQL_CALC_FOUND_ROWS). Помните, что класс Database абстрагируется от конкретной СУБД.
count_last_query генерирует очень тяжелый запрос с точки зрения SQL. Любой оптимизатор застрелиться увидев такой запрос
Оптимизация и универсализм вообще понятия малосовместимые Вообще, как минимум под MySQL можно попытаться данный запрос урезать.
Werewolf — Согласен я тоже его использую
Согласен с Werewolf , проект у меня под Мускуль, юзаю такую фичу.
Правда если перейду на другу СУБД, то поплачусь. Хорошо, что в 3,0,5 вышла такая фича. Теперь можно сделать переключение на SQL_CALC_FOUND_ROWS() или COUNT().