git-svn-id: https://svn.php.net/repository/phpdoc/ru/trunk@342288 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
Andrey Gromov
2017-04-10 13:45:05 +00:00
parent c68bf29f5b
commit 15866ad4db
3 changed files with 617 additions and 0 deletions

View File

@ -0,0 +1,260 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: dc706816c30f61d28686b4bf43f5b09e6d2de8e0 Maintainer: rjhdby Status: ready -->
<!-- Reviewed: no -->
<refentry xml:id="pdo.sqlitecreateaggregate" xmlns="http://docbook.org/ns/docbook">
<refnamediv>
<refname>PDO::sqliteCreateAggregate</refname>
<refpurpose>
Регистрация аггрегирующей пользовательской функции для использования в SQL-запросах
</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>PDO::sqliteCreateAggregate</methodname>
<methodparam><type>string</type><parameter>function_name</parameter></methodparam>
<methodparam><type>callable</type><parameter>step_func</parameter></methodparam>
<methodparam><type>callable</type><parameter>finalize_func</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>num_args</parameter></methodparam>
</methodsynopsis>
&warn.experimental.func;
<para>
Этот метод аналогичен <xref linkend="pdo.sqlitecreatefunction"
/> за исключением того, что он регистрирует функцию, которую можно использовать
для вычисления аггрегированного результата по всем строкам в запросе.
</para>
<para>
Ключевое отличие этого метода от <xref
linkend="pdo.sqlitecreatefunction" /> в том, что для управление аггрегированием требует
использование двух функций.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>function_name</parameter></term>
<listitem>
<para>
Имя функции для использовании в запросах.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>step_func</parameter></term>
<listitem>
<para>
Функция обратного вызова для каждой строки в результирующем наборе.
Ваша PHP-функция должна акумулировать результат и сохранять его в
контексте аггрегации.
</para>
<para>
Эта функция должна быть определена следующим образом:
<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>value1</parameter></methodparam>
<methodparam choice="opt"><type>mixed</type><parameter>value2</parameter></methodparam>
<methodparam choice="opt"><type>mixed</type><parameter>..</parameter></methodparam>
</methodsynopsis>
</para>
<para>
Для первой строки <varname>context</varname> должен равняться &null;;
Для всех последующих строк его значение должно быть равно значению,
возвращенному на предыдущем шаге; вы должны использовать его для сохранения
состояния аггрегации.
</para>
<para>
Параметр <varname>rownumber</varname> должен быть равен номеру текущей строки.
</para>
<para>
Возвращаемое значение функции будет использовано как параметр
<parameter>context</parameter> при следующем запуске функции, либо как
значение передаваемое финализирующей функции.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>finalize_func</parameter></term>
<listitem>
<para>
Функция обратного вызова для вычисление итогового аггрегированного
значения. Она будет вызвана как только все строки результирующего набора
будут обработаны, ей будет передан аггрегирующий контекст и она вернет
финальное значение. Данная функция должна вернуть значение типа понятного
SQLite (т.е. <link
linkend="language.types.intro">скалярный тип</link>).
</para>
<para>
Эта функция должна быть определена следующим образом:
<methodsynopsis>
<type>mixed</type><methodname><replaceable>fini</replaceable></methodname>
<methodparam><type>mixed</type><parameter>context</parameter></methodparam>
<methodparam><type>int</type><parameter>rownumber</parameter></methodparam>
</methodsynopsis>
</para>
<para>
<varname>context</varname> - значение, возвращанное самым последним
вызовом аггрегирующей функции step_func.
</para>
<para>
<varname>rownumber</varname> - количество строк, к которым применялась
аггрегирующая функция.
</para>
<para>
Возвращаемое значение этой функции будет использовано как
результат аггрегации.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>num_args</parameter></term>
<listitem>
<para>
Подсказка для парсера SQLite, если функция обратного вызова получает
заданное количество аргументов.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&return.success;
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title>Пример аггрегирующей функции max_length</title>
<programlisting role="php">
<![CDATA[
<?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());
?>
]]>
</programlisting>
</example>
</para>
<para>
В этом примере мы создали аггрегирующую функцию, которая
вычисляет длину самой большой строки в одном из столбцов таблицы.
Для каждой строки, вызывается функция <literal>max_len_step</literal> и ей
передается параметр <parameter>context</parameter>. Этот параметр,
как и любая другая переменная PHP может содержать и массив и объект.
В данном примере она используется для хранения максимальной длины строки;
Если <parameter>string</parameter> имеет длину большую, чем содержится в
контексте, мы обновляем контекст новым значением.
</para>
<para>
После того, как будут обработаны все строки, SQLite вызовет функцию
<literal>max_len_finalize</literal> для вычисления результата аггрегации.
В ней мы производим вычисления, основываясь на данных из
<parameter>context</parameter>. В нашем простом примере мы просто
возвращаем его значение, так как никакие дополнительные вычисления не требуются.
</para>
<tip>
<para>
КРАЙНЕ НЕ рекомендуется сохранять в контексте копии значений для обработки их
в финализирующей функции, так как это повлечет за собой большой перерасход памяти
SQLite для обработки запроса. Просто представьте, сколько памяти вам понадобится, если
вам потребуется аггрегировать, например, миллион значений по 32 байта.
</para>
</tip>
<tip>
<para>
Вы можете использовать <xref linkend="pdo.sqlitecreatefunction" /> и
<xref linkend="pdo.sqlitecreateaggregate" /> для переопределения
стандартных аггрегирующих функций SQLite.
</para>
</tip>
<note>
<para>
Этот метод недоступен с драйвером SQLite2.
В этом случае используйте старое sqlite API.
</para>
</note>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><xref linkend="pdo.sqlitecreatefunction" /></member>
<member><function>sqlite_create_function</function></member>
<member><function>sqlite_create_aggregate</function></member>
</simplelist>
</para>
</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
-->

View File

@ -0,0 +1,138 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 584b64bff5b56cc21a885926127e80ba5749a83d Maintainer: rjhdby Status: ready -->
<!-- Reviewed: no -->
<refentry xml:id="pdo.sqlitecreatecollation" xmlns="http://docbook.org/ns/docbook">
<refnamediv>
<refname>PDO::sqliteCreateCollation</refname>
<refpurpose>
Регистрация сортирующей пользовательской функции для использования в SQL-запросах
</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>PDO::sqliteCreateCollation</methodname>
<methodparam><type>string</type><parameter>name</parameter></methodparam>
<methodparam><type>callable</type><parameter>callback</parameter></methodparam>
</methodsynopsis>
&warn.experimental.func;
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>name</parameter></term>
<listitem>
<para>
Имя функции для использовании в запросах.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>callback</parameter></term>
<listitem>
<para>
Имя функции PHP, либо определенная пользователем функция для использования
в качестве функции обратного вызова и определяющая поведение при сортировке.
Она должна принимать две строки и возвращать -1 или 1 если первая строка должна
располагаться до, после после второй строки соответственно, либо 0, если порядок
не важен.
</para>
<para>
Эта функция должна быть определена следующим образом:
<methodsynopsis>
<type>int</type><methodname><replaceable>collation</replaceable></methodname>
<methodparam><type>string</type><parameter>string1</parameter></methodparam>
<methodparam><type>string</type><parameter>string2</parameter></methodparam>
</methodsynopsis>
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&return.success;
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title>Пример использования <function>PDO::sqliteCreateCollation</function></title>
<programlisting role="php">
<![CDATA[
<?php
$db = new PDO('sqlite::memory:');
$db->exec("CREATE TABLE test (col1 string)");
$db->exec("INSERT INTO test VALUES ('a1')");
$db->exec("INSERT INTO test VALUES ('a10')");
$db->exec("INSERT INTO test VALUES ('a2')");
$db->sqliteCreateCollation('NATURAL_CMP', 'strnatcmp');
foreach ($db->query("SELECT col1 FROM test ORDER BY col1") as $row) {
echo $row['col1'] . "\n";
}
echo "\n";
foreach ($db->query("SELECT col1 FROM test ORDER BY col1 COLLATE NATURAL_CMP") as $row) {
echo $row['col1'] . "\n";
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
a1
a10
a2
a1
a2
a10
]]>
</screen>
</example>
</para>
</refsect1>
<refsect1 role="notes">
&reftitle.notes;
<note>
<para>
Этот метод недоступен с драйвером SQLite2.
В этом случае используйте старое sqlite API.
</para>
</note>
</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
-->

View File

@ -0,0 +1,219 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 95f1473b200b15b3452222bd655e9e2cde8d517a Maintainer: rjhdby Status: ready -->
<!-- Reviewed: no -->
<refentry xml:id="pdo.sqlitecreatefunction" xmlns="http://docbook.org/ns/docbook">
<refnamediv>
<refname>PDO::sqliteCreateFunction</refname>
<refpurpose>
Регистрация пользовательской функции для использования в SQL-запросах
</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>PDO::sqliteCreateFunction</methodname>
<methodparam><type>string</type><parameter>function_name</parameter></methodparam>
<methodparam><type>callable</type><parameter>callback</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>num_args</parameter><initializer>-1</initializer></methodparam>
<methodparam choice="opt"><type>int</type><parameter>flags</parameter><initializer>0</initializer></methodparam>
</methodsynopsis>
&warn.experimental.func;
<para>
Этот метод позволяет вам регистрировать функцию PHP как пользовательскую
функцию SQLite (User Defined Function или <acronym>UDF</acronym>), что позволит
использовать ее в SQL-запросах.
</para>
<para>
UDF можно использовать в любом SQL-запросе, в котором позволяется использовать
функции, например SELECT, UPDATE, а так же в триггерах.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>function_name</parameter></term>
<listitem>
<para>
Имя функции для использовании в запросах.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>callback</parameter></term>
<listitem>
<para>
Функция обратного вызова для обработки вызовов SQL-функции.
</para>
<note>
<simpara>
Функция обратного вызова должна возвращать значение понятного SQLite типа
(т.е. <link linkend="language.types.intro">скалярного типа</link>).
</simpara>
</note>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>num_args</parameter></term>
<listitem>
<para>
Количество аргументов, которое принимает функция. Если задать
равным <literal>-1</literal>, то функция будет принимать любое количество аргументов.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>flags</parameter></term>
<listitem>
<para>
Побитовая конъюнкция (ИЛИ) флагов. На данный момент поддерживается
только флаг <constant>PDO::SQLITE_DETERMINISTIC</constant>, который
определяет то, что функция всегда возвращает одинаковый результат для
одинаковых входных значений.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&return.success;
</para>
</refsect1>
<refsect1 role="changelog">
&reftitle.changelog;
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>&Version;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row>
<entry>PHP 7.1.4</entry>
<entry>
Добавлен параметр <parameter>flags</parameter>.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title>Пример использования <function>PDO::sqliteCreateFunction</function></title>
<programlisting role="php">
<![CDATA[
<?php
function md5_and_reverse($string)
{
return strrev(md5($string));
}
$db = new PDO('sqlite:sqlitedb');
$db->sqliteCreateFunction('md5rev', 'md5_and_reverse', 1);
$rows = $db->query('SELECT md5rev(filename) FROM files')->fetchAll();
?>
]]>
</programlisting>
</example>
</para>
<para>
В этом примере мы определили функцию, вычисляющую md5 сумму строки и
переворачивающую ее. Когда SQL-запрос будет запущен, полученные
значения filename будут преобразованы этой функцией. Результирующий набор
<parameter>$rows</parameter> будет содержать преобразованные значения.
</para>
<para>
Красота подобного подхода заключается в том, что вам не нужно после получения
результирующего набора пробегаться по нему циклом &foreach; для вычисления
нужных значений.
</para>
<!-- not for PDO it doesn't, at least not yet
<para>
PHP registers a special function named <literal>php</literal> when the
database is first opened. The php function can be used to call any PHP
function without having to register it first.
</para>
<para>
<example>
<title>Example of using the PHP function</title>
<programlisting role="php">
<![CDATA[
<?php
$rows = $db->query("SELECT php('md5', filename) from files")->fetchAll();
?>
]]>
</programlisting>
<para>
This example will call the <function>md5</function> on each
<literal>filename</literal> column in the database and return the result
into <parameter>$rows</parameter>
</para>
</example>
</para>
-->
<tip>
<para>
Вы можете использовать <xref linkend="pdo.sqlitecreatefunction" /> и
<xref linkend="pdo.sqlitecreateaggregate" /> для переопределения
стандартных аггрегирующих функций SQLite.
</para>
</tip>
<note>
<para>
Этот метод недоступен с драйвером SQLite2.
В этом случае используйте старое sqlite API.
</para>
</note>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><xref linkend="pdo.sqlitecreateaggregate" /></member>
<member><function>sqlite_create_function</function></member>
<member><function>sqlite_create_aggregate</function></member>
</simplelist>
</para>
</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
-->