PDO::sqliteCreateAggregate

SQL 文で使用する集約ユーザー定義関数 (UDF) を登録する

説明

public bool PDO::sqliteCreateAggregate(
    string $function_name,
    callable $step_func,
    callable $finalize_func,
    int $num_args = ?
)
警告

この関数は、 実験的 なものです。この関数の動作・ 名前・その他ドキュメントに書かれている事項は、予告なく、将来的な PHP のリリースにおいて変更される可能性があります。 この関数は自己責任で使用してください。

このメソッドは PDO::sqliteCreateFunction と似ていますが、 この関数で登録した関数は、クエリのすべての行の内容を集約する関数を登録します。

この関数と PDO::sqliteCreateFunction の最大の違いは、 集約関数を作成するためには 2 つの関数が必要であるということです。

パラメータ

function_name

SQL 文で使用する関数の名前。

step_func

結果セットの各行についてコールされるコールバック関数。 この PHP 関数は、結果を蓄積して集約コンテキストに保存しなければなりません。

この関数は次のように定義しなければなりません。

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

最初の行では null 二行目以降では、ステップ関数から以前返された値を持ちます。 この値を、集約の状態を管理するのに使うべきです。

rownumber

現在の行番号

value

集約関数に渡されるはじめの引数

values

集約関数に渡されるふたつめ以降の引数

この関数の戻り値を、次のステップあるいはファイナライズ関数の context 引数として使います。

finalize_func

すべての行が処理された後でコールされるコールバック関数。 ここでは、集約コンテキストからデータを取得して結果を返します。 コールバック関数の返す値は、SQLite が理解できる形式 (すなわち スカラー型) でなければなりません。

この関数は次のように定義しなければなりません。

mixed fini(mixed $context, int $rowcount)
context

ステップ関数を最後に呼んだ時の戻り値を保持します。

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, $rownumber) 
{
    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 の内容に基づいた、 なんらかの計算を行うことができます。 しかし、この例ではクエリを処理している過程で既に結果が決定しているので、 ここでは単に context の値を返しているだけです。

ヒント

結果の値を context に溜め込んでおき、最後に一括して処理するという方法は推奨 「しません」。これは、SQLite のメモリ消費量が大きくなるからです。 仮に 32 バイトの長さのデータが百万件あったとして、 それを溜め込むためにどれだけのメモリが必要になるか考えてみましょう。

ヒント

PDO::sqliteCreateFunction および PDO::sqliteCreateAggregate を使用して、 SQLite のネイティブ SQL 関数を上書きすることができます。

参考