mirror of
https://github.com/php/php-src.git
synced 2026-04-27 18:23:26 +02:00
267 lines
8.6 KiB
XML
267 lines
8.6 KiB
XML
<?xml version='1.0' encoding='UTF-8' ?>
|
|
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
|
|
|
<section id="drivers.connect.instantiation">
|
|
<title>Connection Establishment</title>
|
|
|
|
<para>
|
|
When a database connection is to be established, the PDO core will
|
|
create an instance of <type>pdo_dbh_t</type> and initialize it.
|
|
The factory method will then be invoked, which is responsible for
|
|
performing driver specific initialization, connecting to the underlying
|
|
data source and communicating certain database characteristics back to
|
|
the PDO core.
|
|
</para>
|
|
|
|
<section id="drivers.connect.inputs">
|
|
<title>Factory method inputs</title>
|
|
|
|
<para>
|
|
The PDO core initializes various pieces of a <type>pdo_dbh_t</type>
|
|
(we'll refer to it as <varname>dbh</varname> from now on). The
|
|
portions of the structure that are relevant as inputs to the factory
|
|
method are:
|
|
</para>
|
|
|
|
<programlisting role="C"><![CDATA[
|
|
struct _pdo_dbh_t {
|
|
/* credentials */
|
|
char *username, *password;
|
|
/* data source string used to open this handle */
|
|
const char *data_source;
|
|
unsigned long data_source_len;
|
|
|
|
/* if true, then data stored and pointed at by this handle must all be
|
|
* persistently allocated */
|
|
unsigned is_persistent:1;
|
|
|
|
/* if true, driver should act as though a COMMIT were executed between
|
|
* each executed statement; otherwise, COMMIT must be carried out manually
|
|
* */
|
|
unsigned auto_commit:1;
|
|
};
|
|
]]></programlisting>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>username</term>
|
|
<term>password</term>
|
|
<term>data_source</term>
|
|
<term>data_source_len</term>
|
|
<listitem>
|
|
<para>
|
|
These fields describe the data source to which to connect, and the
|
|
credentials that should be used.
|
|
<structfield>username</structfield> and/or
|
|
<structfield>password</structfield> may be <literal>NULL</literal>
|
|
if they were not passed to the constructor. In this case, the
|
|
driver may then take credentials from the
|
|
<structfield>data_source</structfield> string.
|
|
</para>
|
|
<para>
|
|
The <structfield>data_source</structfield> is defined as a string
|
|
prefixed by a driver name and a colon, but is otherwise left
|
|
entirely to a driver to interpret. For instance, and ODBC driver
|
|
could define the data source string as a prefixed version of the
|
|
underlying ODBC data source name and pass
|
|
<structfield>data_source</structfield> directly to the ODBC API
|
|
calls needed for connection establishment.
|
|
</para>
|
|
<para>
|
|
If the underlying database client library doesn't have its own
|
|
concept of encoding the connection parameters in a data source
|
|
string, a driver may find it convenient to use
|
|
<function>php_pdo_parse_data_source</function> to parse defined
|
|
connection parameters out of the
|
|
<structfield>data_source</structfield> string.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>is_persistent</term>
|
|
<listitem>
|
|
<para>
|
|
PHP has a memory manager that can be used for per-request memory
|
|
or for memory that persists beyond the scope of a request. If
|
|
creating a persistent connection,
|
|
<structfield>is_persistent</structfield> will be set to 1
|
|
indicating that all state associated with the
|
|
<varname>dbh</varname> must be allocated using a persistent
|
|
allocator.
|
|
</para>
|
|
<para>
|
|
In practice, drivers will simply call
|
|
<function>pemalloc</function> or <function>pefree</function> and
|
|
pass in <structfield>is_persistent</structfield>, and be able to
|
|
satisfy this requirement.
|
|
</para>
|
|
<para>
|
|
Failure to observe this requirement can lead to memory leaks or
|
|
crashes. If a driver cannot operate correctly when
|
|
<structfield>is_persistent</structfield> is set, then it should
|
|
raise an error as described below.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>auto_commit</term>
|
|
<listitem>
|
|
<para>
|
|
When set to 1, the driver must act as though an implicit commit
|
|
were executed after each successfully executed statement.
|
|
</para>
|
|
<para>
|
|
When set to 0, the driver should implicitly start a transaction.
|
|
</para>
|
|
<para>
|
|
If the underlying data source does not support transactions and
|
|
auto-commit is disabled, the driver must raise an error, as
|
|
described below.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>
|
|
In addition to the <varname>dbh</varname>, the factory method is also
|
|
passed a PHP <type>zval</type> pointer that may be NULL. If it is not
|
|
NULL, it will reference a PHP array type keyed by integer attribute
|
|
identifiers. The driver should use <function>pdo_attr_lval</function>
|
|
and/or <function>pdo_attr_strval</function> to determine if any
|
|
parameters that affect how it will establish the connection are present.
|
|
</para>
|
|
<para>
|
|
The PDO core will iterate all the options and inform the driver of them
|
|
immediately after the connection has been successfully established, so
|
|
the factory method should only process those parameters that are needed to
|
|
establish the connection.
|
|
</para>
|
|
</section>
|
|
|
|
<section id="drivers.connect.outputs">
|
|
<title>Factory method outputs</title>
|
|
|
|
<para>
|
|
The primary purpose of the factory method is to establish a connection
|
|
to a data source. It must also set certain fields of the
|
|
<varname>dbh</varname> so that the PDO core knows how best to interact
|
|
with it.
|
|
</para>
|
|
|
|
<para>
|
|
The portions of the <varname>dbh</varname> that are relevant as outputs
|
|
of the factory method are:
|
|
</para>
|
|
|
|
<programlisting role="C"><![CDATA[
|
|
struct _pdo_dbh_t {
|
|
/* driver specific methods */
|
|
struct pdo_dbh_methods *methods;
|
|
/* driver specific data */
|
|
void *driver_data;
|
|
/* if true, the driver requires that memory be allocated explicitly for
|
|
* the columns that are returned */
|
|
unsigned alloc_own_columns:1;
|
|
/* max length a single character can become after correct quoting */
|
|
unsigned max_escaped_char_length:3;
|
|
};
|
|
]]></programlisting>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>methods</term>
|
|
<listitem>
|
|
<para>
|
|
This field <emphasis>must</emphasis> be set by the factory method
|
|
before it returns, even if the connection attempt failed. This
|
|
allows the core to correctly interrogate the connection handle if
|
|
an error occurs.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>driver_data</term>
|
|
<listitem>
|
|
<para>
|
|
The driver_data field can be used by the driver to store an
|
|
arbitrary pointer to some state. This is typically a structure
|
|
that holds the connection context used by the underlying database
|
|
client library and any other additional state needed by the
|
|
driver.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>alloc_own_columns</term>
|
|
<listitem>
|
|
<para>
|
|
When set to 1, indicates the driver needs to pre-allocate memory
|
|
to hold the data for a result set. In this case, the PDO core
|
|
will trigger a describe immediately after executing a statement
|
|
for the first time. Otherwise, the describe occurs just-in-time.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>max_escaped_char_length</term>
|
|
<listitem>
|
|
<para>
|
|
This is used by the query rewriter to size buffers when quoting
|
|
parameters. If the driver supports parameter binding, then this
|
|
field is unused. If left at its default value of 0, the query
|
|
rewriter will assume 3 bytes per quoted character.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
<section id="drivers.connect.return">
|
|
<title>Factory method return value</title>
|
|
|
|
<para>
|
|
On success, the <structfield>methods</structfield> and
|
|
<structfield>driver_data</structfield> fields of <varname>dbh</varname>
|
|
must be set to non-NULL values. The other fields described above should
|
|
be set as appropriate. The factory method must return 1 to indicate
|
|
success.
|
|
</para>
|
|
|
|
<para>
|
|
On failure, the <structfield>methods</structfield> field of
|
|
<varname>dbh</varname> must be set to a non-NULL value, The other fields
|
|
described above may have been modified by the driver. The PDO core will
|
|
free all resources by calling the <structfield>closer</structfield>
|
|
method provided by the driver. The driver must trigger an exception and
|
|
return 0 to indicate failure.
|
|
</para>
|
|
|
|
<para>
|
|
The connection failure case might look something like this:
|
|
</para>
|
|
|
|
<programlisting role="C"><![CDATA[
|
|
zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC,
|
|
"SQLSTATE[%s] connection failed", sqlstate);
|
|
return 0;
|
|
]]></programlisting>
|
|
|
|
<note>
|
|
<para>
|
|
Implementation bug: the intention was for the exception thrown during
|
|
connection errors to behave identically to the way it behaves after a
|
|
successful connect, in that it should have an errorInfo property as
|
|
described elsewhere. However, there is no exported convenience API for
|
|
this purpose, and so no drivers do this.
|
|
</para>
|
|
</note>
|
|
</section>
|
|
</section>
|
|
|
|
<!--
|
|
vim:ts=2:sw=2:et:tw=78:
|
|
-->
|
|
|