mirror of
https://github.com/php/doc-en.git
synced 2026-03-24 07:42:10 +01:00
286 lines
9.1 KiB
XML
286 lines
9.1 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<refentry xml:id="pdo-sqlite.createaggregate" xmlns="http://docbook.org/ns/docbook">
|
|
<refnamediv>
|
|
<refname>Pdo\Sqlite::createAggregate</refname>
|
|
<refpurpose>
|
|
Registers an aggregating user-defined function for use in SQL statements
|
|
</refpurpose>
|
|
</refnamediv>
|
|
|
|
<refsect1 role="description">
|
|
&reftitle.description;
|
|
<methodsynopsis role="Pdo\\Sqlite">
|
|
<modifier>public</modifier> <type>bool</type><methodname>Pdo\Sqlite::createAggregate</methodname>
|
|
<methodparam><type>string</type><parameter>name</parameter></methodparam>
|
|
<methodparam><type>callable</type><parameter>step</parameter></methodparam>
|
|
<methodparam><type>callable</type><parameter>finalize</parameter></methodparam>
|
|
<methodparam choice="opt"><type>int</type><parameter>numArgs</parameter><initializer>-1</initializer></methodparam>
|
|
</methodsynopsis>
|
|
<simpara>
|
|
This method is similar to <methodname>Pdo\Sqlite::createFunction</methodname>
|
|
except that it registers functions that can be used to calculate a
|
|
result aggregated across all the rows of a query.
|
|
</simpara>
|
|
<simpara>
|
|
The key difference between this method and
|
|
<methodname>Pdo\Sqlite::createFunction</methodname>
|
|
is that two functions are required to manage the aggregate.
|
|
</simpara>
|
|
<tip>
|
|
<simpara>
|
|
By using this method it is possible to override native SQL functions.
|
|
</simpara>
|
|
</tip>
|
|
</refsect1>
|
|
|
|
<refsect1 role="parameters">
|
|
&reftitle.parameters;
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><parameter>name</parameter></term>
|
|
<listitem>
|
|
<simpara>
|
|
The name of the function used in SQL statements.
|
|
</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><parameter>step</parameter></term>
|
|
<listitem>
|
|
<simpara>
|
|
Callback function called for each row of the result set.
|
|
The callback should accumulate the result and store it in the aggregation context.
|
|
</simpara>
|
|
<para>
|
|
This function need to be defined as:
|
|
<methodsynopsis>
|
|
<type>mixed</type><methodname><replaceable>step</replaceable></methodname>
|
|
<methodparam><type>mixed</type><parameter>context</parameter></methodparam>
|
|
<methodparam><type>int</type><parameter>rownumber</parameter></methodparam>
|
|
<methodparam><type>mixed</type><parameter>value</parameter></methodparam>
|
|
<methodparam rep="repeat"><type>mixed</type><parameter>values</parameter></methodparam>
|
|
</methodsynopsis>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><parameter>context</parameter></term>
|
|
<listitem>
|
|
<simpara>
|
|
&null; for the first row; on subsequent rows it will have the value
|
|
that was previously returned from the step function; you should use
|
|
this to maintain the aggregate state.
|
|
</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><parameter>rownumber</parameter></term>
|
|
<listitem>
|
|
<simpara>
|
|
The current row number.
|
|
</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><parameter>value</parameter></term>
|
|
<listitem>
|
|
<simpara>
|
|
The first argument passed to the aggregate.
|
|
</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><parameter>values</parameter></term>
|
|
<listitem>
|
|
<simpara>
|
|
Further arguments passed to the aggregate.
|
|
</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
The return value of this function will be used as the
|
|
<parameter>context</parameter> argument in the next call of the step or
|
|
finalize functions.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><parameter>finalize</parameter></term>
|
|
<listitem>
|
|
<simpara>
|
|
Callback function to aggregate the "stepped" data from each row.
|
|
Once all the rows have been processed, this function will be called,
|
|
and it should then take the data from the aggregation context and return the result.
|
|
This callback function should return a type understood by SQLite
|
|
(i.e. <link linkend="language.types.intro">scalar type</link>).
|
|
</simpara>
|
|
<para>
|
|
This function need to be defined as:
|
|
<methodsynopsis>
|
|
<type>mixed</type><methodname><replaceable>fini</replaceable></methodname>
|
|
<methodparam><type>mixed</type><parameter>context</parameter></methodparam>
|
|
<methodparam><type>int</type><parameter>rowcount</parameter></methodparam>
|
|
</methodsynopsis>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><parameter>context</parameter></term>
|
|
<listitem>
|
|
<para>
|
|
Holds the return value from the very last call to the step function.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><parameter>rowcount</parameter></term>
|
|
<listitem>
|
|
<para>
|
|
Holds the number of rows over which the aggregate was performed.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
The return value of this function will be used as the return value for
|
|
the aggregate.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><parameter>numArgs</parameter></term>
|
|
<listitem>
|
|
<simpara>
|
|
Hint to the SQLite parser if the callback function accepts a
|
|
predetermined number of arguments.
|
|
</simpara>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</refsect1>
|
|
|
|
<refsect1 role="returnvalues">
|
|
&reftitle.returnvalues;
|
|
<simpara>
|
|
&return.success;
|
|
</simpara>
|
|
</refsect1>
|
|
|
|
<refsect1 role="examples">
|
|
&reftitle.examples;
|
|
<example>
|
|
<title><methodname>Pdo\Sqlite::createAggregate</methodname> example</title>
|
|
<simpara>
|
|
In this example we will create a custom aggregate function named
|
|
<literal>max_length</literal> that can be used in SQL queries.
|
|
</simpara>
|
|
<simpara>
|
|
In this example, we are creating an aggregating function,
|
|
named <literal>max_length</literal>, that will calculate the length
|
|
of the longest string in one of the columns of the table.
|
|
For each row, the <literal>max_len_step</literal> function is called and
|
|
passed a <literal>$context</literal> parameter.
|
|
The context parameter is just like any other PHP variable and be set to
|
|
hold an <type>array</type> or even an <type>object</type>.
|
|
In this example, we are using it to hold the maximum length we have seen so far;
|
|
if the <varname>$string</varname> has a length longer than the current maximum,
|
|
we update the context to hold this new maximum length.
|
|
</simpara>
|
|
<simpara>
|
|
After all the rows have been processed,
|
|
SQLite calls the <literal>max_len_finalize</literal> function to determine
|
|
the aggregate result.
|
|
It is possible to perform some kind of calculation based on the data in <literal>$context</literal>.
|
|
In this basic example the result was calculated as the query progressed,
|
|
thus so the context value can be directly returned.
|
|
</simpara>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$data = [
|
|
'one',
|
|
'two',
|
|
'three',
|
|
'four',
|
|
'five',
|
|
'six',
|
|
'seven',
|
|
'eight',
|
|
'nine',
|
|
'ten',
|
|
];
|
|
$db = new Pdo\Sqlite('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, $row_number, $string)
|
|
{
|
|
if (strlen($string) > $context) {
|
|
$context = strlen($string);
|
|
}
|
|
return $context;
|
|
}
|
|
|
|
function max_len_finalize($context, $row_count)
|
|
{
|
|
return $context === null ? 0 : $context;
|
|
}
|
|
|
|
$db->createAggregate('max_len', 'max_len_step', 'max_len_finalize');
|
|
|
|
var_dump($db->query('SELECT max_len(a) from strings')->fetchAll());
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
<!-- TODO
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
Code example
|
|
]]>
|
|
</screen>
|
|
-->
|
|
<tip>
|
|
<simpara>
|
|
It is NOT recommended for you to store a copy of the values in the context
|
|
and then process them at the end, as you would cause SQLite to use a lot of
|
|
memory to process the query - just think of how much memory you would need
|
|
if a million rows were stored in memory, each containing a string 32 bytes
|
|
in length.
|
|
</simpara>
|
|
</tip>
|
|
</example>
|
|
</refsect1>
|
|
|
|
<refsect1 role="seealso">
|
|
&reftitle.seealso;
|
|
<simplelist>
|
|
<member><methodname>Pdo\Sqlite::createFunction</methodname></member>
|
|
<member><methodname>Pdo\Sqlite::createCollation</methodname></member>
|
|
<member><function>sqlite_create_function</function></member>
|
|
<member><function>sqlite_create_aggregate</function></member>
|
|
</simplelist>
|
|
</refsect1>
|
|
|
|
</refentry>
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|