SQLite3::createAggregate
(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
-
Номер текущей строки.
-
value
-
Первый аргумент переданный агрегатору.
-
values
-
Последующие аргументы.
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().