Browse Source

docbook based spec docs

experimental/phar_tar
Wez Furlong 19 years ago
parent
commit
8e1ef43f5b
  1. 51
      ext/pdo/specs/Makefile.in
  2. 8
      ext/pdo/specs/README
  3. 49
      ext/pdo/specs/book.xml.in
  4. BIN
      ext/pdo/specs/build/docbook-xml-4.4.tgz
  5. BIN
      ext/pdo/specs/build/docbook-xsl-1.69.1.tgz
  6. 39
      ext/pdo/specs/build/html-big.xsl
  7. 39
      ext/pdo/specs/build/html.xsl
  8. 70
      ext/pdo/specs/configure.in
  9. 114
      ext/pdo/specs/drivers/all.xml
  10. 18
      ext/pdo/specs/drivers/binding.xml
  11. 266
      ext/pdo/specs/drivers/connect.xml
  12. 285
      ext/pdo/specs/drivers/dbh_methods.xml
  13. 182
      ext/pdo/specs/drivers/prepare.xml
  14. 256
      ext/pdo/specs/drivers/stmt_methods.xml
  15. 162
      ext/pdo/specs/overview.xml
  16. 44
      ext/pdo/specs/preface.xml
  17. 13
      ext/pdo/specs/userspace/all.xml

51
ext/pdo/specs/Makefile.in

@ -0,0 +1,51 @@
# vim:ts=2:sw=2:noet:
XSLTPROC=@XSLTPROC@ --nonet
HERE=@HERE@
TAR=@TAR@
SED=@SED@
BASH=@BASH@
AWK=@AWK@
BUILDDIR=@srcdir@/build
GMAKE=@GMAKE@
BITS=$(BUILDDIR)/bits
.PHONY: book.xml.in
XML_CATALOG_FILES=$(BUILDDIR)/docbook-xsl/catalog.xml $(BUILDDIR)/docbook-xml/catalog.xml
SGML_CATALOG_FILES=$(XML_CATALOG_FILES)
export XML_CATALOG_FILES FOP SGML_CATALOG_FILES SED TAR
all: docbook-env book.xml html
docbook-env: $(BUILDDIR)/docbook-xsl $(BUILDDIR)/docbook-xml $(BUILDDIR)/bits
$(BUILDDIR)/bits:
mkdir $(BUILDDIR)/bits
# need to touch the dir because the timestamp in the tarball
# is older than that of the tarball :)
build/docbook-xsl: $(BUILDDIR)/docbook-xsl-1.69.1.tgz
cd $(BUILDDIR) && $(TAR) xzf docbook-xsl-1.69.1.tgz && touch docbook-xsl
build/docbook-xml: $(BUILDDIR)/docbook-xml-4.4.tgz
cd $(BUILDDIR) && $(TAR) xzf docbook-xml-4.4.tgz && touch docbook-xml
clean:
-rm *.fo html/*.html book.xml
# Build the docs in HTML format
html: html/index.html html/big.html
html/big.html: book.xml
$(XSLTPROC) --xinclude --output html/big.html $(BUILDDIR)/html-big.xsl book.xml
html/index.html: book.xml
$(XSLTPROC) --xinclude --output html/index.html $(BUILDDIR)/html.xsl book.xml
check: book.xml
xmllint --xinclude --nonet --noout --postvalid book.xml
book.xml: $(BUILDDIR)/docbook-xsl $(BUILDDIR)/docbook-xml book.xml.in
sed -e "s/@PUBDATE@/`date`/g;" < book.xml.in > $(BITS)/book.xml
$(XSLTPROC) --output book.xml $(BUILDDIR)/docbook-xsl/profiling/profile.xsl $(BITS)/book.xml

8
ext/pdo/specs/README

@ -1,3 +1,11 @@
Work on the PDO specification to live here
How to build:
You need some unixy tools, including libxml2 (which provides xsltproc), make
and autoconf.
% autoconf
% ./configure
% make

49
ext/pdo/specs/book.xml.in

@ -0,0 +1,49 @@
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"
>
<book id="skel" lang="en"
xmlns:xi="http://www.w3.org/2001/XInclude"
>
<bookinfo>
<title>PDO Specification</title>
<!-- subtitle></subtitle -->
<edition>Version 1</edition>
<pubdate>@PUBDATE@</pubdate>
<author>
<firstname>Wez</firstname>
<surname>Furlong</surname>
<affiliation>
<jobtitle>Lead Architect</jobtitle>
<orgname>OmniTI Computer Consulting, Inc.</orgname>
</affiliation>
</author>
<copyright>
<year>2004</year>
<year>2005</year>
<year>2006</year>
<year>2007</year>
<holder>Wez Furlong</holder>
</copyright>
<copyright>
<year>2005</year>
<year>2006</year>
<year>2007</year>
<holder>OmniTI, Inc.</holder>
</copyright>
</bookinfo>
<xi:include href="preface.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="overview.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="drivers/all.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="userspace/all.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<index id="the.index"/>
</book>
<!--
vim:ts=2:sw=2:et:
-->

BIN
ext/pdo/specs/build/docbook-xml-4.4.tgz

BIN
ext/pdo/specs/build/docbook-xsl-1.69.1.tgz

39
ext/pdo/specs/build/html-big.xsl

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/onechunk.xsl"/>
<xsl:param name="use.extensions">0</xsl:param>
<xsl:param name="use.id.as.filename">0</xsl:param>
<xsl:param name="root.filename">big</xsl:param>
<xsl:param name="base.dir">./</xsl:param>
<xsl:param name="chunk.fast">1</xsl:param>
<xsl:param name="make.valid.html">1</xsl:param>
<xsl:param name="section.autolabel">1</xsl:param>
<xsl:param name="generate.index">1</xsl:param>
<xsl:param name="section.label.includes.component.label">1</xsl:param>
<xsl:param name="chunker.output.indent">yes</xsl:param>
<xsl:param name="chunker.output.encoding">UTF-8</xsl:param>
<xsl:param name="chunk.first.sections">0</xsl:param>
<xsl:param name="chunk.tocs.and.lots">0</xsl:param>
<xsl:param name="html.extra.head.links">1</xsl:param>
<xsl:param name="generate.manifest">0</xsl:param>
<xsl:param name="admon.graphics">0</xsl:param>
<xsl:param name="admon.style"></xsl:param>
<xsl:param name="html.stylesheet">/docbook/style.css</xsl:param>
<xsl:param name="header.rule">0</xsl:param>
<xsl:param name="footer.rule">0</xsl:param>
<xsl:param name="funcsynopsis.style">ansi</xsl:param>
<xsl:param name="callout.graphics.path">/docbook/images/callouts/</xsl:param>
<xsl:param name="admon.graphics.path">/docbook/images/</xsl:param>
<xsl:template match="sect1[@role = 'NotInToc']" mode="toc" />
<xsl:template match="sect2[@role = 'NotInToc']" mode="toc" />
</xsl:stylesheet>
<!--
vim:ts=2:sw=2:et:
-->

39
ext/pdo/specs/build/html.xsl

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl"/>
<!-- xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/profile-chunk.xsl"/ -->
<xsl:param name="use.extensions">0</xsl:param>
<xsl:param name="use.id.as.filename">1</xsl:param>
<xsl:param name="base.dir">./</xsl:param>
<xsl:param name="chunk.fast">1</xsl:param>
<xsl:param name="make.valid.html">1</xsl:param>
<xsl:param name="section.autolabel">1</xsl:param>
<xsl:param name="generate.index">1</xsl:param>
<xsl:param name="section.label.includes.component.label">1</xsl:param>
<xsl:param name="chunker.output.indent">yes</xsl:param>
<xsl:param name="chunker.output.encoding">UTF-8</xsl:param>
<xsl:param name="chunk.first.sections">0</xsl:param>
<xsl:param name="chunk.tocs.and.lots">0</xsl:param>
<xsl:param name="html.extra.head.links">0</xsl:param>
<xsl:param name="generate.manifest">0</xsl:param>
<xsl:param name="admon.graphics">0</xsl:param>
<xsl:param name="admon.style"></xsl:param>
<xsl:param name="html.stylesheet">/docbook/style.css</xsl:param>
<xsl:param name="header.rule">0</xsl:param>
<xsl:param name="footer.rule">0</xsl:param>
<xsl:param name="toc.section.depth">1</xsl:param>
<xsl:param name="funcsynopsis.style">ansi</xsl:param>
<xsl:param name="callout.graphics.path">/docbook/images/callouts/</xsl:param>
<xsl:param name="admon.graphics.path">/docbook/images/</xsl:param>
<xsl:template match="sect1[@role = 'NotInToc']" mode="toc" />
<xsl:template match="sect2[@role = 'NotInToc']" mode="toc" />
</xsl:stylesheet>
<!--
vim:ts=2:sw=2:et:
-->

70
ext/pdo/specs/configure.in

@ -0,0 +1,70 @@
dnl vim:ts=2:sw=2:et:
AC_INIT(Makefile.in)
XSLTPROC=xsltproc
GTAR=gtar
TAR=tar
SED=sed
GSED=gsed
BASH=bash
AWK=awk
AC_PATH_PROG(AWK, $AWK)
AC_PATH_PROG(GAWK, gawk)
AC_PATH_PROG(NAWK, nawk)
AC_PATH_PROG(GTAR, $GTAR)
AC_PATH_PROG(GSED, $GSED)
AC_PATH_PROG(BASH, $BASH)
AC_ARG_WITH(xsltproc, [ --with-xsltproc Where to find xsltproc],
[
if test "x$withval" != "xno"; then
XSLTPROC="$withval"
fi
]
)
AC_PATH_PROG(XSLTPROC, $XSLTPROC)
if test -x "$GTAR" ; then
TAR=$GTAR
fi
if test -x "$GSED" ; then
SED=$GSED
fi
if test -x "$GAWK" ; then
AWK=$GAWK
else
if test -x "$NAWK" ; then
AWK=$NAWK
fi
fi
GMAKE=make
case `uname -s` in
SunOS)
GMAKE=gmake
;;
esac
AC_SUBST(GMAKE)
AC_SUBST(TAR)
AC_SUBST(SED)
AC_SUBST(BASH)
AC_SUBST(AWK)
AC_SUBST(XINC)
AC_SUBST(XEP)
AC_SUBST(FOP)
AC_SUBST(XSLTPROC)
AC_SUBST(DBDOCLET)
HERE=`pwd`
AC_SUBST(HERE)
AC_OUTPUT(Makefile)
cat > config.nice <<EOT
#!/bin/sh
./configure \
--with-xsltproc='$XSLTPROC'
EOT
chmod +x config.nice

114
ext/pdo/specs/drivers/all.xml

@ -0,0 +1,114 @@
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="drivers">
<title>Driver Documentation</title>
<para>
Any PHP extension that is linked against the PDO core module can elect to
register a PDO driver. A PDO driver is represented by the
<type>pdo_driver_t</type> type which describes the version of PDO against
which the driver was built, the name of the driver and a factory method
that can be used to instantiate a database connection handle. A
connection handle is represented by the <type>pdo_dbh_t</type> type which
describes, among other things, how to instantiate a prepared statement
handle, represented by the <type>pdo_stmt_t</type> type.
</para>
<para>
These three types are the main interface between the PDO core and a PDO
driver. In this chapter, we'll refer to an imaginary skeleton driver, and
use <literal>SKEL</literal> as a placeholder for its various functions or
types. In practice, a given database vendor will typically choose to use
a short, lowercase, version of the name of their database or client
library in place of <literal>SKEL</literal>.
</para>
<section id="drivers.registration">
<title>Driver Registration</title>
<para>
A driver extension will typically statically define an instance of
<type>pdo_driver_t</type> and pass the address of it to
<function>php_pdo_register_driver</function> during its module
initialization callback (also known as MINIT, for module init), and
again to <function>php_pdo_unregister_driver</function> during its
module shutdown callback (also known as MSHUTDOWN).
</para>
<para>
<filename>php_pdo_driver.h</filename> defines <type>pdo_driver_t</type>,
<function>php_pdo_register_driver</function> and
<function>php_pdo_unregister_driver</function> as follows:
</para>
<programlisting role="C"><![CDATA[
/* This structure is registered with PDO when a PDO driver extension is
* initialized */
typedef struct {
const char *driver_name;
unsigned long driver_name_len;
unsigned long api_version; /* needs to be compatible with PDO */
#define PDO_DRIVER_HEADER(name) \
#name, sizeof(#name)-1, \
PDO_DRIVER_API
/* create driver specific portion of the database handle and stash it into
* the dbh. dbh contains the data source string and flags for this
* instance. You MUST respect dbh->is_persistent and pass that flag to
* pemalloc() for all allocations that are stored in the dbh or your instance
* data in the db, otherwise you will crash PHP when persistent connections
* are used.
*/
int (*db_handle_factory)(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC);
} pdo_driver_t;
/* call this in MINIT to register your PDO driver */
PDO_API int php_pdo_register_driver(pdo_driver_t *driver);
/* call this in MSHUTDOWN to unregister your PDO driver */
PDO_API void php_pdo_unregister_driver(pdo_driver_t *driver);
]]></programlisting>
<para>
A driver would typically use code like the following to register a
driver:
</para>
<programlisting role="C"><![CDATA[
static pdo_driver_t SKEL_driver = {
PDO_DRIVER_HEADER(SKEL),
SKEL_db_handle_factory
};
PHP_MINIT_FUNCTION(pdo_SKEL)
{
return php_pdo_register_driver(&SKEL_driver);
}
PHP_MSHUTDOWN_FUNCTION(pdo_SKEL)
{
php_pdo_unregister_driver(&SKEL_driver);
return SUCCESS;
}
]]></programlisting>
<para>
The <function>SKEL_db_handle_factory</function> is provided by the
driver; its operation will be discussed in the next section.
</para>
</section>
<xi:include href="connect.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="dbh_methods.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="prepare.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="binding.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="stmt_methods.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
</chapter>
<!--
vim:ts=2:sw=2:et:tw=78:
-->

18
ext/pdo/specs/drivers/binding.xml

@ -0,0 +1,18 @@
<?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.binding">
<title>Parameter Binding</title>
<para>
This section describes the parameter (and column) binding interface in PDO.
</para>
</section>
<!--
vim:ts=2:sw=2:et:tw=78:
-->

266
ext/pdo/specs/drivers/connect.xml

@ -0,0 +1,266 @@
<?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:
-->

285
ext/pdo/specs/drivers/dbh_methods.xml

@ -0,0 +1,285 @@
<?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.dbh.methods">
<title>Database Handle Methods</title>
<para>
The <structname>pdo_dbh_methods</structname> structure defines the methods
for a given database connection handle. The methods are defined below;
each one is subject to the following error handling protocol:
</para>
<section id="dbh.error.protocol">
<title>Error handling protocol</title>
<para>
When a driver encounters an error, it must update the
<structfield>error_code</structfield> field of the
<varname>dbh</varname> to hold an appropriate SQLSTATE error code, and
take some action to record the driver specific error code and human
readable message, if necessary.
</para>
<para>
The method descriptions below describe how to indicate an error
status. The PDO core may invoke the
<function>SKEL_fetch_error_func</function> to obtain the driver
specific error code and human readable message.
</para>
<para>
The driver should not unilaterally raise an exception in reponse to an
error. Instead, it should be left to the PDO core to handle reporting
the error to the script, based on the application preferences for
error handling.
</para>
</section>
<section id="dbh.close_func">
<title>SKEL_close_func</title>
<synopsis>int SKEL_close_func(pdo_dbh_t *dbh TSRMLS_DC);</synopsis>
<para>
This function is called by the PDO core when freeing resources
associated with the <varname>dbh</varname>. It should release any
resources allocated by the driver.
</para>
<para>
Returns 0. An implementation bug means that the return value is not
checked.
</para>
</section>
<section id="dbh.prepare_func">
<title>SKEL_prepare_func</title>
<synopsis>int SKEL_prepare_func(pdo_dbh_t *dbh, const char *sql,
long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC);</synopsis>
<para>
This function is called when creating a statement handle. It is
described in more detail in <xref
linkend="drivers.stmt.prepare"/>.
</para>
<para>
Returns 1 on success, 0 on failure.
</para>
</section>
<section id="dbh.do_func">
<title>SKEL_do_func</title>
<synopsis>int SKEL_do_func(pdo_dbh_t *dbh, const char *sql,
long sql_len TSRMLS_DC);</synopsis>
<para>
Execute a statement that does not return a result set.
</para>
<para>
Returns -1 on failure, or the number of affected rows otherwise.
</para>
</section>
<section id="dbh.quote_func">
<title>SKEL_quote_func</title>
<synopsis>int SKEL_quote_func(pdo_dbh_t *dbh, const char *unquoted,
int unquoted_len, char **quoted, int *quotedlen,
enum pdo_param_type paramtype TSRMLS_DC);</synopsis>
<para>
Quote a parameter, escaping SQL meta-characters as appropriate and
enclosing the parameter in appropriate quotation marks. This function
will allocate an appropriately sized buffer using
<function>emalloc</function> and return it to the caller by setting
<parameter>quoted</parameter> and <parameter>quotedlen</parameter> to
the buffer and its length.
</para>
<para>
The return value should be 1 if the function generated a quoted
string, or 0 otherwise.
</para>
</section>
<section id="dbh.begin_func">
<title>SKEL_begin_func</title>
<synopsis>int SKEL_begin_func(pdo_dbh_t *dbh TSRMLS_DC);</synopsis>
<para>
This function begins a transaction on the connection. If the driver
does not support transactions, it should not provide this method.
</para>
<para>
Returns 1 to indicate that a new transaction has begun, 0 to indicate
error. The PDO core maintains its own idea of whether a transaction
is in progress, so the driver should not maintain its own.
</para>
</section>
<section id="dbh.commit_func">
<title>SKEL_commit_func</title>
<synopsis>int SKEL_commit_func(pdo_dbh_t *dbh TSRMLS_DC);</synopsis>
<para>
This function commits a transaction on the connection. If the driver
does not support transactions, it should not provide this method.
</para>
<para>
Returns 1 to indicate that the transaction was committed, 0 otherwise.
Once committed, PDO assumes that a transaction is no longer active.
</para>
</section>
<section id="dbh.rollback_func">
<title>SKEL_rollback_func</title>
<synopsis>int SKEL_rollback_func(pdo_dbh_t *dbh TSRMLS_DC);</synopsis>
<para>
This function rolls back a transaction on the connection. If the driver
does not support transactions, it should not provide this method.
</para>
<para>
Returns 1 to indicate a successful rollback, 0 otherwise.
Once rolled back, PDO assumes that a transaction is no longer active.
</para>
</section>
<section id="dbh.set_attr_func">
<title>SKEL_set_attr_func</title>
<synopsis>int SKEL_set_attr_func(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);</synopsis>
<para>
Sets an attribute on the database handle. Returns 1 if the attribute
was set successfully, 0 otherwise. There are a number of attributes
that can be set, and these are discussed in <xref
linkend="attributes.dbh"/>.
</para>
</section>
<section id="dbh.last_id_func">
<title>SKEL_last_id_func</title>
<synopsis>char *SKEL_last_id_func(pdo_dbh_t *dbh, const char *name,
unsigned int *len TSRMLS_DC);</synopsis>
<para>
Returns the last insert id. A NULL return value indicates an error
condition, otherwise the return value must be a NUL terminated string
allocated using <function>emalloc</function>.
</para>
</section>
<section id="dbh.fetch_error_func">
<title>SKEL_fetch_error_func</title>
<synopsis>int SKEL_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt *stmt,
zval *info TSRMLS_DC);</synopsis>
<para>
Fetch error information. If stmt is not NULL, fetch information
pertaining to the statement, otherwise fetch the connection level
error information. The driver should add the following information
to the array "info" in this order: a) the native error code and b) a
string representation of the error code.
</para>
<para>
A driver may optionally append any other arbitrary, useful,
information to the info array.
</para>
<para>
Returns 1 to indicate that it populated info, 0 otherwise.
</para>
</section>
<section id="dbh.get_attr_func">
<title>SKEL_get_attr_func</title>
<synopsis>int SKEL_get_attr_func(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);</synopsis>
<para>
Retrieves an attribute from a database handle. Returns 0 if the
driver doesn't support the attribute. Returns -1 if the driver
encountered an error. Returns 1 on success. There are a number of
attributes that can be fetched, and these are discussed in <xref
linkend="attributes.dbh"/>.
</para>
</section>
<section id="dbh.check_liveness">
<title>SKEL_check_liveness_func</title>
<synopsis>int SKEL_check_liveness_func(pdo_dbh_t *dbh TSRMLS_DC);</synopsis>
<para>
Performs some driver dependent action to determine if a connection is
still valid for use, typically a low overhead ping. Returns
<constant>SUCCESS</constant> if the connection is still alive and
ready to be used, <constant>FAILURE</constant> if the connection is
no longer alive (perhaps it timed out). If this function is not
provided, it is equivalent to defining a function that always returns
<constant>SUCCESS</constant>.
</para>
</section>
<section id="dbh.get_driver_methods">
<title>SKEL_get_driver_methods_func</title>
<synopsis>zend_function_entry *SKEL_get_driver_methods_func(
pdo_dbh_t *dbh, int kind TSRMLS_DC);</synopsis>
<para>
When a PHP script attempts to call a method on a PDO or PDOStatement
object that is not covered by either this specification or by a user
defined class that extends either PDO or a PDOStatement, then
<function>SKEL_get_driver_methods_func</function> is called to
determine the driver extension methods that are present.
</para>
<para>
When kind is <constant>PDO_DBH_DRIVER_METHOD_KIND_DBH</constant>, the
driver extension method table for the connection handle must be
returned. When kind is
<constant>PDO_DBH_DRIVER_METHOD_KIND_STMT</constant>, the driver
extension method table for the statement handle must be returned.
</para>
<para>
The return value is either a <type>zend_function_entry</type> pointer
referencing a table of methods, or NULL to indicate that there are no
extension methods available.
</para>
<para>
Driver extension methods must be prefixed with the driver name used to
register the driver so that they are less likely to collide with
either future PDO methods or user defined functions in derived
classes.
</para>
</section>
<section id="dbh.request_shutdown">
<title>SKEL_request_shutdown_func</title>
<synopsis>void SKEL_request_shutdown_func(pdo_dbh_t *dbh TSRMLS_DC);</synopsis>
<para>
Called when a script terminates (request shutdown) for a persistent
connection handle. This provides the opportunity to safely releases
resources that only have per-request scope.
</para>
</section>
</section>
<!--
vim:ts=2:sw=2:et:tw=78:
-->

182
ext/pdo/specs/drivers/prepare.xml

@ -0,0 +1,182 @@
<?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:
-->

256
ext/pdo/specs/drivers/stmt_methods.xml

@ -0,0 +1,256 @@
<?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.methods">
<title>Statement Handle Methods</title>
<para>
The <structname>pdo_stmt_methods</structname> structure defines the
methods for a given prepared statement handle. The methods are defined
below; each one is subject to the error handling protocol below.
</para>
<para>
Note that the <structfield>dbh</structfield> of the
<varname>stmt</varname> handle references the connection handle associated
with the statement.
</para>
<section id="stmt.error.protocol">
<title>Error handling protocol</title>
<para>
When a driver encounters an error on a prepared statement handle, it
must update the <structfield>error_code</structfield> field of the
<varname>stmt</varname> to hold an appropriate SQLSTATE error code, and
take some action to record the driver specific error code and human
readable message, if necessary.
</para>
<para>
The method descriptions below describe how to indicate an error
status. The PDO core may invoke the
<function>SKEL_fetch_error_func</function> to obtain the driver
specific error code and human readable message.
</para>
<para>
The driver should not unilaterally raise an exception in reponse to an
error. Instead, it should be left to the PDO core to handle reporting
the error to the script, based on the application preferences for
error handling.
</para>
</section>
<section id="stmt.dtor_func">
<title>SKEL_stmt_dtor_func</title>
<synopsis>int SKEL_stmt_dtor_func(pdo_stmt_t *stmt TSRMLS_DC);</synopsis>
<para>
This function is called by the PDO core when freeing resources
associated with the <varname>stmt</varname>. It should release any
resources allocated by the driver.
</para>
<para>
Returns 0. An implementation bug means that the return value is not
checked.
</para>
</section>
<section id="stmt.execute_func">
<title>SKEL_stmt_execute_func</title>
<synopsis>int SKEL_stmt_execute_func(pdo_stmt_t *stmt TSRMLS_DC);</synopsis>
<para>
Starts the query. This is typically implemented as a call to the
database specific prepared statement execute function. Prior to calling
this function, the PDO core will trigger a
<constant>PDO_PARAM_EVT_EXEC_PRE</constant> event for each parameter,
offering the driver an opportunity to perform some final binding or
allocation actions prior to executing the statement.
</para>
<para>
<structfield>active_query_string</structfield> and
<structfield>active_query_stringlen</structfield> will be set by the PDO
core to reflect the query being executed. This is largely for the
convenience of drivers that don't natively support parameterized
queries; the query rewriter will have synthesized a query string with
the parameters expanded, if the
<structfield>supports_placeholders</structfield> indicates that it
should have. For drivers that do support parameterized queries, it is
anticipated that they will have already prepared their statement handles
and associated the parameters with it during the
<constant>PDO_PARAM_EVT_EXEC_PRE</constant> notification.
</para>
<para>
Immediately after executing, the PDO core will trigger a
<constant>PDO_PARAM_EVT_EXEC_POST</constant> event for each parameter,
offering the driver an opportunity to take some action, for example,
with parameters bound as OUT parameters.
</para>
<para>
Returns 1 on success, 0 on failure.
</para>
</section>
<section id="stmt.fetch_func">
<title>SKEL_stmt_fetch_func</title>
<synopsis>int SKEL_stmt_fetch_func(pdo_stmt_t *stmt,
enum pdo_fetch_orientation ori, long offset TSRMLS_DC);</synopsis>
<para>
Requests that the driver fetch the next row into driver storage. Prior to
calling this function the PDO core will trigger a
<constant>PDO_PARAM_EVT_FETCH_PRE</constant> event for each column,
offering the driver an opportunity to perform per-column allocations or
binding.
</para>
<para>
After calling this function, the PDO core will trigger a describe of the
columns if they haven't already been queried, and will then trigger a
<constant>PDO_PARAM_EVT_FETCH_POST</constant> event.
</para>
<para>
The orientation and offset parameters allow scrolling cursor operation.
</para>
<para>
Returns 1 if data was returned, 0 otherwise.
</para>
</section>
<section id="stmt.describe_col_func">
<title>SKEL_stmt_describe_col_func</title>
<synopsis>int SKEL_stmt_describe_col_func(pdo_stmt_t *stmt,
int colno TSRMLS_DC);</synopsis>
<para>
Requests that the driver populate the <structfield>columns</structfield>
field of <varname>stmt</varname> with information about a given column.
Columns are numbered zero-based in this function.
</para>
<para>
Returns 1 if successful, 0 otherwise.
</para>
</section>
<section id="stmt.get_col_data_func">
<title>SKEL_stmt_get_col_data_func</title>
<synopsis>int SKEL_stmt_get_col_data_func(pdo_stmt_t *stmt,
int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC);</synopsis>
<para>
Requests that the driver return a pointer and size of the data for a
particular column. PDO prefers that the driver manage the lifetime of
this data (it can often reuse the same memory block for repeated
fetches). The PDO core will translate this memory, copying it if
necessary. If the driver must allocate transient memory for a column,
then it should do so using emalloc() and set caller_frees to a non-zero
value. This informs PDO that it is responsible for freeing the column
data when it is no longer required.
</para>
<para>
The type of pointer is specified by the column description prepared by
SKEL_stmt_describe_col_func.
</para>
<para>
Returns 1 if successful, 0 otherwise.
</para>
</section>
<section id="stmt.param_hook_func">
<title>SKEL_stmt_param_hook_func</title>
<synopsis>int SKEL_stmt_param_hook_func(pdo_stmt_t *stmt,
struct pdo_bound_param_data *param, enum pdo_param_event event_type
TSRMLS_DC);</synopsis>
<para>
The param hook function is called by the PDO core at certain key points
in the setup of a statement handle, per parameter or column, to notify
the driver, so that it can perform some driver specific function.
</para>
<para>
The PDO core has no expectations for the hook function, except that it
should return 0 if there was an error, 1 otherwise.
</para>
<para>
The events that are possible are:
</para>
<bridgehead>PDO_PARAM_EVT_NORMALIZE</bridgehead>
<para>
Triggered before PDO_PARAM_EVT_ALLOC to normalize the parameter name.
This is not typically used by most drivers. The pgsql driver uses
this opportunity to fixup the parameter name and ordinal position before
the core registers its parameter state.
</para>
<bridgehead>PDO_PARAM_EVT_ALLOC</bridgehead>
<para>
Triggered in response to binding a parameter or column. This is the
drivers opportunity to allocate its driver-specific state for the
parameter.
</para>
<para>
Some drivers will take this opportunity to set up bind descriptors
if enough information is present in the param data. Note that this
stage is too early to be sure of the value (it may change between the
bind call and statement execution), so drivers must not snapshot
the value of the parameter at this point.
</para>
<bridgehead>PDO_PARAM_EVT_FREE</bridgehead>
<para>
Triggered when the core is done with a parameter, typically at statement
handle tear-down time. The driver must release any resources it may
have allocated for the parameter.
</para>
<bridgehead>PDO_PARAM_EVT_EXEC_PRE</bridgehead>
<para>
Triggered for each parameter immediately before invoking the
<function>SKEL_stmt_execute_func</function>. This is the correct time
to capture or reference the parameter value and finalize the binding of
the parameter.
</para>
<bridgehead>PDO_PARAM_EVT_EXEC_POST</bridgehead>
<para>
Triggered for each parameter immediately after invoking the
<function>SKEL_stmt_execute_func</function>. This allows a driver to
fixup or reconcile state, in particular for OUT parameters that have
been bound to a zval.
</para>
<bridgehead>PDO_PARAM_EVT_FETCH_PRE</bridgehead>
<para>
Triggered for each bound column immediately before invoking the
<function>SKEL_stmt_fetch_func</function>. This has similar semantics
to PDO_PARAM_EVT_EXEC_PRE, except that it applies to binding columns in
a result set to zvals rather than parameters in a prepared statement.
</para>
<bridgehead>PDO_PARAM_EVT_FETCH_POST</bridgehead>
<para>
Triggered for each bound column immediately after invoking the
<function>SKEL_stmt_fetch_func</function>. This has similar semantics
to PDO_PARAM_EVT_EXEC_POST, except that it applies to binding columns in
a result set to zvals rather than parameters in a prepared statement.
</para>
</section>
</section>
<!--
vim:ts=2:sw=2:et:tw=78:
-->

162
ext/pdo/specs/overview.xml

@ -0,0 +1,162 @@
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="overview">
<title>Overview</title>
<para>
PDO is structured as depicted below; a core PDO module provides a framework
for loading driver extensions and calling into them, similar in some ways to
ODBC, although PDO is a very lightweight bridge when compared to ODBC. The
core module is responsible for managing the user-space portions of the the
PHP/Database interaction, delegating the database/vendor specific portions to
the appropriate driver extension module. It is typical for a driver
extension to delegate, in turn, to a pre-existing database client library to
carry out its duties.
</para>
<para>
<screen>
+---------------------------------------------+
| PDO Core |
+---------------------------------------------+
+--------------------+ +--------------------+
|PDO Driver Extension| |PDO Driver Extension|
+--------------------+ +--------------------+
+--------------------+ +--------------------+
| DB Client Library | | DB Client Library |
+--------------------+ +--------------------+
</screen>
</para>
<section id="overview.design">
<title>Design Principles</title>
<para>
PDO was built around the ideal of being able to provide a common data access
paradigm across a variety of data providers. The goal was to provide the
lowest common denominator of features using a common API, while still
being able to provide access to database/vendor specific features.
There are some important behavior traits in PDO; most are general behaviors
that most drivers exhibit; some deviation is allowed if it the net effect of
the deviation is not a big problem (for instance, type juggling). There are
a couple of hard rules that must be adhered to for conformance, however.
</para>
<section id="overview.design.connection">
<title>Connection Management</title>
<para>
While an instance of the PDO class exists, it represents an open connection
to the database.
</para>
</section>
<section id="overview.design.typing">
<title>Data typing</title>
<para>
As a "typeless" environment, PHP doesn't mind whether data is returned as
integer, floating point or string; it can convert to the appropriate type as
needed. This conversion process may cause loss in data fidelity in some
cases, in particular when it comes to floating point numbers. The type of
choice for PDO when binding or requesting data is to use the string type, as
this has the best data fidelity.
</para>
<para>
Note that some database client library implementations don't provide the
application with a means to specify their preferred data type, returning it
in their own perception of the best native data type. For those drivers it
would typically be wasted effort to convert to a string in the PDO driver
layer, so the native type is passed up and returned to the script in that
form.
</para>
<para>
The net result of this is that data is usually, but not always, returned as
strings unless otherwise specified by the PHP script.
</para>
</section>
<section id="overview.design.xact">
<title>Transaction Support</title>
<para>
Many, but not all, database implementations support the notion of
transactions. The transaction reflects a block of database operations
that can be either committed or rolled back. Some database implementations
support nesting transactions, or transactions across multiple connection
handles. Most databases that support transactions start out in a mode known
as "auto-commit", which emulates non-transactional behavior.
</para>
<para>
PDO, as an abstraction layer, is responsible for making sure that the
behavior of two freshly opened connections to different databases don't
exhibit drastically different behavior. The principle of least surprise is
particularly important when it comes to transactions, so PDO requires that
its driver extensions observe the following rules, since an application that
assumes that transactions are available when they are not could proceed and
cause damage to the data in the database when it attempts to rollback its
changes.
</para>
<para>
Freshly created connections must start in auto-commit mode. This allows
non-transactional scripts to operate without having to do anything special
to get auto-commit enabled.
</para>
<para>
Attempting to use transactions when the underlying database doesn't support
them must return an error to the PDO core layer. PDO itself will generate a
runtime exception which will cause the script to terminate unless handled by
the script. Note that PDO will not normally generate exceptions unless
explicitly told to do so by the script. Forcing an exception in this case
helps to reinforce that something is seriously wrong.
</para>
<para>
PDO only supports the notion of being in a transaction or not. It does not
support nested transactions, it is an error to start a new transaction while
a transaction is active.
</para>
<para>
Ad-hoc SQL executed by the script that affects the transactional state of
the connection as seen by the database is allowed, but its effect on the
PDO-core notion of the transactional state is undefined. A driver must not
attempt to reconcile the effect of ad-hoc SQL with the PDO-core
transactional state.
</para>
</section>
<section id="overview.design.err">
<title>Error Handling</title>
<para>
The behavior of PDO in the face of errors varies based on application
preference. The default is to silently return error codes back to the
script, but also allows the option of emitting a warning in addition to
returning the error code, or to throw an exception object containing the
error state.
</para>
<para>
In the interests of portability and fidelity of information, PDO requires
its drivers to record the ANSI SQL 92 SQLSTATE error code along with their
native and human readable error codes when an error is encountered. This
allows portable scripts the ability to use vendor-independent error handling
logic as well as the freedom to also use vendor-dependent logic if required.
</para>
</section>
</section>
</chapter>
<!--
vim:ts=2:sw=2:et:fileencoding=utf-8:encoding=utf-8:
-->

44
ext/pdo/specs/preface.xml

@ -0,0 +1,44 @@
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<preface id="preface">
<title>Preface</title>
<para>
This document specifies the implementation of PDO, PHP Data Objects, both
from the perspective of PHP script level APIs used by people developing PHP
applications, and from the perspective of C level APIs in the PDO internals
that will be used by people developing PDO drivers.
</para>
<para>
Briefly summarize the chapters here.
</para>
<bridgehead>Acknowledgments</bridgehead>
<para>
A number of people were involved in the development of PDO and its drivers;
without them it wouldn't be what it is, and you wouldn't be reading this
text. Those people are:
Ilia Alshanetsky,
Ard Biesheuvel,
Marcus B&ouml;rger,
Sara Golemon,
Sterling Hughes,
Edin Kadribašić
Frank Kroman
and George Schlossnagle from the PHP community,
Chris Jones from Oracle,
Dan Scott,
Bill Abt,
Kellen Bombardier
Rick McGuire
and
Krishna Raman from IBM.
</para>
</preface>
<!--
vim:ts=2:sw=2:et:fileencoding=utf-8:encoding=utf-8:
-->

13
ext/pdo/specs/userspace/all.xml

@ -0,0 +1,13 @@
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="user">
<title>User-space Documentation</title>
<para>bar</para>
</chapter>
<!--
vim:ts=2:sw=2:et:
-->
Loading…
Cancel
Save