(PHP 5 >= 5.3.0, PHP 7)
SQLite3::createAggregate — Зарегистрировать функцию PHP в качестве агрегирующей функции SQL
$name
, mixed $step_callback
, mixed $final_callback
[, int $argument_count
= -1
] ) : boolРегистрирует функцию PHP или пользовательскую функцию в качестве агрегирующей функции SQL для использования в запросах.
name
Имя агрегирующей функции SQL, которая должна быть создана или переопределена.
step_callback
Функция обратного вызова, которая будет вызвана для каждой строки результирующего набора. Ваша PHP-функция должна аккумулировать результат и хранить его в контексте агрегации.
Эта функция должна быть определена следующим образом:
context
Для первой строки должено равняться NULL
;
Для всех последующих строк его значение должно быть равно значению,
возвращенному на предыдущем шаге; вы должны использовать его для сохранения
состояния агрегации.
rownumber
Номер текущей строки.
value1
Первый аргумент переданный агрегатору.
...
Последующие аргументы.
context
при следующем запуске функции, либо как
значение передаваемое финализирующей функции.
final_callback
Функция обратного вызова для вычисление итогового агрегированного значения. Она будет вызвана как только все строки результирующего набора будут обработаны, ей будет передан агрегирующий контекст и она вернет финальное значение. Данная функция должна вернуть значение типа понятного SQLite (т.е. скалярный тип).
Эта функция должна быть определена следующим образом:
context
Содержит результат самого последнего вызова агрегирующей функции.
rownumber
Всегда 0.
argument_count
Количество аргументов, которое принимает функция агрегированиия SQL. Если значение отрицательное, то функция может использовать любое количество аргументов.
Возвращает TRUE
или FALSE
в зависимости от успешности создания.
Пример #1 Пример агрегирующей функции max_length
<?php
$data = array(
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine',
'ten',
);
$db = new SQLite3(':memory:');
$db->exec("CREATE TABLE strings(a)");
$insert = $db->prepare('INSERT INTO strings VALUES (?)');
foreach ($data as $str) {
$insert->bindValue(1, $str);
$insert->execute();
}
$insert = null;
function max_len_step($context, $rownumber, $string)
{
if (strlen($string) > $context) {
$context = strlen($string);
}
return $context;
}
function max_len_finalize($context, $rownumber)
{
return $context === null ? 0 : $context;
}
$db->createAggregate('max_len', 'max_len_step', 'max_len_finalize');
var_dump($db->querySingle('SELECT max_len(a) from strings'));
?>
Результат выполнения данного примера:
int(5)
В этом примере мы написали агрегирующую функцию, которая вычисляет самой длинной строки в одной колонке таблицы. Для каждой строки вызывается функция max_len_step и ей передается параметр $context. Этот параметр ничем не отличается от обычной переменной PHP и спокойно может содержать массив или объект. В этом примере мы используем ее для хранения максимальной найденной длины строки. Если $string будет иметь длину больше, чем текущая сохраненная, то значение контекста будет обновлено.
После того, как все строки обработаны, SQLite вызовет функцию max_len_finalize, для окончательной подготовки результата. Тут мы можем произвести необходимые расчеты на основе данных из $context. В нашем простом примере никакая постобрпботке не нужна и мы просто возвращаем полученное значение.
НЕ рекомендуется хранить копию значений в контексте, а обработку производить в финализирующей функции, так как это может привести к большому потреблению памяти при обработке запроса. Просто представьте, сколько памяти вам понадобится для хранения миллиона строк, по 32 байта каждая, в памяти.
Для переопределения встроенных в SQLite агрегирующих функций вы можете использовать SQLite3::createAggregate().