]> granicus.if.org Git - php/commitdiff
docbook based spec docs
authorWez Furlong <wez@php.net>
Tue, 27 Nov 2007 19:33:10 +0000 (19:33 +0000)
committerWez Furlong <wez@php.net>
Tue, 27 Nov 2007 19:33:10 +0000 (19:33 +0000)
17 files changed:
ext/pdo/specs/Makefile.in [new file with mode: 0644]
ext/pdo/specs/README
ext/pdo/specs/book.xml.in [new file with mode: 0644]
ext/pdo/specs/build/docbook-xml-4.4.tgz [new file with mode: 0644]
ext/pdo/specs/build/docbook-xsl-1.69.1.tgz [new file with mode: 0644]
ext/pdo/specs/build/html-big.xsl [new file with mode: 0644]
ext/pdo/specs/build/html.xsl [new file with mode: 0644]
ext/pdo/specs/configure.in [new file with mode: 0644]
ext/pdo/specs/drivers/all.xml [new file with mode: 0644]
ext/pdo/specs/drivers/binding.xml [new file with mode: 0644]
ext/pdo/specs/drivers/connect.xml [new file with mode: 0644]
ext/pdo/specs/drivers/dbh_methods.xml [new file with mode: 0644]
ext/pdo/specs/drivers/prepare.xml [new file with mode: 0644]
ext/pdo/specs/drivers/stmt_methods.xml [new file with mode: 0644]
ext/pdo/specs/overview.xml [new file with mode: 0644]
ext/pdo/specs/preface.xml [new file with mode: 0644]
ext/pdo/specs/userspace/all.xml [new file with mode: 0644]

diff --git a/ext/pdo/specs/Makefile.in b/ext/pdo/specs/Makefile.in
new file mode 100644 (file)
index 0000000..d9cfc13
--- /dev/null
@@ -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
+
index 5a73899414a9db32f5326bf8f0b9060cf801b105..beaf5e0be2e1293d3c549ff95181b37941c39a4f 100644 (file)
@@ -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 (file)
index 0000000..64df008
--- /dev/null
@@ -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 (file)
index 0000000..de414a0
Binary files /dev/null and b/ext/pdo/specs/build/docbook-xml-4.4.tgz 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 (file)
index 0000000..d6d99d3
Binary files /dev/null and b/ext/pdo/specs/build/docbook-xsl-1.69.1.tgz differ
diff --git a/ext/pdo/specs/build/html-big.xsl b/ext/pdo/specs/build/html-big.xsl
new file mode 100644 (file)
index 0000000..d026cbc
--- /dev/null
@@ -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 (file)
index 0000000..eb112db
--- /dev/null
@@ -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 (file)
index 0000000..f31a29c
--- /dev/null
@@ -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 (file)
index 0000000..e68fa39
--- /dev/null
@@ -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 (file)
index 0000000..2825697
--- /dev/null
@@ -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 (file)
index 0000000..38c293d
--- /dev/null
@@ -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 (file)
index 0000000..f28c7ad
--- /dev/null
@@ -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 (file)
index 0000000..c9e43b5
--- /dev/null
@@ -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 (file)
index 0000000..849be98
--- /dev/null
@@ -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 (file)
index 0000000..5b4187d
--- /dev/null
@@ -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 (file)
index 0000000..8b88e7a
--- /dev/null
@@ -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 (file)
index 0000000..496f835
--- /dev/null
@@ -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:
+-->
+