summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWez Furlong <wez@php.net>2007-11-27 19:33:10 +0000
committerWez Furlong <wez@php.net>2007-11-27 19:33:10 +0000
commit8e1ef43f5b5e2d00e4cb862c2348b005e7069a75 (patch)
tree8099da84cf81244249a609677784d57306a07492
parent2f1ee5031a472a6d6e2531dd3a6ecd7df1504270 (diff)
downloadphp-git-8e1ef43f5b5e2d00e4cb862c2348b005e7069a75.tar.gz
docbook based spec docs
-rw-r--r--ext/pdo/specs/Makefile.in51
-rw-r--r--ext/pdo/specs/README8
-rw-r--r--ext/pdo/specs/book.xml.in49
-rw-r--r--ext/pdo/specs/build/docbook-xml-4.4.tgzbin0 -> 75974 bytes
-rw-r--r--ext/pdo/specs/build/docbook-xsl-1.69.1.tgzbin0 -> 851027 bytes
-rw-r--r--ext/pdo/specs/build/html-big.xsl39
-rw-r--r--ext/pdo/specs/build/html.xsl39
-rw-r--r--ext/pdo/specs/configure.in70
-rw-r--r--ext/pdo/specs/drivers/all.xml114
-rw-r--r--ext/pdo/specs/drivers/binding.xml18
-rw-r--r--ext/pdo/specs/drivers/connect.xml266
-rw-r--r--ext/pdo/specs/drivers/dbh_methods.xml285
-rw-r--r--ext/pdo/specs/drivers/prepare.xml182
-rw-r--r--ext/pdo/specs/drivers/stmt_methods.xml256
-rw-r--r--ext/pdo/specs/overview.xml162
-rw-r--r--ext/pdo/specs/preface.xml44
-rw-r--r--ext/pdo/specs/userspace/all.xml13
17 files changed, 1596 insertions, 0 deletions
diff --git a/ext/pdo/specs/Makefile.in b/ext/pdo/specs/Makefile.in
new file mode 100644
index 0000000000..d9cfc13c62
--- /dev/null
+++ b/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
+
diff --git a/ext/pdo/specs/README b/ext/pdo/specs/README
index 5a73899414..beaf5e0be2 100644
--- a/ext/pdo/specs/README
+++ b/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
diff --git a/ext/pdo/specs/book.xml.in b/ext/pdo/specs/book.xml.in
new file mode 100644
index 0000000000..64df008590
--- /dev/null
+++ b/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:
+-->
diff --git a/ext/pdo/specs/build/docbook-xml-4.4.tgz b/ext/pdo/specs/build/docbook-xml-4.4.tgz
new file mode 100644
index 0000000000..de414a0edc
--- /dev/null
+++ b/ext/pdo/specs/build/docbook-xml-4.4.tgz
Binary files differ
diff --git a/ext/pdo/specs/build/docbook-xsl-1.69.1.tgz b/ext/pdo/specs/build/docbook-xsl-1.69.1.tgz
new file mode 100644
index 0000000000..d6d99d3b8e
--- /dev/null
+++ b/ext/pdo/specs/build/docbook-xsl-1.69.1.tgz
Binary files differ
diff --git a/ext/pdo/specs/build/html-big.xsl b/ext/pdo/specs/build/html-big.xsl
new file mode 100644
index 0000000000..d026cbc2b5
--- /dev/null
+++ b/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:
+-->
diff --git a/ext/pdo/specs/build/html.xsl b/ext/pdo/specs/build/html.xsl
new file mode 100644
index 0000000000..eb112db662
--- /dev/null
+++ b/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:
+-->
diff --git a/ext/pdo/specs/configure.in b/ext/pdo/specs/configure.in
new file mode 100644
index 0000000000..f31a29cfc2
--- /dev/null
+++ b/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
+
diff --git a/ext/pdo/specs/drivers/all.xml b/ext/pdo/specs/drivers/all.xml
new file mode 100644
index 0000000000..e68fa39c52
--- /dev/null
+++ b/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:
+-->
+
diff --git a/ext/pdo/specs/drivers/binding.xml b/ext/pdo/specs/drivers/binding.xml
new file mode 100644
index 0000000000..2825697cdd
--- /dev/null
+++ b/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:
+-->
+
diff --git a/ext/pdo/specs/drivers/connect.xml b/ext/pdo/specs/drivers/connect.xml
new file mode 100644
index 0000000000..38c293d8de
--- /dev/null
+++ b/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:
+-->
+
diff --git a/ext/pdo/specs/drivers/dbh_methods.xml b/ext/pdo/specs/drivers/dbh_methods.xml
new file mode 100644
index 0000000000..f28c7addae
--- /dev/null
+++ b/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:
+-->
+
diff --git a/ext/pdo/specs/drivers/prepare.xml b/ext/pdo/specs/drivers/prepare.xml
new file mode 100644
index 0000000000..c9e43b5fdc
--- /dev/null
+++ b/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:
+-->
+
diff --git a/ext/pdo/specs/drivers/stmt_methods.xml b/ext/pdo/specs/drivers/stmt_methods.xml
new file mode 100644
index 0000000000..849be98b36
--- /dev/null
+++ b/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:
+-->
+
diff --git a/ext/pdo/specs/overview.xml b/ext/pdo/specs/overview.xml
new file mode 100644
index 0000000000..5b4187d524
--- /dev/null
+++ b/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:
+-->
diff --git a/ext/pdo/specs/preface.xml b/ext/pdo/specs/preface.xml
new file mode 100644
index 0000000000..8b88e7aa3f
--- /dev/null
+++ b/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:
+-->
diff --git a/ext/pdo/specs/userspace/all.xml b/ext/pdo/specs/userspace/all.xml
new file mode 100644
index 0000000000..496f835735
--- /dev/null
+++ b/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:
+-->
+