php-src/ext/pdo/specs/drivers/prepare.xml
2007-11-27 19:33:10 +00:00

183 lines
6.2 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.stmt.prepare">
<title>Preparing Statements</title>
<para>
When building a prepared statement, the PDO core will allocate and
initialize an instance of the <type>pdo_stmt_t</type> type and pass it to
the <function>SKEL_prepare_func</function> function.
</para>
<para>
The <varname>stmt</varname> passed to the preparer will have
<structfield>query_string</structfield> and
<structfield>query_stringlen</structfield> initialized, along with some
other state that is not relevant to a driver implementation.
</para>
<para>
The preparer is responsible for setting up the driver specific portion of
the prepared statement state. This typically involves invoking the PDO
query rewriter and then passing the resultant query string to a database
client library API that sets up the prepared statement handle.
</para>
<para>
The <varname>stmt</varname> has the following fields that can be set by
the preparer function:
</para>
<programlisting role="C"><![CDATA[
struct _pdo_stmt_t {
/* driver specific methods */
struct pdo_stmt_methods *methods;
/* driver specific data */
void *driver_data;
unsigned supports_placeholders:2;
const char *named_rewrite_template;
};
]]></programlisting>
<variablelist>
<varlistentry>
<term>methods</term>
<listitem>
<para>
This field <emphasis>must</emphasis> be set by the preparer
before it returns, even if the prepare failed. This
allows the core to correctly interrogate the statement 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 statement context used by the underlying database
client library and any other additional state needed by the
driver.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>supports_placeholders</term>
<listitem>
<para>
The driver should set this to either
<constant>PDO_PLACEHOLDER_NONE</constant> or one or both of
<constant>PDO_PLACEHOLDER_NAMED</constant> or
<constant>PDO_PLACEHOLDER_POSITIONAL</constant> bitwise OR'd together.
This indicates to the query rewriter what level of parameter subsitution
is supported natively by the driver. <quote>named</quote> style
placeholders are Oracle style named parameters whereas
<quote>positional</quote> style parameters are ODBC style question mark
parameter placeholders.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>named_rewrite_template</term>
<listitem>
<para>
Some drivers may only support alternative named parameter syntax that is
not recognized by PDO. Those drivers may set
<structfield>named_rewrite_template</structfield> to a printf style
format string that can be used by the query rewriter to map the ordinal
position of a parameter to a name that is recognized by the driver.
</para>
<para>
<function>snprintf</function> will be invoked using this string as the
format specifier, and will be passed a single integer parameter
representing the ordinal position of the parameter.
</para>
<para>
The PostgreSQL driver sets
<structfield>named_rewrite_template</structfield> to
<literal>$%d</literal>, which allows PDO to rewrite Oracle style named
parameters to position style, and from there, uses the rewrite template
to map them to the PostgreSQL named format.
</para>
<para>
A driver must set <structfield>supports_placeholders</structfield> to
<constant>PDO_PLACEHOLDER_NAMED</constant> to make use of this feature.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
If the driver natively supports both placeholder styles, it can pass
<structfield>query_string</structfield> through to its native prepare API.
Otherwise, it must set <structfield>supports_placeholders</structfield>
appropriately and then invoke <function>pdo_parse_params</function> to analyze
and possibly rewrite the query string.
</para>
<para>
If an error is encountered, the preparer function should record error
state in the <varname>dbh</varname> rather than the
<varname>stmt</varname> as a failed prepare will result in the
<varname>stmt</varname> being freed and it will thus not be available for
interrogation. The state recorded in the <varname>dbh</varname> must be
compatible with the error handling protocol described in <xref
linkend="dbh.error.protocol"/>.
</para>
<para>
Returns 1 on success, 0 on failure.
</para>
<section id="drivers.stmt.pdo_parse_params">
<title>pdo_parse_params</title>
<synopsis>PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery,
int inquery_len, char **outquery, int *outquery_len TSRMLS_DC);</synopsis>
<para>
Given an input <parameter>inquery</parameter> and its length,
<parameter>inquery_len</parameter>, analyzes the SQL and potentially
rewrites it to an appropriate native form based on the
<structfield>supports_placeholders</structfield> field in
<parameter>stmt</parameter>.
</para>
<para>
Returns 0 if the input query is in a suitable native form that the
driver understands.
</para>
<para>
Returns 1 if the query was rewritten; <parameter>outquery</parameter>
and <parameter>outquery_len</parameter> will be updated to reference the
rewritten query string and its length. If
<parameter>outquery</parameter> is not NULL, the caller is responsible
for freeing it via <function>efree</function> when it is no longer
required.
</para>
<para>
Returns -1 if an error ocurred. The
<structfield>error_code</structfield> field of
<parameter>stmt</parameter> will have been set to an appropriate
SQLSTATE error code. A driver will usually copy this code into the
equivalent field of the <varname>dbh</varname>.
</para>
</section>
</section>
<!--
vim:ts=2:sw=2:et:tw=78:
-->