PHP 8.4.2 Released!

SQLite3::createAggregate

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

SQLite3::createAggregateRegistra uma função PHP para uso como uma função de agregação SQL

Descrição

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

Registra uma função PHP ou uma função definida pelo usuário para uso como uma função de agregação SQL dentro de declarações SQL.

Parâmetros

name

Nome do agregado SQL a ser criado ou redefinido.

stepCallback

Função de retorno de chamada chamada para cada linha do conjunto de resultados. Sua função PHP deve acumular o resultado e armazená-lo no contexto de agregação.

Esta função deve ser definida como:

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

null para a primeira linha; nas linhas subsequentes, terá o valor que foi retornado anteriormente pela função step; você deve usar isso para manter o estado de agregação.

rownumber

O número da linha atual.

value

O primeiro argumento passado para a agregação.

values

Outros argumentos passados para a agregação.

O valor de retorno desta função será usado como o argumento context na próxima chamada das funções step ou finalize.

finalCallback

Função de retorno de chamada para agregar os dados "passados" de cada linha. Depois que todas as linhas forem processadas, esta função será chamada e ela deve então pegar os dados do contexto de agregação e retornar o resultado. Esta função de retorno de chamada deve retornar um tipo compreendido pelo SQLite (ou seja, tipo escalar).

Esta função deve ser definida como:

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

Mantém o valor de retorno da última chamada à função step.

rownumber

Sempre 0.

O valor de retorno desta função será usado como o valor de retorno para o agregado.

argCount

O número de argumentos que o agregado SQL recebe. Se este parâmetro for negativo, então o agregado SQL pode receber qualquer número de argumentos.

Valor Retornado

Retorna true após a criação bem-sucedida do agregado, ou false em caso de falha.

Exemplos

Exemplo #1 Exemplo de função de agregação 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'));
?>

O exemplo acima produzirá:

int(5)

Neste exemplo, estamos criando uma função de agregação que calculará o comprimento da string mais longa em uma das colunas da tabela. Para cada linha, a função max_len_step é chamada e passada um parâmetro $context. O parâmetro de contexto é como qualquer outra variável PHP e pode ser definido para conter um array ou até mesmo um valor de objeto. Neste exemplo, estamos simplesmente usando-o para conter o comprimento máximo que vimos até agora; se a $string tiver um comprimento maior do que o máximo atual, atualizamos o contexto para armazenar este novo comprimento máximo.

Depois que todas as linhas forem processadas, o SQLite chama a função max_len_finalize para determinar o resultado da agregação. Aqui, poderíamos realizar algum tipo de cálculo com base nos dados encontrados no $context. Em nosso exemplo simples porém, estivemos calculando o resultado à medida que a consulta progredia, então simplesmente precisamos retornar o valor de contexto.

Dica

NÃO é recomendado que você armazene uma cópia dos valores no contexto e depois os processe no final, pois você faria com que o SQLite usasse muita memória para processar a consulta - apenas pense em quanto de memória você precisaria se um milhão de linhas fossem armazenadas em memória, cada uma contendo uma string de 32 bytes de comprimento.

Dica

Você pode usar SQLite3::createAggregate() para substituir funções SQL nativas do SQLite.

adicione uma nota

Notas Enviadas por Usuários (em inglês) 2 notes

up
4
boris dot dd at gmail dot com
7 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
9 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