PHP 8.5.0 Alpha 2 available for testing

SQLite3::createAggregate

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

SQLite3::createAggregateRegistra una función PHP para ser utilizada como función de agregación SQLite

Descripción

public SQLite3::createAggregate(
    string $name,
    callable $stepCallback,
    callable $finalCallback,
    int $argCount = -1
): bool

Registra una función PHP o una función definida por el usuario para ser utilizada como función de agregación SQL, que será utilizada en las consultas SQL.

Parámetros

name

Nombre de la función de agregación SQL a crear o redefinir.

stepCallback

Función de retrollamada llamada para cada fila en el conjunto de resultados. Su función PHP debería acumular el resultado y almacenar su contexto de agregación.

Esta función debe ser definida como:

step(
    mixed $context,
    int $rownumber,
    mixed $value,
    mixed ...$values
): mixed
context

null para la primera fila; en las filas siguientes esto tendrá el valor que previamente fue retornado por la función step; debería utilizarse esto para mantener el estado de agregación.

rownumber

El número de fila actual.

value

El primer argumento a pasar al agregador.

values

Argumentos adicionales a pasar al agregador.

El valor retornado por esta función será utilizado como argumento context durante la próxima llamada a una función de paso o final.

finalCallback

Función de retrollamada para agregar los "pasos" de datos de cada fila. Una vez que todas las filas han sido procesadas, la función será llamada, tomará los datos del contexto de agregación y retornará el resultado. La función de retrollamada debe retornar un tipo comprendido por SQLite (i.e. un tipo escalar).

Esta función debe ser definida como:

fini(mixed $context, int $rownumber): mixed
context

Contiene el valor de retorno de la última llamada a la función step.

rownumber

Siempre 0.

El valor de retorno de esta función será utilizado como valor de retorno para la agregación.

argCount

El número de argumentos tomados por la función de agregación SQL. Si este número es negativo, entonces la función de agregación SQL podrá tomar un número no definido de argumentos.

Valores devueltos

Retorna true si la creación del agregado ha tenido éxito, o false si ocurre un error.

Ejemplos

Ejemplo #1 Ejemplo de una función de agregación con 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'));
?>

El ejemplo anterior mostrará :

int(5)

En este ejemplo, se crea una función agregativa que calculará la longitud de la cadena de caracteres más larga en una de las columnas de la tabla. Para cada fila, la función max_len_step es llamada y el parámetro $context es pasado. El parámetro de contexto es como cualquier otra variable PHP y debe ser fijado para contener un array o incluso, un objeto. En este ejemplo, se utiliza para contener la longitud máxima que se ha visto hasta el momento; si el parámetro $string tiene una longitud mayor que la actual, se actualiza el contexto para contener esta nueva longitud máxima.

Una vez que todas las filas han sido procesadas, SQLite llama a la función max_len_finalize para determinar el resultado agregativo. Aquí, se podrían realizar cálculos basados en los datos encontrados en $context. En nuestro ejemplo simple, hemos calculado el resultado como si la consulta estuviera progresando, aunque simplemente necesitamos retornar el valor de contexto.

Sugerencia

No se RECOMIENDA registrar una copia de los valores en el contexto para finalmente procesarlos. En este caso, SQLite utilizaría mucha memoria para procesar la consulta - imagine la cantidad de memoria necesaria si un millón de filas fueran registradas en memoria, sabiendo que cada fila contiene una cadena de caracteres (32 bytes por cadena).

Sugerencia

Puede utilizarse SQLite3::createAggregate() para sobrescribir las funciones nativas de SQLite.

add a note

User Contributed Notes 2 notes

up
8
boris dot dd at gmail dot com
8 years ago
<?php
class Test extends SQLite3
{
public function
__construct($file)
{
parent::__construct($file);
$this->createAggregate('groupConcat', [$this, 'concatStep'], [$this, 'concatFinal']);
}
public function
concatStep(&$context, $rowId, $string, $delimiter)
{
if (!isset(
$context)) {
$context = [
'delimiter' => $delimiter,
'data' => []
];
}
$context['data'][] = $string;
return
$context;
}
public function
concatFinal(&$context)
{
return
implode($context['delimiter'], $context['data']);
}
}
$SQLite = new Test('/tmp/test.sqlite');
$SQLite->exec("create table `test` (`id` TEXT, `color` TEXT, `size` TEXT)");
$SQLite->exec("insert into `test` (`id`, `color`, `size`) values ('1', 'red', 'M')");
$SQLite->exec("insert into `test` (`id`, `color`, `size`) values ('1', 'green', 'M')");
$SQLite->exec("insert into `test` (`id`, `color`, `size`) values ('1', 'blue', 'S')");
$Result = $SQLite->query("select `size`, groupConcat(`color`, ';') as `color` from `test` group by `size`");
while (
$row = $Result->fetchArray(SQLITE3_ASSOC)) {
print_r($row);
}
/*
Array
(
[size] => M
[color] => red;green
)
Array
(
[size] => S
[color] => blue
)
*/
up
-3
sukmaagungsaputra at gmail dot com
10 years ago
Lacks of example, right?
Let's try to give to SQlite3 the capability like ones of MySQL's
- REGEXP operator,
- MD5 function, and
- GROUP_CONCAT aggregate function

$db = new SQLite3($filename);
$db->createFunction('regexp', function ($a,$b) { return preg_match("/$a/i", $b); });
$db->createFunction('md5', function ($a) { return md5($a); });
$db->createAggregate ('group_concat',
function(&$context, $rownumber, $str) { $context[]=$str; return $context; },
function(&$context) {return implode(",", (array) $context); });
To Top