diff options
author | Wez Furlong <wez@php.net> | 2007-11-27 19:33:10 +0000 |
---|---|---|
committer | Wez Furlong <wez@php.net> | 2007-11-27 19:33:10 +0000 |
commit | 8e1ef43f5b5e2d00e4cb862c2348b005e7069a75 (patch) | |
tree | 8099da84cf81244249a609677784d57306a07492 | |
parent | 2f1ee5031a472a6d6e2531dd3a6ecd7df1504270 (diff) | |
download | php-git-8e1ef43f5b5e2d00e4cb862c2348b005e7069a75.tar.gz |
docbook based spec docs
-rw-r--r-- | ext/pdo/specs/Makefile.in | 51 | ||||
-rw-r--r-- | ext/pdo/specs/README | 8 | ||||
-rw-r--r-- | ext/pdo/specs/book.xml.in | 49 | ||||
-rw-r--r-- | ext/pdo/specs/build/docbook-xml-4.4.tgz | bin | 0 -> 75974 bytes | |||
-rw-r--r-- | ext/pdo/specs/build/docbook-xsl-1.69.1.tgz | bin | 0 -> 851027 bytes | |||
-rw-r--r-- | ext/pdo/specs/build/html-big.xsl | 39 | ||||
-rw-r--r-- | ext/pdo/specs/build/html.xsl | 39 | ||||
-rw-r--r-- | ext/pdo/specs/configure.in | 70 | ||||
-rw-r--r-- | ext/pdo/specs/drivers/all.xml | 114 | ||||
-rw-r--r-- | ext/pdo/specs/drivers/binding.xml | 18 | ||||
-rw-r--r-- | ext/pdo/specs/drivers/connect.xml | 266 | ||||
-rw-r--r-- | ext/pdo/specs/drivers/dbh_methods.xml | 285 | ||||
-rw-r--r-- | ext/pdo/specs/drivers/prepare.xml | 182 | ||||
-rw-r--r-- | ext/pdo/specs/drivers/stmt_methods.xml | 256 | ||||
-rw-r--r-- | ext/pdo/specs/overview.xml | 162 | ||||
-rw-r--r-- | ext/pdo/specs/preface.xml | 44 | ||||
-rw-r--r-- | ext/pdo/specs/userspace/all.xml | 13 |
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 Binary files differnew file mode 100644 index 0000000000..de414a0edc --- /dev/null +++ b/ext/pdo/specs/build/docbook-xml-4.4.tgz diff --git a/ext/pdo/specs/build/docbook-xsl-1.69.1.tgz b/ext/pdo/specs/build/docbook-xsl-1.69.1.tgz Binary files differnew file mode 100644 index 0000000000..d6d99d3b8e --- /dev/null +++ b/ext/pdo/specs/build/docbook-xsl-1.69.1.tgz 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ö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: +--> + |