PDO::sqliteCreateAggregate
(PHP 5 >= 5.1.0, PHP 7, PECL pdo_sqlite >= 1.0.0)
PDO::sqliteCreateAggregate — Регистрация агрегирующей пользовательской функции для использования в SQL-запросах
Описание
$function_name
, callable $step_func
, callable $finalize_func
, int $num_args
= ?
) : boolЭта функция является ЭКСПЕРИМЕНТАЛЬНОЙ. Поведение этой функции, ее имя и относящаяся к ней документация могут измениться в последующих версиях PHP без уведомления. Используйте эту функцию на свой страх и риск.
Этот метод аналогичен PDO::sqliteCreateFunction, за исключением того, что он регистрирует функцию, которую можно использовать для вычисления агрегированного результата по всем строкам в запросе.
Ключевое отличие этого метода от PDO::sqliteCreateFunction в том, что для управление агрегированием требует использование двух функций.
Список параметров
-
function_name
-
Имя функции для использовании в запросах.
-
step_func
-
Функция обратного вызова для каждой строки в результирующем наборе. Ваша PHP-функция должна аккумулировать результат и сохранять его в контексте агрегации.
Эта функция должна быть определена следующим образом:
-
context
-
Для первой строки должено равняться
null
; Для всех последующих строк его значение должно быть равно значению, возвращенному на предыдущем шаге; вы должны использовать его для сохранения состояния агрегации. -
rownumber
-
Номер текущей строки.
-
value
-
Первый аргумент переданный агрегатору.
-
values
-
Последующие аргументы.
context
при следующем запуске функции, либо как значение передаваемое финализирующей функции. -
-
finalize_func
-
Функция обратного вызова для вычисление итогового агрегированного значения. Она будет вызвана как только все строки результирующего набора будут обработаны, ей будет передан агрегирующий контекст и она вернет финальное значение. Данная функция должна вернуть значение типа понятного SQLite (т.е. скалярный тип).
Эта функция должна быть определена следующим образом:
-
context
-
Содержит значение, возвращанное самым последним вызовом агрегирующей функции step_func.
-
rowcount
-
Количество строк, к которым применялась агрегирующая функция.
-
-
num_args
-
Подсказка для парсера SQLite, если функция обратного вызова получает заданное количество аргументов.
Возвращаемые значения
Возвращает true
в случае успешного завершения или false
в случае возникновения ошибки.
Примеры
Пример #1 Пример агрегирующей функции max_length
<?php
$data = array(
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine',
'ten',
);
$db = new PDO('sqlite::memory:');
$db->exec("CREATE TABLE strings(a)");
$insert = $db->prepare('INSERT INTO strings VALUES (?)');
foreach ($data as $str) {
$insert->execute(array($str));
}
$insert = null;
function max_len_step($context, $rownumber, $string)
{
if (strlen($string) > $context) {
$context = strlen($string);
}
return $context;
}
function max_len_finalize($context, $rowcount)
{
return $context === null ? 0 : $context;
}
$db->sqliteCreateAggregate('max_len', 'max_len_step', 'max_len_finalize');
var_dump($db->query('SELECT max_len(a) from strings')->fetchAll());
?>
В этом примере мы создали агрегирующую функцию, которая
вычисляет длину самой большой строки в одном из столбцов таблицы.
Для каждой строки, вызывается функция max_len_step
и ей
передается параметр $context
. Этот параметр,
как и любая другая переменная PHP может содержать и массив и объект.
В данном примере она используется для хранения максимальной длины строки;
Если $string
имеет длину большую, чем содержится в
контексте, мы обновляем контекст новым значением.
После того, как будут обработаны все строки, SQLite вызовет функцию
max_len_finalize
для вычисления результата агрегации.
В ней мы производим вычисления, основываясь на данных из
$context
. В нашем простом примере мы просто
возвращаем его значение, так как никакие дополнительные вычисления не требуются.
КРАЙНЕ НЕ рекомендуется сохранять в контексте копии значений для обработки их в финализирующей функции, так как это повлечет за собой большой перерасход памяти SQLite для обработки запроса. Просто представьте, сколько памяти вам понадобится, если вам потребуется агрегировать, например, миллион значений по 32 байта.
Вы можете использовать PDO::sqliteCreateFunction и PDO::sqliteCreateAggregate для переопределения стандартных агрегирующих функций SQLite.