Imported Upstream version 2.5.0 upstream/2.5.0
authorJoel Rosdahl <joel@debian.org>
Mon, 11 Jan 2010 20:47:01 +0000 (21:47 +0100)
committerJoel Rosdahl <joel@debian.org>
Mon, 11 Jan 2010 20:47:01 +0000 (21:47 +0100)
73 files changed:
MANIFEST.in
PKG-INFO
cross_bdist_wininst.py [new file with mode: 0644]
doc/default.css [deleted file]
doc/docutils.css [deleted file]
doc/includes/sqlite3/adapter_datetime.py [new file with mode: 0644]
doc/includes/sqlite3/adapter_point_1.py [new file with mode: 0644]
doc/includes/sqlite3/adapter_point_2.py [new file with mode: 0644]
doc/includes/sqlite3/apsw_example.py [new file with mode: 0644]
doc/includes/sqlite3/authorizer.py [new file with mode: 0644]
doc/includes/sqlite3/collation_reverse.py [new file with mode: 0644]
doc/includes/sqlite3/complete_statement.py [new file with mode: 0644]
doc/includes/sqlite3/connect_db_1.py [new file with mode: 0644]
doc/includes/sqlite3/connect_db_2.py [new file with mode: 0644]
doc/includes/sqlite3/converter_point.py [new file with mode: 0644]
doc/includes/sqlite3/countcursors.py [new file with mode: 0644]
doc/includes/sqlite3/createdb.py [new file with mode: 0644]
doc/includes/sqlite3/ctx_manager.py [new file with mode: 0644]
doc/includes/sqlite3/execsql_fetchonerow.py [new file with mode: 0644]
doc/includes/sqlite3/execsql_printall_1.py [new file with mode: 0644]
doc/includes/sqlite3/execute_1.py [new file with mode: 0644]
doc/includes/sqlite3/execute_2.py [new file with mode: 0644]
doc/includes/sqlite3/execute_3.py [new file with mode: 0644]
doc/includes/sqlite3/executemany_1.py [new file with mode: 0644]
doc/includes/sqlite3/executemany_2.py [new file with mode: 0644]
doc/includes/sqlite3/executescript.py [new file with mode: 0644]
doc/includes/sqlite3/insert_more_people.py [new file with mode: 0644]
doc/includes/sqlite3/load_extension.py [new file with mode: 0644]
doc/includes/sqlite3/md5func.py [new file with mode: 0644]
doc/includes/sqlite3/mysumaggr.py [new file with mode: 0644]
doc/includes/sqlite3/parse_colnames.py [new file with mode: 0644]
doc/includes/sqlite3/progress.py [new file with mode: 0644]
doc/includes/sqlite3/pysqlite_datetime.py [new file with mode: 0644]
doc/includes/sqlite3/row_factory.py [new file with mode: 0644]
doc/includes/sqlite3/rowclass.py [new file with mode: 0644]
doc/includes/sqlite3/shared_cache.py [new file with mode: 0644]
doc/includes/sqlite3/shortcut_methods.py [new file with mode: 0644]
doc/includes/sqlite3/simple_tableprinter.py [new file with mode: 0644]
doc/includes/sqlite3/text_factory.py [new file with mode: 0644]
doc/install-source-win32.html [deleted file]
doc/install-source.html [deleted file]
doc/silvercity.css [deleted file]
doc/sphinx/.static/.keepme [new file with mode: 0644]
doc/sphinx/Makefile [new file with mode: 0644]
doc/sphinx/conf.py [new file with mode: 0644]
doc/sphinx/index.rst [new file with mode: 0644]
doc/sphinx/sqlite3.rst [new file with mode: 0644]
doc/usage-guide.html [deleted file]
doc/usage-guide.txt [deleted file]
docutilsupport.py [deleted file]
extended_setup.py
pysqlite2/dump.py [new file with mode: 0644]
pysqlite2/test/__init__.py
pysqlite2/test/dbapi.py
pysqlite2/test/dump.py [new file with mode: 0644]
pysqlite2/test/factory.py
pysqlite2/test/regression.py
pysqlite2/test/transactions.py
pysqlite2/test/types.py
setup.py
src/connection.c
src/cursor.c
src/cursor.h
src/microprotocols.c
src/microprotocols.h
src/module.c
src/module.h
src/row.c
src/sqlitecompat.h
src/statement.c
src/statement.h
src/util.c
src/util.h

index 78c82b6..3ddb093 100644 (file)
@@ -2,9 +2,9 @@ include MANIFEST.in
 include LICENSE
 include ez_setup.py
 include extended_setup.py
-include docutilsupport.py
-include src/*.h
-include doc/*.html
+include cross_bdist_wininst.py
 include doc/*.txt
-include doc/*.css
-include doc/code/*.py
+include doc/includes/sqlite3/*.py
+include doc/sphinx/*
+include doc/sphinx/.static/.keepme
+include src/*.h
index 1c4c6f5..6a6d1bf 100644 (file)
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,12 +1,12 @@
 Metadata-Version: 1.0
 Name: pysqlite
-Version: 2.4.1
+Version: 2.5.0
 Summary: DB-API 2.0 interface for SQLite 3.x
-Home-page: http://pysqlite.org/
+Home-page: http://oss.itsystementwicklung.de/trac/pysqlite
 Author: Gerhard Haering
 Author-email: gh@ghaering.de
 License: zlib/libpng license
-Download-URL: http://initd.org/pub/software/pysqlite/releases/2.4/2.4.1/
+Download-URL: http://oss.itsystementwicklung.de/download/pysqlite/2.5/2.5.0/
 Description: Python interface to SQLite 3
         
         pysqlite is an interface to the SQLite 3.x embedded relational database engine.
diff --git a/cross_bdist_wininst.py b/cross_bdist_wininst.py
new file mode 100644 (file)
index 0000000..6d4a1fd
--- /dev/null
@@ -0,0 +1,344 @@
+# Gerhard Haering <gh@gharing.d> is responsible for the hacked version of this
+# module.
+#
+# This is a modified version of the bdist_wininst distutils command to make it
+# possible to build installers *with extension modules* on Unix.
+
+"""distutils.command.bdist_wininst
+
+Implements the Distutils 'bdist_wininst' command: create a windows installer
+exe-program."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id: bdist_wininst.py 59620 2007-12-31 14:47:07Z christian.heimes $"
+
+import sys, os, string
+from distutils.core import Command
+from distutils.util import get_platform
+from distutils.dir_util import create_tree, remove_tree
+from distutils.errors import *
+from distutils.sysconfig import get_python_version
+from distutils import log
+
+class bdist_wininst (Command):
+
+    description = "create an executable installer for MS Windows"
+
+    user_options = [('bdist-dir=', None,
+                     "temporary directory for creating the distribution"),
+                    ('keep-temp', 'k',
+                     "keep the pseudo-installation tree around after " +
+                     "creating the distribution archive"),
+                    ('target-version=', None,
+                     "require a specific python version" +
+                     " on the target system"),
+                    ('no-target-compile', 'c',
+                     "do not compile .py to .pyc on the target system"),
+                    ('no-target-optimize', 'o',
+                     "do not compile .py to .pyo (optimized)"
+                     "on the target system"),
+                    ('dist-dir=', 'd',
+                     "directory to put final built distributions in"),
+                    ('bitmap=', 'b',
+                     "bitmap to use for the installer instead of python-powered logo"),
+                    ('title=', 't',
+                     "title to display on the installer background instead of default"),
+                    ('skip-build', None,
+                     "skip rebuilding everything (for testing/debugging)"),
+                    ('install-script=', None,
+                     "basename of installation script to be run after"
+                     "installation or before deinstallation"),
+                    ('pre-install-script=', None,
+                     "Fully qualified filename of a script to be run before "
+                     "any files are installed.  This script need not be in the "
+                     "distribution"),
+                   ]
+
+    boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
+                       'skip-build']
+
+    def initialize_options (self):
+        self.bdist_dir = None
+        self.keep_temp = 0
+        self.no_target_compile = 0
+        self.no_target_optimize = 0
+        self.target_version = None
+        self.dist_dir = None
+        self.bitmap = None
+        self.title = None
+        self.skip_build = 0
+        self.install_script = None
+        self.pre_install_script = None
+
+    # initialize_options()
+
+
+    def finalize_options (self):
+        if self.bdist_dir is None:
+            bdist_base = self.get_finalized_command('bdist').bdist_base
+            self.bdist_dir = os.path.join(bdist_base, 'wininst')
+        if not self.target_version:
+            self.target_version = ""
+        if not self.skip_build and self.distribution.has_ext_modules():
+            short_version = get_python_version()
+            if self.target_version and self.target_version != short_version:
+                raise DistutilsOptionError, \
+                      "target version can only be %s, or the '--skip_build'" \
+                      " option must be specified" % (short_version,)
+            self.target_version = short_version
+
+        self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'))
+
+        if self.install_script:
+            for script in self.distribution.scripts:
+                if self.install_script == os.path.basename(script):
+                    break
+            else:
+                raise DistutilsOptionError, \
+                      "install_script '%s' not found in scripts" % \
+                      self.install_script
+    # finalize_options()
+
+
+    def run (self):
+        # HACK I disabled this check.
+        if 0 and (sys.platform != "win32" and
+            (self.distribution.has_ext_modules() or
+             self.distribution.has_c_libraries())):
+            raise DistutilsPlatformError \
+                  ("distribution contains extensions and/or C libraries; "
+                   "must be compiled on a Windows 32 platform")
+
+        if not self.skip_build:
+            self.run_command('build')
+
+        install = self.reinitialize_command('install', reinit_subcommands=1)
+        install.root = self.bdist_dir
+        install.skip_build = self.skip_build
+        install.warn_dir = 0
+
+        install_lib = self.reinitialize_command('install_lib')
+        # we do not want to include pyc or pyo files
+        install_lib.compile = 0
+        install_lib.optimize = 0
+
+        if self.distribution.has_ext_modules():
+            # If we are building an installer for a Python version other
+            # than the one we are currently running, then we need to ensure
+            # our build_lib reflects the other Python version rather than ours.
+            # Note that for target_version!=sys.version, we must have skipped the
+            # build step, so there is no issue with enforcing the build of this
+            # version.
+            target_version = self.target_version
+            if not target_version:
+                assert self.skip_build, "Should have already checked this"
+                target_version = sys.version[0:3]
+            plat_specifier = ".%s-%s" % (get_platform(), target_version)
+            build = self.get_finalized_command('build')
+            build.build_lib = os.path.join(build.build_base,
+                                           'lib' + plat_specifier)
+
+        # Use a custom scheme for the zip-file, because we have to decide
+        # at installation time which scheme to use.
+        for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'):
+            value = string.upper(key)
+            if key == 'headers':
+                value = value + '/Include/$dist_name'
+            setattr(install,
+                    'install_' + key,
+                    value)
+
+        log.info("installing to %s", self.bdist_dir)
+        install.ensure_finalized()
+
+        # avoid warning of 'install_lib' about installing
+        # into a directory not in sys.path
+        sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB'))
+
+        install.run()
+
+        del sys.path[0]
+
+        # And make an archive relative to the root of the
+        # pseudo-installation tree.
+        from tempfile import mktemp
+        archive_basename = mktemp()
+        fullname = self.distribution.get_fullname()
+        arcname = self.make_archive(archive_basename, "zip",
+                                    root_dir=self.bdist_dir)
+        # create an exe containing the zip-file
+        self.create_exe(arcname, fullname, self.bitmap)
+        if self.distribution.has_ext_modules():
+            pyversion = get_python_version()
+        else:
+            pyversion = 'any'
+        self.distribution.dist_files.append(('bdist_wininst', pyversion,
+                                             self.get_installer_filename(fullname)))
+        # remove the zip-file again
+        log.debug("removing temporary file '%s'", arcname)
+        os.remove(arcname)
+
+        if not self.keep_temp:
+            remove_tree(self.bdist_dir, dry_run=self.dry_run)
+
+    # run()
+
+    def get_inidata (self):
+        # Return data describing the installation.
+
+        lines = []
+        metadata = self.distribution.metadata
+
+        # Write the [metadata] section.
+        lines.append("[metadata]")
+
+        # 'info' will be displayed in the installer's dialog box,
+        # describing the items to be installed.
+        info = (metadata.long_description or '') + '\n'
+
+        # Escape newline characters
+        def escape(s):
+            return string.replace(s, "\n", "\\n")
+
+        for name in ["author", "author_email", "description", "maintainer",
+                     "maintainer_email", "name", "url", "version"]:
+            data = getattr(metadata, name, "")
+            if data:
+                info = info + ("\n    %s: %s" % \
+                               (string.capitalize(name), escape(data)))
+                lines.append("%s=%s" % (name, escape(data)))
+
+        # The [setup] section contains entries controlling
+        # the installer runtime.
+        lines.append("\n[Setup]")
+        if self.install_script:
+            lines.append("install_script=%s" % self.install_script)
+        lines.append("info=%s" % escape(info))
+        lines.append("target_compile=%d" % (not self.no_target_compile))
+        lines.append("target_optimize=%d" % (not self.no_target_optimize))
+        if self.target_version:
+            lines.append("target_version=%s" % self.target_version)
+
+        title = self.title or self.distribution.get_fullname()
+        lines.append("title=%s" % escape(title))
+        import time
+        import distutils
+        build_info = "Built %s with distutils-%s" % \
+                     (time.ctime(time.time()), distutils.__version__)
+        lines.append("build_info=%s" % build_info)
+        return string.join(lines, "\n")
+
+    # get_inidata()
+
+    def create_exe (self, arcname, fullname, bitmap=None):
+        import struct
+
+        self.mkpath(self.dist_dir)
+
+        cfgdata = self.get_inidata()
+
+        installer_name = self.get_installer_filename(fullname)
+        self.announce("creating %s" % installer_name)
+
+        if bitmap:
+            bitmapdata = open(bitmap, "rb").read()
+            bitmaplen = len(bitmapdata)
+        else:
+            bitmaplen = 0
+
+        file = open(installer_name, "wb")
+        file.write(self.get_exe_bytes())
+        if bitmap:
+            file.write(bitmapdata)
+
+        # Convert cfgdata from unicode to ascii, mbcs encoded
+        try:
+            unicode
+        except NameError:
+            pass
+        else:
+            if isinstance(cfgdata, unicode):
+                cfgdata = cfgdata.encode("mbcs")
+
+        # Append the pre-install script
+        cfgdata = cfgdata + "\0"
+        if self.pre_install_script:
+            script_data = open(self.pre_install_script, "r").read()
+            cfgdata = cfgdata + script_data + "\n\0"
+        else:
+            # empty pre-install script
+            cfgdata = cfgdata + "\0"
+        file.write(cfgdata)
+
+        # The 'magic number' 0x1234567B is used to make sure that the
+        # binary layout of 'cfgdata' is what the wininst.exe binary
+        # expects.  If the layout changes, increment that number, make
+        # the corresponding changes to the wininst.exe sources, and
+        # recompile them.
+        header = struct.pack("<iii",
+                             0x1234567B,       # tag
+                             len(cfgdata),     # length
+                             bitmaplen,        # number of bytes in bitmap
+                             )
+        file.write(header)
+        file.write(open(arcname, "rb").read())
+
+    # create_exe()
+
+    def get_installer_filename(self, fullname):
+        # Factored out to allow overriding in subclasses
+        if self.target_version:
+            # if we create an installer for a specific python version,
+            # it's better to include this in the name
+            installer_name = os.path.join(self.dist_dir,
+                                          "%s.win32-py%s.exe" %
+                                           (fullname, self.target_version))
+        else:
+            installer_name = os.path.join(self.dist_dir,
+                                          "%s.win32.exe" % fullname)
+        return installer_name
+    # get_installer_filename()
+
+    def get_exe_bytes (self):
+        from distutils.msvccompiler import get_build_version
+        # If a target-version other than the current version has been
+        # specified, then using the MSVC version from *this* build is no good.
+        # Without actually finding and executing the target version and parsing
+        # its sys.version, we just hard-code our knowledge of old versions.
+        # NOTE: Possible alternative is to allow "--target-version" to
+        # specify a Python executable rather than a simple version string.
+        # We can then execute this program to obtain any info we need, such
+        # as the real sys.version string for the build.
+        cur_version = get_python_version()
+        if self.target_version and self.target_version != cur_version:
+            # If the target version is *later* than us, then we assume they
+            # use what we use
+            # string compares seem wrong, but are what sysconfig.py itself uses
+            if self.target_version > cur_version:
+                bv = get_build_version()
+            else:
+                if self.target_version < "2.4":
+                    bv = "6"
+                else:
+                    bv = "7.1"
+        else:
+            # for current version - use authoritative check.
+            bv = get_build_version()
+
+        # wininst-x.y.exe is in the same directory as this file
+        directory = os.path.dirname(__file__)
+        # we must use a wininst-x.y.exe built with the same C compiler
+        # used for python.  XXX What about mingw, borland, and so on?
+
+        # The uninstallers need to be available in $PYEXT_CROSS/uninst/*.exe
+        # Use http://oss.itsystementwicklung.de/hg/pyext_cross_linux_to_win32/
+        # and copy it alongside your pysqlite checkout.
+        if self.target_version in ("2.3", "2.4"):
+            uninst_ver = "6"
+        else:
+            uninst_ver = "7.1"
+
+        filename = os.path.join(directory, os.path.join(os.environ["PYEXT_CROSS"], "uninst", "wininst-%s.exe" % uninst_ver))
+        return open(filename, "rb").read()
+# class bdist_wininst
diff --git a/doc/default.css b/doc/default.css
deleted file mode 100644 (file)
index 05ca4b1..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-@import url(docutils.css);
-@import url(silvercity.css);
-
-div.code-block{
-margin-left: 2em ;
-margin-right: 2em ;
-background-color: #eeeeee;
-font-family: "Courier New", Courier, monospace;
-font-size: 10pt;
-}
diff --git a/doc/docutils.css b/doc/docutils.css
deleted file mode 100644 (file)
index 43074c6..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
-:Author: David Goodger
-:Contact: goodger@users.sourceforge.net
-:Date: $Date: 2005-04-25 22:24:49 +0200 (Mon, 25 Apr 2005) $
-:Version: $Revision: 3256 $
-:Copyright: This stylesheet has been placed in the public domain.
-
-Default cascading style sheet for the HTML output of Docutils.
-*/
-
-/* "! important" is used here to override other ``margin-top`` and
-   ``margin-bottom`` styles that are later in the stylesheet or 
-   more specific.  See http://www.w3.org/TR/CSS1#the-cascade */
-.first {
-  margin-top: 0 ! important }
-
-.last {
-  margin-bottom: 0 ! important }
-
-.hidden {
-  display: none }
-
-a.toc-backref {
-  text-decoration: none ;
-  color: black }
-
-blockquote.epigraph {
-  margin: 2em 5em ; }
-
-dl.docutils dd {
-  margin-bottom: 0.5em }
-
-/* Uncomment (and remove this text!) to get bold-faced definition list terms
-dl.docutils dt {
-  font-weight: bold }
-*/
-
-div.abstract {
-  margin: 2em 5em }
-
-div.abstract p.topic-title {
-  font-weight: bold ;
-  text-align: center }
-
-div.admonition, div.attention, div.caution, div.danger, div.error,
-div.hint, div.important, div.note, div.tip, div.warning {
-  margin: 2em ;
-  border: medium outset ;
-  padding: 1em }
-
-div.admonition p.admonition-title, div.hint p.admonition-title,
-div.important p.admonition-title, div.note p.admonition-title,
-div.tip p.admonition-title {
-  font-weight: bold ;
-  font-family: sans-serif }
-
-div.attention p.admonition-title, div.caution p.admonition-title,
-div.danger p.admonition-title, div.error p.admonition-title,
-div.warning p.admonition-title {
-  color: red ;
-  font-weight: bold ;
-  font-family: sans-serif }
-
-/* Uncomment (and remove this text!) to get reduced vertical space in
-   compound paragraphs.
-div.compound .compound-first, div.compound .compound-middle {
-  margin-bottom: 0.5em }
-
-div.compound .compound-last, div.compound .compound-middle {
-  margin-top: 0.5em }
-*/
-
-div.dedication {
-  margin: 2em 5em ;
-  text-align: center ;
-  font-style: italic }
-
-div.dedication p.topic-title {
-  font-weight: bold ;
-  font-style: normal }
-
-div.figure {
-  margin-left: 2em }
-
-div.footer, div.header {
-  font-size: smaller }
-
-div.line-block {
-  display: block ;
-  margin-top: 1em ;
-  margin-bottom: 1em }
-
-div.line-block div.line-block {
-  margin-top: 0 ;
-  margin-bottom: 0 ;
-  margin-left: 1.5em }
-
-div.sidebar {
-  margin-left: 1em ;
-  border: medium outset ;
-  padding: 1em ;
-  background-color: #ffffee ;
-  width: 40% ;
-  float: right ;
-  clear: right }
-
-div.sidebar p.rubric {
-  font-family: sans-serif ;
-  font-size: medium }
-
-div.system-messages {
-  margin: 5em }
-
-div.system-messages h1 {
-  color: red }
-
-div.system-message {
-  border: medium outset ;
-  padding: 1em }
-
-div.system-message p.system-message-title {
-  color: red ;
-  font-weight: bold }
-
-div.topic {
-  margin: 2em }
-
-h1.title {
-  text-align: center }
-
-h2.subtitle {
-  text-align: center }
-
-hr.docutils {
-  width: 75% }
-
-ol.simple, ul.simple {
-  margin-bottom: 1em }
-
-ol.arabic {
-  list-style: decimal }
-
-ol.loweralpha {
-  list-style: lower-alpha }
-
-ol.upperalpha {
-  list-style: upper-alpha }
-
-ol.lowerroman {
-  list-style: lower-roman }
-
-ol.upperroman {
-  list-style: upper-roman }
-
-p.attribution {
-  text-align: right ;
-  margin-left: 50% }
-
-p.caption {
-  font-style: italic }
-
-p.credits {
-  font-style: italic ;
-  font-size: smaller }
-
-p.label {
-  white-space: nowrap }
-
-p.rubric {
-  font-weight: bold ;
-  font-size: larger ;
-  color: maroon ;
-  text-align: center }
-
-p.sidebar-title {
-  font-family: sans-serif ;
-  font-weight: bold ;
-  font-size: larger }
-
-p.sidebar-subtitle {
-  font-family: sans-serif ;
-  font-weight: bold }
-
-p.topic-title {
-  font-weight: bold }
-
-pre.address {
-  margin-bottom: 0 ;
-  margin-top: 0 ;
-  font-family: serif ;
-  font-size: 100% }
-
-pre.line-block {
-  font-family: serif ;
-  font-size: 100% }
-
-pre.literal-block, pre.doctest-block {
-  margin-left: 2em ;
-  margin-right: 2em ;
-  background-color: #eeeeee }
-
-span.classifier {
-  font-family: sans-serif ;
-  font-style: oblique }
-
-span.classifier-delimiter {
-  font-family: sans-serif ;
-  font-weight: bold }
-
-span.interpreted {
-  font-family: sans-serif }
-
-span.option {
-  white-space: nowrap }
-
-span.pre {
-  white-space: pre }
-
-span.problematic {
-  color: red }
-
-table.citation {
-  border-left: solid thin gray }
-
-table.docinfo {
-  margin: 2em 4em }
-
-table.docutils {
-  margin-top: 0.5em ;
-  margin-bottom: 0.5em }
-
-table.footnote {
-  border-left: solid thin black }
-
-table.docutils td, table.docutils th,
-table.docinfo td, table.docinfo th {
-  padding-left: 0.5em ;
-  padding-right: 0.5em ;
-  vertical-align: top }
-
-table.docutils th.field-name, table.docinfo th.docinfo-name {
-  font-weight: bold ;
-  text-align: left ;
-  white-space: nowrap ;
-  padding-left: 0 }
-
-h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
-h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
-  font-size: 100% }
-
-tt.docutils {
-  background-color: #eeeeee }
-
-ul.auto-toc {
-  list-style-type: none }
-
-body {
- background-color: #eeeeff;
- font-family: Verdana, Arial, Helvetica, sans-serif;
-}
diff --git a/doc/includes/sqlite3/adapter_datetime.py b/doc/includes/sqlite3/adapter_datetime.py
new file mode 100644 (file)
index 0000000..5a43b02
--- /dev/null
@@ -0,0 +1,14 @@
+from pysqlite2 import dbapi2 as sqlite3
+import datetime, time
+
+def adapt_datetime(ts):
+    return time.mktime(ts.timetuple())
+
+sqlite3.register_adapter(datetime.datetime, adapt_datetime)
+
+con = sqlite3.connect(":memory:")
+cur = con.cursor()
+
+now = datetime.datetime.now()
+cur.execute("select ?", (now,))
+print cur.fetchone()[0]
diff --git a/doc/includes/sqlite3/adapter_point_1.py b/doc/includes/sqlite3/adapter_point_1.py
new file mode 100644 (file)
index 0000000..d9acb8d
--- /dev/null
@@ -0,0 +1,16 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+class Point(object):
+    def __init__(self, x, y):
+        self.x, self.y = x, y
+
+    def __conform__(self, protocol):
+        if protocol is sqlite3.PrepareProtocol:
+            return "%f;%f" % (self.x, self.y)
+
+con = sqlite3.connect(":memory:")
+cur = con.cursor()
+
+p = Point(4.0, -3.2)
+cur.execute("select ?", (p,))
+print cur.fetchone()[0]
diff --git a/doc/includes/sqlite3/adapter_point_2.py b/doc/includes/sqlite3/adapter_point_2.py
new file mode 100644 (file)
index 0000000..6ec58a8
--- /dev/null
@@ -0,0 +1,17 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+class Point(object):
+    def __init__(self, x, y):
+        self.x, self.y = x, y
+
+def adapt_point(point):
+    return "%f;%f" % (point.x, point.y)
+
+sqlite3.register_adapter(Point, adapt_point)
+
+con = sqlite3.connect(":memory:")
+cur = con.cursor()
+
+p = Point(4.0, -3.2)
+cur.execute("select ?", (p,))
+print cur.fetchone()[0]
diff --git a/doc/includes/sqlite3/apsw_example.py b/doc/includes/sqlite3/apsw_example.py
new file mode 100644 (file)
index 0000000..bdca0c9
--- /dev/null
@@ -0,0 +1,12 @@
+from pysqlite2 import dbapi2 as sqlite3
+import apsw
+
+apsw_con = apsw.Connection(":memory:")
+apsw_con.createscalarfunction("times_two", lambda x: 2*x, 1)
+
+# Create pysqlite connection from APSW connection
+con = sqlite3.connect(apsw_con)
+result = con.execute("select times_two(15)").fetchone()[0]
+assert result == 30
+con.close()
+
diff --git a/doc/includes/sqlite3/authorizer.py b/doc/includes/sqlite3/authorizer.py
new file mode 100644 (file)
index 0000000..0176c6c
--- /dev/null
@@ -0,0 +1,26 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+def authorizer_callback(action, arg1, arg2, dbname, source):
+    if action != sqlite3.SQLITE_SELECT:
+        return sqlite3.SQLITE_DENY
+    if arg1 == "private_table":
+        return sqlite3.SQLITE_DENY
+    return sqlite3.SQLITE_OK
+
+con = sqlite3.connect(":memory:")
+con.executescript("""
+    create table public_table(c1, c2);
+    create table private_table(c1, c2);
+    """)
+con.set_authorizer(authorizer_callback)
+
+try:
+    con.execute("select * from private_table")
+except sqlite3.DatabaseError, e:
+    print "SELECT FROM private_table =>", e.args[0]     # access ... prohibited
+
+try:
+    con.execute("insert into public_table(c1, c2) values (1, 2)")
+except sqlite3.DatabaseError, e:
+    print "DML command =>", e.args[0]     # access ... prohibited
+
diff --git a/doc/includes/sqlite3/collation_reverse.py b/doc/includes/sqlite3/collation_reverse.py
new file mode 100644 (file)
index 0000000..100fac9
--- /dev/null
@@ -0,0 +1,15 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+def collate_reverse(string1, string2):
+    return -cmp(string1, string2)
+
+con = sqlite3.connect(":memory:")
+con.create_collation("reverse", collate_reverse)
+
+cur = con.cursor()
+cur.execute("create table test(x)")
+cur.executemany("insert into test(x) values (?)", [("a",), ("b",)])
+cur.execute("select x from test order by x collate reverse")
+for row in cur:
+    print row
+con.close()
diff --git a/doc/includes/sqlite3/complete_statement.py b/doc/includes/sqlite3/complete_statement.py
new file mode 100644 (file)
index 0000000..2bb49d4
--- /dev/null
@@ -0,0 +1,30 @@
+# A minimal SQLite shell for experiments
+
+from pysqlite2 import dbapi2 as sqlite3
+
+con = sqlite3.connect(":memory:")
+con.isolation_level = None
+cur = con.cursor()
+
+buffer = ""
+
+print "Enter your SQL commands to execute in SQLite."
+print "Enter a blank line to exit."
+
+while True:
+    line = raw_input()
+    if line == "":
+        break
+    buffer += line
+    if sqlite3.complete_statement(buffer):
+        try:
+            buffer = buffer.strip()
+            cur.execute(buffer)
+
+            if buffer.lstrip().upper().startswith("SELECT"):
+                print cur.fetchall()
+        except sqlite3.Error, e:
+            print "An error occurred:", e.args[0]
+        buffer = ""
+
+con.close()
diff --git a/doc/includes/sqlite3/connect_db_1.py b/doc/includes/sqlite3/connect_db_1.py
new file mode 100644 (file)
index 0000000..360bf21
--- /dev/null
@@ -0,0 +1,3 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+con = sqlite3.connect("mydb")
diff --git a/doc/includes/sqlite3/connect_db_2.py b/doc/includes/sqlite3/connect_db_2.py
new file mode 100644 (file)
index 0000000..6899843
--- /dev/null
@@ -0,0 +1,3 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+con = sqlite3.connect(":memory:")
diff --git a/doc/includes/sqlite3/converter_point.py b/doc/includes/sqlite3/converter_point.py
new file mode 100644 (file)
index 0000000..4ba0df5
--- /dev/null
@@ -0,0 +1,47 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+class Point(object):
+    def __init__(self, x, y):
+        self.x, self.y = x, y
+
+    def __repr__(self):
+        return "(%f;%f)" % (self.x, self.y)
+
+def adapt_point(point):
+    return "%f;%f" % (point.x, point.y)
+
+def convert_point(s):
+    x, y = map(float, s.split(";"))
+    return Point(x, y)
+
+# Register the adapter
+sqlite3.register_adapter(Point, adapt_point)
+
+# Register the converter
+sqlite3.register_converter("point", convert_point)
+
+p = Point(4.0, -3.2)
+
+#########################
+# 1) Using declared types
+con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
+cur = con.cursor()
+cur.execute("create table test(p point)")
+
+cur.execute("insert into test(p) values (?)", (p,))
+cur.execute("select p from test")
+print "with declared types:", cur.fetchone()[0]
+cur.close()
+con.close()
+
+#######################
+# 1) Using column names
+con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)
+cur = con.cursor()
+cur.execute("create table test(p)")
+
+cur.execute("insert into test(p) values (?)", (p,))
+cur.execute('select p as "p [point]" from test')
+print "with column names:", cur.fetchone()[0]
+cur.close()
+con.close()
diff --git a/doc/includes/sqlite3/countcursors.py b/doc/includes/sqlite3/countcursors.py
new file mode 100644 (file)
index 0000000..9ba7614
--- /dev/null
@@ -0,0 +1,15 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+class CountCursorsConnection(sqlite3.Connection):
+    def __init__(self, *args, **kwargs):
+        sqlite3.Connection.__init__(self, *args, **kwargs)
+        self.numcursors = 0
+
+    def cursor(self, *args, **kwargs):
+        self.numcursors += 1
+        return sqlite3.Connection.cursor(self, *args, **kwargs)
+
+con = sqlite3.connect(":memory:", factory=CountCursorsConnection)
+cur1 = con.cursor()
+cur2 = con.cursor()
+print con.numcursors
diff --git a/doc/includes/sqlite3/createdb.py b/doc/includes/sqlite3/createdb.py
new file mode 100644 (file)
index 0000000..28e9514
--- /dev/null
@@ -0,0 +1,28 @@
+# Not referenced from the documentation, but builds the database file the other
+# code snippets expect.
+
+from pysqlite2 import dbapi2 as sqlite3
+import os
+
+DB_FILE = "mydb"
+
+if os.path.exists(DB_FILE):
+    os.remove(DB_FILE)
+
+con = sqlite3.connect(DB_FILE)
+cur = con.cursor()
+cur.execute("""
+        create table people
+        (
+          name_last      varchar(20),
+          age            integer
+        )
+        """)
+
+cur.execute("insert into people (name_last, age) values ('Yeltsin',   72)")
+cur.execute("insert into people (name_last, age) values ('Putin',     51)")
+
+con.commit()
+
+cur.close()
+con.close()
diff --git a/doc/includes/sqlite3/ctx_manager.py b/doc/includes/sqlite3/ctx_manager.py
new file mode 100644 (file)
index 0000000..2821e8f
--- /dev/null
@@ -0,0 +1,19 @@
+from __future__ import with_statement
+from pysqlite2 import dbapi2 as sqlite3
+
+con = sqlite3.connect(":memory:")
+con.execute("create table person (id integer primary key, firstname varchar unique)")
+
+# Successful, con.commit() is called automatically afterwards
+with con:
+    con.execute("insert into person(firstname) values (?)", ("Joe",))
+
+# con.rollback() is called after the with block finishes with an exception, the
+# exception is still raised and must be catched
+try:
+    with con:
+        con.execute("insert into person(firstname) values (?)", ("Joe",))
+except sqlite3.IntegrityError:
+    print "couldn't add Joe twice"
+
+
diff --git a/doc/includes/sqlite3/execsql_fetchonerow.py b/doc/includes/sqlite3/execsql_fetchonerow.py
new file mode 100644 (file)
index 0000000..e3aa578
--- /dev/null
@@ -0,0 +1,17 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+con = sqlite3.connect("mydb")
+
+cur = con.cursor()
+SELECT = "select name_last, age from people order by age, name_last"
+
+# 1. Iterate over the rows available from the cursor, unpacking the
+# resulting sequences to yield their elements (name_last, age):
+cur.execute(SELECT)
+for (name_last, age) in cur:
+    print '%s is %d years old.' % (name_last, age)
+
+# 2. Equivalently:
+cur.execute(SELECT)
+for row in cur:
+    print '%s is %d years old.' % (row[0], row[1])
diff --git a/doc/includes/sqlite3/execsql_printall_1.py b/doc/includes/sqlite3/execsql_printall_1.py
new file mode 100644 (file)
index 0000000..62e48bd
--- /dev/null
@@ -0,0 +1,13 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+# Create a connection to the database file "mydb":
+con = sqlite3.connect("mydb")
+
+# Get a Cursor object that operates in the context of Connection con:
+cur = con.cursor()
+
+# Execute the SELECT statement:
+cur.execute("select * from people order by age")
+
+# Retrieve all rows as a sequence and print that sequence:
+print cur.fetchall()
diff --git a/doc/includes/sqlite3/execute_1.py b/doc/includes/sqlite3/execute_1.py
new file mode 100644 (file)
index 0000000..70967ea
--- /dev/null
@@ -0,0 +1,11 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+con = sqlite3.connect("mydb")
+
+cur = con.cursor()
+
+who = "Yeltsin"
+age = 72
+
+cur.execute("select name_last, age from people where name_last=? and age=?", (who, age))
+print cur.fetchone()
diff --git a/doc/includes/sqlite3/execute_2.py b/doc/includes/sqlite3/execute_2.py
new file mode 100644 (file)
index 0000000..416b116
--- /dev/null
@@ -0,0 +1,12 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+con = sqlite3.connect("mydb")
+
+cur = con.cursor()
+
+who = "Yeltsin"
+age = 72
+
+cur.execute("select name_last, age from people where name_last=:who and age=:age",
+    {"who": who, "age": age})
+print cur.fetchone()
diff --git a/doc/includes/sqlite3/execute_3.py b/doc/includes/sqlite3/execute_3.py
new file mode 100644 (file)
index 0000000..868be99
--- /dev/null
@@ -0,0 +1,12 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+con = sqlite3.connect("mydb")
+
+cur = con.cursor()
+
+who = "Yeltsin"
+age = 72
+
+cur.execute("select name_last, age from people where name_last=:who and age=:age",
+    locals())
+print cur.fetchone()
diff --git a/doc/includes/sqlite3/executemany_1.py b/doc/includes/sqlite3/executemany_1.py
new file mode 100644 (file)
index 0000000..b076389
--- /dev/null
@@ -0,0 +1,24 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+class IterChars:
+    def __init__(self):
+        self.count = ord('a')
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        if self.count > ord('z'):
+            raise StopIteration
+        self.count += 1
+        return (chr(self.count - 1),) # this is a 1-tuple
+
+con = sqlite3.connect(":memory:")
+cur = con.cursor()
+cur.execute("create table characters(c)")
+
+theIter = IterChars()
+cur.executemany("insert into characters(c) values (?)", theIter)
+
+cur.execute("select c from characters")
+print cur.fetchall()
diff --git a/doc/includes/sqlite3/executemany_2.py b/doc/includes/sqlite3/executemany_2.py
new file mode 100644 (file)
index 0000000..9913909
--- /dev/null
@@ -0,0 +1,15 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+def char_generator():
+    import string
+    for c in string.letters[:26]:
+        yield (c,)
+
+con = sqlite3.connect(":memory:")
+cur = con.cursor()
+cur.execute("create table characters(c)")
+
+cur.executemany("insert into characters(c) values (?)", char_generator())
+
+cur.execute("select c from characters")
+print cur.fetchall()
diff --git a/doc/includes/sqlite3/executescript.py b/doc/includes/sqlite3/executescript.py
new file mode 100644 (file)
index 0000000..57c2613
--- /dev/null
@@ -0,0 +1,24 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+con = sqlite3.connect(":memory:")
+cur = con.cursor()
+cur.executescript("""
+    create table person(
+        firstname,
+        lastname,
+        age
+    );
+
+    create table book(
+        title,
+        author,
+        published
+    );
+
+    insert into book(title, author, published)
+    values (
+        'Dirk Gently''s Holistic Detective Agency',
+        'Douglas Adams',
+        1987
+    );
+    """)
diff --git a/doc/includes/sqlite3/insert_more_people.py b/doc/includes/sqlite3/insert_more_people.py
new file mode 100644 (file)
index 0000000..40600dc
--- /dev/null
@@ -0,0 +1,16 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+con = sqlite3.connect("mydb")
+
+cur = con.cursor()
+
+newPeople = (
+    ('Lebed'       , 53),
+    ('Zhirinovsky' , 57),
+  )
+
+for person in newPeople:
+    cur.execute("insert into people (name_last, age) values (?, ?)", person)
+
+# The changes will not be saved unless the transaction is committed explicitly:
+con.commit()
diff --git a/doc/includes/sqlite3/load_extension.py b/doc/includes/sqlite3/load_extension.py
new file mode 100644 (file)
index 0000000..8b6b4e5
--- /dev/null
@@ -0,0 +1,21 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+con = sqlite3.connect(":memory:")
+
+# Load the fulltext search extension
+con.enable_load_extension(True)
+con.execute("select load_extension('./fts3.so')")
+con.enable_load_extension(False)
+
+# example from SQLite wiki
+con.execute("create virtual table recipe using fts3(name, ingredients)")
+con.executescript("""
+    insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes');
+    insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery');
+    insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour');
+    insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter');
+    """)
+for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"):
+    print row
+
+
diff --git a/doc/includes/sqlite3/md5func.py b/doc/includes/sqlite3/md5func.py
new file mode 100644 (file)
index 0000000..5b8b983
--- /dev/null
@@ -0,0 +1,11 @@
+from pysqlite2 import dbapi2 as sqlite3
+import md5
+
+def md5sum(t):
+    return md5.md5(t).hexdigest()
+
+con = sqlite3.connect(":memory:")
+con.create_function("md5", 1, md5sum)
+cur = con.cursor()
+cur.execute("select md5(?)", ("foo",))
+print cur.fetchone()[0]
diff --git a/doc/includes/sqlite3/mysumaggr.py b/doc/includes/sqlite3/mysumaggr.py
new file mode 100644 (file)
index 0000000..4fbcad5
--- /dev/null
@@ -0,0 +1,20 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+class MySum:
+    def __init__(self):
+        self.count = 0
+
+    def step(self, value):
+        self.count += value
+
+    def finalize(self):
+        return self.count
+
+con = sqlite3.connect(":memory:")
+con.create_aggregate("mysum", 1, MySum)
+cur = con.cursor()
+cur.execute("create table test(i)")
+cur.execute("insert into test(i) values (1)")
+cur.execute("insert into test(i) values (2)")
+cur.execute("select mysum(i) from test")
+print cur.fetchone()[0]
diff --git a/doc/includes/sqlite3/parse_colnames.py b/doc/includes/sqlite3/parse_colnames.py
new file mode 100644 (file)
index 0000000..702fa8d
--- /dev/null
@@ -0,0 +1,8 @@
+from pysqlite2 import dbapi2 as sqlite3
+import datetime
+
+con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)
+cur = con.cursor()
+cur.execute('select ? as "x [timestamp]"', (datetime.datetime.now(),))
+dt = cur.fetchone()[0]
+print dt, type(dt)
diff --git a/doc/includes/sqlite3/progress.py b/doc/includes/sqlite3/progress.py
new file mode 100644 (file)
index 0000000..b30941d
--- /dev/null
@@ -0,0 +1,29 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+def progress():
+    print "Query still executing. Please wait ..."
+
+con = sqlite3.connect(":memory:")
+con.execute("create table test(x)")
+
+# Let's create some data
+con.executemany("insert into test(x) values (?)", [(x,) for x in xrange(300)])
+
+# A progress handler, executed every 10 million opcodes
+con.set_progress_handler(progress, 10000000)
+
+# A particularly long-running query
+killer_stament = """
+    select count(*) from (
+        select t1.x from test t1, test t2, test t3
+    )
+    """
+
+con.execute(killer_stament)
+print "-" * 50
+
+# Clear the progress handler
+con.set_progress_handler(None, 0)
+
+con.execute(killer_stament)
+
diff --git a/doc/includes/sqlite3/pysqlite_datetime.py b/doc/includes/sqlite3/pysqlite_datetime.py
new file mode 100644 (file)
index 0000000..9075b46
--- /dev/null
@@ -0,0 +1,20 @@
+from pysqlite2 import dbapi2 as sqlite3
+import datetime
+
+con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
+cur = con.cursor()
+cur.execute("create table test(d date, ts timestamp)")
+
+today = datetime.date.today()
+now = datetime.datetime.now()
+
+cur.execute("insert into test(d, ts) values (?, ?)", (today, now))
+cur.execute("select d, ts from test")
+row = cur.fetchone()
+print today, "=>", row[0], type(row[0])
+print now, "=>", row[1], type(row[1])
+
+cur.execute('select current_date as "d [date]", current_timestamp as "ts [timestamp]"')
+row = cur.fetchone()
+print "current_date", row[0], type(row[0])
+print "current_timestamp", row[1], type(row[1])
diff --git a/doc/includes/sqlite3/row_factory.py b/doc/includes/sqlite3/row_factory.py
new file mode 100644 (file)
index 0000000..bfbc64d
--- /dev/null
@@ -0,0 +1,13 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+def dict_factory(cursor, row):
+    d = {}
+    for idx, col in enumerate(cursor.description):
+        d[col[0]] = row[idx]
+    return d
+
+con = sqlite3.connect(":memory:")
+con.row_factory = dict_factory
+cur = con.cursor()
+cur.execute("select 1 as a")
+print cur.fetchone()["a"]
diff --git a/doc/includes/sqlite3/rowclass.py b/doc/includes/sqlite3/rowclass.py
new file mode 100644 (file)
index 0000000..e210ef2
--- /dev/null
@@ -0,0 +1,12 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+con = sqlite3.connect("mydb")
+con.row_factory = sqlite3.Row
+
+cur = con.cursor()
+cur.execute("select name_last, age from people")
+for row in cur:
+    assert row[0] == row["name_last"]
+    assert row["name_last"] == row["nAmE_lAsT"]
+    assert row[1] == row["age"]
+    assert row[1] == row["AgE"]
diff --git a/doc/includes/sqlite3/shared_cache.py b/doc/includes/sqlite3/shared_cache.py
new file mode 100644 (file)
index 0000000..98adf78
--- /dev/null
@@ -0,0 +1,6 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+# The shared cache is only available in SQLite versions 3.3.3 or later
+# See the SQLite documentaton for details.
+
+sqlite3.enable_shared_cache(True)
diff --git a/doc/includes/sqlite3/shortcut_methods.py b/doc/includes/sqlite3/shortcut_methods.py
new file mode 100644 (file)
index 0000000..fcfc631
--- /dev/null
@@ -0,0 +1,21 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+persons = [
+    ("Hugo", "Boss"),
+    ("Calvin", "Klein")
+    ]
+
+con = sqlite3.connect(":memory:")
+
+# Create the table
+con.execute("create table person(firstname, lastname)")
+
+# Fill the table
+con.executemany("insert into person(firstname, lastname) values (?, ?)", persons)
+
+# Print the table contents
+for row in con.execute("select firstname, lastname from person"):
+    print row
+
+# Using a dummy WHERE clause to not let SQLite take the shortcut table deletes.
+print "I just deleted", con.execute("delete from person where 1=1").rowcount, "rows"
diff --git a/doc/includes/sqlite3/simple_tableprinter.py b/doc/includes/sqlite3/simple_tableprinter.py
new file mode 100644 (file)
index 0000000..2237dc5
--- /dev/null
@@ -0,0 +1,26 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+FIELD_MAX_WIDTH = 20
+TABLE_NAME = 'people'
+SELECT = 'select * from %s order by age, name_last' % TABLE_NAME
+
+con = sqlite3.connect("mydb")
+
+cur = con.cursor()
+cur.execute(SELECT)
+
+# Print a header.
+for fieldDesc in cur.description:
+    print fieldDesc[0].ljust(FIELD_MAX_WIDTH) ,
+print # Finish the header with a newline.
+print '-' * 78
+
+# For each row, print the value of each field left-justified within
+# the maximum possible width of that field.
+fieldIndices = range(len(cur.description))
+for row in cur:
+    for fieldIndex in fieldIndices:
+        fieldValue = str(row[fieldIndex])
+        print fieldValue.ljust(FIELD_MAX_WIDTH) ,
+
+    print # Finish the row with a newline.
diff --git a/doc/includes/sqlite3/text_factory.py b/doc/includes/sqlite3/text_factory.py
new file mode 100644 (file)
index 0000000..cb38d52
--- /dev/null
@@ -0,0 +1,42 @@
+from pysqlite2 import dbapi2 as sqlite3
+
+con = sqlite3.connect(":memory:")
+cur = con.cursor()
+
+# Create the table
+con.execute("create table person(lastname, firstname)")
+
+AUSTRIA = u"\xd6sterreich"
+
+# by default, rows are returned as Unicode
+cur.execute("select ?", (AUSTRIA,))
+row = cur.fetchone()
+assert row[0] == AUSTRIA
+
+# but we can make pysqlite always return bytestrings ...
+con.text_factory = str
+cur.execute("select ?", (AUSTRIA,))
+row = cur.fetchone()
+assert type(row[0]) == str
+# the bytestrings will be encoded in UTF-8, unless you stored garbage in the
+# database ...
+assert row[0] == AUSTRIA.encode("utf-8")
+
+# we can also implement a custom text_factory ...
+# here we implement one that will ignore Unicode characters that cannot be
+# decoded from UTF-8
+con.text_factory = lambda x: unicode(x, "utf-8", "ignore")
+cur.execute("select ?", ("this is latin1 and would normally create errors" + u"\xe4\xf6\xfc".encode("latin1"),))
+row = cur.fetchone()
+assert type(row[0]) == unicode
+
+# pysqlite offers a builtin optimized text_factory that will return bytestring
+# objects, if the data is in ASCII only, and otherwise return unicode objects
+con.text_factory = sqlite3.OptimizedUnicode
+cur.execute("select ?", (AUSTRIA,))
+row = cur.fetchone()
+assert type(row[0]) == unicode
+
+cur.execute("select ?", ("Germany",))
+row = cur.fetchone()
+assert type(row[0]) == str
diff --git a/doc/install-source-win32.html b/doc/install-source-win32.html
deleted file mode 100644 (file)
index c030632..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Docutils 0.4.1: http://docutils.sourceforge.net/" />
-<title>pysqlite installation guide - installing from source on Windows</title>
-<style type="text/css">
-
-@import url(docutils.css);
-@import url(silvercity.css);
-
-div.code-block{
-margin-left: 2em ;
-margin-right: 2em ;
-background-color: #eeeeee;
-font-family: "Courier New", Courier, monospace;
-font-size: 10pt;
-}
-
-</style>
-</head>
-<body>
-<div class="document" id="pysqlite-installation-guide-installing-from-source-on-windows">
-<h1 class="title">pysqlite installation guide - installing from source on Windows</h1>
-<p>(c) 2005 Gerhard Häring</p>
-<p>Steps:</p>
-<blockquote>
-<ul class="simple">
-<li><a class="reference" href="#step-1-download-and-install-required-tools">Step 1: Download and install required tools</a></li>
-<li><a class="reference" href="#step-2-download-and-compile-sqlite">Step 2: Download and compile SQLite</a></li>
-<li><a class="reference" href="#step-3-compile-pysqlite">Step 3: Compile pysqlite</a></li>
-<li><a class="reference" href="#step-4-install-pysqlite-or-create-an-installer">Step 4: Install pysqlite or create an installer</a></li>
-<li><a class="reference" href="#step-5-test-your-pysqlite-installation">Step 5: Test your pysqlite installation</a></li>
-</ul>
-</blockquote>
-<div class="section">
-<h1><a id="step-1-download-and-install-required-tools" name="step-1-download-and-install-required-tools">Step 1: Download and install required tools</a></h1>
-<p>This guide explains how to build SQLite and pysqlite with free and commercial
-Microsoft compilers for Python 2.4 and later. Other compilers might work, too,
-and MINGW is known to work well for Python 2.3, but in order to keep this
-document to the point, only one obvious way to do it is documented.</p>
-<p>First we need to have a working compiler. These two work fine:</p>
-<blockquote>
-<ul class="simple">
-<li>Microsoft Visual Studio .NET 2003</li>
-<li>MS Toolkit Compiler (<a class="reference" href="http://www.vrplumber.com/programming/mstoolkit/">http://www.vrplumber.com/programming/mstoolkit/</a>)</li>
-</ul>
-</blockquote>
-<p>Then, we need GNU make. Download a Windows version from
-<a class="reference" href="http://mingw.sourceforge.net/download.shtml">http://mingw.sourceforge.net/download.shtml</a> and extract it.</p>
-<p>Make sure your PATH is set up correctly, so that the make.exe you just
-downloaded is in the PATH and that your compiler's environment is set up
-correctly. For MS Visual Studio .NET 2003, just execute
-Start/Programs/Microsoft Visual Studio .NET/Visual Studio .NET Tools/Visual
-Studio .NET 2003 Command Prompt. For the MS Toolkit Compiler write yourself a
-batch file that sets up the environment as neccessary.</p>
-</div>
-<div class="section">
-<h1><a id="step-2-download-and-compile-sqlite" name="step-2-download-and-compile-sqlite">Step 2: Download and compile SQLite</a></h1>
-<p>From now on, let's suppose you do all your development work in $SRCDIR.</p>
-<p>Now download the latest versions of the SQLite 3.x Windows sources from <a class="reference" href="http://sqlite.org/download.html">http://sqlite.org/download.html</a>.</p>
-<p>Pick the download that looks like this:</p>
-<p>sqlite-source-3_{major}_{minor}.zip</p>
-<p>Extract this file in $SRCDIR/sqlite</p>
-<p>Now copy this file into your $SRCDIR/sqlite directory:
-<a class="reference" href="http://initd.org/svn/pysqlite/pysqlite/trunk/misc/Makefile">http://initd.org/svn/pysqlite/pysqlite/trunk/misc/Makefile</a></p>
-<p>Then on a Windows command prompt, change into the $SRCDIR/sqlite directory and
-issue a &quot;make&quot;. This should build a statically linked SQLite library now:</p>
-<pre class="literal-block">
-Setting environment for using Microsoft Visual Studio .NET 2003 tools.
-(If you have another version of Visual Studio or Visual C++ installed and wish
-to use its tools from the command line, run vcvars32.bat for that version.)
-
-C:\Documents and Settings\Gerhard&gt;set path=c:\msys\1.0\bin;%PATH%
-
-C:\Documents and Settings\Gerhard&gt;d:
-
-D:\&gt;cd src\sqlite
-
-D:\src\sqlite&gt;make
-cl -c -O2 -Og -G7 -Foalter.o alter.c
-Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
-Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
-
-alter.c
-cl -c -O2 -Og -G7 -Foanalyze.o analyze.c
-Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
-Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
-
-[...]
-
-utf.c
-cl -c -O2 -Og -G7 -Folegacy.o legacy.c
-Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
-Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
-
-legacy.c
-link -LIB -OUT:sqlite3.lib alter.o analyze.o attach.o auth.o btree.o build.o cal
-lback.o complete.o date.o delete.o expr.o func.o hash.o insert.o main.o opcodes.
-o os_unix.o os_win.o pager.o parse.o pragma.o prepare.o printf.o random.o select
-.o table.o tokenize.o trigger.o update.o util.o vacuum.o vdbe.o vdbeapi.o vdbeau
-x.o vdbefifo.o vdbemem.o where.o utf.o legacy.o
-Microsoft (R) Library Manager Version 7.10.3077
-Copyright (C) Microsoft Corporation.  All rights reserved.
-
-done
-
-D:\src\sqlite&gt;
-</pre>
-</div>
-<div class="section">
-<h1><a id="step-3-compile-pysqlite" name="step-3-compile-pysqlite">Step 3: Compile pysqlite</a></h1>
-<p>Unpack the latest pysqlite sources in $SRCDIR/pysqlite</p>
-<p>Now change the include_dirs and library_dirs settings in <tt class="docutils literal"><span class="pre">setup.cfg</span></tt> like
-this:</p>
-<pre class="literal-block">
-[build_ext]
-define=
-include_dirs=../sqlite
-library_dirs=../sqlite
-libraries=sqlite3
-</pre>
-<p>Now open a command prompt, change to the directory where you decompressed the
-pysqlite source distribution, and type:</p>
-<pre class="literal-block">
-python setup.py build
-</pre>
-<p>If setup.py raises no errors and its output concludes with something like
-&quot;Creating library...&quot;, then you are ready to proceed to the next step.</p>
-<p>If you receive an error message from the compiler, then try to look at the
-first error it reports. Other errors will most likely be aftereffects from the
-first error (like not finding the sqlite3.h header file).</p>
-</div>
-<div class="section">
-<h1><a id="step-4-install-pysqlite-or-create-an-installer" name="step-4-install-pysqlite-or-create-an-installer">Step 4: Install pysqlite or create an installer</a></h1>
-<p>To install pysqlite now, invoke:</p>
-<pre class="literal-block">
-python setup.py install
-</pre>
-<p>from the commandline. In order to create an installer executable, invoke:</p>
-<pre class="literal-block">
-python setup.py bdist_wininst
-</pre>
-<p>from the commandline.</p>
-</div>
-<div class="section">
-<h1><a id="step-5-test-your-pysqlite-installation" name="step-5-test-your-pysqlite-installation">Step 5: Test Your pysqlite Installation</a></h1>
-<p>Switch to a directory other than the temporary directory into which you
-decompressed the source distribution (to avoid conflict between the copy of
-pysqlite in that directory and the copy placed under the standard Python
-site-packages directory), then run the pysqlite test suite by starting a Python
-interpreter for the Python version you installed pysqlite for and entering the
-following:</p>
-<pre class="literal-block">
-&gt;&gt;&gt; from pysqlite2 import test
-&gt;&gt;&gt; test.test()
-......................................................................
-......................................................................
-...........
-----------------------------------------------------------------------
-Ran 151 tests in 1.059s
-
-OK
-&gt;&gt;&gt;
-</pre>
-<p>If the test suite runs without any errors, you are finished.</p>
-<p>You should not encounter any errors at this stage since you have already
-completed the compilation and installation steps successfully. If you do,
-please report them to the <a class="reference" href="http://initd.org/tracker/pysqlite">pysqlite bug tracker</a> or the <a class="reference" href="http://lists.initd.org/mailman/listinfo/pysqlite">pysqlite mailing
-list</a>.</p>
-</div>
-</div>
-</body>
-</html>
diff --git a/doc/install-source.html b/doc/install-source.html
deleted file mode 100644 (file)
index 60222da..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Docutils 0.4.1: http://docutils.sourceforge.net/" />
-<title>pysqlite installation guide - source distribution</title>
-<style type="text/css">
-
-@import url(docutils.css);
-@import url(silvercity.css);
-
-div.code-block{
-margin-left: 2em ;
-margin-right: 2em ;
-background-color: #eeeeee;
-font-family: "Courier New", Courier, monospace;
-font-size: 10pt;
-}
-
-</style>
-</head>
-<body>
-<div class="document" id="pysqlite-installation-guide-source-distribution">
-<h1 class="title">pysqlite installation guide - source distribution</h1>
-<p>(c) 2005 Gerhard Häring</p>
-<dl class="docutils">
-<dt>Note: For Windows users, it is recommended that you use the win32 binary</dt>
-<dd>distribution of pysqlite!</dd>
-</dl>
-<p>Steps:</p>
-<blockquote>
-<ul class="simple">
-<li><a class="reference" href="#step-1-satisfy-the-dependencies">Step 1: Satisfy the dependencies</a></li>
-<li><a class="reference" href="#step-2-compile-pysqlite">Step 2: Compile pysqlite</a></li>
-<li><a class="reference" href="#step-3-install-pysqlite">Step 3: Install pysqlite</a></li>
-<li><a class="reference" href="#step-4-test-your-pysqlite-installation">Step 4: Test your pysqlite installation</a></li>
-</ul>
-</blockquote>
-<div class="section">
-<h1><a id="step-1-satisfy-the-dependencies" name="step-1-satisfy-the-dependencies">Step 1: Satisfy The Dependencies</a></h1>
-<p>pysqlite requires a valid combination of the dependencies in the list below.</p>
-<p>Detailed instructions on how to install each dependency are beyond the scope of
-this document; consult the dependency distributor for installation
-instructions.</p>
-<p>Dependencies:</p>
-<blockquote>
-<ol class="arabic simple">
-<li>Operating System and C Compiler - one of:<ul>
-<li>Linux/FreeBSD/NetBSD/OpenBSD and GCC</li>
-<li>Other POSIX-compliant operating system and a C compiler</li>
-</ul>
-</li>
-<li>SQLite:<ul>
-<li>SQLite version 3.0.8 or later (as of pysqlite 2.2.0). This means we need
-the SQLite library installed - either statically or dynamically linked -
-and the SQLite header files. On Linux, the chances are very high that
-your distribution offers packages for SQLite 3. Be sure to verify the
-package is recent enough (version 3.0.8 or higher) and that you're
-installing the development package as well, which will be need for
-building pysqlite. On Debian and derivatives, the package to look for is
-called libsqlite3-dev.</li>
-</ul>
-</li>
-<li>Python:<ul>
-<li>Python 2.3 or later</li>
-</ul>
-</li>
-</ol>
-</blockquote>
-</div>
-<div class="section">
-<h1><a id="step-2-compile-pysqlite" name="step-2-compile-pysqlite">Step 2: Compile pysqlite</a></h1>
-<p>Once you have successfully installed the dependencies, you may proceed with the
-installation of pysqlite itself.</p>
-<p>pysqlite has full support for the <a class="reference" href="http://www.python.org/sigs/distutils-sig/">distutils</a>, the standard facility for Python
-package distribution and installation. Full instructions for using the
-distutils are available in <a class="reference" href="http://www.python.org/doc/current/inst/inst.html">this section of the Python documentation</a>, but you
-can skip them unless you have an otherwise insoluble problem.</p>
-<p>Open a command prompt, change to the directory where you decompressed the
-pysqlite source distribution, and type:</p>
-<pre class="literal-block">
-python setup.py build
-</pre>
-<p>The installation script, setup.py, will attempt to automatically detect the
-information needed by the C compiler; then it will invoke the distutils to
-perform the actual compilation. If you installed automatic distributions of the
-dependencies that place themselves in standard locations (on UNIX-style
-operating systems), the compilation should proceed without incident.</p>
-<p>Otherwise you will have to customize the build process. That's what the file
-<em>setup.cfg</em> is meant for. It's contains a few lines that you can customize so
-your C compiler will find the library and header files and you can also do a
-few other tweaks, like build pysqlite in debug mode.</p>
-<p>After you've customized <em>setup.cfg</em> apprporiately, try invoking <tt class="docutils literal"><span class="pre">python</span>
-<span class="pre">setup.py</span> <span class="pre">build</span></tt> again.</p>
-<p>If setup.py raises no errors and its output concludes with something like
-&quot;Creating library...&quot;, then you are ready to proceed to the next step.</p>
-<p>If you receive an error message from the compiler, then try to look at the
-first error it reports. Other errors will most likely be aftereffects from the
-first error (like not finding the sqlite3.h header file).</p>
-</div>
-<div class="section">
-<h1><a id="step-3-install-pysqlite" name="step-3-install-pysqlite">Step 3: Install pysqlite</a></h1>
-<p>During this step, the setup script moves the <em>pysqlite2</em> package (including the
-newly compiled C extension) to the standard package directory of your Python
-installation so that Python will be able to import pysqlite2.dbapi2 and
-pysqlite2.test.</p>
-<p>In addition to the Python code and shared library files actually used by the
-Python interpreter, the setup script typically installs some supporting files,
-such as documentation. Depending on your system configuration, these supporting
-files may be placed in the same directory or a different directory from the
-files used by the Python interpreter.</p>
-<p>Run the following command:</p>
-<pre class="literal-block">
-python setup.py install
-</pre>
-<p>The setup script will install pysqlite, listing each file it installs.</p>
-<p>Errors during this step are rare because compilation (the finicky part of this
-process) has already taken place; installation is really just a matter of
-copying files. However, there will be file system permission errors if the
-Python installation directory is not writable by the user running the setup
-script. If you encounter such an error, try one of the following:</p>
-<ul class="simple">
-<li>Log in as a user who has the required file system permissions and repeat the
-installation step.</li>
-<li>Manually copy the directory build/lib.platform-pyver/pysqlite2 (which
-contains the Python modules and compiled library files created during the
-compilation step) to a directory in your PYTHONPATH. This approach will not
-install the supporting files, but they are for the benefit of the programmer
-rather than the Python interpreter anyway.</li>
-</ul>
-</div>
-<div class="section">
-<h1><a id="step-4-test-your-pysqlite-installation" name="step-4-test-your-pysqlite-installation">Step 4: Test Your pysqlite Installation</a></h1>
-<p>Switch to a directory other than the temporary directory into which you
-decompressed the source distribution (to avoid conflict between the copy of
-pysqlite in that directory and the copy placed under the standard Python
-site-packages directory), then run the pysqlite test suite by starting a Python
-interpreter for the Python version you installed pysqlite for and entering the
-following:</p>
-<pre class="literal-block">
-&gt;&gt;&gt; from pysqlite2 import test
-&gt;&gt;&gt; test.test()
-.....................................................................................................
-----------------------------------------------------------------------
-Ran 101 tests in 0.182s
-</pre>
-<p>If the test suite runs without any errors, you are finished.</p>
-<p>You should not encounter any errors at this stage since you have already
-completed the compilation and installation steps successfully. If you do,
-please report them to the <a class="reference" href="http://initd.org/tracker/pysqlite">pysqlite bug tracker</a> or the <a class="reference" href="http://lists.initd.org/mailman/listinfo/pysqlite">pysqlite mailing
-list</a>.</p>
-</div>
-</div>
-</body>
-</html>
diff --git a/doc/silvercity.css b/doc/silvercity.css
deleted file mode 100644 (file)
index aa54711..0000000
+++ /dev/null
@@ -1,542 +0,0 @@
-\r
-.code_default\r
-{\r
-    FONT-FAMILY: "Courier New", Courier, monospace;\r
-    FONT-SIZE: 10pt;\r
-}\r
-\r
-.css_class\r
-{\r
-    color: #900000;\r
-}\r
-\r
-.css_comment\r
-{\r
-       color: green;\r
-       font-style: italic;\r
-}\r
-\r
-.css_default\r
-{\r
-}\r
-\r
-.css_directive\r
-{\r
-    color: #009000;\r
-       font-weight: bold;\r
-}\r
-\r
-.css_doublestring\r
-{\r
-       color: navy;\r
-}\r
-\r
-.css_id\r
-{\r
-    color: #900000;\r
-}\r
-\r
-.css_identifier\r
-{\r
-       color: black;\r
-}\r
-\r
-.css_important\r
-{\r
-       color: blue;\r
-}\r
-\r
-.css_operator\r
-{\r
-    color: #000090;\r
-       font-weight: bold;\r
-}\r
-\r
-.css_pseudoclass\r
-{\r
-    color: #900000;\r
-}\r
-\r
-.css_singlestring\r
-{\r
-       color: navy;\r
-}\r
-\r
-.css_tag\r
-{\r
-    color: #900000;\r
-       font-weight: bold;\r
-}\r
-\r
-.css_unknown_identifier\r
-{\r
-       color: red;\r
-}\r
-\r
-.css_unknown_pseudoclass\r
-{\r
-    color: #ff0000;\r
-}\r
-\r
-.css_value\r
-{\r
-       color: navy;\r
-}\r
-\r
-.c_character\r
-{\r
-       color: olive;\r
-}\r
-\r
-.c_comment\r
-{\r
-       color: green;\r
-       font-style: italic;\r
-}\r
-\r
-.c_commentdoc\r
-{\r
-       color: green;\r
-       font-style: italic;\r
-}\r
-\r
-.c_commentdockeyword\r
-{\r
-       color: navy;\r
-       font-weight: bold;\r
-}\r
-\r
-.c_commentdockeyworderror\r
-{\r
-       color: red;\r
-       font-weight: bold;\r
-}\r
-\r
-.c_commentline\r
-{\r
-       color: green;\r
-       font-style: italic;\r
-}\r
-\r
-.c_commentlinedoc\r
-{\r
-       color: green;\r
-       font-style: italic;\r
-}\r
-\r
-.c_default\r
-{\r
-}\r
-\r
-.c_identifier\r
-{\r
-       color: black;\r
-}\r
-\r
-.c_number\r
-{\r
-    color: #009999;\r
-}\r
-\r
-.c_operator\r
-{\r
-       color: black;\r
-}\r
-\r
-.c_preprocessor\r
-{\r
-       color: navy;\r
-       font-weight: bold;\r
-}\r
-\r
-.c_regex\r
-{\r
-       color: olive;\r
-}\r
-\r
-.c_string\r
-{\r
-       color: olive;\r
-}\r
-\r
-.c_stringeol\r
-{\r
-       color: olive;\r
-}\r
-\r
-.c_uuid\r
-{\r
-       color: olive;\r
-}\r
-\r
-.c_verbatim\r
-{\r
-       color: olive;\r
-}\r
-\r
-.c_word\r
-{\r
-       color: navy;\r
-       font-weight: bold;\r
-}\r
-\r
-.c_word2\r
-{\r
-       color: navy;\r
-       font-weight: bold;\r
-}\r
-\r
-.h_asp\r
-{\r
-    color: #ffff00;\r
-}\r
-\r
-.h_aspat\r
-{\r
-    color: #ffdf00;\r
-}\r
-\r
-.h_attribute\r
-{\r
-    color: #008080;\r
-}\r
-\r
-.h_attributeunknown\r
-{\r
-    color: #ff0000;\r
-}\r
-\r
-.h_cdata\r
-{\r
-    color: #ffdf00;\r
-}\r
-\r
-.h_comment\r
-{\r
-    color: #808000;\r
-}\r
-\r
-.h_default\r
-{\r
-}\r
-\r
-.h_doublestring\r
-{\r
-       color: olive;\r
-}\r
-\r
-.h_entity\r
-{\r
-    color: #800080;\r
-}\r
-\r
-.h_number\r
-{\r
-    color: #009999;\r
-}\r
-\r
-.h_other\r
-{\r
-    color: #800080;\r
-}\r
-\r
-.h_script\r
-{\r
-    color: #000080;\r
-}\r
-\r
-.h_singlestring\r
-{\r
-       color: olive;\r
-}\r
-\r
-.h_tag\r
-{\r
-    color: #000080;\r
-}\r
-\r
-.h_tagend\r
-{\r
-    color: #000080;\r
-}\r
-\r
-.h_tagunknown\r
-{\r
-    color: #ff0000;\r
-}\r
-\r
-.h_xmlend\r
-{\r
-    color: #0000ff;\r
-}\r
-\r
-.h_xmlstart\r
-{\r
-    color: #0000ff;\r
-}\r
-\r
-.pl_array\r
-{\r
-       color: black;\r
-}\r
-\r
-.pl_backticks\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_character\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_commentline\r
-{\r
-       color: green;\r
-       font-style: italic;\r
-}\r
-\r
-.pl_datasection\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_default\r
-{\r
-}\r
-\r
-.pl_error\r
-{\r
-       color: red;\r
-       font-style: bold;\r
-}\r
-\r
-.pl_hash\r
-{\r
-       color: black;\r
-}\r
-\r
-.pl_here_delim\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_here_q\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_here_qq\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_here_qx\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_identifier\r
-{\r
-       color: black;\r
-}\r
-\r
-.pl_longquote\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_number\r
-{\r
-    color: #009999;\r
-}\r
-\r
-.pl_operator\r
-{\r
-       color: black;\r
-}\r
-\r
-.pl_pod\r
-{\r
-       color: black;\r
-       font-style: italic;\r
-}\r
-\r
-.pl_preprocessor\r
-{\r
-       color: navy;\r
-       font-weight: bold;\r
-}\r
-\r
-.pl_punctuation\r
-{\r
-       color: black;\r
-}\r
-\r
-.pl_regex\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_regsubst\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_scalar\r
-{\r
-       color: black;\r
-}\r
-\r
-.pl_string\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_string_q\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_string_qq\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_string_qr\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_string_qw\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_string_qx\r
-{\r
-       color: olive;\r
-}\r
-\r
-.pl_symboltable\r
-{\r
-       color: black;\r
-}\r
-\r
-.pl_word\r
-{\r
-       color: navy;\r
-       font-weight: bold;\r
-}\r
-\r
-.p_character\r
-{\r
-       color: olive;\r
-}\r
-\r
-.p_classname\r
-{\r
-       color: blue;\r
-       font-weight: bold;\r
-}\r
-\r
-.p_commentblock\r
-{\r
-       color: gray;\r
-       font-style: italic;\r
-}\r
-\r
-.p_commentline\r
-{\r
-       color: green;\r
-       font-style: italic;\r
-}\r
-\r
-.p_default\r
-{\r
-}\r
-\r
-.p_defname\r
-{\r
-    color: #009999;\r
-       font-weight: bold;\r
-}\r
-\r
-.p_identifier\r
-{\r
-       color: black;\r
-}\r
-\r
-.p_number\r
-{\r
-    color: #009999;\r
-}\r
-\r
-.p_operator\r
-{\r
-       color: black;\r
-}\r
-\r
-.p_string\r
-{\r
-       color: olive;\r
-}\r
-\r
-.p_stringeol\r
-{\r
-       color: olive;\r
-}\r
-\r
-.p_triple\r
-{\r
-       color: olive;\r
-}\r
-\r
-.p_tripledouble\r
-{\r
-       color: olive;\r
-}\r
-\r
-.p_word\r
-{\r
-       color: navy;\r
-       font-weight: bold;\r
-}\r
-\r
-.yaml_comment\r
-{\r
-    color: #008800;\r
-       font-style: italic;\r
-}\r
-\r
-.yaml_default\r
-{\r
-}\r
-\r
-.yaml_document\r
-{\r
-    color: #808080;\r
-       font-style: italic;\r
-}\r
-\r
-.yaml_identifier\r
-{\r
-       color: navy;\r
-       font-weight: bold;\r
-}\r
-\r
-.yaml_keyword\r
-{\r
-    color: #880088;\r
-}\r
-\r
-.yaml_number\r
-{\r
-    color: #880000;\r
-}\r
-\r
-.yaml_reference\r
-{\r
-    color: #008888;\r
-}\r
-\r
diff --git a/doc/sphinx/.static/.keepme b/doc/sphinx/.static/.keepme
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/doc/sphinx/Makefile b/doc/sphinx/Makefile
new file mode 100644 (file)
index 0000000..33e3361
--- /dev/null
@@ -0,0 +1,66 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS   =
+SPHINXBUILD  = sphinx-build.py
+PAPER        =
+
+ALLSPHINXOPTS = -d .build/doctrees -D latex_paper_size=$(PAPER) \
+                $(SPHINXOPTS) .
+
+.PHONY: help clean html web htmlhelp latex changes linkcheck
+
+help:
+       @echo "Please use \`make <target>' where <target> is one of"
+       @echo "  html      to make standalone HTML files"
+       @echo "  web       to make files usable by Sphinx.web"
+       @echo "  htmlhelp  to make HTML files and a HTML help project"
+       @echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+       @echo "  changes   to make an overview over all changed/added/deprecated items"
+       @echo "  linkcheck to check all external links for integrity"
+
+clean:
+       -rm -rf .build/*
+
+html:
+       mkdir -p .build/html .build/doctrees
+       $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) .build/html
+       @echo
+       @echo "Build finished. The HTML pages are in .build/html."
+
+web:
+       mkdir -p .build/web .build/doctrees
+       $(SPHINXBUILD) -b web $(ALLSPHINXOPTS) .build/web
+       @echo
+       @echo "Build finished; now you can run"
+       @echo "  python -m sphinx.web .build/web"
+       @echo "to start the server."
+
+htmlhelp:
+       mkdir -p .build/htmlhelp .build/doctrees
+       $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) .build/htmlhelp
+       @echo
+       @echo "Build finished; now you can run HTML Help Workshop with the" \
+             ".hhp project file in .build/htmlhelp."
+
+latex:
+       mkdir -p .build/latex .build/doctrees
+       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) .build/latex
+       @echo
+       @echo "Build finished; the LaTeX files are in .build/latex."
+       @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+             "run these through (pdf)latex."
+
+changes:
+       mkdir -p .build/changes .build/doctrees
+       $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) .build/changes
+       @echo
+       @echo "The overview file is in .build/changes."
+
+linkcheck:
+       mkdir -p .build/linkcheck .build/doctrees
+       $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) .build/linkcheck
+       @echo
+       @echo "Link check complete; look for any errors in the above output " \
+             "or in .build/linkcheck/output.txt."
diff --git a/doc/sphinx/conf.py b/doc/sphinx/conf.py
new file mode 100644 (file)
index 0000000..216f56e
--- /dev/null
@@ -0,0 +1,132 @@
+# -*- coding: utf-8 -*-
+#
+# pysqlite documentation build configuration file, created by
+# sphinx-quickstart.py on Sat Mar 22 02:47:54 2008.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# The contents of this file are pickled, so don't put values in the namespace
+# that aren't pickleable (module imports are okay, they're removed automatically).
+#
+# All configuration values have a default value; values that are commented out
+# serve to show the default value.
+
+import sys
+
+# If your extensions are in another directory, add it here.
+#sys.path.append('some/directory')
+
+# General configuration
+# ---------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.addons.*') or your custom ones.
+#extensions = []
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['.templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General substitutions.
+project = 'pysqlite'
+copyright = '2008, Gerhard Häring'
+
+# The default replacements for |version| and |release|, also used in various
+# other places throughout the built documents.
+#
+# The short X.Y version.
+version = '2.5.0'
+# The full version, including alpha/beta/rc tags.
+release = '2.5.0'
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+
+# Options for HTML output
+# -----------------------
+
+# The style sheet to use for HTML and HTML Help pages. A file of that name
+# must exist either in Sphinx' static/ path, or in one of the custom paths
+# given in html_static_path.
+html_style = 'default.css'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['.static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Content template for the index page.
+#html_index = ''
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+#html_copy_source = True
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'pysqlitedoc'
+
+
+# Options for LaTeX output
+# ------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, document class [howto/manual]).
+#latex_documents = []
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True
diff --git a/doc/sphinx/index.rst b/doc/sphinx/index.rst
new file mode 100644 (file)
index 0000000..522f986
--- /dev/null
@@ -0,0 +1,19 @@
+.. pysqlite documentation master file, created by sphinx-quickstart.py on Sat Mar 22 02:47:54 2008.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to pysqlite's documentation!
+====================================
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/doc/sphinx/sqlite3.rst b/doc/sphinx/sqlite3.rst
new file mode 100644 (file)
index 0000000..ca0b13a
--- /dev/null
@@ -0,0 +1,799 @@
+:mod:`sqlite3` --- DB-API 2.0 interface for SQLite databases
+============================================================
+
+.. module:: sqlite3
+   :synopsis: A DB-API 2.0 implementation using SQLite 3.x.
+.. sectionauthor:: Gerhard Häring <gh@ghaering.de>
+
+
+SQLite is a C library that provides a lightweight disk-based database that
+doesn't require a separate server process and allows accessing the database
+using a nonstandard variant of the SQL query language. Some applications can use
+SQLite for internal data storage.  It's also possible to prototype an
+application using SQLite and then port the code to a larger database such as
+PostgreSQL or Oracle.
+
+pysqlite was written by Gerhard Häring and provides a SQL interface compliant
+with the DB-API 2.0 specification described by :pep:`249`.
+
+To use the module, you must first create a :class:`Connection` object that
+represents the database.  Here the data will be stored in the
+:file:`/tmp/example` file::
+
+   conn = sqlite3.connect('/tmp/example')
+
+You can also supply the special name ``:memory:`` to create a database in RAM.
+
+Once you have a :class:`Connection`, you can create a :class:`Cursor`  object
+and call its :meth:`execute` method to perform SQL commands::
+
+   c = conn.cursor()
+
+   # Create table
+   c.execute('''create table stocks
+   (date text, trans text, symbol text,
+    qty real, price real)''')
+
+   # Insert a row of data
+   c.execute("""insert into stocks
+             values ('2006-01-05','BUY','RHAT',100,35.14)""")
+
+   # Save (commit) the changes
+   conn.commit()
+
+   # We can also close the cursor if we are done with it
+   c.close()
+
+Usually your SQL operations will need to use values from Python variables.  You
+shouldn't assemble your query using Python's string operations because doing so
+is insecure; it makes your program vulnerable to an SQL injection attack.
+
+Instead, use the DB-API's parameter substitution.  Put ``?`` as a placeholder
+wherever you want to use a value, and then provide a tuple of values as the
+second argument to the cursor's :meth:`execute` method.  (Other database modules
+may use a different placeholder, such as ``%s`` or ``:1``.) For example::
+
+   # Never do this -- insecure!
+   symbol = 'IBM'
+   c.execute("... where symbol = '%s'" % symbol)
+
+   # Do this instead
+   t = (symbol,)
+   c.execute('select * from stocks where symbol=?', t)
+
+   # Larger example
+   for t in (('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
+             ('2006-04-05', 'BUY', 'MSOFT', 1000, 72.00),
+             ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
+            ):
+       c.execute('insert into stocks values (?,?,?,?,?)', t)
+
+To retrieve data after executing a SELECT statement, you can either treat the
+cursor as an :term:`iterator`, call the cursor's :meth:`fetchone` method to
+retrieve a single matching row, or call :meth:`fetchall` to get a list of the
+matching rows.
+
+This example uses the iterator form::
+
+   >>> c = conn.cursor()
+   >>> c.execute('select * from stocks order by price')
+   >>> for row in c:
+   ...    print row
+   ...
+   (u'2006-01-05', u'BUY', u'RHAT', 100, 35.140000000000001)
+   (u'2006-03-28', u'BUY', u'IBM', 1000, 45.0)
+   (u'2006-04-06', u'SELL', u'IBM', 500, 53.0)
+   (u'2006-04-05', u'BUY', u'MSOFT', 1000, 72.0)
+   >>>
+
+
+.. seealso::
+
+   http://www.pysqlite.org
+      The pysqlite web page.
+
+   http://www.sqlite.org
+      The SQLite web page; the documentation describes the syntax and the available
+      data types for the supported SQL dialect.
+
+   :pep:`249` - Database API Specification 2.0
+      PEP written by Marc-André Lemburg.
+
+
+.. _sqlite3-module-contents:
+
+Module functions and constants
+------------------------------
+
+
+.. data:: PARSE_DECLTYPES
+
+   This constant is meant to be used with the *detect_types* parameter of the
+   :func:`connect` function.
+
+   Setting it makes the :mod:`sqlite3` module parse the declared type for each
+   column it returns.  It will parse out the first word of the declared type,
+   i. e.  for "integer primary key", it will parse out "integer", or for
+   "number(10)" it will parse out "number". Then for that column, it will look
+   into the converters dictionary and use the converter function registered for
+   that type there.
+
+
+.. data:: PARSE_COLNAMES
+
+   This constant is meant to be used with the *detect_types* parameter of the
+   :func:`connect` function.
+
+   Setting this makes the SQLite interface parse the column name for each column it
+   returns.  It will look for a string formed [mytype] in there, and then decide
+   that 'mytype' is the type of the column. It will try to find an entry of
+   'mytype' in the converters dictionary and then use the converter function found
+   there to return the value. The column name found in :attr:`cursor.description`
+   is only the first word of the column name, i.  e. if you use something like
+   ``'as "x [datetime]"'`` in your SQL, then we will parse out everything until the
+   first blank for the column name: the column name would simply be "x".
+
+
+.. function:: connect(database[, timeout, isolation_level, detect_types, factory])
+
+   Opens a connection to the SQLite database file *database*. You can use
+   ``":memory:"`` to open a database connection to a database that resides in RAM
+   instead of on disk.
+
+   When a database is accessed by multiple connections, and one of the processes
+   modifies the database, the SQLite database is locked until that transaction is
+   committed. The *timeout* parameter specifies how long the connection should wait
+   for the lock to go away until raising an exception. The default for the timeout
+   parameter is 5.0 (five seconds).
+
+   For the *isolation_level* parameter, please see the
+   :attr:`Connection.isolation_level` property of :class:`Connection` objects.
+
+   SQLite natively supports only the types TEXT, INTEGER, FLOAT, BLOB and NULL. If
+   you want to use other types you must add support for them yourself. The
+   *detect_types* parameter and the using custom **converters** registered with the
+   module-level :func:`register_converter` function allow you to easily do that.
+
+   *detect_types* defaults to 0 (i. e. off, no type detection), you can set it to
+   any combination of :const:`PARSE_DECLTYPES` and :const:`PARSE_COLNAMES` to turn
+   type detection on.
+
+   By default, the :mod:`sqlite3` module uses its :class:`Connection` class for the
+   connect call.  You can, however, subclass the :class:`Connection` class and make
+   :func:`connect` use your class instead by providing your class for the *factory*
+   parameter.
+
+   Consult the section :ref:`sqlite3-types` of this manual for details.
+
+   The :mod:`sqlite3` module internally uses a statement cache to avoid SQL parsing
+   overhead. If you want to explicitly set the number of statements that are cached
+   for the connection, you can set the *cached_statements* parameter. The currently
+   implemented default is to cache 100 statements.
+
+
+.. function:: register_converter(typename, callable)
+
+   Registers a callable to convert a bytestring from the database into a custom
+   Python type. The callable will be invoked for all database values that are of
+   the type *typename*. Confer the parameter *detect_types* of the :func:`connect`
+   function for how the type detection works. Note that the case of *typename* and
+   the name of the type in your query must match!
+
+
+.. function:: register_adapter(type, callable)
+
+   Registers a callable to convert the custom Python type *type* into one of
+   SQLite's supported types. The callable *callable* accepts as single parameter
+   the Python value, and must return a value of the following types: int, long,
+   float, str (UTF-8 encoded), unicode or buffer.
+
+
+.. function:: complete_statement(sql)
+
+   Returns :const:`True` if the string *sql* contains one or more complete SQL
+   statements terminated by semicolons. It does not verify that the SQL is
+   syntactically correct, only that there are no unclosed string literals and the
+   statement is terminated by a semicolon.
+
+   This can be used to build a shell for SQLite, as in the following example:
+
+
+   .. literalinclude:: ../includes/sqlite3/complete_statement.py
+
+
+.. function:: enable_callback_tracebacks(flag)
+
+   By default you will not get any tracebacks in user-defined functions,
+   aggregates, converters, authorizer callbacks etc. If you want to debug them, you
+   can call this function with *flag* as True. Afterwards, you will get tracebacks
+   from callbacks on ``sys.stderr``. Use :const:`False` to disable the feature
+   again.
+
+
+.. _sqlite3-connection-objects:
+
+Connection Objects
+------------------
+
+A :class:`Connection` instance has the following attributes and methods:
+
+.. attribute:: Connection.isolation_level
+
+   Get or set the current isolation level. None for autocommit mode or one of
+   "DEFERRED", "IMMEDIATE" or "EXLUSIVE". See section
+   :ref:`sqlite3-controlling-transactions` for a more detailed explanation.
+
+
+.. method:: Connection.cursor([cursorClass])
+
+   The cursor method accepts a single optional parameter *cursorClass*. If
+   supplied, this must be a custom cursor class that extends
+   :class:`sqlite3.Cursor`.
+
+
+.. method:: Connection.commit()
+
+   This method commits the current transaction. If you don't call this method,
+   anything you did since the last call to commit() is not visible from from
+   other database connections. If you wonder why you don't see the data you've
+   written to the database, please check you didn't forget to call this method.
+
+.. method:: Connection.rollback()
+
+   This method rolls back any changes to the database since the last call to 
+   :meth:`commit`.
+
+.. method:: Connection.close()
+
+   This closes the database connection. Note that this does not automatically
+   call :meth:`commit`. If you just close your database connection without
+   calling :meth:`commit` first, your changes will be lost!
+
+.. method:: Connection.execute(sql, [parameters])
+
+   This is a nonstandard shortcut that creates an intermediate cursor object by
+   calling the cursor method, then calls the cursor's :meth:`execute` method with
+   the parameters given.
+
+
+.. method:: Connection.executemany(sql, [parameters])
+
+   This is a nonstandard shortcut that creates an intermediate cursor object by
+   calling the cursor method, then calls the cursor's :meth:`executemany` method
+   with the parameters given.
+
+
+.. method:: Connection.executescript(sql_script)
+
+   This is a nonstandard shortcut that creates an intermediate cursor object by
+   calling the cursor method, then calls the cursor's :meth:`executescript` method
+   with the parameters given.
+
+
+.. method:: Connection.create_function(name, num_params, func)
+
+   Creates a user-defined function that you can later use from within SQL
+   statements under the function name *name*. *num_params* is the number of
+   parameters the function accepts, and *func* is a Python callable that is called
+   as the SQL function.
+
+   The function can return any of the types supported by SQLite: unicode, str, int,
+   long, float, buffer and None.
+
+   Example:
+
+   .. literalinclude:: ../includes/sqlite3/md5func.py
+
+
+.. method:: Connection.create_aggregate(name, num_params, aggregate_class)
+
+   Creates a user-defined aggregate function.
+
+   The aggregate class must implement a ``step`` method, which accepts the number
+   of parameters *num_params*, and a ``finalize`` method which will return the
+   final result of the aggregate.
+
+   The ``finalize`` method can return any of the types supported by SQLite:
+   unicode, str, int, long, float, buffer and None.
+
+   Example:
+
+   .. literalinclude:: ../includes/sqlite3/mysumaggr.py
+
+
+.. method:: Connection.create_collation(name, callable)
+
+   Creates a collation with the specified *name* and *callable*. The callable will
+   be passed two string arguments. It should return -1 if the first is ordered
+   lower than the second, 0 if they are ordered equal and 1 if the first is ordered
+   higher than the second.  Note that this controls sorting (ORDER BY in SQL) so
+   your comparisons don't affect other SQL operations.
+
+   Note that the callable will get its parameters as Python bytestrings, which will
+   normally be encoded in UTF-8.
+
+   The following example shows a custom collation that sorts "the wrong way":
+
+   .. literalinclude:: ../includes/sqlite3/collation_reverse.py
+
+   To remove a collation, call ``create_collation`` with None as callable::
+
+      con.create_collation("reverse", None)
+
+
+.. method:: Connection.interrupt()
+
+   You can call this method from a different thread to abort any queries that might
+   be executing on the connection. The query will then abort and the caller will
+   get an exception.
+
+
+.. method:: Connection.set_authorizer(authorizer_callback)
+
+   This routine registers a callback. The callback is invoked for each attempt to
+   access a column of a table in the database. The callback should return
+   :const:`SQLITE_OK` if access is allowed, :const:`SQLITE_DENY` if the entire SQL
+   statement should be aborted with an error and :const:`SQLITE_IGNORE` if the
+   column should be treated as a NULL value. These constants are available in the
+   :mod:`sqlite3` module.
+
+   The first argument to the callback signifies what kind of operation is to be
+   authorized. The second and third argument will be arguments or :const:`None`
+   depending on the first argument. The 4th argument is the name of the database
+   ("main", "temp", etc.) if applicable. The 5th argument is the name of the
+   inner-most trigger or view that is responsible for the access attempt or
+   :const:`None` if this access attempt is directly from input SQL code.
+
+   Please consult the SQLite documentation about the possible values for the first
+   argument and the meaning of the second and third argument depending on the first
+   one. All necessary constants are available in the :mod:`sqlite3` module.
+
+
+.. method:: Connection.set_progress_handler(handler, n)
+
+   This routine registers a callback. The callback is invoked for every *n*
+   instructions of the SQLite virtual machine. This is useful if you want to
+   get called from SQLite during long-running operations, for example to update
+   a GUI.
+
+   If you want to clear any previously installed progress handler, call the
+   method with :const:`None` for *handler*.
+
+
+.. method:: Connection.enable_load_extension(enabled)
+
+   This routine allows/disallows the SQLite engine to load SQLite extensions
+   from shared libraries.  SQLite extensions can define new functions,
+   aggregates or whole new virtual table implementations. One well-known
+   extension is the fulltext-search extension distributed with SQLite.
+
+   .. literalinclude:: ../includes/sqlite3/load_extension.py
+
+
+.. attribute:: Connection.row_factory
+
+   You can change this attribute to a callable that accepts the cursor and the
+   original row as a tuple and will return the real result row.  This way, you can
+   implement more advanced ways of returning results, such  as returning an object
+   that can also access columns by name.
+
+   Example:
+
+   .. literalinclude:: ../includes/sqlite3/row_factory.py
+
+   If returning a tuple doesn't suffice and you want name-based access to
+   columns, you should consider setting :attr:`row_factory` to the
+   highly-optimized :class:`sqlite3.Row` type. :class:`Row` provides both
+   index-based and case-insensitive name-based access to columns with almost no
+   memory overhead. It will probably be better than your own custom
+   dictionary-based approach or even a db_row based solution.
+
+   .. XXX what's a db_row-based solution?
+
+
+.. attribute:: Connection.text_factory
+
+   Using this attribute you can control what objects are returned for the TEXT data
+   type. By default, this attribute is set to :class:`unicode` and the
+   :mod:`sqlite3` module will return Unicode objects for TEXT. If you want to
+   return bytestrings instead, you can set it to :class:`str`.
+
+   For efficiency reasons, there's also a way to return Unicode objects only for
+   non-ASCII data, and bytestrings otherwise. To activate it, set this attribute to
+   :const:`sqlite3.OptimizedUnicode`.
+
+   You can also set it to any other callable that accepts a single bytestring
+   parameter and returns the resulting object.
+
+   See the following example code for illustration:
+
+   .. literalinclude:: ../includes/sqlite3/text_factory.py
+
+
+.. attribute:: Connection.total_changes
+
+   Returns the total number of database rows that have been modified, inserted, or
+   deleted since the database connection was opened.
+.. attribute:: Connection.iterdump
+
+   Returns an iterator to dump the database in an SQL text format.  Useful when
+   saving an in-memory database for later restoration.  This function provides
+   the same capabilities as the :kbd:`.dump` command in the :program:`sqlite3`
+   shell.
+
+   Example::
+
+      # Convert file existing_db.db to SQL dump file dump.sql
+      import sqlite3, os
+
+      con = sqlite3.connect('existing_db.db')
+      full_dump = os.linesep.join([line for line in con.iterdump()])
+      f = open('dump.sql', 'w')
+      f.writelines(full_dump)
+      f.close()
+
+
+.. _sqlite3-cursor-objects:
+
+Cursor Objects
+--------------
+
+A :class:`Cursor` instance has the following attributes and methods:
+
+
+.. method:: Cursor.execute(sql, [parameters])
+
+   Executes an SQL statement. The SQL statement may be parametrized (i. e.
+   placeholders instead of SQL literals). The :mod:`sqlite3` module supports two
+   kinds of placeholders: question marks (qmark style) and named placeholders
+   (named style).
+
+   This example shows how to use parameters with qmark style:
+
+   .. literalinclude:: ../includes/sqlite3/execute_1.py
+
+   This example shows how to use the named style:
+
+   .. literalinclude:: ../includes/sqlite3/execute_2.py
+
+   :meth:`execute` will only execute a single SQL statement. If you try to execute
+   more than one statement with it, it will raise a Warning. Use
+   :meth:`executescript` if you want to execute multiple SQL statements with one
+   call.
+
+
+.. method:: Cursor.executemany(sql, seq_of_parameters)
+
+   Executes an SQL command against all parameter sequences or mappings found in
+   the sequence *sql*.  The :mod:`sqlite3` module also allows using an
+   :term:`iterator` yielding parameters instead of a sequence.
+
+   .. literalinclude:: ../includes/sqlite3/executemany_1.py
+
+   Here's a shorter example using a :term:`generator`:
+
+   .. literalinclude:: ../includes/sqlite3/executemany_2.py
+
+
+.. method:: Cursor.executescript(sql_script)
+
+   This is a nonstandard convenience method for executing multiple SQL statements
+   at once. It issues a COMMIT statement first, then executes the SQL script it
+   gets as a parameter.
+
+   *sql_script* can be a bytestring or a Unicode string.
+
+   Example:
+
+   .. literalinclude:: ../includes/sqlite3/executescript.py
+
+
+.. method:: Cursor.fetchone()
+
+   Fetches the next row of a query result set, returning a single sequence,
+   or ``None`` when no more data is available.
+
+
+.. method:: Cursor.fetchmany([size=cursor.arraysize])
+
+   Fetches the next set of rows of a query result, returning a list.  An empty
+   list is returned when no more rows are available.
+
+   The number of rows to fetch per call is specified by the *size* parameter.
+   If it is not given, the cursor's arraysize determines the number of rows
+   to be fetched. The method should try to fetch as many rows as indicated by
+   the size parameter. If this is not possible due to the specified number of
+   rows not being available, fewer rows may be returned.
+
+   Note there are performance considerations involved with the *size* parameter.
+   For optimal performance, it is usually best to use the arraysize attribute.
+   If the *size* parameter is used, then it is best for it to retain the same
+   value from one :meth:`fetchmany` call to the next.
+
+.. method:: Cursor.fetchall()
+
+   Fetches all (remaining) rows of a query result, returning a list.  Note that
+   the cursor's arraysize attribute can affect the performance of this operation.
+   An empty list is returned when no rows are available.
+
+
+.. attribute:: Cursor.rowcount
+
+   Although the :class:`Cursor` class of the :mod:`sqlite3` module implements this
+   attribute, the database engine's own support for the determination of "rows
+   affected"/"rows selected" is quirky.
+
+   For ``DELETE`` statements, SQLite reports :attr:`rowcount` as 0 if you make a
+   ``DELETE FROM table`` without any condition.
+
+   For :meth:`executemany` statements, the number of modifications are summed up
+   into :attr:`rowcount`.
+
+   As required by the Python DB API Spec, the :attr:`rowcount` attribute "is -1 in
+   case no executeXX() has been performed on the cursor or the rowcount of the last
+   operation is not determinable by the interface".
+
+   This includes ``SELECT`` statements because we cannot determine the number of
+   rows a query produced until all rows were fetched.
+
+.. attribute:: Cursor.lastrowid
+
+   This read-only attribute provides the rowid of the last modified row. It is
+   only set if you issued a ``INSERT`` statement using the :meth:`execute`
+   method. For operations other than ``INSERT`` or when :meth:`executemany` is
+   called, :attr:`lastrowid` is set to :const:`None`.
+
+.. _sqlite3-types:
+
+SQLite and Python types
+-----------------------
+
+
+Introduction
+^^^^^^^^^^^^
+
+SQLite natively supports the following types: NULL, INTEGER, REAL, TEXT, BLOB.
+
+The following Python types can thus be sent to SQLite without any problem:
+
++------------------------+-------------+
+| Python type            | SQLite type |
++========================+=============+
+| ``None``               | NULL        |
++------------------------+-------------+
+| ``int``                | INTEGER     |
++------------------------+-------------+
+| ``long``               | INTEGER     |
++------------------------+-------------+
+| ``float``              | REAL        |
++------------------------+-------------+
+| ``str (UTF8-encoded)`` | TEXT        |
++------------------------+-------------+
+| ``unicode``            | TEXT        |
++------------------------+-------------+
+| ``buffer``             | BLOB        |
++------------------------+-------------+
+
+This is how SQLite types are converted to Python types by default:
+
++-------------+---------------------------------------------+
+| SQLite type | Python type                                 |
++=============+=============================================+
+| ``NULL``    | None                                        |
++-------------+---------------------------------------------+
+| ``INTEGER`` | int or long, depending on size              |
++-------------+---------------------------------------------+
+| ``REAL``    | float                                       |
++-------------+---------------------------------------------+
+| ``TEXT``    | depends on text_factory, unicode by default |
++-------------+---------------------------------------------+
+| ``BLOB``    | buffer                                      |
++-------------+---------------------------------------------+
+
+The type system of the :mod:`sqlite3` module is extensible in two ways: you can
+store additional Python types in a SQLite database via object adaptation, and
+you can let the :mod:`sqlite3` module convert SQLite types to different Python
+types via converters.
+
+
+Using adapters to store additional Python types in SQLite databases
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+As described before, SQLite supports only a limited set of types natively. To
+use other Python types with SQLite, you must **adapt** them to one of the
+sqlite3 module's supported types for SQLite: one of NoneType, int, long, float,
+str, unicode, buffer.
+
+The :mod:`sqlite3` module uses Python object adaptation, as described in
+:pep:`246` for this.  The protocol to use is :class:`PrepareProtocol`.
+
+There are two ways to enable the :mod:`sqlite3` module to adapt a custom Python
+type to one of the supported ones.
+
+
+Letting your object adapt itself
+""""""""""""""""""""""""""""""""
+
+This is a good approach if you write the class yourself. Let's suppose you have
+a class like this::
+
+   class Point(object):
+       def __init__(self, x, y):
+           self.x, self.y = x, y
+
+Now you want to store the point in a single SQLite column.  First you'll have to
+choose one of the supported types first to be used for representing the point.
+Let's just use str and separate the coordinates using a semicolon. Then you need
+to give your class a method ``__conform__(self, protocol)`` which must return
+the converted value. The parameter *protocol* will be :class:`PrepareProtocol`.
+
+.. literalinclude:: ../includes/sqlite3/adapter_point_1.py
+
+
+Registering an adapter callable
+"""""""""""""""""""""""""""""""
+
+The other possibility is to create a function that converts the type to the
+string representation and register the function with :meth:`register_adapter`.
+
+.. note::
+
+   The type/class to adapt must be a :term:`new-style class`, i. e. it must have
+   :class:`object` as one of its bases.
+
+.. literalinclude:: ../includes/sqlite3/adapter_point_2.py
+
+The :mod:`sqlite3` module has two default adapters for Python's built-in
+:class:`datetime.date` and :class:`datetime.datetime` types.  Now let's suppose
+we want to store :class:`datetime.datetime` objects not in ISO representation,
+but as a Unix timestamp.
+
+.. literalinclude:: ../includes/sqlite3/adapter_datetime.py
+
+
+Converting SQLite values to custom Python types
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Writing an adapter lets you send custom Python types to SQLite. But to make it
+really useful we need to make the Python to SQLite to Python roundtrip work.
+
+Enter converters.
+
+Let's go back to the :class:`Point` class. We stored the x and y coordinates
+separated via semicolons as strings in SQLite.
+
+First, we'll define a converter function that accepts the string as a parameter
+and constructs a :class:`Point` object from it.
+
+.. note::
+
+   Converter functions **always** get called with a string, no matter under which
+   data type you sent the value to SQLite.
+
+::
+
+   def convert_point(s):
+       x, y = map(float, s.split(";"))
+       return Point(x, y)
+
+Now you need to make the :mod:`sqlite3` module know that what you select from
+the database is actually a point. There are two ways of doing this:
+
+* Implicitly via the declared type
+
+* Explicitly via the column name
+
+Both ways are described in section :ref:`sqlite3-module-contents`, in the entries
+for the constants :const:`PARSE_DECLTYPES` and :const:`PARSE_COLNAMES`.
+
+The following example illustrates both approaches.
+
+.. literalinclude:: ../includes/sqlite3/converter_point.py
+
+
+Default adapters and converters
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There are default adapters for the date and datetime types in the datetime
+module. They will be sent as ISO dates/ISO timestamps to SQLite.
+
+The default converters are registered under the name "date" for
+:class:`datetime.date` and under the name "timestamp" for
+:class:`datetime.datetime`.
+
+This way, you can use date/timestamps from Python without any additional
+fiddling in most cases. The format of the adapters is also compatible with the
+experimental SQLite date/time functions.
+
+The following example demonstrates this.
+
+.. literalinclude:: ../includes/sqlite3/pysqlite_datetime.py
+
+
+.. _sqlite3-controlling-transactions:
+
+Controlling Transactions
+------------------------
+
+By default, the :mod:`sqlite3` module opens transactions implicitly before a
+Data Modification Language (DML)  statement (i.e. INSERT/UPDATE/DELETE/REPLACE),
+and commits transactions implicitly before a non-DML, non-query statement (i. e.
+anything other than SELECT/INSERT/UPDATE/DELETE/REPLACE).
+
+So if you are within a transaction and issue a command like ``CREATE TABLE
+...``, ``VACUUM``, ``PRAGMA``, the :mod:`sqlite3` module will commit implicitly
+before executing that command. There are two reasons for doing that. The first
+is that some of these commands don't work within transactions. The other reason
+is that pysqlite needs to keep track of the transaction state (if a transaction
+is active or not).
+
+You can control which kind of "BEGIN" statements pysqlite implicitly executes
+(or none at all) via the *isolation_level* parameter to the :func:`connect`
+call, or via the :attr:`isolation_level` property of connections.
+
+If you want **autocommit mode**, then set :attr:`isolation_level` to None.
+
+Otherwise leave it at its default, which will result in a plain "BEGIN"
+statement, or set it to one of SQLite's supported isolation levels: DEFERRED,
+IMMEDIATE or EXCLUSIVE.
+
+
+
+Using pysqlite efficiently
+--------------------------
+
+
+Using shortcut methods
+^^^^^^^^^^^^^^^^^^^^^^
+
+Using the nonstandard :meth:`execute`, :meth:`executemany` and
+:meth:`executescript` methods of the :class:`Connection` object, your code can
+be written more concisely because you don't have to create the (often
+superfluous) :class:`Cursor` objects explicitly. Instead, the :class:`Cursor`
+objects are created implicitly and these shortcut methods return the cursor
+objects. This way, you can execute a SELECT statement and iterate over it
+directly using only a single call on the :class:`Connection` object.
+
+.. literalinclude:: ../includes/sqlite3/shortcut_methods.py
+
+
+Accessing columns by name instead of by index
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+One useful feature of the :mod:`sqlite3` module is the builtin
+:class:`sqlite3.Row` class designed to be used as a row factory.
+
+Rows wrapped with this class can be accessed both by index (like tuples) and
+case-insensitively by name:
+
+.. literalinclude:: ../includes/sqlite3/rowclass.py
+
+
+Using the connection as a context manager
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+With Python 2.5 or higher, connection objects can be used as context managers
+that automatically commit or rollback transactions.  In the event of an
+exception, the transaction is rolled back; otherwise, the transaction is
+committed:
+
+.. literalinclude:: ../includes/sqlite3/ctx_manager.py
+
+
+Combining APSW and pysqlite
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+APSW is "Another Python SQLite Wrapper". Its goal is to directly wrap the
+SQLite API for Python. If there's SQLite functionality that is only wrapped via
+APSW, but not (yet) via pysqlite, then you can still use the APSW functionality
+in pysqlite.
+
+Just use the APSW Connection as a parameter to the connect function and reuse
+an existing APSW connection like this.
+
+.. literalinclude:: ../includes/sqlite3/apsw_example.py
+
+This feature only works if both APSW and pysqlite are dynamically linked
+against the same SQLite shared library. I. e. it will *not* work on Windows
+without a custom built pysqlite and APSW.
+
diff --git a/doc/usage-guide.html b/doc/usage-guide.html
deleted file mode 100644 (file)
index ce4972e..0000000
+++ /dev/null
@@ -1,1469 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Docutils 0.4.1: http://docutils.sourceforge.net/" />
-<title>pysqlite usage guide</title>
-<style type="text/css">
-
-@import url(docutils.css);
-@import url(silvercity.css);
-
-div.code-block{
-margin-left: 2em ;
-margin-right: 2em ;
-background-color: #eeeeee;
-font-family: "Courier New", Courier, monospace;
-font-size: 10pt;
-}
-
-</style>
-</head>
-<body>
-<div class="document" id="pysqlite-usage-guide">
-<h1 class="title">pysqlite usage guide</h1>
-<div class="line-block">
-<div class="line">(c) 2004-2005 David Rushby</div>
-<div class="line">(c) 2005-2007 Gerhard Häring</div>
-</div>
-<p>Last updated for pysqlite 2.4.0</p>
-<div class="section">
-<h1><a id="table-of-contents" name="table-of-contents">Table Of Contents</a></h1>
-<div class="line-block">
-<div class="line"><a class="reference" href="#introduction">0. Introduction</a></div>
-<div class="line"><a class="reference" href="#python-database-api-2-0-compliance">1. Python Database API 2.0 Compliance</a></div>
-<div class="line-block">
-<div class="line"><a class="reference" href="#incompatibilities">1.1 Incompatibilities</a></div>
-<div class="line"><a class="reference" href="#unsupported-optional-features">1.2 Unsupported Optional Features</a></div>
-<div class="line"><a class="reference" href="#nominally-supported-optional-features">1.3 Nominally Supported Optional Features</a></div>
-<div class="line"><a class="reference" href="#extensions-and-caveats">1.4 Extensions and Caveats</a></div>
-</div>
-<div class="line"><a class="reference" href="#brief-tutorial">2. Brief Tutorial</a></div>
-<div class="line-block">
-<div class="line"><a class="reference" href="#connecting-to-a-database">2.1 Connecting to a Database</a></div>
-<div class="line"><a class="reference" href="#executing-sql-statements">2.2 Executing SQL statements</a></div>
-</div>
-<div class="line"><a class="reference" href="#native-database-engine-features-and-extensions-beyond-the-python-db-api">3. Native Database Engine Features and Extensions Beyond the Python DB API</a></div>
-<div class="line-block">
-<div class="line"><a class="reference" href="#creating-user-defined-functions">3.1 Creating user-defined functions</a></div>
-<div class="line"><a class="reference" href="#creating-user-defined-aggregates">3.2 Creating user-defined aggregates</a></div>
-<div class="line"><a class="reference" href="#creating-and-using-collations">3.3 Creating and using collations</a></div>
-<div class="line"><a class="reference" href="#checking-for-complete-statements">3.4 Checking for complete statements</a></div>
-<div class="line"><a class="reference" href="#enabling-sqlite-s-shared-cache">3.5 Enabling SQLite's shared cache</a></div>
-<div class="line"><a class="reference" href="#setting-an-authorizer-callback">3.6 Setting an authorizer callback</a></div>
-<div class="line"><a class="reference" href="#setting-a-progress-handler">3.7 Setting a progress handler</a></div>
-<div class="line"><a class="reference" href="#using-the-connection-as-a-context-manager">3.8 Using the connection as a context manager</a></div>
-</div>
-<div class="line"><a class="reference" href="#sqlite-and-python-types">4. SQLite and Python types</a></div>
-<div class="line-block">
-<div class="line"><a class="reference" href="#id1">4.1 Introduction</a></div>
-<div class="line"><a class="reference" href="#using-adapters-to-store-additional-python-types-in-sqlite-databases">4.2 Using adapters to store additional Python types in SQLite databases</a></div>
-<div class="line-block">
-<div class="line"><a class="reference" href="#letting-your-object-adapt-itself">4.2.1 Letting your object adapt itself</a></div>
-<div class="line"><a class="reference" href="#registering-an-adapter-callable">4.2.2 Registering an adapter callable</a></div>
-</div>
-<div class="line"><a class="reference" href="#converting-sqlite-values-to-custom-python-types">4.3 Converting SQLite values to custom Python types</a></div>
-<div class="line"><a class="reference" href="#default-pysqlite-adapters-and-converters">4.4 Default pysqlite adapters and converters</a></div>
-</div>
-<div class="line"><a class="reference" href="#controlling-transactions">5. Controlling Transactions</a></div>
-<div class="line"><a class="reference" href="#using-pysqlite-efficiently">6. Using pysqlite efficiently</a></div>
-<div class="line-block">
-<div class="line"><a class="reference" href="#using-shortcut-methods">6.1 Using shortcut methods</a></div>
-<div class="line"><a class="reference" href="#accessing-columns-by-name-instead-of-by-index">6.2 Accessing columns by name instead of by index</a></div>
-</div>
-<div class="line"><a class="reference" href="#combining-apsw-and-pysqlite">7. Combining APSW and pysqlite</a></div>
-</div>
-</div>
-<div class="section">
-<h1><a id="introduction" name="introduction">0. Introduction</a></h1>
-<p>This Usage Guide is not a tutorial on Python, SQL, or SQLite; rather, it is a
-topical presentation of pysqlite's feature set, with example code to
-demonstrate basic usage patterns. This guide is meant to be consumed in
-conjunction with the Python Database API Specification and the SQLite
-documentation.</p>
-<p>It was originally written by David Rushby for kinterbasdb. He kindly gave the
-permission to adapt it for pysqlite.</p>
-</div>
-<div class="section">
-<h1><a id="python-database-api-2-0-compliance" name="python-database-api-2-0-compliance">1. Python Database API 2.0 Compliance</a></h1>
-<div class="section">
-<h2><a id="incompatibilities" name="incompatibilities">1.1 Incompatibilities</a></h2>
-<ul>
-<li><p class="first">No type information in cursor.description</p>
-<p><em>cursor.description</em> has a tuple with the fields (<em>name</em>, <em>type_code</em>,
-<em>display_size</em>, <em>internal_size</em>, <em>precision</em>, <em>scale</em>, <em>null_ok</em>) for each
-column that a query returns. The DB-API spec requires that at least <em>name</em>
-and <em>type_code</em> are filled, but at the time cursor.description is built,
-pysqlite cannot determine any types, yet. So, the only field of
-<em>cursor.description</em> that pysqlite fills is <em>name</em>. All other fields are set to
-None.</p>
-</li>
-<li><p class="first">No type objects</p>
-<p>Consequently, there are also no type objects STRING, BINARY, NUMBER,
-DATETIME, ROWID at module-level. They would be useless.</p>
-</li>
-</ul>
-</div>
-<div class="section">
-<h2><a id="unsupported-optional-features" name="unsupported-optional-features">1.2 Unsupported Optional Features</a></h2>
-<ul>
-<li><p class="first"><strong>Cursor</strong> class</p>
-<ul>
-<li><p class="first"><strong>nextset</strong> method</p>
-<p>This method is not implemented because the database engine does not
-support opening multiple result sets simultaneously with a single
-cursor.</p>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="section">
-<h2><a id="nominally-supported-optional-features" name="nominally-supported-optional-features">1.3 Nominally Supported Optional Features</a></h2>
-<ul>
-<li><p class="first"><strong>Cursor</strong> class</p>
-<ul>
-<li><p class="first"><strong>arraysize</strong> attribute</p>
-<p>As required by the spec, the value of this attribute is observed
-with respect to the fetchmany method. However, changing the value
-of this attribute does not make any difference in fetch efficiency
-because the database engine only supports fetching a single row at
-a time.</p>
-</li>
-<li><p class="first"><strong>setinputsizes</strong> method</p>
-<p>Although this method is present, it does nothing, as allowed by the
-spec.</p>
-</li>
-<li><p class="first"><strong>setoutputsize</strong> method</p>
-<p>Although this method is present, it does nothing, as allowed by the
-spec.</p>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="section">
-<h2><a id="extensions-and-caveats" name="extensions-and-caveats">1.4 Extensions and Caveats</a></h2>
-<p>pysqlite offers a large feature set beyond the minimal requirements of the
-Python DB API. Most of these extensions are documented in the section of this
-document entitled Native Database Engine Features and Extensions Beyond the
-Python DB API.</p>
-<ul>
-<li><p class="first"><strong>connect</strong> function</p>
-<p>The parameter <em>database</em> refers to the database file for the SQLite
-database. It's a normal filesystem path and you can use absolute or
-relative path names.</p>
-<p>The connect function supports the following optional keyword arguments
-in addition to those required by the spec:</p>
-<ul>
-<li><p class="first"><strong>timeout</strong> - When a database is accessed by multiple connections, and</p>
-<p>one of the processes modifies the database, the SQLite database is
-locked until that transaction is committed. The timeout parameter
-specifies how long the connection should wait for the lock to go away
-until raising an exception. The default for the timeout parameter is
-5.0 (five seconds).</p>
-<dl class="docutils">
-<dt>Example:</dt>
-<dd><div class="first last"><div class="code-block">
-<span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_identifier">database</span><span class="p_operator">=</span><span class="p_string">"mydb"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">timeout</span><span class="p_operator">=</span><span class="p_number">10.0</span><span class="p_operator">)</span>
-</div>
-</div></dd>
-</dl>
-</li>
-<li><p class="first"><strong>isolation_level</strong> - pysqlite will by default open transactions with a
-&quot;BEGIN&quot; statement, when it encounters a DML statement like
-INSERT/UPDATE/DELETE/REPLACE. Some users don't want pysqlite to implicitly
-open transactions for them - they want an autocommit mode. Other users want
-pysqlite to open different kinds of transactions, like with &quot;BEGIN
-IMMEDIATE&quot;. See <a class="reference" href="#controlling-transactions">5. Controlling Transactions</a>  for a more detailed
-explanation.</p>
-<p>Note that you can also switch to a different isolation level by setting the
-<strong>isolation_level</strong> property of connections.</p>
-<dl class="docutils">
-<dt>Example:</dt>
-<dd><div class="first last"><div class="code-block">
-<span class="p_commentline">#&nbsp;Turn&nbsp;on&nbsp;autocommit&nbsp;mode</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">"mydb"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">isolation_level</span><span class="p_operator">=</span><span class="p_word">None</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Set&nbsp;isolation_level&nbsp;to&nbsp;"IMMEDIATE"</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">isolation_level</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_string">"IMMEDIATE"</span>
-</div>
-</div></dd>
-</dl>
-</li>
-<li><p class="first"><strong>detect_types</strong> - SQLite natively supports only the types TEXT,
-INTEGER, FLOAT, BLOB and NULL. If you want to use other types, like you
-have to add support for them yourself.  The <em>detect_types</em> parameter and
-using custom <em>converters</em> registered with the module-level
-<em>register_converter</em> function allow you to easily do that.</p>
-<p><em>detect_types</em> defaults to 0 (i. e. off, no type detection), you can
-set it to any combination of <em>PARSE_DECLTYPES</em> and <em>PARSE_COLNAMES</em> to turn
-type detection on.</p>
-<p>Consult the section <a class="reference" href="#sqlite-and-python-types">4. SQLite and Python types</a> of this manual for
-details.</p>
-<ul>
-<li><p class="first"><strong>sqlite.PARSE_DECLTYPES</strong> - This makes pysqlite parse the declared
-type for each column it returns. It will parse out the first word of the
-declared type, i. e. for &quot;integer primary key&quot;, it will parse out
-&quot;integer&quot;. Then for that column, it will look into pysqlite's converters
-dictionary and use the converter function registered for that type there.</p>
-</li>
-<li><p class="first"><strong>sqlite.PARSE_COLNAMES</strong> - This makes pysqlite parse the column name
-for each column it returns. It will look for a string formed
-[mytype] in there, and then decide that 'mytype' is the type of
-the column. It will try to find an entry of 'mytype' in the
-converters dictionary and then use the converter function found
-there to return the value. The column name found in
-cursor.description is only the first word of the column name, i.
-e. if you use something like 'as &quot;x [datetime]&quot;' in your SQL,
-then pysqlite will parse out everything until the first blank for
-the column name: the column name would simply be &quot;x&quot;.</p>
-<p>The following example uses the column name <em>timestamp</em>, which is already
-registered by default in the converters dictionary with an appropriate
-converter!</p>
-<p>Example:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">datetime</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">detect_types</span><span class="p_operator">=</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">PARSE_COLNAMES</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_character">'select&nbsp;?&nbsp;as&nbsp;"x&nbsp;[timestamp]"'</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">datetime</span><span class="p_operator">.</span><span class="p_identifier">datetime</span><span class="p_operator">.</span><span class="p_identifier">now</span><span class="p_operator">(),))</span><span class="p_default"><br/>
-</span><span class="p_identifier">dt</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()[</span><span class="p_number">0</span><span class="p_operator">]</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">dt</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">type</span><span class="p_operator">(</span><span class="p_identifier">dt</span><span class="p_operator">)</span>
-</div>
-</li>
-</ul>
-</li>
-<li><p class="first"><strong>check_same_thread</strong> - SQLite connections/cursors can only safely be
-used in the same thread they were created in. pysqlite checks for
-this each time it would do a call to the SQLite engine. If you are
-confident that you are ensuring safety otherwise, you can disable
-that checks by setting check_same_thread to False.</p>
-</li>
-<li><p class="first"><strong>factory</strong> - By default, pysqlite uses the Connection class for the
-connect call. You can, however, subclass the Connection class and
-make .connect() use your class instead by providing your class for
-the factory parameter.</p>
-<p>Example:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">class</span><span class="p_default">&nbsp;</span><span class="p_classname">CountCursorsConnection</span><span class="p_operator">(</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">Connection</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">__init__</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">*</span><span class="p_identifier">args</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">**</span><span class="p_identifier">kwargs</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">Connection</span><span class="p_operator">.</span><span class="p_identifier">__init__</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">*</span><span class="p_identifier">args</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">**</span><span class="p_identifier">kwargs</span><span class="p_operator">)</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">numcursors</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_number">0</span><span class="p_default"><br/>
-<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">cursor</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">*</span><span class="p_identifier">args</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">**</span><span class="p_identifier">kwargs</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">numcursors</span><span class="p_default">&nbsp;</span><span class="p_operator">+=</span><span class="p_default">&nbsp;</span><span class="p_number">1</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">Connection</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">*</span><span class="p_identifier">args</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">**</span><span class="p_identifier">kwargs</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">factory</span><span class="p_operator">=</span><span class="p_identifier">CountCursorsConnection</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur1</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur2</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">numcursors</span>
-</div>
-</li>
-<li><p class="first"><strong>cached_statements</strong> - pysqlite internally uses a statement cache to avoid
-SQL parsing overhead. If you want to explicitly set the number of
-statements that are cached for the connection, you can set this parameter.
-The currently implemented default is to cache 100 statements.</p>
-</li>
-</ul>
-<div class="line-block">
-<div class="line"><br /></div>
-<div class="line"><br /></div>
-</div>
-</li>
-<li><p class="first"><strong>register_converter</strong> function - <tt class="docutils literal"><span class="pre">register_converter(typename,</span> <span class="pre">callable)</span></tt>
-registers a callable to convert a bytestring from the database into a custom
-Python type. The converter will be invoked for all database values that are
-of the type <tt class="docutils literal"><span class="pre">typename</span></tt>. Confer the parameter <strong>detect_types</strong> of the
-<strong>connect</strong> method for how the type detection works.</p>
-</li>
-<li><p class="first"><strong>register_adapter</strong> function - <tt class="docutils literal"><span class="pre">register_adapter(type,</span> <span class="pre">callable)</span></tt>
-registers a callable to convert the custom Python <strong>type</strong> into one of
-SQLite's supported types. The callable accepts as single parameter the Python
-value, and must return a value of the following types: int, long, float, str
-(UTF-8 encoded), unicode or buffer.</p>
-</li>
-<li><p class="first"><strong>enable_callback_tracebacks</strong> function - <tt class="docutils literal"><span class="pre">enable_callback_tracebacks(flag)</span></tt>
-Can be used to enable displaying tracebacks of exceptions in user-defined functions, aggregates and other callbacks being printed to stderr.
-methods should never raise any exception. This feature is off by default.</p>
-</li>
-<li><p class="first"><strong>Connection</strong> class</p>
-<ul>
-<li><p class="first"><strong>isolation_level</strong> attribute (read-write)</p>
-<p>Get or set the current <em>isolation level</em>: None for autocommit mode or one
-of &quot;DEFERRED&quot;, &quot;IMMEDIATE&quot; or &quot;EXLUSIVE&quot;. See <a class="reference" href="#controlling-transactions">5. Controlling
-Transactions</a> for a more detailed explanation.</p>
-</li>
-<li><p class="first"><strong>cursor method</strong> - The cursor method accepts a single optional parameter:
-a custom cursor class extending pysqlite's <em>Cursor</em> class that you can
-adapt to your needs. Note that it is required that your custom cursor class
-extends pysqlite's <em>Cursor</em> class.</p>
-</li>
-<li><p class="first"><strong>execute method</strong> - Nonstandard - this works as a shortcut for not having
-to create a cursor object and is implemented like this:</p>
-<blockquote>
-<div class="code-block">
-<span class="p_word">class</span><span class="p_default">&nbsp;</span><span class="p_classname">Connection</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">execute</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">*</span><span class="p_identifier">args</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(*</span><span class="p_identifier">args</span><span class="p_operator">)</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span>
-</div>
-</blockquote>
-</li>
-<li><p class="first"><strong>executemany method</strong> - Nonstandard - The same shortcut as the nonstandard
-<tt class="docutils literal"><span class="pre">execute</span></tt> method.</p>
-</li>
-<li><p class="first"><strong>executesript method</strong> - Nonstandard - The same shortcut as the nonstandard
-<tt class="docutils literal"><span class="pre">execute</span></tt> method.</p>
-</li>
-<li><p class="first"><strong>row_factory</strong> attribute (read-write)</p>
-<p>You can change this attribute to a callable that accepts the cursor and
-the original row as tuple and will return the real result row.  This
-way, you can implement more advanced ways of returning results, like
-ones that can also access columns by name.</p>
-<p>Example:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">dict_factory</span><span class="p_operator">(</span><span class="p_identifier">cursor</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">d</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_operator">{}</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">for</span><span class="p_default">&nbsp;</span><span class="p_identifier">idx</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">col</span><span class="p_default">&nbsp;</span><span class="p_word">in</span><span class="p_default">&nbsp;</span><span class="p_identifier">enumerate</span><span class="p_operator">(</span><span class="p_identifier">cursor</span><span class="p_operator">.</span><span class="p_identifier">description</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">d</span><span class="p_operator">[</span><span class="p_identifier">col</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">]]</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_identifier">idx</span><span class="p_operator">]</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_identifier">d</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">row_factory</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">dict_factory</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;1&nbsp;as&nbsp;a"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()[</span><span class="p_string">"a"</span><span class="p_operator">]</span>
-</div>
-<p>If the standard tuple types don't suffice for you, and you want name-based
-access to columns, you should consider setting <tt class="docutils literal"><span class="pre">row_factory</span></tt> to the
-highly-optimized <tt class="docutils literal"><span class="pre">pysqlite2.dbapi2.Row</span></tt> type. It provides both
-index-based and case-insensitive name-based access to columns with almost
-no memory overhead. Much better than your own custom dictionary-based
-approach or even a <tt class="docutils literal"><span class="pre">db_row</span></tt> based solution.</p>
-</li>
-<li><p class="first"><strong>text_factory</strong> attribute (read-write)</p>
-<p>Using this attribute you can control what objects pysqlite returns for the
-TEXT data type. By default, this attribute is set to <tt class="docutils literal"><span class="pre">unicode</span></tt> and
-pysqlite will return Unicode objects for TEXT. If you want to return
-bytestrings instead, you can set it to <tt class="docutils literal"><span class="pre">str</span></tt>.</p>
-<p>For efficiency reasons, there's also a way to return Unicode objects only
-for non-ASCII data, and bytestrings otherwise. To activate it, set this
-attribute to <tt class="docutils literal"><span class="pre">pysqlite2.dbapi2.OptimizedUnicode</span></tt>.</p>
-<p>You can also set it to any other callable that accepts a single bytestring
-parameter and returns the result object.</p>
-<p>See the following example code for illustration:</p>
-<blockquote>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Create&nbsp;the&nbsp;table</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"create&nbsp;table&nbsp;person(lastname,&nbsp;firstname)"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">AUSTRIA</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_string">u"\xd6sterreich"</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;by&nbsp;default,&nbsp;rows&nbsp;are&nbsp;returned&nbsp;as&nbsp;Unicode</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;?"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">AUSTRIA</span><span class="p_operator">,))</span><span class="p_default"><br/>
-</span><span class="p_identifier">row</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_word">assert</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">]</span><span class="p_default">&nbsp;</span><span class="p_operator">==</span><span class="p_default">&nbsp;</span><span class="p_identifier">AUSTRIA</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;but&nbsp;we&nbsp;can&nbsp;make&nbsp;pysqlite&nbsp;always&nbsp;return&nbsp;bytestrings&nbsp;...</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">text_factory</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">str</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;?"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">AUSTRIA</span><span class="p_operator">,))</span><span class="p_default"><br/>
-</span><span class="p_identifier">row</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_word">assert</span><span class="p_default">&nbsp;</span><span class="p_identifier">type</span><span class="p_operator">(</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">])</span><span class="p_default">&nbsp;</span><span class="p_operator">==</span><span class="p_default">&nbsp;</span><span class="p_identifier">str</span><span class="p_default"><br/>
-</span><span class="p_commentline">#&nbsp;the&nbsp;bytestrings&nbsp;will&nbsp;be&nbsp;encoded&nbsp;in&nbsp;UTF-8,&nbsp;unless&nbsp;you&nbsp;stored&nbsp;garbage&nbsp;in&nbsp;the</span><span class="p_default"><br/>
-</span><span class="p_commentline">#&nbsp;database&nbsp;...</span><span class="p_default"><br/>
-</span><span class="p_word">assert</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">]</span><span class="p_default">&nbsp;</span><span class="p_operator">==</span><span class="p_default">&nbsp;</span><span class="p_identifier">AUSTRIA</span><span class="p_operator">.</span><span class="p_identifier">encode</span><span class="p_operator">(</span><span class="p_string">"utf-8"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;we&nbsp;can&nbsp;also&nbsp;implement&nbsp;a&nbsp;custom&nbsp;text_factory&nbsp;...</span><span class="p_default"><br/>
-</span><span class="p_commentline">#&nbsp;here&nbsp;we&nbsp;implement&nbsp;one&nbsp;that&nbsp;will&nbsp;ignore&nbsp;Unicode&nbsp;characters&nbsp;that&nbsp;cannot&nbsp;be</span><span class="p_default"><br/>
-</span><span class="p_commentline">#&nbsp;decoded&nbsp;from&nbsp;UTF-8</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">text_factory</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_word">lambda</span><span class="p_default">&nbsp;</span><span class="p_identifier">x</span><span class="p_operator">:</span><span class="p_default">&nbsp;</span><span class="p_identifier">unicode</span><span class="p_operator">(</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_string">"utf-8"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_string">"ignore"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;?"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_string">"this&nbsp;is&nbsp;latin1&nbsp;and&nbsp;would&nbsp;normally&nbsp;create&nbsp;errors"</span><span class="p_default">&nbsp;</span><span class="p_operator">+</span><span class="p_default">&nbsp;</span><span class="p_string">u"\xe4\xf6\xfc"</span><span class="p_operator">.</span><span class="p_identifier">encode</span><span class="p_operator">(</span><span class="p_string">"latin1"</span><span class="p_operator">),))</span><span class="p_default"><br/>
-</span><span class="p_identifier">row</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_word">assert</span><span class="p_default">&nbsp;</span><span class="p_identifier">type</span><span class="p_operator">(</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">])</span><span class="p_default">&nbsp;</span><span class="p_operator">==</span><span class="p_default">&nbsp;</span><span class="p_identifier">unicode</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;pysqlite&nbsp;offers&nbsp;a&nbsp;builtin&nbsp;optimized&nbsp;text_factory&nbsp;that&nbsp;will&nbsp;return&nbsp;bytestring</span><span class="p_default"><br/>
-</span><span class="p_commentline">#&nbsp;objects,&nbsp;if&nbsp;the&nbsp;data&nbsp;is&nbsp;in&nbsp;ASCII&nbsp;only,&nbsp;and&nbsp;otherwise&nbsp;return&nbsp;unicode&nbsp;objects</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">text_factory</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">OptimizedUnicode</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;?"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">AUSTRIA</span><span class="p_operator">,))</span><span class="p_default"><br/>
-</span><span class="p_identifier">row</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_word">assert</span><span class="p_default">&nbsp;</span><span class="p_identifier">type</span><span class="p_operator">(</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">])</span><span class="p_default">&nbsp;</span><span class="p_operator">==</span><span class="p_default">&nbsp;</span><span class="p_identifier">unicode</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;?"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_string">"Germany"</span><span class="p_operator">,))</span><span class="p_default"><br/>
-</span><span class="p_identifier">row</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_word">assert</span><span class="p_default">&nbsp;</span><span class="p_identifier">type</span><span class="p_operator">(</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">])</span><span class="p_default">&nbsp;</span><span class="p_operator">==</span><span class="p_default">&nbsp;</span><span class="p_identifier">str</span>
-</div>
-</blockquote>
-</li>
-<li><p class="first"><strong>total_changes</strong> attribute (read-only)</p>
-<p>Returns the total number of database rows that have be modified, inserted,
-or deleted since the database connection was opened.</p>
-</li>
-</ul>
-<div class="line-block">
-<div class="line"><br /></div>
-</div>
-</li>
-<li><p class="first"><strong>Cursor</strong> class</p>
-<ul>
-<li><p class="first"><strong>execute</strong> method</p>
-<p>pysqlite uses <em>paramstyle = &quot;qmark&quot;</em>. That means if you use parametrized
-statements, you use the question mark as placeholder.</p>
-<p>This is a basic example showing the use of question marks as placeholders
-and a parameter tuple:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">"mydb"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">who</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_string">"Yeltsin"</span><span class="p_default"><br/>
-</span><span class="p_identifier">age</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_number">72</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;name_last,&nbsp;age&nbsp;from&nbsp;people&nbsp;where&nbsp;name_last=?&nbsp;and&nbsp;age=?"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">who</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">age</span><span class="p_operator">))</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()</span>
-</div>
-<p>pysqlite also supports <em>paramstyle = &quot;named&quot;</em>. That means you can use named
-placeholders in the format &quot;:name&quot;, i. e. a colon followed by the parameter
-name. As parameters, you then supply a mapping instead of a sequence. In
-the simplest case, a dictionary instead of a tuple.</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">"mydb"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">who</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_string">"Yeltsin"</span><span class="p_default"><br/>
-</span><span class="p_identifier">age</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_number">72</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;name_last,&nbsp;age&nbsp;from&nbsp;people&nbsp;where&nbsp;name_last=:who&nbsp;and&nbsp;age=:age"</span><span class="p_operator">,</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_operator">{</span><span class="p_string">"who"</span><span class="p_operator">:</span><span class="p_default">&nbsp;</span><span class="p_identifier">who</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_string">"age"</span><span class="p_operator">:</span><span class="p_default">&nbsp;</span><span class="p_identifier">age</span><span class="p_operator">})</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()</span>
-</div>
-<p>The following example shows a shortcut that you can often use when using
-named parameters. It exploits the fact that locals() is a dictionary, too.
-So you can also use it as parameter for <em>execute</em>:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">"mydb"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">who</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_string">"Yeltsin"</span><span class="p_default"><br/>
-</span><span class="p_identifier">age</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_number">72</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;name_last,&nbsp;age&nbsp;from&nbsp;people&nbsp;where&nbsp;name_last=:who&nbsp;and&nbsp;age=:age"</span><span class="p_operator">,</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">locals</span><span class="p_operator">())</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()</span>
-</div>
-<p><em>execute</em> will only execute a single SQL statement. If you try to execute
-more than one statement with it, it will raise a Warning. Use
-<em>executescript</em> if want to execute multiple SQL statements with one call.</p>
-</li>
-<li><p class="first"><strong>executemany</strong> method</p>
-<p>The DB-API specifies the executemany method like this:</p>
-<div class="code-block">
-<span class="p_operator">.</span><span class="p_identifier">executemany</span><span class="p_operator">(</span><span class="p_identifier">operation</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">seq_of_parameters</span><span class="p_operator">)</span>
-</div>
-<p>pysqlite, however, extends <em>executemany</em> so it can be used more efficiently
-for inserting bulk data. The second parameter to <em>executemany</em> can be a
-<em>sequence of parameters</em>, but it can also be an <em>iterator</em> returning
-parameters.</p>
-<p>Example:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">class</span><span class="p_default">&nbsp;</span><span class="p_classname">IterChars</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">__init__</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">count</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">ord</span><span class="p_operator">(</span><span class="p_character">'a'</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">__iter__</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_identifier">self</span><span class="p_default"><br/>
-<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">next</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">if</span><span class="p_default">&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">count</span><span class="p_default">&nbsp;</span><span class="p_operator">&gt;</span><span class="p_default">&nbsp;</span><span class="p_identifier">ord</span><span class="p_operator">(</span><span class="p_character">'z'</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">raise</span><span class="p_default">&nbsp;</span><span class="p_identifier">StopIteration</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">count</span><span class="p_default">&nbsp;</span><span class="p_operator">+=</span><span class="p_default">&nbsp;</span><span class="p_number">1</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">chr</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">count</span><span class="p_default">&nbsp;</span><span class="p_operator">-</span><span class="p_default">&nbsp;</span><span class="p_number">1</span><span class="p_operator">),)</span><span class="p_default">&nbsp;</span><span class="p_commentline">#&nbsp;this&nbsp;is&nbsp;a&nbsp;1-tuple</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"create&nbsp;table&nbsp;characters(c)"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">theIter</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">IterChars</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">executemany</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;characters(c)&nbsp;values&nbsp;(?)"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">theIter</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;c&nbsp;from&nbsp;characters"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchall</span><span class="p_operator">()</span>
-</div>
-<p>As generators are iterators, too, here's a much simpler, equivalent example
-using a generator:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">char_generator</span><span class="p_operator">():</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">string</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">for</span><span class="p_default">&nbsp;</span><span class="p_identifier">c</span><span class="p_default">&nbsp;</span><span class="p_word">in</span><span class="p_default">&nbsp;</span><span class="p_identifier">string</span><span class="p_operator">.</span><span class="p_identifier">letters</span><span class="p_operator">[:</span><span class="p_number">26</span><span class="p_operator">]:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">yield</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">c</span><span class="p_operator">,)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"create&nbsp;table&nbsp;characters(c)"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">executemany</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;characters(c)&nbsp;values&nbsp;(?)"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">char_generator</span><span class="p_operator">())</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;c&nbsp;from&nbsp;characters"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchall</span><span class="p_operator">()</span>
-</div>
-<p><em>executemany</em> will only execute a single SQL statement. If you try to
-execute more than one statement with it, it will raise a Warning. Use
-<em>executescript</em> if want to execute multiple SQL statements with one call.</p>
-</li>
-<li><p class="first"><strong>executescript</strong> method</p>
-<div class="code-block">
-<span class="p_operator">.</span><span class="p_identifier">executemany</span><span class="p_operator">(</span><span class="p_identifier">sqlscript</span><span class="p_operator">)</span>
-</div>
-<p>This is a nonstandard convenience method for executing multiple SQL
-statements at once. It issues a COMMIT statement before, then executes the
-SQL script it gets as a parameter.</p>
-<p>The SQL script <tt class="docutils literal"><span class="pre">sqlscript</span></tt> can be a bytestring or a Unicode string.</p>
-<p>Example:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">executescript</span><span class="p_operator">(</span><span class="p_tripledouble">"""<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;create&nbsp;table&nbsp;person(<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstname,<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lastname,<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;age<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;);<br/>
-<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;create&nbsp;table&nbsp;book(<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;title,<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;author,<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;published<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;);<br/>
-<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;insert&nbsp;into&nbsp;book(title,&nbsp;author,&nbsp;published)<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;values&nbsp;(<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'Dirk&nbsp;Gently''s&nbsp;Holistic&nbsp;Detective&nbsp;Agency',<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'Douglas&nbsp;Adams',<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1987<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;);<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;"""</span><span class="p_operator">)</span>
-</div>
-</li>
-<li><p class="first"><strong>interrupt</strong> method</p>
-<p>This method has no arguments. You can call it from a different thread to
-abort any queries that are currently executing on the connection. This can
-be used to let the user abort runaway queries, for example.</p>
-</li>
-<li><p class="first"><strong>rowcount</strong> attribute</p>
-<p>Although pysqlite's Cursors implement this attribute, the database
-engine's own support for the determination of &quot;rows affected&quot;/&quot;rows
-selected&quot; is quirky.</p>
-<p>For <tt class="docutils literal"><span class="pre">SELECT</span></tt> statements, <em>rowcount</em> is always -1 because pysqlite
-cannot determine the number of rows a query produced until all rows
-were fetched.</p>
-<p>For <tt class="docutils literal"><span class="pre">DELETE</span></tt> statements, SQLite reports <em>rowcount</em> as 0 if you make a
-<tt class="docutils literal"><span class="pre">DELETE</span> <span class="pre">FROM</span> <span class="pre">table</span></tt> without any condition.</p>
-<p>For <em>executemany</em> statements, pysqlite sums up the number of
-modifications into <em>rowcount</em>.</p>
-<p>As required by the Python DB API Spec, the <em>rowcount</em> attribute &quot;is -1
-in case no executeXX() has been performed on the cursor or the rowcount
-of the last operation is not determinable by the interface&quot;.</p>
-</li>
-</ul>
-</li>
-</ul>
-<div class="line-block">
-<div class="line"><br /></div>
-</div>
-<hr class="docutils" />
-<div class="line-block">
-<div class="line"><br /></div>
-</div>
-</div>
-</div>
-<div class="section">
-<h1><a id="brief-tutorial" name="brief-tutorial">2. Brief Tutorial</a></h1>
-<p>This brief tutorial aims to get the reader started by demonstrating elementary
-usage of pysqlite. It is not a comprehensive Python Database API tutorial, nor
-is it comprehensive in its coverage of anything else.</p>
-<div class="section">
-<h2><a id="connecting-to-a-database" name="connecting-to-a-database">2.1 Connecting to a Database</a></h2>
-<blockquote>
-<p><strong>Example 1</strong></p>
-<p>Connecting to a database file <em>mydb</em>:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">"mydb"</span><span class="p_operator">)</span>
-</div>
-<p><strong>Example 2</strong></p>
-<p>Creating an in-memory database:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span>
-</div>
-</blockquote>
-</div>
-<div class="section">
-<h2><a id="executing-sql-statements" name="executing-sql-statements">2.2 Executing SQL statements</a></h2>
-<p>For this section, we have a database <em>mydb</em> defined and populated by the
-following SQL code:</p>
-<blockquote>
-<div class="code-block">
-<span class="c_identifier">create</span><span class="c_default">&nbsp;</span><span class="c_identifier">table</span><span class="c_default">&nbsp;</span><span class="c_identifier">people</span><span class="c_default"><br/>
-</span><span class="c_operator">(</span><span class="c_default"><br/>
-&nbsp;&nbsp;</span><span class="c_identifier">name_last</span><span class="c_default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c_identifier">varchar</span><span class="c_operator">(</span><span class="c_number">20</span><span class="c_operator">),</span><span class="c_default"><br/>
-&nbsp;&nbsp;</span><span class="c_identifier">age</span><span class="c_default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c_identifier">integer</span><span class="c_default"><br/>
-</span><span class="c_operator">);</span><span class="c_default"><br/>
-<br/>
-</span><span class="c_identifier">insert</span><span class="c_default">&nbsp;</span><span class="c_identifier">into</span><span class="c_default">&nbsp;</span><span class="c_identifier">people</span><span class="c_default">&nbsp;</span><span class="c_operator">(</span><span class="c_identifier">name_last</span><span class="c_operator">,</span><span class="c_default">&nbsp;</span><span class="c_identifier">age</span><span class="c_operator">)</span><span class="c_default">&nbsp;</span><span class="c_identifier">values</span><span class="c_default">&nbsp;</span><span class="c_operator">(</span><span class="c_character">'Yeltsin'</span><span class="c_operator">,</span><span class="c_default">&nbsp;&nbsp;&nbsp;</span><span class="c_number">72</span><span class="c_operator">);</span><span class="c_default"><br/>
-</span><span class="c_identifier">insert</span><span class="c_default">&nbsp;</span><span class="c_identifier">into</span><span class="c_default">&nbsp;</span><span class="c_identifier">people</span><span class="c_default">&nbsp;</span><span class="c_operator">(</span><span class="c_identifier">name_last</span><span class="c_operator">,</span><span class="c_default">&nbsp;</span><span class="c_identifier">age</span><span class="c_operator">)</span><span class="c_default">&nbsp;</span><span class="c_identifier">values</span><span class="c_default">&nbsp;</span><span class="c_operator">(</span><span class="c_character">'Putin'</span><span class="c_operator">,</span><span class="c_default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c_number">51</span><span class="c_operator">);</span>
-</div>
-</blockquote>
-<p><em>Example 1</em></p>
-<p>This example shows the simplest way to print the entire contents of the <tt class="docutils literal"><span class="pre">people</span></tt> table:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Create&nbsp;a&nbsp;connection&nbsp;to&nbsp;the&nbsp;database&nbsp;file&nbsp;"mydb":</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">"mydb"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Get&nbsp;a&nbsp;Cursor&nbsp;object&nbsp;that&nbsp;operates&nbsp;in&nbsp;the&nbsp;context&nbsp;of&nbsp;Connection&nbsp;con:</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Execute&nbsp;the&nbsp;SELECT&nbsp;statement:</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;*&nbsp;from&nbsp;people&nbsp;order&nbsp;by&nbsp;age"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Retrieve&nbsp;all&nbsp;rows&nbsp;as&nbsp;a&nbsp;sequence&nbsp;and&nbsp;print&nbsp;that&nbsp;sequence:</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchall</span><span class="p_operator">()</span>
-</div>
-<p>Sample output:</p>
-<pre class="literal-block">
-[(u'Putin', 51), (u'Yeltsin', 72)]
-</pre>
-<p><em>Example 2</em></p>
-<p>Here's another trivial example that demonstrates various ways of fetching a
-single row at a time from a SELECT-cursor:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">"mydb"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">SELECT</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_string">"select&nbsp;name_last,&nbsp;age&nbsp;from&nbsp;people&nbsp;order&nbsp;by&nbsp;age,&nbsp;name_last"</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;1.&nbsp;Iterate&nbsp;over&nbsp;the&nbsp;rows&nbsp;available&nbsp;from&nbsp;the&nbsp;cursor,&nbsp;unpacking&nbsp;the</span><span class="p_default"><br/>
-</span><span class="p_commentline">#&nbsp;resulting&nbsp;sequences&nbsp;to&nbsp;yield&nbsp;their&nbsp;elements&nbsp;(name_last,&nbsp;age):</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_identifier">SELECT</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_word">for</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">name_last</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">age</span><span class="p_operator">)</span><span class="p_default">&nbsp;</span><span class="p_word">in</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_character">'%s&nbsp;is&nbsp;%d&nbsp;years&nbsp;old.'</span><span class="p_default">&nbsp;</span><span class="p_operator">%</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">name_last</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">age</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;2.&nbsp;Equivalently:</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_identifier">SELECT</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_word">for</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_default">&nbsp;</span><span class="p_word">in</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_character">'%s&nbsp;is&nbsp;%d&nbsp;years&nbsp;old.'</span><span class="p_default">&nbsp;</span><span class="p_operator">%</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">],</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">1</span><span class="p_operator">])</span>
-</div>
-<p>Sample output:</p>
-<pre class="literal-block">
-Putin is 51 years old.
-Yeltsin is 72 years old.
-Putin is 51 years old.
-Yeltsin is 72 years old.
-</pre>
-<p><em>Example 3</em></p>
-<p>The following program is a simplistic table printer (applied in this example to
-people)</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">FIELD_MAX_WIDTH</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_number">20</span><span class="p_default"><br/>
-</span><span class="p_identifier">TABLE_NAME</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_character">'people'</span><span class="p_default"><br/>
-</span><span class="p_identifier">SELECT</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_character">'select&nbsp;*&nbsp;from&nbsp;%s&nbsp;order&nbsp;by&nbsp;age,&nbsp;name_last'</span><span class="p_default">&nbsp;</span><span class="p_operator">%</span><span class="p_default">&nbsp;</span><span class="p_identifier">TABLE_NAME</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">"mydb"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_identifier">SELECT</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Print&nbsp;a&nbsp;header.</span><span class="p_default"><br/>
-</span><span class="p_word">for</span><span class="p_default">&nbsp;</span><span class="p_identifier">fieldDesc</span><span class="p_default">&nbsp;</span><span class="p_word">in</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">description</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">fieldDesc</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">].</span><span class="p_identifier">ljust</span><span class="p_operator">(</span><span class="p_identifier">FIELD_MAX_WIDTH</span><span class="p_operator">)</span><span class="p_default">&nbsp;</span><span class="p_operator">,</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_commentline">#&nbsp;Finish&nbsp;the&nbsp;header&nbsp;with&nbsp;a&nbsp;newline.</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_character">'-'</span><span class="p_default">&nbsp;</span><span class="p_operator">*</span><span class="p_default">&nbsp;</span><span class="p_number">78</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;For&nbsp;each&nbsp;row,&nbsp;print&nbsp;the&nbsp;value&nbsp;of&nbsp;each&nbsp;field&nbsp;left-justified&nbsp;within</span><span class="p_default"><br/>
-</span><span class="p_commentline">#&nbsp;the&nbsp;maximum&nbsp;possible&nbsp;width&nbsp;of&nbsp;that&nbsp;field.</span><span class="p_default"><br/>
-</span><span class="p_identifier">fieldIndices</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">range</span><span class="p_operator">(</span><span class="p_identifier">len</span><span class="p_operator">(</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">description</span><span class="p_operator">))</span><span class="p_default"><br/>
-</span><span class="p_word">for</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_default">&nbsp;</span><span class="p_word">in</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">for</span><span class="p_default">&nbsp;</span><span class="p_identifier">fieldIndex</span><span class="p_default">&nbsp;</span><span class="p_word">in</span><span class="p_default">&nbsp;</span><span class="p_identifier">fieldIndices</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">fieldValue</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">str</span><span class="p_operator">(</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_identifier">fieldIndex</span><span class="p_operator">])</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">fieldValue</span><span class="p_operator">.</span><span class="p_identifier">ljust</span><span class="p_operator">(</span><span class="p_identifier">FIELD_MAX_WIDTH</span><span class="p_operator">)</span><span class="p_default">&nbsp;</span><span class="p_operator">,</span><span class="p_default"><br/>
-<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_commentline">#&nbsp;Finish&nbsp;the&nbsp;row&nbsp;with&nbsp;a&nbsp;newline.</span>
-</div>
-<p>Sample output:</p>
-<pre class="literal-block">
-name_last            age
-------------------------------------------------------------------------------
-Putin                51
-Yeltsin              72
-</pre>
-<p><em>Example 4</em></p>
-<p>Let's insert more people into the people table:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">"mydb"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">newPeople</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_operator">(</span><span class="p_character">'Lebed'</span><span class="p_default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_number">53</span><span class="p_operator">),</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_operator">(</span><span class="p_character">'Zhirinovsky'</span><span class="p_default">&nbsp;</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_number">57</span><span class="p_operator">),</span><span class="p_default"><br/>
-&nbsp;&nbsp;</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">for</span><span class="p_default">&nbsp;</span><span class="p_identifier">person</span><span class="p_default">&nbsp;</span><span class="p_word">in</span><span class="p_default">&nbsp;</span><span class="p_identifier">newPeople</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;people&nbsp;(name_last,&nbsp;age)&nbsp;values&nbsp;(?,&nbsp;?)"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">person</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;The&nbsp;changes&nbsp;will&nbsp;not&nbsp;be&nbsp;saved&nbsp;unless&nbsp;the&nbsp;transaction&nbsp;is&nbsp;committed&nbsp;explicitly:</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">commit</span><span class="p_operator">()</span>
-</div>
-<p>Note the use of a parameterized SQL statement above. When dealing with
-repetitive statements, this is much faster and less error-prone than assembling
-each SQL statement manually.</p>
-<p>It's also worth noting that in the example above, the code:</p>
-<p>It's also worth noting that in the example above, the code:</p>
-<div class="code-block">
-<span class="p_word">for</span><span class="p_default">&nbsp;</span><span class="p_identifier">person</span><span class="p_default">&nbsp;</span><span class="p_word">in</span><span class="p_default">&nbsp;</span><span class="p_identifier">newPeople</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;people&nbsp;(name_last,&nbsp;age)&nbsp;values&nbsp;(?,&nbsp;?)"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">person</span><span class="p_operator">)</span>
-</div>
-<p>could be rewritten as:</p>
-<div class="code-block">
-<span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">executemany</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;people&nbsp;(name_last,&nbsp;age)&nbsp;values&nbsp;(?,&nbsp;?)"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">newPeople</span><span class="p_operator">)</span>
-</div>
-<p>After running Example 4, the table printer from Example 3 would print:</p>
-<pre class="literal-block">
-name_last            age
-------------------------------------------------------------------------------
-Putin                51
-Lebed                53
-Zhirinovsky          57
-Yeltsin              72
-</pre>
-<div class="line-block">
-<div class="line"><br /></div>
-</div>
-<hr class="docutils" />
-<div class="line-block">
-<div class="line"><br /></div>
-</div>
-</div>
-</div>
-<div class="section">
-<h1><a id="native-database-engine-features-and-extensions-beyond-the-python-db-api" name="native-database-engine-features-and-extensions-beyond-the-python-db-api">3. Native Database Engine Features and Extensions Beyond the Python DB API</a></h1>
-<div class="section">
-<h2><a id="creating-user-defined-functions" name="creating-user-defined-functions">3.1 Creating user-defined functions</a></h2>
-<p>SQLite supports user-defined functions.  Using pysqlite, you can create new
-functions with the connection's <strong>create_function</strong> method:</p>
-<blockquote>
-<div class="code-block">
-<span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">create_function</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">name</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">numparams</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">func</span><span class="p_operator">)</span>
-</div>
-<dl class="docutils">
-<dt><em>name</em></dt>
-<dd>the name of your function in SQL</dd>
-<dt><em>numparams</em></dt>
-<dd>the number of parameters your function accepts, -1 if it accepts any
-number of parameters</dd>
-<dt><em>func</em></dt>
-<dd>the Python function</dd>
-</dl>
-<p>The function can return any of pysqlite's supported SQLite types: unicode,
-str, int, long, float, buffer and None.  Any exception in the user-defined
-function leads to the SQL statement executed being aborted.</p>
-<p>Example:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">md5</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">md5sum</span><span class="p_operator">(</span><span class="p_identifier">t</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_identifier">md5</span><span class="p_operator">.</span><span class="p_identifier">md5</span><span class="p_operator">(</span><span class="p_identifier">t</span><span class="p_operator">).</span><span class="p_identifier">hexdigest</span><span class="p_operator">()</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">create_function</span><span class="p_operator">(</span><span class="p_string">"md5"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_number">1</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">md5sum</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;md5(?)"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_string">"foo"</span><span class="p_operator">,))</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()[</span><span class="p_number">0</span><span class="p_operator">]</span>
-</div>
-</blockquote>
-</div>
-<div class="section">
-<h2><a id="creating-user-defined-aggregates" name="creating-user-defined-aggregates">3.2 Creating user-defined aggregates</a></h2>
-<p>SQLite supports user-defined aggregate functions. Using pysqlite, you can
-create new aggregate functions with the connection's <em>create_aggregate</em> method.</p>
-<blockquote>
-<div class="code-block">
-<span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">create_aggregate</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">name</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">numparams</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">aggregate_class</span><span class="p_operator">)</span>
-</div>
-<p>The aggregate class must implement a <em>step</em> method, which accepts the
-number of parameters defined in <em>create_aggregate</em>, and a <em>finalize</em>
-method which will return the final result of the aggregate.</p>
-<p>The <em>finalize</em> method can return any of pysqlite's supported SQLite types:
-unicode, str, int, long, float, buffer and None. Any exception in the
-aggregate's <em>__init__</em>, <em>step</em> or <em>finalize</em> methods lead to the SQL
-statement executed being aborted.</p>
-<p>Example:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">class</span><span class="p_default">&nbsp;</span><span class="p_classname">MySum</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">__init__</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">count</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_number">0</span><span class="p_default"><br/>
-<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">step</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">value</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">count</span><span class="p_default">&nbsp;</span><span class="p_operator">+=</span><span class="p_default">&nbsp;</span><span class="p_identifier">value</span><span class="p_default"><br/>
-<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">finalize</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">count</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">create_aggregate</span><span class="p_operator">(</span><span class="p_string">"mysum"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_number">1</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">MySum</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"create&nbsp;table&nbsp;test(i)"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;test(i)&nbsp;values&nbsp;(1)"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;test(i)&nbsp;values&nbsp;(2)"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;mysum(i)&nbsp;from&nbsp;test"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()[</span><span class="p_number">0</span><span class="p_operator">]</span>
-</div>
-</blockquote>
-</div>
-<div class="section">
-<h2><a id="creating-and-using-collations" name="creating-and-using-collations">3.3 Creating and using collations</a></h2>
-<blockquote>
-<div class="code-block">
-<span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">create_collation</span><span class="p_operator">(</span><span class="p_identifier">name</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">callable</span><span class="p_operator">)</span>
-</div>
-</blockquote>
-<p>Creates a collation with the specified name and callable. The callable will be
-passed two string arguments. It should return -1 if the first is less than the
-second, 0 if they are equal and 1 and if the first is greater than the second.
-Note that this controls sorting (ORDER BY in SQL) so your comparisons don't
-affect other SQL operations. Read more about SQLite's handling of collations.
-(This calls sqlite3_create_collation.) If there is an error in your Python code
-then 0 (ie items are equal) is returned.</p>
-<p>Note that the callable will get its parameters as Python bytestrings, which
-will normally be encoded in UTF-8.</p>
-<p>The following example shows a custom collation that sorts &quot;the wrong way&quot;:</p>
-<blockquote>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">collate_reverse</span><span class="p_operator">(</span><span class="p_identifier">string1</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">string2</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_operator">-</span><span class="p_identifier">cmp</span><span class="p_operator">(</span><span class="p_identifier">string1</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">string2</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">create_collation</span><span class="p_operator">(</span><span class="p_string">"reverse"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">collate_reverse</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"create&nbsp;table&nbsp;test(x)"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">executemany</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;test(x)&nbsp;values&nbsp;(?)"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">[(</span><span class="p_string">"a"</span><span class="p_operator">,),</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_string">"b"</span><span class="p_operator">,)])</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;x&nbsp;from&nbsp;test&nbsp;order&nbsp;by&nbsp;x&nbsp;collate&nbsp;reverse"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_word">for</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_default">&nbsp;</span><span class="p_word">in</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">close</span><span class="p_operator">()</span>
-</div>
-</blockquote>
-<p>To remove a collation, call <cite>create_collation</cite> with None as callable:</p>
-<blockquote>
-<div class="code-block">
-<span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">create_collation</span><span class="p_operator">(</span><span class="p_string">"reverse"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_word">None</span><span class="p_operator">)</span>
-</div>
-</blockquote>
-</div>
-<div class="section">
-<h2><a id="checking-for-complete-statements" name="checking-for-complete-statements">3.4 Checking for complete statements</a></h2>
-<p>The module-level function <em>complete_statement(sql)</em> can be used to check if a
-string contains a complete SQL statement or is still incomplete. The given
-string could still contain invalid SQL, but be parsable as a &quot;complete&quot;
-statement!</p>
-<p>This can be used to build a shell for SQLite, like in the following example:</p>
-<blockquote>
-<div class="code-block">
-<span class="p_commentline">#&nbsp;A&nbsp;minimal&nbsp;SQLite&nbsp;shell&nbsp;for&nbsp;experiments</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">isolation_level</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_word">None</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">buffer</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_string">""</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_string">"Enter&nbsp;your&nbsp;SQL&nbsp;commands&nbsp;to&nbsp;execute&nbsp;in&nbsp;SQLite."</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_string">"Enter&nbsp;a&nbsp;blank&nbsp;line&nbsp;to&nbsp;exit."</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">while</span><span class="p_default">&nbsp;</span><span class="p_identifier">True</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">line</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">raw_input</span><span class="p_operator">()</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">if</span><span class="p_default">&nbsp;</span><span class="p_identifier">line</span><span class="p_default">&nbsp;</span><span class="p_operator">==</span><span class="p_default">&nbsp;</span><span class="p_string">""</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">break</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">buffer</span><span class="p_default">&nbsp;</span><span class="p_operator">+=</span><span class="p_default">&nbsp;</span><span class="p_identifier">line</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">if</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">complete_statement</span><span class="p_operator">(</span><span class="p_identifier">buffer</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">try</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">buffer</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">buffer</span><span class="p_operator">.</span><span class="p_identifier">strip</span><span class="p_operator">()</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_identifier">buffer</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">if</span><span class="p_default">&nbsp;</span><span class="p_identifier">buffer</span><span class="p_operator">.</span><span class="p_identifier">lstrip</span><span class="p_operator">().</span><span class="p_identifier">upper</span><span class="p_operator">().</span><span class="p_identifier">startswith</span><span class="p_operator">(</span><span class="p_string">"SELECT"</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchall</span><span class="p_operator">()</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">except</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">Error</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">e</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_string">"An&nbsp;error&nbsp;occurred:"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">e</span><span class="p_operator">.</span><span class="p_identifier">args</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">]</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">buffer</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_string">""</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">close</span><span class="p_operator">()</span>
-</div>
-</blockquote>
-</div>
-<div class="section">
-<h2><a id="enabling-sqlite-s-shared-cache" name="enabling-sqlite-s-shared-cache">3.5 Enabling SQLite's shared cache</a></h2>
-<p>To enable SQLite's shared cache for the calling thread, call the function
-<em>enable_shared_cache</em>.</p>
-<blockquote>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;The&nbsp;shared&nbsp;cache&nbsp;is&nbsp;only&nbsp;available&nbsp;in&nbsp;SQLite&nbsp;versions&nbsp;3.3.3&nbsp;or&nbsp;later</span><span class="p_default"><br/>
-</span><span class="p_commentline">#&nbsp;See&nbsp;the&nbsp;SQLite&nbsp;documentaton&nbsp;for&nbsp;details.</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">enable_shared_cache</span><span class="p_operator">(</span><span class="p_identifier">True</span><span class="p_operator">)</span>
-</div>
-</blockquote>
-</div>
-<div class="section">
-<h2><a id="setting-an-authorizer-callback" name="setting-an-authorizer-callback">3.6 Setting an authorizer callback</a></h2>
-<p>You can set an authorizer callback if you want to restrict what your users can
-do with the database. This is mostly useful if you accept arbitrary SQL from
-users and want to execute it safely. See the relevant section in the SQL
-documentation for details:
-<a class="reference" href="http://sqlite.org/capi3ref.html#sqlite3_set_authorizer">http://sqlite.org/capi3ref.html#sqlite3_set_authorizer</a></p>
-<p>All necessary constants like SQLITE_OK, SQLITE_DENY, SQLITE_IGNORE,
-SQLITE_SELECT, SQLITE_CREATE_INDEX and all other authorizer-related constants
-are available through the dbapi2 module.</p>
-<p>Here's an example that demonstrates the usage of this function:</p>
-<blockquote>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">authorizer_callback</span><span class="p_operator">(</span><span class="p_identifier">action</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">arg1</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">arg2</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbname</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">source</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">if</span><span class="p_default">&nbsp;</span><span class="p_identifier">action</span><span class="p_default">&nbsp;</span><span class="p_operator">!=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">SQLITE_SELECT</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">SQLITE_DENY</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">if</span><span class="p_default">&nbsp;</span><span class="p_identifier">arg1</span><span class="p_default">&nbsp;</span><span class="p_operator">==</span><span class="p_default">&nbsp;</span><span class="p_string">"private_table"</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">SQLITE_DENY</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">SQLITE_OK</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">executescript</span><span class="p_operator">(</span><span class="p_tripledouble">"""<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;create&nbsp;table&nbsp;public_table(c1,&nbsp;c2);<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;create&nbsp;table&nbsp;private_table(c1,&nbsp;c2);<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;"""</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">set_authorizer</span><span class="p_operator">(</span><span class="p_identifier">authorizer_callback</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">try</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;*&nbsp;from&nbsp;private_table"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_word">except</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">DatabaseError</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">e</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_string">"SELECT&nbsp;FROM&nbsp;private_table&nbsp;=&gt;"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">e</span><span class="p_operator">.</span><span class="p_identifier">args</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">]</span><span class="p_default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_commentline">#&nbsp;access&nbsp;...&nbsp;prohibited</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">try</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;public_table(c1,&nbsp;c2)&nbsp;values&nbsp;(1,&nbsp;2)"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_word">except</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">DatabaseError</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">e</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_string">"DML&nbsp;command&nbsp;=&gt;"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">e</span><span class="p_operator">.</span><span class="p_identifier">args</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">]</span><span class="p_default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_commentline">#&nbsp;access&nbsp;...&nbsp;prohibited</span><span class="p_default"><br/>
-</span>
-</div>
-</blockquote>
-</div>
-<div class="section">
-<h2><a id="setting-a-progress-handler" name="setting-a-progress-handler">3.7 Setting a progress handler</a></h2>
-<p>If you want to get called by SQLite during long-running operations, you can set
-a progress handler. An example use for this is to keep a GUI updated during a
-long-running query.</p>
-<blockquote>
-<div class="code-block">
-<span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">set_progress_handler</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">handler</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">n</span><span class="p_operator">)</span>
-</div>
-</blockquote>
-<p>The progress handler will be called every n SQLite virtual machine opcodes. If
-handler returns a nonzero value, the query is aborted with an OperationalError.</p>
-<p>Here's an example that demonstrates the usage of this function:</p>
-<blockquote>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">progress</span><span class="p_operator">():</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_string">"Query&nbsp;still&nbsp;executing.&nbsp;Please&nbsp;wait&nbsp;..."</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"create&nbsp;table&nbsp;test(x)"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Let's&nbsp;create&nbsp;some&nbsp;data</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">executemany</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;test(x)&nbsp;values&nbsp;(?)"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">[(</span><span class="p_identifier">x</span><span class="p_operator">,)</span><span class="p_default">&nbsp;</span><span class="p_word">for</span><span class="p_default">&nbsp;</span><span class="p_identifier">x</span><span class="p_default">&nbsp;</span><span class="p_word">in</span><span class="p_default">&nbsp;</span><span class="p_identifier">xrange</span><span class="p_operator">(</span><span class="p_number">300</span><span class="p_operator">)])</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;A&nbsp;progress&nbsp;handler,&nbsp;executed&nbsp;every&nbsp;10&nbsp;million&nbsp;opcodes</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">set_progress_handler</span><span class="p_operator">(</span><span class="p_identifier">progress</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_number">10000000</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;A&nbsp;particularly&nbsp;long-running&nbsp;query</span><span class="p_default"><br/>
-</span><span class="p_identifier">killer_stament</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_tripledouble">"""<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;count(*)&nbsp;from&nbsp;(<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;t1.x&nbsp;from&nbsp;test&nbsp;t1,&nbsp;test&nbsp;t2,&nbsp;test&nbsp;t3<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;)<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;"""</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_identifier">killer_stament</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_string">"-"</span><span class="p_default">&nbsp;</span><span class="p_operator">*</span><span class="p_default">&nbsp;</span><span class="p_number">50</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Clear&nbsp;the&nbsp;progress&nbsp;handler</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">set_progress_handler</span><span class="p_operator">(</span><span class="p_word">None</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_number">0</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_identifier">killer_stament</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span>
-</div>
-</blockquote>
-</div>
-<div class="section">
-<h2><a id="using-the-connection-as-a-context-manager" name="using-the-connection-as-a-context-manager">3.8 Using the connection as a context manager</a></h2>
-<p>With Python 2.5 or higher, pysqlite's connection objects can be used as context
-managers that automatically commit or rollback transactions.  In the event of
-an exception, the transaction is rolled back; otherwise, the transaction is
-committed:</p>
-<blockquote>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">__future__</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">with_statement</span><span class="p_default"><br/>
-</span><span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"create&nbsp;table&nbsp;person&nbsp;(id&nbsp;integer&nbsp;primary&nbsp;key,&nbsp;firstname&nbsp;varchar&nbsp;unique)"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Successful,&nbsp;con.commit()&nbsp;is&nbsp;called&nbsp;automatically&nbsp;afterwards</span><span class="p_default"><br/>
-</span><span class="p_identifier">with</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;person(firstname)&nbsp;values&nbsp;(?)"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_string">"Joe"</span><span class="p_operator">,))</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;con.rollback()&nbsp;is&nbsp;called&nbsp;after&nbsp;the&nbsp;with&nbsp;block&nbsp;finishes&nbsp;with&nbsp;an&nbsp;exception,&nbsp;the</span><span class="p_default"><br/>
-</span><span class="p_commentline">#&nbsp;exception&nbsp;is&nbsp;still&nbsp;raised&nbsp;and&nbsp;must&nbsp;be&nbsp;catched</span><span class="p_default"><br/>
-</span><span class="p_word">try</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">with</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;person(firstname)&nbsp;values&nbsp;(?)"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_string">"Joe"</span><span class="p_operator">,))</span><span class="p_default"><br/>
-</span><span class="p_word">except</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">IntegrityError</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_string">"couldn't&nbsp;add&nbsp;Joe&nbsp;twice"</span><span class="p_default"><br/>
-<br/>
-</span>
-</div>
-</blockquote>
-</div>
-</div>
-<div class="section">
-<h1><a id="sqlite-and-python-types" name="sqlite-and-python-types">4. SQLite and Python types</a></h1>
-<div class="section">
-<h2><a id="id1" name="id1">4.1 Introduction</a></h2>
-<p><a class="reference" href="http://sqlite.org/datatype3.html">http://sqlite.org/datatype3.html</a></p>
-<p>SQLite natively supports the following types: NULL, INTEGER, REAL, TEXT, BLOB.</p>
-<p>The following Python types can thus be sent to SQLite without any problem:</p>
-<table border="1" class="docutils">
-<colgroup>
-<col width="67%" />
-<col width="33%" />
-</colgroup>
-<thead valign="bottom">
-<tr><th class="head">Python type</th>
-<th class="head">SQLite type</th>
-</tr>
-</thead>
-<tbody valign="top">
-<tr><td>NoneType</td>
-<td>NULL</td>
-</tr>
-<tr><td>int</td>
-<td>INTEGER</td>
-</tr>
-<tr><td>long</td>
-<td>INTEGER</td>
-</tr>
-<tr><td>float</td>
-<td>REAL</td>
-</tr>
-<tr><td>str (utf-8 encoded)</td>
-<td>TEXT</td>
-</tr>
-<tr><td>unicode</td>
-<td>TEXT</td>
-</tr>
-<tr><td>buffer</td>
-<td>BLOB</td>
-</tr>
-</tbody>
-</table>
-<p>This is how SQLite types are converted to Python types by default:</p>
-<table border="1" class="docutils">
-<colgroup>
-<col width="27%" />
-<col width="73%" />
-</colgroup>
-<thead valign="bottom">
-<tr><th class="head">SQLite type</th>
-<th class="head">Python type</th>
-</tr>
-</thead>
-<tbody valign="top">
-<tr><td>NULL</td>
-<td>NoneType</td>
-</tr>
-<tr><td>INTEGER</td>
-<td>int or long, depending on size</td>
-</tr>
-<tr><td>REAL</td>
-<td>float</td>
-</tr>
-<tr><td>TEXT</td>
-<td>unicode</td>
-</tr>
-<tr><td>BLOB</td>
-<td>buffer</td>
-</tr>
-</tbody>
-</table>
-<p>pysqlite's type system is extensible in both ways: you can store additional
-Python types in a SQLite database via object adaptation, and you can let
-pysqlite convert SQLite types to different Python types via pysqlite's
-converters.</p>
-</div>
-<div class="section">
-<h2><a id="using-adapters-to-store-additional-python-types-in-sqlite-databases" name="using-adapters-to-store-additional-python-types-in-sqlite-databases">4.2 Using adapters to store additional Python types in SQLite databases</a></h2>
-<p>Like described before, SQLite supports only a limited set of types natively. To
-use other Python types with SQLite, you must <em>adapt</em> them to one of pysqlite's
-supported types for SQLite. So, one of NoneType, int, long, float, str,
-unicode, buffer.</p>
-<p>pysqlite uses the Python object adaptation, like described in PEP 246 for this.
-The protocol to use is <tt class="docutils literal"><span class="pre">PrepareProtocol</span></tt>.</p>
-<p>There are two ways to enable pysqlite to adapt a custom Python type to one of
-the supported ones.</p>
-</div>
-<div class="section">
-<h2><a id="letting-your-object-adapt-itself" name="letting-your-object-adapt-itself">4.2.1 Letting your object adapt itself</a></h2>
-<p>This is a good approach if you write the class yourself. Let's suppose you have
-a class like this:</p>
-<blockquote>
-<div class="code-block">
-<span class="p_word">class</span><span class="p_default">&nbsp;</span><span class="p_classname">Point</span><span class="p_operator">(</span><span class="p_identifier">object</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">__init__</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">y</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">y</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">y</span>
-</div>
-</blockquote>
-<p>Now you want to store the point in a single SQLite column. You'll have to
-choose one of the supported types first that you use to represent the point in.
-Let's just use str and separate the coordinates using a semicolon. Then you
-need to give your class a method <tt class="docutils literal"><span class="pre">__conform__(self,</span> <span class="pre">protocol)</span></tt> which must
-return the converted value. The parameter <tt class="docutils literal"><span class="pre">protocol</span></tt> will be
-<tt class="docutils literal"><span class="pre">PrepareProtocol</span></tt>.</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">class</span><span class="p_default">&nbsp;</span><span class="p_classname">Point</span><span class="p_operator">(</span><span class="p_identifier">object</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">__init__</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">y</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">y</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">y</span><span class="p_default"><br/>
-<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">__conform__</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">protocol</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">if</span><span class="p_default">&nbsp;</span><span class="p_identifier">protocol</span><span class="p_default">&nbsp;</span><span class="p_word">is</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">PrepareProtocol</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_string">"%f;%f"</span><span class="p_default">&nbsp;</span><span class="p_operator">%</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">y</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">p</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">Point</span><span class="p_operator">(</span><span class="p_number">4.0</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">-</span><span class="p_number">3.2</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;?"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">p</span><span class="p_operator">,))</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()[</span><span class="p_number">0</span><span class="p_operator">]</span>
-</div>
-</div>
-<div class="section">
-<h2><a id="registering-an-adapter-callable" name="registering-an-adapter-callable">4.2.2 Registering an adapter callable</a></h2>
-<p>The other possibility is to create a function that converts the type to the
-string representation and register the function with <tt class="docutils literal"><span class="pre">register_adapter</span></tt>.</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">class</span><span class="p_default">&nbsp;</span><span class="p_classname">Point</span><span class="p_operator">(</span><span class="p_identifier">object</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">__init__</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">y</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">y</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">y</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">adapt_point</span><span class="p_operator">(</span><span class="p_identifier">point</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_string">"%f;%f"</span><span class="p_default">&nbsp;</span><span class="p_operator">%</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">point</span><span class="p_operator">.</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">point</span><span class="p_operator">.</span><span class="p_identifier">y</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">register_adapter</span><span class="p_operator">(</span><span class="p_identifier">Point</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">adapt_point</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">p</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">Point</span><span class="p_operator">(</span><span class="p_number">4.0</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">-</span><span class="p_number">3.2</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;?"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">p</span><span class="p_operator">,))</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()[</span><span class="p_number">0</span><span class="p_operator">]</span>
-</div>
-<p>The type/class to adapt must be a new-style class, i. e. it must have
-<tt class="docutils literal"><span class="pre">object</span></tt> as one of its bases!!!</p>
-<p>pysqlite has two default adapters for Python's builtin <em>date</em> and <em>datetime</em>
-types. Now let's suppose we want to store <em>datetime</em> objects not in ISO
-representation, but as Unix timestamp.</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">datetime</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">time</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">adapt_datetime</span><span class="p_operator">(</span><span class="p_identifier">ts</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_identifier">time</span><span class="p_operator">.</span><span class="p_identifier">mktime</span><span class="p_operator">(</span><span class="p_identifier">ts</span><span class="p_operator">.</span><span class="p_identifier">timetuple</span><span class="p_operator">())</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">register_adapter</span><span class="p_operator">(</span><span class="p_identifier">datetime</span><span class="p_operator">.</span><span class="p_identifier">datetime</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">adapt_datetime</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">now</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">datetime</span><span class="p_operator">.</span><span class="p_identifier">datetime</span><span class="p_operator">.</span><span class="p_identifier">now</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;?"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">now</span><span class="p_operator">,))</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()[</span><span class="p_number">0</span><span class="p_operator">]</span>
-</div>
-</div>
-<div class="section">
-<h2><a id="converting-sqlite-values-to-custom-python-types" name="converting-sqlite-values-to-custom-python-types">4.3 Converting SQLite values to custom Python types</a></h2>
-<p>Now that's all nice and dandy that you can send custom Python types to SQLite.
-But to make it really useful we need to make the Python to SQLite to Python
-roundtrip work.</p>
-<p>Enter pysqlite converters.</p>
-<p>Let's go back to the Point class. We stored the x and y coordinates separated
-via semicolons as strings in SQLite.</p>
-<p>Let's first define a converter function that accepts the string as a parameter and constructs a Point object from it.</p>
-<p>!!! Note that converter functions <em>always</em> get called with a string, no matter
-under which data type you sent the value to SQLite !!!</p>
-<blockquote>
-<div class="code-block">
-<span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">convert_point</span><span class="p_operator">(</span><span class="p_identifier">s</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">y</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">map</span><span class="p_operator">(</span><span class="p_identifier">float</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">s</span><span class="p_operator">.</span><span class="p_identifier">split</span><span class="p_operator">(</span><span class="p_string">";"</span><span class="p_operator">))</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_identifier">Point</span><span class="p_operator">(</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">y</span><span class="p_operator">)</span>
-</div>
-</blockquote>
-<p>Now you need to make pysqlite know that what you select from the database is
-actually a point. There are two ways of doing this:</p>
-<blockquote>
-<ul class="simple">
-<li>Implicitly via the declared type</li>
-<li>Explicitly via the column name</li>
-</ul>
-</blockquote>
-<p>Both ways are described in section <a class="reference" href="#extensions-and-caveats">1.4 Extensions and Caveats</a> in the
-paragraphs describing the connect function, and specifically the meaning of the
-<em>detect_types</em> parameter.</p>
-<p>The following example illustrates both ways.</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">class</span><span class="p_default">&nbsp;</span><span class="p_classname">Point</span><span class="p_operator">(</span><span class="p_identifier">object</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">__init__</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">y</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">y</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">y</span><span class="p_default"><br/>
-<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">__repr__</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_string">"(%f;%f)"</span><span class="p_default">&nbsp;</span><span class="p_operator">%</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">y</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">adapt_point</span><span class="p_operator">(</span><span class="p_identifier">point</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_string">"%f;%f"</span><span class="p_default">&nbsp;</span><span class="p_operator">%</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">point</span><span class="p_operator">.</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">point</span><span class="p_operator">.</span><span class="p_identifier">y</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_word">def</span><span class="p_default">&nbsp;</span><span class="p_defname">convert_point</span><span class="p_operator">(</span><span class="p_identifier">s</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">y</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">map</span><span class="p_operator">(</span><span class="p_identifier">float</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">s</span><span class="p_operator">.</span><span class="p_identifier">split</span><span class="p_operator">(</span><span class="p_string">";"</span><span class="p_operator">))</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">return</span><span class="p_default">&nbsp;</span><span class="p_identifier">Point</span><span class="p_operator">(</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">y</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Register&nbsp;the&nbsp;adapter</span><span class="p_default"><br/>
-</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">register_adapter</span><span class="p_operator">(</span><span class="p_identifier">Point</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">adapt_point</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Register&nbsp;the&nbsp;converter</span><span class="p_default"><br/>
-</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">register_converter</span><span class="p_operator">(</span><span class="p_string">"point"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">convert_point</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">p</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">Point</span><span class="p_operator">(</span><span class="p_number">4.0</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">-</span><span class="p_number">3.2</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentblock">#########################</span><span class="p_default"><br/>
-</span><span class="p_commentline">#&nbsp;1)&nbsp;Using&nbsp;declared&nbsp;types</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">detect_types</span><span class="p_operator">=</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">PARSE_DECLTYPES</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"create&nbsp;table&nbsp;test(p&nbsp;point)"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;test(p)&nbsp;values&nbsp;(?)"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">p</span><span class="p_operator">,))</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;p&nbsp;from&nbsp;test"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_string">"with&nbsp;declared&nbsp;types:"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()[</span><span class="p_number">0</span><span class="p_operator">]</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">close</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">close</span><span class="p_operator">()</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentblock">#######################</span><span class="p_default"><br/>
-</span><span class="p_commentline">#&nbsp;1)&nbsp;Using&nbsp;column&nbsp;names</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">detect_types</span><span class="p_operator">=</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">PARSE_COLNAMES</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"create&nbsp;table&nbsp;test(p)"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;test(p)&nbsp;values&nbsp;(?)"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">p</span><span class="p_operator">,))</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_character">'select&nbsp;p&nbsp;as&nbsp;"p&nbsp;[point]"&nbsp;from&nbsp;test'</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_string">"with&nbsp;column&nbsp;names:"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()[</span><span class="p_number">0</span><span class="p_operator">]</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">close</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">close</span><span class="p_operator">()</span>
-</div>
-</div>
-<div class="section">
-<h2><a id="default-pysqlite-adapters-and-converters" name="default-pysqlite-adapters-and-converters">4.4 Default pysqlite adapters and converters</a></h2>
-<p>pysqlite has default adapters for the date and datetime types in the datetime
-module. They will be sent as ISO dates/ISO timestamps to SQLite.</p>
-<p>pysqlite has default converters registered under the name &quot;date&quot; for
-datetime.date and under the name &quot;timestamp&quot; for datetime.datetime.</p>
-<p>This way, you can use date/timestamps from pysqlite without any additional
-fiddling in most cases. The format of the adapters is also compatible with the
-experimental SQLite date/time functions.</p>
-<p>The following example demonstrates this.</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">datetime</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">detect_types</span><span class="p_operator">=</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">PARSE_DECLTYPES</span><span class="p_operator">|</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">PARSE_COLNAMES</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"create&nbsp;table&nbsp;test(d&nbsp;date,&nbsp;ts&nbsp;timestamp)"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">today</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">datetime</span><span class="p_operator">.</span><span class="p_identifier">date</span><span class="p_operator">.</span><span class="p_identifier">today</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">now</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">datetime</span><span class="p_operator">.</span><span class="p_identifier">datetime</span><span class="p_operator">.</span><span class="p_identifier">now</span><span class="p_operator">()</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;test(d,&nbsp;ts)&nbsp;values&nbsp;(?,&nbsp;?)"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_operator">(</span><span class="p_identifier">today</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">now</span><span class="p_operator">))</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;d,&nbsp;ts&nbsp;from&nbsp;test"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">row</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">today</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_string">"=&gt;"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">],</span><span class="p_default">&nbsp;</span><span class="p_identifier">type</span><span class="p_operator">(</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">])</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">now</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_string">"=&gt;"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">1</span><span class="p_operator">],</span><span class="p_default">&nbsp;</span><span class="p_identifier">type</span><span class="p_operator">(</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">1</span><span class="p_operator">])</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_character">'select&nbsp;current_date&nbsp;as&nbsp;"d&nbsp;[date]",&nbsp;current_timestamp&nbsp;as&nbsp;"ts&nbsp;[timestamp]"'</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">row</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">fetchone</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_string">"current_date"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">],</span><span class="p_default">&nbsp;</span><span class="p_identifier">type</span><span class="p_operator">(</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">])</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_string">"current_timestamp"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">1</span><span class="p_operator">],</span><span class="p_default">&nbsp;</span><span class="p_identifier">type</span><span class="p_operator">(</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">1</span><span class="p_operator">])</span>
-</div>
-</div>
-<div class="section">
-<h2><a id="controlling-transactions" name="controlling-transactions">5. Controlling Transactions</a></h2>
-<p>By default, pysqlite opens transactions implicitly before a DML statement
-(<em>INSERT/UPDATE/DELETE/REPLACE</em>), and commits transactions implicitly before a
-non-DML, non-DQL statement (i. e. anything other than
-<em>SELECT/INSERT/UPDATE/DELETE/REPLACE</em>).</p>
-<p>So if you are within a transaction, and issue a command like <tt class="docutils literal"><span class="pre">CREATE</span> <span class="pre">TABLE</span>
-<span class="pre">...</span></tt>, <tt class="docutils literal"><span class="pre">VACUUM</span></tt>, <tt class="docutils literal"><span class="pre">PRAGMA</span></tt>, pysqlite will commit implicitly before executing
-that command. There are two reasons for doing that. The first is that most of
-these commands don't work within transactions. The other reason is that
-pysqlite needs to keep track of the transaction state (if a transaction is
-active or not).</p>
-<p>You can control which kind of &quot;BEGIN&quot; statements pysqlite implicitly executes
-(or none at all) via the <strong>isolation_level</strong> parameter to the <em>connect</em> call,
-or via the <strong>isolation_level</strong> property of connections.</p>
-<p>If you want <em>autocommit mode</em>, then set <strong>isolation_level</strong> to None.</p>
-<p>Otherwise leave it at it's default, which will result in a plain &quot;BEGIN&quot;
-statement, or set it to one of SQLite's supported isolation levels: DEFERRED,
-IMMEDIATE or EXCLUSIVE.</p>
-</div>
-<div class="section">
-<h2><a id="using-pysqlite-efficiently" name="using-pysqlite-efficiently">6. Using pysqlite efficiently</a></h2>
-</div>
-<div class="section">
-<h2><a id="using-shortcut-methods" name="using-shortcut-methods">6.1 Using shortcut methods</a></h2>
-<p>Using the nonstandard <tt class="docutils literal"><span class="pre">execute()</span></tt>, <tt class="docutils literal"><span class="pre">executemany()</span></tt> and <tt class="docutils literal"><span class="pre">executescript()</span></tt>
-methods of the Connection object, your code can be written more concisely,
-because you don't have to create the - often superfluous Cursor objects
-explicitly. Instead, the Cursor objects are created implicitly and
-these shortcut methods return the cursor objects. This way, you can for
-example execute a SELECT statement and iterate over it directly using
-only a single call on the Connection object.</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">persons</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_operator">[</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_operator">(</span><span class="p_string">"Hugo"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_string">"Boss"</span><span class="p_operator">),</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_operator">(</span><span class="p_string">"Calvin"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_string">"Klein"</span><span class="p_operator">)</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_operator">]</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Create&nbsp;the&nbsp;table</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"create&nbsp;table&nbsp;person(firstname,&nbsp;lastname)"</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Fill&nbsp;the&nbsp;table</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">executemany</span><span class="p_operator">(</span><span class="p_string">"insert&nbsp;into&nbsp;person(firstname,&nbsp;lastname)&nbsp;values&nbsp;(?,&nbsp;?)"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">persons</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Print&nbsp;the&nbsp;table&nbsp;contents</span><span class="p_default"><br/>
-</span><span class="p_word">for</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_default">&nbsp;</span><span class="p_word">in</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;firstname,&nbsp;lastname&nbsp;from&nbsp;person"</span><span class="p_operator">):</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Using&nbsp;a&nbsp;dummy&nbsp;WHERE&nbsp;clause&nbsp;to&nbsp;not&nbsp;let&nbsp;SQLite&nbsp;take&nbsp;the&nbsp;shortcut&nbsp;table&nbsp;deletes.</span><span class="p_default"><br/>
-</span><span class="p_word">print</span><span class="p_default">&nbsp;</span><span class="p_string">"I&nbsp;just&nbsp;deleted"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"delete&nbsp;from&nbsp;person&nbsp;where&nbsp;1=1"</span><span class="p_operator">).</span><span class="p_identifier">rowcount</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_string">"rows"</span>
-</div>
-</div>
-<div class="section">
-<h2><a id="accessing-columns-by-name-instead-of-by-index" name="accessing-columns-by-name-instead-of-by-index">6.2 Accessing columns by name instead of by index</a></h2>
-<p>A cool new feature of pysqlite 2.1.0 is the new builtin sqlite.Row class
-designed to be used as a row factory.</p>
-<p>Rows wrapped with this class can be accessed both by index (like tuples) and
-case-insensitively by name:</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_string">"mydb"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">row_factory</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">Row</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">cur</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">cursor</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span><span class="p_identifier">cur</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;name_last,&nbsp;age&nbsp;from&nbsp;people"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_word">for</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_default">&nbsp;</span><span class="p_word">in</span><span class="p_default">&nbsp;</span><span class="p_identifier">cur</span><span class="p_operator">:</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">assert</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">]</span><span class="p_default">&nbsp;</span><span class="p_operator">==</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_string">"name_last"</span><span class="p_operator">]</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">assert</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_string">"name_last"</span><span class="p_operator">]</span><span class="p_default">&nbsp;</span><span class="p_operator">==</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_string">"nAmE_lAsT"</span><span class="p_operator">]</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">assert</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">1</span><span class="p_operator">]</span><span class="p_default">&nbsp;</span><span class="p_operator">==</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_string">"age"</span><span class="p_operator">]</span><span class="p_default"><br/>
-&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p_word">assert</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_number">1</span><span class="p_operator">]</span><span class="p_default">&nbsp;</span><span class="p_operator">==</span><span class="p_default">&nbsp;</span><span class="p_identifier">row</span><span class="p_operator">[</span><span class="p_string">"AgE"</span><span class="p_operator">]</span>
-</div>
-</div>
-<div class="section">
-<h2><a id="combining-apsw-and-pysqlite" name="combining-apsw-and-pysqlite">7. Combining APSW and pysqlite</a></h2>
-<p>APSW is &quot;Another Python SQLite Wrapper&quot;. Its goal is to directly wrap the
-SQLite API for Python. If there's SQLite functionality that is only wrapped via
-APSW, but not (yet) via pysqlite, then you can still use the APSW functionality
-in pysqlite.</p>
-<p>Just use the APSW Connection as a parameter to the connect function and reuse
-an existing APSW connection like this.</p>
-<div class="code-block">
-<span class="p_word">from</span><span class="p_default">&nbsp;</span><span class="p_identifier">pysqlite2</span><span class="p_default">&nbsp;</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">dbapi2</span><span class="p_default">&nbsp;</span><span class="p_identifier">as</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_default"><br/>
-</span><span class="p_word">import</span><span class="p_default">&nbsp;</span><span class="p_identifier">apsw</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_identifier">apsw_con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">apsw</span><span class="p_operator">.</span><span class="p_identifier">Connection</span><span class="p_operator">(</span><span class="p_string">":memory:"</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">apsw_con</span><span class="p_operator">.</span><span class="p_identifier">createscalarfunction</span><span class="p_operator">(</span><span class="p_string">"times_two"</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_word">lambda</span><span class="p_default">&nbsp;</span><span class="p_identifier">x</span><span class="p_operator">:</span><span class="p_default">&nbsp;</span><span class="p_number">2</span><span class="p_operator">*</span><span class="p_identifier">x</span><span class="p_operator">,</span><span class="p_default">&nbsp;</span><span class="p_number">1</span><span class="p_operator">)</span><span class="p_default"><br/>
-<br/>
-</span><span class="p_commentline">#&nbsp;Create&nbsp;pysqlite&nbsp;connection&nbsp;from&nbsp;APSW&nbsp;connection</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">sqlite</span><span class="p_operator">.</span><span class="p_identifier">connect</span><span class="p_operator">(</span><span class="p_identifier">apsw_con</span><span class="p_operator">)</span><span class="p_default"><br/>
-</span><span class="p_identifier">result</span><span class="p_default">&nbsp;</span><span class="p_operator">=</span><span class="p_default">&nbsp;</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">execute</span><span class="p_operator">(</span><span class="p_string">"select&nbsp;times_two(15)"</span><span class="p_operator">).</span><span class="p_identifier">fetchone</span><span class="p_operator">()[</span><span class="p_number">0</span><span class="p_operator">]</span><span class="p_default"><br/>
-</span><span class="p_word">assert</span><span class="p_default">&nbsp;</span><span class="p_identifier">result</span><span class="p_default">&nbsp;</span><span class="p_operator">==</span><span class="p_default">&nbsp;</span><span class="p_number">30</span><span class="p_default"><br/>
-</span><span class="p_identifier">con</span><span class="p_operator">.</span><span class="p_identifier">close</span><span class="p_operator">()</span><span class="p_default"><br/>
-</span>
-</div>
-<p>This feature only works if both APSW and pysqlite are dynamically linked
-against the same SQLite shared library. I. e. it will <em>not</em> work on Windows
-without a custom built pysqlite and APSW.</p>
-</div>
-</div>
-</div>
-</body>
-</html>
diff --git a/doc/usage-guide.txt b/doc/usage-guide.txt
deleted file mode 100644 (file)
index 24b0d8d..0000000
+++ /dev/null
@@ -1,958 +0,0 @@
---------------------
-pysqlite usage guide
---------------------
-
-| (c) 2004-2005 David Rushby
-| (c) 2005-2007 Gerhard Häring
-
-Last updated for pysqlite 2.4.0
-
-Table Of Contents
-=================
-
-| `0. Introduction`_
-| `1. Python Database API 2.0 Compliance`_
-|   `1.1 Incompatibilities`_
-|   `1.2 Unsupported Optional Features`_
-|   `1.3 Nominally Supported Optional Features`_
-|   `1.4 Extensions and Caveats`_
-| `2. Brief Tutorial`_
-|   `2.1 Connecting to a Database`_
-|   `2.2 Executing SQL statements`_
-| `3. Native Database Engine Features and Extensions Beyond the Python DB API`_
-|   `3.1 Creating user-defined functions`_
-|   `3.2 Creating user-defined aggregates`_
-|   `3.3 Creating and using collations`_
-|   `3.4 Checking for complete statements`_
-|   `3.5 Enabling SQLite's shared cache`_
-|   `3.6 Setting an authorizer callback`_
-|   `3.7 Setting a progress handler`_
-|   `3.8 Using the connection as a context manager`_
-| `4. SQLite and Python types`_
-|   `4.1 Introduction`_
-|   `4.2 Using adapters to store additional Python types in SQLite databases`_
-|     `4.2.1 Letting your object adapt itself`_
-|     `4.2.2 Registering an adapter callable`_
-|   `4.3 Converting SQLite values to custom Python types`_
-|   `4.4 Default pysqlite adapters and converters`_
-| `5. Controlling Transactions`_
-| `6. Using pysqlite efficiently`_
-|   `6.1 Using shortcut methods`_
-|   `6.2 Accessing columns by name instead of by index`_
-| `7. Combining APSW and pysqlite`_
-
-0. Introduction
-===============
-
-This Usage Guide is not a tutorial on Python, SQL, or SQLite; rather, it is a
-topical presentation of pysqlite's feature set, with example code to
-demonstrate basic usage patterns. This guide is meant to be consumed in
-conjunction with the Python Database API Specification and the SQLite
-documentation.
-
-It was originally written by David Rushby for kinterbasdb. He kindly gave the
-permission to adapt it for pysqlite.
-
-1. Python Database API 2.0 Compliance
-=====================================
-
-1.1 Incompatibilities
----------------------
-
-* No type information in cursor.description
-
-  *cursor.description* has a tuple with the fields (*name*, *type_code*,
-  *display_size*, *internal_size*, *precision*, *scale*, *null_ok*) for each
-  column that a query returns. The DB-API spec requires that at least *name*
-  and *type_code* are filled, but at the time cursor.description is built,
-  pysqlite cannot determine any types, yet. So, the only field of
-  *cursor.description* that pysqlite fills is *name*. All other fields are set to
-  None.
-
-* No type objects
-
-  Consequently, there are also no type objects STRING, BINARY, NUMBER,
-  DATETIME, ROWID at module-level. They would be useless.
-
-1.2 Unsupported Optional Features
----------------------------------
-
-* **Cursor** class
-
-  * **nextset** method
-
-    This method is not implemented because the database engine does not
-    support opening multiple result sets simultaneously with a single
-    cursor.
-
-1.3 Nominally Supported Optional Features
------------------------------------------
-
-* **Cursor** class
-
-  * **arraysize** attribute
-
-    As required by the spec, the value of this attribute is observed
-    with respect to the fetchmany method. However, changing the value
-    of this attribute does not make any difference in fetch efficiency
-    because the database engine only supports fetching a single row at
-    a time.
-
-  * **setinputsizes** method
-
-    Although this method is present, it does nothing, as allowed by the
-    spec.
-
-  * **setoutputsize** method
-
-    Although this method is present, it does nothing, as allowed by the
-    spec.
-
-1.4 Extensions and Caveats
---------------------------
-
-pysqlite offers a large feature set beyond the minimal requirements of the
-Python DB API. Most of these extensions are documented in the section of this
-document entitled Native Database Engine Features and Extensions Beyond the
-Python DB API.
-
-* **connect** function
-
-  The parameter *database* refers to the database file for the SQLite
-  database. It's a normal filesystem path and you can use absolute or
-  relative path names.
-
-  The connect function supports the following optional keyword arguments
-  in addition to those required by the spec:
-
-  * **timeout** - When a database is accessed by multiple connections, and
-
-    one of the processes modifies the database, the SQLite database is
-    locked until that transaction is committed. The timeout parameter
-    specifies how long the connection should wait for the lock to go away
-    until raising an exception. The default for the timeout parameter is
-    5.0 (five seconds).
-
-    Example:
-     .. code-block:: Python
-
-      sqlite.connect(database="mydb", timeout=10.0)
-
-
-  * **isolation_level** - pysqlite will by default open transactions with a
-    "BEGIN" statement, when it encounters a DML statement like
-    INSERT/UPDATE/DELETE/REPLACE. Some users don't want pysqlite to implicitly
-    open transactions for them - they want an autocommit mode. Other users want
-    pysqlite to open different kinds of transactions, like with "BEGIN
-    IMMEDIATE". See `5. Controlling Transactions`_  for a more detailed
-    explanation.
-
-    Note that you can also switch to a different isolation level by setting the
-    **isolation_level** property of connections.
-
-    Example:
-     .. code-block:: Python
-
-      # Turn on autocommit mode
-      con = sqlite.connect("mydb", isolation_level=None)
-
-      # Set isolation_level to "IMMEDIATE"
-      con.isolation_level = "IMMEDIATE"
-
-  * **detect_types** - SQLite natively supports only the types TEXT,
-    INTEGER, FLOAT, BLOB and NULL. If you want to use other types, like you
-    have to add support for them yourself.  The *detect_types* parameter and
-    using custom *converters* registered with the module-level
-    *register_converter* function allow you to easily do that.
-
-    *detect_types* defaults to 0 (i. e. off, no type detection), you can
-    set it to any combination of *PARSE_DECLTYPES* and *PARSE_COLNAMES* to turn
-    type detection on.
-
-    Consult the section `4. SQLite and Python types`_ of this manual for
-    details.
-
-    * **sqlite.PARSE_DECLTYPES** - This makes pysqlite parse the declared
-      type for each column it returns. It will parse out the first word of the
-      declared type, i. e. for "integer primary key", it will parse out
-      "integer". Then for that column, it will look into pysqlite's converters
-      dictionary and use the converter function registered for that type there.
-
-    * **sqlite.PARSE_COLNAMES** - This makes pysqlite parse the column name
-      for each column it returns. It will look for a string formed
-      [mytype] in there, and then decide that 'mytype' is the type of
-      the column. It will try to find an entry of 'mytype' in the
-      converters dictionary and then use the converter function found
-      there to return the value. The column name found in
-      cursor.description is only the first word of the column name, i.
-      e. if you use something like 'as "x [datetime]"' in your SQL,
-      then pysqlite will parse out everything until the first blank for
-      the column name: the column name would simply be "x".
-
-      The following example uses the column name *timestamp*, which is already
-      registered by default in the converters dictionary with an appropriate
-      converter!
-
-      Example:
-
-      .. code-block::
-       :language: Python
-       :source-file: includes/sqlite3/parse_colnames.py
-
-  * **check_same_thread** - SQLite connections/cursors can only safely be
-    used in the same thread they were created in. pysqlite checks for
-    this each time it would do a call to the SQLite engine. If you are
-    confident that you are ensuring safety otherwise, you can disable
-    that checks by setting check_same_thread to False.
-
-  * **factory** - By default, pysqlite uses the Connection class for the
-    connect call. You can, however, subclass the Connection class and
-    make .connect() use your class instead by providing your class for
-    the factory parameter.
-
-    Example:
-
-    .. code-block::
-     :language: Python
-     :source-file: includes/sqlite3/countcursors.py
-
-  * **cached_statements** - pysqlite internally uses a statement cache to avoid
-    SQL parsing overhead. If you want to explicitly set the number of
-    statements that are cached for the connection, you can set this parameter.
-    The currently implemented default is to cache 100 statements.
-
-  |
-  |
-
-* **register_converter** function - ``register_converter(typename, callable)``
-  registers a callable to convert a bytestring from the database into a custom
-  Python type. The converter will be invoked for all database values that are
-  of the type ``typename``. Confer the parameter **detect_types** of the
-  **connect** method for how the type detection works.
-
-* **register_adapter** function - ``register_adapter(type, callable)``
-  registers a callable to convert the custom Python **type** into one of
-  SQLite's supported types. The callable accepts as single parameter the Python
-  value, and must return a value of the following types: int, long, float, str
-  (UTF-8 encoded), unicode or buffer.
-
-* **enable_callback_tracebacks** function - ``enable_callback_tracebacks(flag)``
-  Can be used to enable displaying tracebacks of exceptions in user-defined functions, aggregates and other callbacks being printed to stderr.
-  methods should never raise any exception. This feature is off by default.
-
-* **Connection** class
-
-  * **isolation_level** attribute (read-write)
-
-    Get or set the current *isolation level*: None for autocommit mode or one
-    of "DEFERRED", "IMMEDIATE" or "EXLUSIVE". See `5. Controlling
-    Transactions`_ for a more detailed explanation.
-
-  * **cursor method** - The cursor method accepts a single optional parameter:
-    a custom cursor class extending pysqlite's *Cursor* class that you can
-    adapt to your needs. Note that it is required that your custom cursor class
-    extends pysqlite's *Cursor* class.
-
-  * **execute method** - Nonstandard - this works as a shortcut for not having
-    to create a cursor object and is implemented like this:
-
-     .. code-block:: Python
-
-      class Connection:
-        def execute(self, *args):
-          cur = self.cursor()
-          cur.execute(*args)
-          return cur
-
-  * **executemany method** - Nonstandard - The same shortcut as the nonstandard
-    ``execute`` method.
-
-  * **executesript method** - Nonstandard - The same shortcut as the nonstandard
-    ``execute`` method.
-
-  * **row_factory** attribute (read-write)
-
-    You can change this attribute to a callable that accepts the cursor and
-    the original row as tuple and will return the real result row.  This
-    way, you can implement more advanced ways of returning results, like
-    ones that can also access columns by name.
-
-    Example:
-
-    .. code-block::
-     :language: Python
-     :source-file: includes/sqlite3/row_factory.py
-
-    If the standard tuple types don't suffice for you, and you want name-based
-    access to columns, you should consider setting ``row_factory`` to the
-    highly-optimized ``pysqlite2.dbapi2.Row`` type. It provides both
-    index-based and case-insensitive name-based access to columns with almost
-    no memory overhead. Much better than your own custom dictionary-based
-    approach or even a ``db_row`` based solution.
-
-  * **text_factory** attribute (read-write)
-
-    Using this attribute you can control what objects pysqlite returns for the
-    TEXT data type. By default, this attribute is set to ``unicode`` and
-    pysqlite will return Unicode objects for TEXT. If you want to return
-    bytestrings instead, you can set it to ``str``.
-
-    For efficiency reasons, there's also a way to return Unicode objects only
-    for non-ASCII data, and bytestrings otherwise. To activate it, set this
-    attribute to ``pysqlite2.dbapi2.OptimizedUnicode``.
-
-    You can also set it to any other callable that accepts a single bytestring
-    parameter and returns the result object.
-
-    See the following example code for illustration:
-
-     .. code-block::
-      :language: Python
-      :source-file: includes/sqlite3/text_factory.py
-
-  * **total_changes** attribute (read-only)
-
-    Returns the total number of database rows that have be modified, inserted,
-    or deleted since the database connection was opened.
-
-  |
-* **Cursor** class
-
-  * **execute** method
-
-    pysqlite uses *paramstyle = "qmark"*. That means if you use parametrized
-    statements, you use the question mark as placeholder.
-
-    This is a basic example showing the use of question marks as placeholders
-    and a parameter tuple:
-
-    .. code-block::
-     :language: Python
-     :source-file: includes/sqlite3/execute_1.py
-
-    pysqlite also supports *paramstyle = "named"*. That means you can use named
-    placeholders in the format ":name", i. e. a colon followed by the parameter
-    name. As parameters, you then supply a mapping instead of a sequence. In
-    the simplest case, a dictionary instead of a tuple.
-
-    .. code-block::
-     :language: Python
-     :source-file: includes/sqlite3/execute_2.py
-
-    The following example shows a shortcut that you can often use when using
-    named parameters. It exploits the fact that locals() is a dictionary, too.
-    So you can also use it as parameter for *execute*:
-
-    .. code-block::
-     :language: Python
-     :source-file: includes/sqlite3/execute_3.py
-
-    *execute* will only execute a single SQL statement. If you try to execute
-    more than one statement with it, it will raise a Warning. Use
-    *executescript* if want to execute multiple SQL statements with one call.
-
-
-  * **executemany** method
-
-    The DB-API specifies the executemany method like this:
-
-    .. code-block:: Python
-
-      .executemany(operation, seq_of_parameters)
-
-    pysqlite, however, extends *executemany* so it can be used more efficiently
-    for inserting bulk data. The second parameter to *executemany* can be a
-    *sequence of parameters*, but it can also be an *iterator* returning
-    parameters.
-
-    Example:
-
-    .. code-block::
-     :language: Python
-     :source-file: includes/sqlite3/executemany_1.py
-
-    As generators are iterators, too, here's a much simpler, equivalent example
-    using a generator:
-
-    .. code-block::
-     :language: Python
-     :source-file: includes/sqlite3/executemany_2.py
-
-    *executemany* will only execute a single SQL statement. If you try to
-    execute more than one statement with it, it will raise a Warning. Use
-    *executescript* if want to execute multiple SQL statements with one call.
-
-  * **executescript** method
-
-    .. code-block:: Python
-
-        .executemany(sqlscript)
-
-    This is a nonstandard convenience method for executing multiple SQL
-    statements at once. It issues a COMMIT statement before, then executes the
-    SQL script it gets as a parameter.
-
-    The SQL script ``sqlscript`` can be a bytestring or a Unicode string.
-
-    Example:
-
-    .. code-block::
-     :language: Python
-     :source-file: includes/sqlite3/executescript.py
-
-  * **interrupt** method
-
-    This method has no arguments. You can call it from a different thread to
-    abort any queries that are currently executing on the connection. This can
-    be used to let the user abort runaway queries, for example.
-
-  * **rowcount** attribute
-
-    Although pysqlite's Cursors implement this attribute, the database
-    engine's own support for the determination of "rows affected"/"rows
-    selected" is quirky.
-
-    For ``SELECT`` statements, *rowcount* is always -1 because pysqlite
-    cannot determine the number of rows a query produced until all rows
-    were fetched.
-
-    For ``DELETE`` statements, SQLite reports *rowcount* as 0 if you make a
-    ``DELETE FROM table`` without any condition.
-
-    For *executemany* statements, pysqlite sums up the number of
-    modifications into *rowcount*.
-
-    As required by the Python DB API Spec, the *rowcount* attribute "is -1
-    in case no executeXX() has been performed on the cursor or the rowcount
-    of the last operation is not determinable by the interface".
-
-|
-
-----
-
-|
-
-2. Brief Tutorial
-=================
-
-This brief tutorial aims to get the reader started by demonstrating elementary
-usage of pysqlite. It is not a comprehensive Python Database API tutorial, nor
-is it comprehensive in its coverage of anything else.
-
-2.1 Connecting to a Database
-----------------------------
-
-    **Example 1**
-
-    Connecting to a database file *mydb*:
-
-    .. code-block::
-     :language: Python
-     :source-file: includes/sqlite3/connect_db_1.py
-
-
-    **Example 2**
-
-    Creating an in-memory database:
-
-    .. code-block::
-     :language: Python
-     :source-file: includes/sqlite3/connect_db_2.py
-
-
-2.2 Executing SQL statements
-----------------------------
-
-For this section, we have a database *mydb* defined and populated by the
-following SQL code:
-
-  .. code-block:: SQL
-
-    create table people
-    (
-      name_last      varchar(20),
-      age            integer
-    );
-
-    insert into people (name_last, age) values ('Yeltsin',   72);
-    insert into people (name_last, age) values ('Putin',     51);
-
-*Example 1*
-
-This example shows the simplest way to print the entire contents of the ``people`` table:
-
-.. code-block::
- :language: Python
- :source-file: includes/sqlite3/execsql_printall_1.py
-
-Sample output::
-
-  [(u'Putin', 51), (u'Yeltsin', 72)]
-
-*Example 2*
-
-Here's another trivial example that demonstrates various ways of fetching a
-single row at a time from a SELECT-cursor:
-
-.. code-block::
- :language: Python
- :source-file: includes/sqlite3/execsql_fetchonerow.py
-
-Sample output::
-
-  Putin is 51 years old.
-  Yeltsin is 72 years old.
-  Putin is 51 years old.
-  Yeltsin is 72 years old.
-
-*Example 3*
-
-The following program is a simplistic table printer (applied in this example to
-people)
-
-.. code-block::
- :language: Python
- :source-file: includes/sqlite3/simple_tableprinter.py
-
-Sample output::
-
-  name_last            age
-  ------------------------------------------------------------------------------
-  Putin                51
-  Yeltsin              72
-
-*Example 4*
-
-Let's insert more people into the people table: 
-
-.. code-block::
- :language: Python
- :source-file: includes/sqlite3/insert_more_people.py
-
-Note the use of a parameterized SQL statement above. When dealing with
-repetitive statements, this is much faster and less error-prone than assembling
-each SQL statement manually.
-
-It's also worth noting that in the example above, the code: 
-
-It's also worth noting that in the example above, the code:
-
-.. code-block:: Python
-
-  for person in newPeople:
-      cur.execute("insert into people (name_last, age) values (?, ?)", person)
-
-could be rewritten as:
-
-.. code-block:: Python
-
-  cur.executemany("insert into people (name_last, age) values (?, ?)", newPeople)
-
-After running Example 4, the table printer from Example 3 would print::
-
-  name_last            age
-  ------------------------------------------------------------------------------
-  Putin                51
-  Lebed                53
-  Zhirinovsky          57
-  Yeltsin              72
-
-|
-
-----
-
-|
-
-3. Native Database Engine Features and Extensions Beyond the Python DB API
-==========================================================================
-
-3.1 Creating user-defined functions
------------------------------------
-
-SQLite supports user-defined functions.  Using pysqlite, you can create new
-functions with the connection's **create_function** method:
-
-  .. code-block:: Python
-
-    def create_function(self, name, numparams, func)
-
-  *name*
-    the name of your function in SQL
-  *numparams*
-    the number of parameters your function accepts, -1 if it accepts any
-    number of parameters
-  *func*
-    the Python function
-
-  The function can return any of pysqlite's supported SQLite types: unicode,
-  str, int, long, float, buffer and None.  Any exception in the user-defined
-  function leads to the SQL statement executed being aborted.
-
-  Example:
-
-  .. code-block::
-   :language: Python
-   :source-file: includes/sqlite3/md5func.py
-
-3.2 Creating user-defined aggregates
-------------------------------------
-
-SQLite supports user-defined aggregate functions. Using pysqlite, you can
-create new aggregate functions with the connection's *create_aggregate* method.
-
-  .. code-block:: Python
-
-    def create_aggregate(self, name, numparams, aggregate_class)
-
-  The aggregate class must implement a *step* method, which accepts the
-  number of parameters defined in *create_aggregate*, and a *finalize*
-  method which will return the final result of the aggregate.
-
-  The *finalize* method can return any of pysqlite's supported SQLite types:
-  unicode, str, int, long, float, buffer and None. Any exception in the
-  aggregate's *__init__*, *step* or *finalize* methods lead to the SQL
-  statement executed being aborted.
-
-  Example:
-
-  .. code-block::
-   :language: Python
-   :source-file: includes/sqlite3/mysumaggr.py
-
-3.3 Creating and using collations
----------------------------------
-
-  .. code-block:: Python
-
-    def create_collation(name, callable)
-
-Creates a collation with the specified name and callable. The callable will be
-passed two string arguments. It should return -1 if the first is less than the
-second, 0 if they are equal and 1 and if the first is greater than the second.
-Note that this controls sorting (ORDER BY in SQL) so your comparisons don't
-affect other SQL operations. Read more about SQLite's handling of collations.
-(This calls sqlite3_create_collation.) If there is an error in your Python code
-then 0 (ie items are equal) is returned.
-
-Note that the callable will get its parameters as Python bytestrings, which
-will normally be encoded in UTF-8.
-
-The following example shows a custom collation that sorts "the wrong way":
-
-  .. code-block::
-   :language: Python
-   :source-file: includes/sqlite3/collation_reverse.py
-
-To remove a collation, call `create_collation` with None as callable:
-
-  .. code-block:: Python
-
-    con.create_collation("reverse", None)
-
-3.4 Checking for complete statements
-------------------------------------
-
-The module-level function *complete_statement(sql)* can be used to check if a
-string contains a complete SQL statement or is still incomplete. The given
-string could still contain invalid SQL, but be parsable as a "complete"
-statement!
-
-This can be used to build a shell for SQLite, like in the following example:
-
-  .. code-block::
-   :language: Python
-   :source-file: includes/sqlite3/complete_statement.py
-
-3.5 Enabling SQLite's shared cache
-----------------------------------
-
-To enable SQLite's shared cache for the calling thread, call the function
-*enable_shared_cache*.
-
-  .. code-block::
-   :language: Python
-   :source-file: includes/sqlite3/shared_cache.py
-
-3.6 Setting an authorizer callback
-----------------------------------
-
-You can set an authorizer callback if you want to restrict what your users can
-do with the database. This is mostly useful if you accept arbitrary SQL from
-users and want to execute it safely. See the relevant section in the SQL
-documentation for details:
-http://sqlite.org/capi3ref.html#sqlite3_set_authorizer
-
-All necessary constants like SQLITE_OK, SQLITE_DENY, SQLITE_IGNORE,
-SQLITE_SELECT, SQLITE_CREATE_INDEX and all other authorizer-related constants
-are available through the dbapi2 module.
-
-Here's an example that demonstrates the usage of this function:
-
-  .. code-block::
-   :language: Python
-   :source-file: includes/sqlite3/authorizer.py
-
-3.7 Setting a progress handler
-------------------------------
-
-If you want to get called by SQLite during long-running operations, you can set
-a progress handler. An example use for this is to keep a GUI updated during a
-long-running query. 
-
-  .. code-block:: Python
-
-    def set_progress_handler(self, handler, n)
-
-The progress handler will be called every n SQLite virtual machine opcodes. If
-handler returns a nonzero value, the query is aborted with an OperationalError.
-
-Here's an example that demonstrates the usage of this function:
-
-  .. code-block::
-   :language: Python
-   :source-file: includes/sqlite3/progress.py
-
-3.8 Using the connection as a context manager
----------------------------------------------
-
-With Python 2.5 or higher, pysqlite's connection objects can be used as context
-managers that automatically commit or rollback transactions.  In the event of
-an exception, the transaction is rolled back; otherwise, the transaction is
-committed:
-
-  .. code-block::
-    :language: Python
-    :source-file: includes/sqlite3/ctx_manager.py
-
-4. SQLite and Python types
-==========================
-
-4.1 Introduction
-----------------
-
-http://sqlite.org/datatype3.html
-
-SQLite natively supports the following types: NULL, INTEGER, REAL, TEXT, BLOB.
-
-The following Python types can thus be sent to SQLite without any problem:
-
-======================  ===========
-Python type             SQLite type
-======================  ===========
-NoneType                NULL
-int                     INTEGER
-long                    INTEGER
-float                   REAL
-str (utf-8 encoded)     TEXT
-unicode                 TEXT
-buffer                  BLOB
-======================  ===========
-
-This is how SQLite types are converted to Python types by default:
-
-===========  ==============================
-SQLite type  Python type
-===========  ==============================
-NULL         NoneType
-INTEGER      int or long, depending on size
-REAL         float
-TEXT         unicode
-BLOB         buffer
-===========  ==============================
-
-pysqlite's type system is extensible in both ways: you can store additional
-Python types in a SQLite database via object adaptation, and you can let
-pysqlite convert SQLite types to different Python types via pysqlite's
-converters.
-
-4.2 Using adapters to store additional Python types in SQLite databases
------------------------------------------------------------------------
-
-Like described before, SQLite supports only a limited set of types natively. To
-use other Python types with SQLite, you must *adapt* them to one of pysqlite's
-supported types for SQLite. So, one of NoneType, int, long, float, str,
-unicode, buffer.
-
-pysqlite uses the Python object adaptation, like described in PEP 246 for this.
-The protocol to use is ``PrepareProtocol``.
-
-There are two ways to enable pysqlite to adapt a custom Python type to one of
-the supported ones.
-
-4.2.1 Letting your object adapt itself
---------------------------------------
-
-This is a good approach if you write the class yourself. Let's suppose you have
-a class like this:
-
-  .. code-block:: Python
-
-    class Point(object):
-        def __init__(self, x, y):
-            self.x, self.y = x, y
-
-Now you want to store the point in a single SQLite column. You'll have to
-choose one of the supported types first that you use to represent the point in.
-Let's just use str and separate the coordinates using a semicolon. Then you
-need to give your class a method ``__conform__(self, protocol)`` which must
-return the converted value. The parameter ``protocol`` will be
-``PrepareProtocol``.
-
-.. code-block::
- :language: Python
- :source-file: includes/sqlite3/adapter_point_1.py
-
-4.2.2 Registering an adapter callable
--------------------------------------
-
-The other possibility is to create a function that converts the type to the
-string representation and register the function with ``register_adapter``.
-
-.. code-block::
- :language: Python
- :source-file: includes/sqlite3/adapter_point_2.py
-
-The type/class to adapt must be a new-style class, i. e. it must have
-``object`` as one of its bases!!!
-
-pysqlite has two default adapters for Python's builtin *date* and *datetime*
-types. Now let's suppose we want to store *datetime* objects not in ISO
-representation, but as Unix timestamp.
-
-.. code-block::
- :language: Python
- :source-file: includes/sqlite3/adapter_datetime.py
-
-4.3 Converting SQLite values to custom Python types
----------------------------------------------------
-
-Now that's all nice and dandy that you can send custom Python types to SQLite.
-But to make it really useful we need to make the Python to SQLite to Python
-roundtrip work.
-
-Enter pysqlite converters.
-
-Let's go back to the Point class. We stored the x and y coordinates separated
-via semicolons as strings in SQLite.
-
-Let's first define a converter function that accepts the string as a parameter and constructs a Point object from it.
-
-!!! Note that converter functions *always* get called with a string, no matter
-under which data type you sent the value to SQLite !!!
-
-  .. code-block:: Python
-
-    def convert_point(s):
-        x, y = map(float, s.split(";"))
-        return Point(x, y)
-
-Now you need to make pysqlite know that what you select from the database is
-actually a point. There are two ways of doing this:
-
- * Implicitly via the declared type
- * Explicitly via the column name
-
-Both ways are described in section `1.4 Extensions and Caveats`_ in the
-paragraphs describing the connect function, and specifically the meaning of the
-*detect_types* parameter.
-
-The following example illustrates both ways.
-
-.. code-block::
- :language: Python
- :source-file: includes/sqlite3/converter_point.py
-
-4.4 Default pysqlite adapters and converters
---------------------------------------------
-
-pysqlite has default adapters for the date and datetime types in the datetime
-module. They will be sent as ISO dates/ISO timestamps to SQLite.
-
-pysqlite has default converters registered under the name "date" for
-datetime.date and under the name "timestamp" for datetime.datetime.
-
-This way, you can use date/timestamps from pysqlite without any additional
-fiddling in most cases. The format of the adapters is also compatible with the
-experimental SQLite date/time functions.
-
-The following example demonstrates this.
-
-.. code-block::
- :language: Python
- :source-file: includes/sqlite3/pysqlite_datetime.py
-
-5. Controlling Transactions
----------------------------
-
-By default, pysqlite opens transactions implicitly before a DML statement
-(*INSERT/UPDATE/DELETE/REPLACE*), and commits transactions implicitly before a
-non-DML, non-DQL statement (i. e. anything other than
-*SELECT/INSERT/UPDATE/DELETE/REPLACE*).
-
-So if you are within a transaction, and issue a command like ``CREATE TABLE
-...``, ``VACUUM``, ``PRAGMA``, pysqlite will commit implicitly before executing
-that command. There are two reasons for doing that. The first is that most of
-these commands don't work within transactions. The other reason is that
-pysqlite needs to keep track of the transaction state (if a transaction is
-active or not).
-
-You can control which kind of "BEGIN" statements pysqlite implicitly executes
-(or none at all) via the **isolation_level** parameter to the *connect* call,
-or via the **isolation_level** property of connections.
-
-If you want *autocommit mode*, then set **isolation_level** to None.
-
-Otherwise leave it at it's default, which will result in a plain "BEGIN"
-statement, or set it to one of SQLite's supported isolation levels: DEFERRED,
-IMMEDIATE or EXCLUSIVE.
-
-6. Using pysqlite efficiently
------------------------------
-
-6.1 Using shortcut methods
---------------------------
-
-Using the nonstandard ``execute()``, ``executemany()`` and ``executescript()``
-methods of the Connection object, your code can be written more concisely,
-because you don't have to create the - often superfluous Cursor objects
-explicitly. Instead, the Cursor objects are created implicitly and
-these shortcut methods return the cursor objects. This way, you can for
-example execute a SELECT statement and iterate over it directly using
-only a single call on the Connection object.
-
-.. code-block::
- :language: Python
- :source-file: includes/sqlite3/shortcut_methods.py
-
-6.2 Accessing columns by name instead of by index
--------------------------------------------------
-
-A cool new feature of pysqlite 2.1.0 is the new builtin sqlite.Row class
-designed to be used as a row factory.
-
-Rows wrapped with this class can be accessed both by index (like tuples) and
-case-insensitively by name:
-
-.. code-block::
- :language: Python
- :source-file: includes/sqlite3/rowclass.py
-
-7. Combining APSW and pysqlite
-------------------------------
-
-APSW is "Another Python SQLite Wrapper". Its goal is to directly wrap the
-SQLite API for Python. If there's SQLite functionality that is only wrapped via
-APSW, but not (yet) via pysqlite, then you can still use the APSW functionality
-in pysqlite.
-
-Just use the APSW Connection as a parameter to the connect function and reuse
-an existing APSW connection like this.
-
-.. code-block::
-  :language: Python
-  :source-file: includes/sqlite3/apsw_example.py
-
-This feature only works if both APSW and pysqlite are dynamically linked
-against the same SQLite shared library. I. e. it will *not* work on Windows
-without a custom built pysqlite and APSW.
-
diff --git a/docutilsupport.py b/docutilsupport.py
deleted file mode 100644 (file)
index e79842a..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/env python\r
-\r
-import SilverCity\r
-import docutils.parsers.rst\r
-import StringIO\r
-\r
-def code_block( name, arguments, options, content, lineno,\r
-             content_offset, block_text, state, state_machine ):\r
-  """\r
-  The code-block directive provides syntax highlighting for blocks\r
-  of code.  It is used with the the following syntax::\r
-  \r
-  .. code-block:: CPP\r
-     \r
-    #include <iostream>\r
-    \r
-    int main( int argc, char* argv[] )\r
-    {\r
-      std::cout << "Hello world" << std::endl;\r
-    }\r
-    \r
-  The directive requires the name of a language supported by SilverCity\r
-  as its only argument.  All code in the indented block following\r
-  the directive will be colourized.  Note that this directive is only\r
-  supported for HTML writers.\r
-\r
-  The directive can also be told to include a source file directly::\r
-\r
-  .. code-block::\r
-     :language: Python\r
-     :source-file: ../myfile.py\r
-\r
-  You cannot both specify a source-file and include code directly.\r
-  """\r
-\r
-  try:\r
-    language = arguments[0]\r
-  except IndexError:\r
-    language = options['language']\r
-\r
-  if content and 'source-file' in options:\r
-    error = state_machine.reporter.error( "You cannot both specify a source-file and include code directly.",\r
-                                          docutils.nodes.literal_block(block_text,block_text), line=lineno)\r
-    return [error]\r
-\r
-  if not content:\r
-    try:\r
-      content = [line.rstrip() for line in file(options['source-file'])]\r
-    except KeyError:\r
-      # source-file was not specified\r
-      pass\r
-    except IOError:\r
-      error = state_machine.reporter.error( "Could not read file %s."%options['source-file'],\r
-                                            docutils.nodes.literal_block(block_text,block_text), line=lineno)\r
-      return [error]\r
-  try:\r
-    module = getattr(SilverCity, language)\r
-    generator = getattr(module, language+"HTMLGenerator")\r
-  except AttributeError:\r
-    error = state_machine.reporter.error( "No SilverCity lexer found "\r
-      "for language '%s'." % language, \r
-      docutils.nodes.literal_block(block_text, block_text), line=lineno )\r
-    return [error]\r
-  io = StringIO.StringIO()\r
-  generator().generate_html( io, '\n'.join(content) )\r
-  html = '<div class="code-block">\n%s\n</div>\n' % io.getvalue()\r
-  raw = docutils.nodes.raw('',html, format = 'html')\r
-  return [raw]\r
-\r
-#code_block.arguments = (1,0,0)\r
-code_block.arguments = (0,2,1)\r
-code_block.options = {'language' : docutils.parsers.rst.directives.unchanged,\r
-                      'source-file' : docutils.parsers.rst.directives.path,}\r
-code_block.content = 1\r
-  \r
-# Simply importing this module will make the directive available.\r
-docutils.parsers.rst.directives.register_directive( 'code-block', code_block )\r
-\r
-if __name__ == "__main__":\r
-  import docutils.core\r
-  docutils.core.publish_cmdline(writer_name='html')\r
-\r
index 1155e49..c155695 100644 (file)
@@ -22,6 +22,7 @@
 # 3. This notice may not be removed or altered from any source distribution.
 
 import glob, os, sys
+import cross_bdist_wininst
 
 from ez_setup import use_setuptools
 from distutils.command.build import build
@@ -29,43 +30,29 @@ from distutils.command.build_ext import build_ext
 use_setuptools()
 
 import setuptools
-import setup
-
-class DocBuilder(setuptools.Command):
-    description = "Builds the documentation"
-    user_options = []
-
-    def initialize_options(self):
-        pass
-
-    def finalize_options(self):
-        pass
-
-    def run(self):
-        import os, stat
-
-        try:
-            import docutils.core
-            import docutilsupport
-        except ImportError:
-            print "Error: the build-docs command requires docutils and SilverCity to be installed"
-            return
-
-        docfiles = {
-            "usage-guide.html": "usage-guide.txt",
-            "install-source.html": "install-source.txt",
-            "install-source-win32.html": "install-source-win32.txt"
-        }
-
-        os.chdir("doc")
-        for dest, source in docfiles.items():
-            if not os.path.exists(dest) or os.stat(dest)[stat.ST_MTIME] < os.stat(source)[stat.ST_MTIME]:
-                print "Building documentation file %s." % dest
-                docutils.core.publish_cmdline(
-                    writer_name='html',
-                    argv=["--stylesheet=default.css", source, dest])
-
-        os.chdir("..")
+import urllib
+import zipfile
+
+from setup import get_setup_args, DocBuilder
+
+AMALGAMATION_ROOT = "amalgamation"
+
+def get_amalgamation():
+    """Download the SQLite amalgamation if it isn't there, already."""
+    if os.path.exists(AMALGAMATION_ROOT):
+        return
+    os.mkdir(AMALGAMATION_ROOT)
+    print "Downloading amalgation."
+    urllib.urlretrieve("http://sqlite.org/sqlite-amalgamation-3_6_1.zip", "tmp.zip")
+    zf = zipfile.ZipFile("tmp.zip")
+    files = ["sqlite3.c", "sqlite3.h"]
+    for fn in files:
+        print "Extracting", fn
+        outf = open(AMALGAMATION_ROOT + os.sep + fn, "wb")
+        outf.write(zf.read(fn))
+        outf.close()
+    zf.close()
+    os.unlink("tmp.zip")
 
 class AmalgamationBuilder(build):
     description = "Build a statically built pysqlite using the amalgamtion."
@@ -78,9 +65,10 @@ class MyBuildExt(build_ext):
     amalgamation = False
 
     def build_extension(self, ext):
+        get_amalgamation()
         if self.amalgamation:
-            ext.sources.append("sqlite3.c")
-        build_ext.build_extension(self, ext)
+            ext.sources.append(os.path.join(AMALGAMATION_ROOT, "sqlite3.c"))
+            build_ext.build_extension(self, ext)
 
     def __setattr__(self, k, v):
         # Make sure we don't link against the SQLite library, no matter what setup.cfg says
@@ -90,11 +78,9 @@ class MyBuildExt(build_ext):
 
 
 def main():
-    setup_args = setup.get_setup_args()
-    setup_args["extras_require"] = {"build_docs": ["docutils", "SilverCity"]}
+    setup_args = get_setup_args()
     setup_args["test_suite"] = "pysqlite2.test.suite"
-    setup_args["cmdclass"] = {"build_docs": DocBuilder, "build_ext": MyBuildExt, "build_static": AmalgamationBuilder}
-    setup_args["extras_require"] = {"build_docs": ["docutils", "SilverCity"]}
+    setup_args["cmdclass"].update({"build_docs": DocBuilder, "build_ext": MyBuildExt, "build_static": AmalgamationBuilder, "cross_bdist_wininst": cross_bdist_wininst.bdist_wininst})
     setuptools.setup(**setup_args)
 
 if __name__ == "__main__":
diff --git a/pysqlite2/dump.py b/pysqlite2/dump.py
new file mode 100644 (file)
index 0000000..409a405
--- /dev/null
@@ -0,0 +1,63 @@
+# Mimic the sqlite3 console shell's .dump command
+# Author: Paul Kippes <kippesp@gmail.com>
+
+def _iterdump(connection):
+    """
+    Returns an iterator to the dump of the database in an SQL text format.
+
+    Used to produce an SQL dump of the database.  Useful to save an in-memory
+    database for later restoration.  This function should not be called
+    directly but instead called from the Connection method, iterdump().
+    """
+
+    cu = connection.cursor()
+    yield('BEGIN TRANSACTION;')
+
+    # sqlite_master table contains the SQL CREATE statements for the database.
+    q = """
+        SELECT name, type, sql
+        FROM sqlite_master
+            WHERE sql NOT NULL AND
+            type == 'table'
+        """
+    schema_res = cu.execute(q)
+    for table_name, type, sql in schema_res.fetchall():
+        if table_name == 'sqlite_sequence':
+            yield('DELETE FROM sqlite_sequence;')
+        elif table_name == 'sqlite_stat1':
+            yield('ANALYZE sqlite_master;')
+        elif table_name.startswith('sqlite_'):
+            continue
+        # NOTE: Virtual table support not implemented
+        #elif sql.startswith('CREATE VIRTUAL TABLE'):
+        #    qtable = table_name.replace("'", "''")
+        #    yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"\
+        #        "VALUES('table','%s','%s',0,'%s');" %
+        #        qtable,
+        #        qtable,
+        #        sql.replace("''"))
+        else:
+            yield('%s;' % sql)
+
+        # Build the insert statement for each row of the current table
+        res = cu.execute("PRAGMA table_info('%s')" % table_name)
+        column_names = [str(table_info[1]) for table_info in res.fetchall()]
+        q = "SELECT 'INSERT INTO \"%(tbl_name)s\" VALUES("
+        q += ",".join(["'||quote(" + col + ")||'" for col in column_names])
+        q += ")' FROM '%(tbl_name)s'"
+        query_res = cu.execute(q % {'tbl_name': table_name})
+        for row in query_res:
+            yield("%s;" % row[0])
+
+    # Now when the type is 'index', 'trigger', or 'view'
+    q = """
+        SELECT name, type, sql
+        FROM sqlite_master
+            WHERE sql NOT NULL AND
+            type IN ('index', 'trigger', 'view')
+        """
+    schema_res = cu.execute(q)
+    for name, type, sql in schema_res.fetchall():
+        yield('%s;' % sql)
+
+    yield('COMMIT;')
index 5b10c77..7503fc1 100644 (file)
@@ -33,12 +33,12 @@ if os.path.exists("extended_setup.py"):
     sys.exit(1)
 
 from pysqlite2.test import dbapi, types, userfunctions, factory, transactions,\
-    hooks, regression
+    hooks, regression, dump
 from pysqlite2 import dbapi2 as sqlite
 
 def suite():
     tests = [dbapi.suite(), types.suite(), userfunctions.suite(),
-      factory.suite(), transactions.suite(), hooks.suite(), regression.suite()]
+      factory.suite(), transactions.suite(), hooks.suite(), regression.suite(), dump.suite()]
     if sys.version_info >= (2, 5, 0):
         from pysqlite2.test import py25tests
         tests.append(py25tests.suite())
index f715217..5e0ad7d 100644 (file)
@@ -297,6 +297,15 @@ class CursorTests(unittest.TestCase):
         self.cu.execute("update test set name='bar'")
         self.failUnlessEqual(self.cu.rowcount, 2)
 
+    def CheckRowcountSelect(self):
+        """
+        pysqlite does not know the rowcount of SELECT statements, because we
+        don't fetch all rows after executing the select statement. The rowcount
+        has thus to be -1.
+        """
+        self.cu.execute("select 5 union select 6")
+        self.failUnlessEqual(self.cu.rowcount, -1)
+
     def CheckRowcountExecutemany(self):
         self.cu.execute("delete from test")
         self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
diff --git a/pysqlite2/test/dump.py b/pysqlite2/test/dump.py
new file mode 100644 (file)
index 0000000..c4b3e13
--- /dev/null
@@ -0,0 +1,52 @@
+# Author: Paul Kippes <kippesp@gmail.com>
+
+import unittest
+from pysqlite2 import dbapi2 as sqlite
+
+class DumpTests(unittest.TestCase):
+    def setUp(self):
+        self.cx = sqlite.connect(":memory:")
+        self.cu = self.cx.cursor()
+
+    def tearDown(self):
+        self.cx.close()
+
+    def CheckTableDump(self):
+        expected_sqls = [
+                "CREATE TABLE t1(id integer primary key, s1 text, " \
+                "t1_i1 integer not null, i2 integer, unique (s1), " \
+                "constraint t1_idx1 unique (i2));"
+                ,
+                "INSERT INTO \"t1\" VALUES(1,'foo',10,20);"
+                ,
+                "INSERT INTO \"t1\" VALUES(2,'foo2',30,30);"
+                ,
+                "CREATE TABLE t2(id integer, t2_i1 integer, " \
+                "t2_i2 integer, primary key (id)," \
+                "foreign key(t2_i1) references t1(t1_i1));"
+                ,
+                "CREATE TRIGGER trigger_1 update of t1_i1 on t1 " \
+                "begin " \
+                "update t2 set t2_i1 = new.t1_i1 where t2_i1 = old.t1_i1; " \
+                "end;"
+                ,
+                "CREATE VIEW v1 as select * from t1 left join t2 " \
+                "using (id);"
+                ]
+        [self.cu.execute(s) for s in expected_sqls]
+        i = self.cx.iterdump()
+        actual_sqls = [s for s in i]
+        expected_sqls = ['BEGIN TRANSACTION;'] + expected_sqls + \
+            ['COMMIT;']
+        [self.assertEqual(expected_sqls[i], actual_sqls[i])
+            for i in xrange(len(expected_sqls))]
+
+def suite():
+    return unittest.TestSuite(unittest.makeSuite(DumpTests, "Check"))
+
+def test():
+    runner = unittest.TextTestRunner()
+    runner.run(suite())
+
+if __name__ == "__main__":
+    test()
index de32c75..81d2356 100644 (file)
@@ -131,6 +131,26 @@ class RowFactoryTests(unittest.TestCase):
         self.failUnlessEqual(d["a"], row["a"])
         self.failUnlessEqual(d["b"], row["b"])
 
+    def CheckSqliteRowHashCmp(self):
+        """Checks if the row object compares and hashes correctly"""
+        self.con.row_factory = sqlite.Row
+        row_1 = self.con.execute("select 1 as a, 2 as b").fetchone()
+        row_2 = self.con.execute("select 1 as a, 2 as b").fetchone()
+        row_3 = self.con.execute("select 1 as a, 3 as b").fetchone()
+
+        self.failUnless(row_1 == row_1)
+        self.failUnless(row_1 == row_2)
+        self.failUnless(row_2 != row_3)
+
+        self.failIf(row_1 != row_1)
+        self.failIf(row_1 != row_2)
+        self.failIf(row_2 == row_3)
+
+        self.failUnlessEqual(row_1, row_2)
+        self.failUnlessEqual(hash(row_1), hash(row_2))
+        self.failIfEqual(row_1, row_3)
+        self.failIfEqual(hash(row_1), hash(row_3))
+
     def tearDown(self):
         self.con.close()
 
index 1dac1e3..80fec5f 100644 (file)
@@ -21,6 +21,7 @@
 #    misrepresented as being the original software.
 # 3. This notice may not be removed or altered from any source distribution.
 
+import datetime
 import unittest
 import pysqlite2.dbapi2 as sqlite
 
@@ -114,8 +115,9 @@ class RegressionTests(unittest.TestCase):
         pysqlite would crash with older SQLite versions unless
         a workaround is implemented.
         """
-        self.con.execute("create table if not exists foo(bar)")
-        self.con.execute("create table if not exists foo(bar)")
+        self.con.execute("create table foo(bar)")
+        self.con.execute("drop table foo")
+        self.con.execute("create table foo(bar)")
 
     def CheckEmptyStatement(self):
         """
@@ -126,7 +128,7 @@ class RegressionTests(unittest.TestCase):
 
     def CheckUnicodeConnect(self):
         """
-        With pysqlite 2.5.0 you needed to use a string or a APSW connection
+        With pysqlite 2.4.0 you needed to use a string or a APSW connection
         object for opening database connections.
 
         Formerly, both bytestrings and unicode strings used to work.
@@ -136,6 +138,36 @@ class RegressionTests(unittest.TestCase):
         con = sqlite.connect(u":memory:")
         con.close()
 
+    def CheckTypeMapUsage(self):
+        """
+        pysqlite until 2.4.1 did not rebuild the row_cast_map when recompiling
+        a statement. This test exhibits the problem.
+        """
+        SELECT = "select * from foo"
+        con = sqlite.connect(":memory:",detect_types=sqlite.PARSE_DECLTYPES)
+        con.execute("create table foo(bar timestamp)")
+        con.execute("insert into foo(bar) values (?)", (datetime.datetime.now(),))
+        con.execute(SELECT)
+        con.execute("drop table foo")
+        con.execute("create table foo(bar integer)")
+        con.execute("insert into foo(bar) values (5)")
+        con.execute(SELECT)
+
+    def CheckRegisterAdapter(self):
+        """
+        See issue 3312.
+        """
+        self.assertRaises(TypeError, sqlite.register_adapter, {}, None)
+
+    def CheckSetIsolationLevel(self):
+        """
+        See issue 3312.
+        """
+        con = sqlite.connect(":memory:")
+        self.assertRaises(UnicodeEncodeError, setattr, con,
+                          "isolation_level", u"\xe9")
+
+
 def suite():
     regression_suite = unittest.makeSuite(RegressionTests, "Check")
     return unittest.TestSuite((regression_suite,))
index 130b82d..9011b24 100644 (file)
@@ -32,7 +32,7 @@ class TransactionTests(unittest.TestCase):
     def setUp(self):
         try:
             os.remove(get_db_path())
-        except:
+        except OSError:
             pass
 
         self.con1 = sqlite.connect(get_db_path(), timeout=0.1)
@@ -48,7 +48,10 @@ class TransactionTests(unittest.TestCase):
         self.cur2.close()
         self.con2.close()
 
-        os.unlink(get_db_path())
+        try:
+            os.unlink(get_db_path())
+        except OSError:
+            pass
 
     def CheckDMLdoesAutoCommitBefore(self):
         self.cur1.execute("create table test(i)")
@@ -110,6 +113,10 @@ class TransactionTests(unittest.TestCase):
         self.failUnlessEqual(len(res), 1)
 
     def CheckRaiseTimeout(self):
+        if sqlite.sqlite_version_info < (3, 2, 2):
+            # This will fail (hang) on earlier versions of sqlite.
+            # Determine exact version it was fixed. 3.2.1 hangs.
+            return
         self.cur1.execute("create table test(i)")
         self.cur1.execute("insert into test(i) values (5)")
         try:
@@ -125,6 +132,10 @@ class TransactionTests(unittest.TestCase):
         This tests the improved concurrency with pysqlite 2.3.4. You needed
         to roll back con2 before you could commit con1.
         """
+        if sqlite.sqlite_version_info < (3, 2, 2):
+            # This will fail (hang) on earlier versions of sqlite.
+            # Determine exact version it was fixed. 3.2.1 hangs.
+            return
         self.cur1.execute("create table test(i)")
         self.cur1.execute("insert into test(i) values (5)")
         try:
index d7a2df2..7a0b76c 100644 (file)
@@ -98,7 +98,7 @@ class DeclTypesTests(unittest.TestCase):
     def setUp(self):
         self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_DECLTYPES)
         self.cur = self.con.cursor()
-        self.cur.execute("create table test(i int, s str, f float, b bool, u unicode, foo foo, bin blob)")
+        self.cur.execute("create table test(i int, s str, f float, b bool, u unicode, foo foo, bin blob, n1 number, n2 number(5))")
 
         # override float, make them always return the same number
         sqlite.converters["FLOAT"] = lambda x: 47.2
@@ -107,11 +107,13 @@ class DeclTypesTests(unittest.TestCase):
         sqlite.converters["BOOL"] = lambda x: bool(int(x))
         sqlite.converters["FOO"] = DeclTypesTests.Foo
         sqlite.converters["WRONG"] = lambda x: "WRONG"
+        sqlite.converters["NUMBER"] = float
 
     def tearDown(self):
         del sqlite.converters["FLOAT"]
         del sqlite.converters["BOOL"]
         del sqlite.converters["FOO"]
+        del sqlite.converters["NUMBER"]
         self.cur.close()
         self.con.close()
 
@@ -203,6 +205,19 @@ class DeclTypesTests(unittest.TestCase):
         row = self.cur.fetchone()
         self.failUnlessEqual(row[0], val)
 
+    def CheckNumber1(self):
+        self.cur.execute("insert into test(n1) values (5)")
+        value = self.cur.execute("select n1 from test").fetchone()[0]
+        # if the converter is not used, it's an int instead of a float
+        self.failUnlessEqual(type(value), float)
+
+    def CheckNumber2(self):
+        """Checks wether converter names are cut off at '(' characters"""
+        self.cur.execute("insert into test(n2) values (5)")
+        value = self.cur.execute("select n2 from test").fetchone()[0]
+        # if the converter is not used, it's an int instead of a float
+        self.failUnlessEqual(type(value), float)
+
 class ColNamesTests(unittest.TestCase):
     def setUp(self):
         self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES)
index 1f5b7d6..f6de2b3 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -63,30 +63,13 @@ class DocBuilder(Command):
         pass
 
     def run(self):
-        import os, stat
-
+        import os, shutil
         try:
-            import docutils.core
-            import docutilsupport
-        except ImportError:
-            print "Error: the build-docs command requires docutils and SilverCity to be installed"
-            return
-
-        docfiles = {
-            "usage-guide.html": "usage-guide.txt",
-            "install-source.html": "install-source.txt",
-            "install-source-win32.html": "install-source-win32.txt"
-        }
-
-        os.chdir("doc")
-        for dest, source in docfiles.items():
-            if not os.path.exists(dest) or os.stat(dest)[stat.ST_MTIME] < os.stat(source)[stat.ST_MTIME]:
-                print "Building documentation file %s." % dest
-                docutils.core.publish_cmdline(
-                    writer_name='html',
-                    argv=["--stylesheet=default.css", source, dest])
-
-        os.chdir("..")
+            shutil.rmtree("build/doc")
+        except OSError:
+            pass
+        os.makedirs("build/doc")
+        os.system("sphinx-build doc/sphinx build/doc")
 
 def get_setup_args():
     PYSQLITE_VERSION = None
@@ -122,8 +105,8 @@ def get_setup_args():
             author_email = "gh@ghaering.de",
             license = "zlib/libpng license",
             platforms = "ALL",
-            url = "http://pysqlite.org/",
-            download_url = "http://initd.org/pub/software/pysqlite/releases/%s/%s/" % \
+            url = "http://oss.itsystementwicklung.de/trac/pysqlite",
+            download_url = "http://oss.itsystementwicklung.de/download/pysqlite/%s/%s/" % \
                 (PYSQLITE_MINOR_VERSION, PYSQLITE_VERSION),
 
 
@@ -152,7 +135,8 @@ def get_setup_args():
             "Programming Language :: C",
             "Programming Language :: Python",
             "Topic :: Database :: Database Engines/Servers",
-            "Topic :: Software Development :: Libraries :: Python Modules"]
+            "Topic :: Software Development :: Libraries :: Python Modules"],
+            cmdclass = {"build_docs": DocBuilder}
             )
     return setup_args
 
index e2ee01a..7dd0ffc 100644 (file)
 #define ACTION_FINALIZE 1
 #define ACTION_RESET 2
 
+#if SQLITE_VERSION_NUMBER >= 3003008
+#define HAVE_LOAD_EXTENSION
+#endif
+
 static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level);
 
 
-void _sqlite3_result_error(sqlite3_context* ctx, const char* errmsg, int len)
+static void _sqlite3_result_error(sqlite3_context* ctx, const char* errmsg, int len)
 {
     /* in older SQLite versions, calling sqlite3_result_error in callbacks
      * triggers a bug in SQLite that leads either to irritating results or
@@ -363,7 +367,7 @@ PyObject* _pysqlite_connection_begin(pysqlite_Connection* self)
         goto error;
     }
 
-    rc = _sqlite_step_with_busyhandler(statement, self);
+    rc = pysqlite_step(statement, self);
     if (rc == SQLITE_DONE) {
         self->inTransaction = 1;
     } else {
@@ -406,7 +410,7 @@ PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args)
             goto error;
         }
 
-        rc = _sqlite_step_with_busyhandler(statement, self);
+        rc = pysqlite_step(statement, self);
         if (rc == SQLITE_DONE) {
             self->inTransaction = 0;
         } else {
@@ -452,7 +456,7 @@ PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args
             goto error;
         }
 
-        rc = _sqlite_step_with_busyhandler(statement, self);
+        rc = pysqlite_step(statement, self);
         if (rc == SQLITE_DONE) {
             self->inTransaction = 0;
         } else {
@@ -849,9 +853,9 @@ static int _progress_handler(void* user_arg)
         rc = 1; 
     } else {
         rc = (int)PyObject_IsTrue(ret);
+        Py_DECREF(ret);
     }
 
-    Py_DECREF(ret);
     PyGILState_Release(gilstate);
     return rc;
 }
@@ -905,6 +909,28 @@ PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* self, Py
     return Py_None;
 }
 
+#ifdef HAVE_LOAD_EXTENSION
+PyObject* pysqlite_enable_load_extension(pysqlite_Connection* self, PyObject* args)
+{
+    int rc;
+    int onoff;
+
+    if (!PyArg_ParseTuple(args, "i", &onoff)) {
+        return NULL;
+    }
+
+    rc = sqlite3_enable_load_extension(self->db, onoff);
+
+    if (rc != SQLITE_OK) {
+        PyErr_SetString(pysqlite_OperationalError, "Error enabling load extension");
+        return NULL;
+    } else {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+}
+#endif
+
 int pysqlite_check_thread(pysqlite_Connection* self)
 {
     if (self->check_same_thread) {
@@ -940,6 +966,7 @@ static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, Py
 {
     PyObject* res;
     PyObject* begin_statement;
+    char* begin_statement_str;
 
     Py_XDECREF(self->isolation_level);
 
@@ -972,12 +999,18 @@ static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, Py
             return -1;
         }
 
-        self->begin_statement = PyMem_Malloc(PyString_Size(begin_statement) + 2);
+        begin_statement_str = PyString_AsString(begin_statement);
+        if (!begin_statement_str) {
+            Py_DECREF(begin_statement);
+            return -1;
+        }
+        self->begin_statement = PyMem_Malloc(strlen(begin_statement_str) + 2);
         if (!self->begin_statement) {
+            Py_DECREF(begin_statement);
             return -1;
         }
 
-        strcpy(self->begin_statement, PyString_AsString(begin_statement));
+        strcpy(self->begin_statement, begin_statement_str);
         Py_DECREF(begin_statement);
     }
 
@@ -1014,19 +1047,16 @@ PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, Py
             _pysqlite_seterror(self->db, NULL);
         }
 
-        Py_DECREF(statement);
-        statement = 0;
+        Py_CLEAR(statement);
     } else {
         weakref = PyWeakref_NewRef((PyObject*)statement, NULL);
         if (!weakref) {
-            Py_DECREF(statement);
-            statement = 0;
+            Py_CLEAR(statement);
             goto error;
         }
 
         if (PyList_Append(self->statements, weakref) != 0) {
-            Py_DECREF(weakref);
-            statement = 0;
+            Py_CLEAR(weakref);
             goto error;
         }
 
@@ -1050,15 +1080,13 @@ PyObject* pysqlite_connection_execute(pysqlite_Connection* self, PyObject* args,
 
     method = PyObject_GetAttrString(cursor, "execute");
     if (!method) {
-        Py_DECREF(cursor);
-        cursor = 0;
+        Py_CLEAR(cursor);
         goto error;
     }
 
     result = PyObject_CallObject(method, args);
     if (!result) {
-        Py_DECREF(cursor);
-        cursor = 0;
+        Py_CLEAR(cursor);
     }
 
 error:
@@ -1081,15 +1109,13 @@ PyObject* pysqlite_connection_executemany(pysqlite_Connection* self, PyObject* a
 
     method = PyObject_GetAttrString(cursor, "executemany");
     if (!method) {
-        Py_DECREF(cursor);
-        cursor = 0;
+        Py_CLEAR(cursor);
         goto error;
     }
 
     result = PyObject_CallObject(method, args);
     if (!result) {
-        Py_DECREF(cursor);
-        cursor = 0;
+        Py_CLEAR(cursor);
     }
 
 error:
@@ -1112,15 +1138,13 @@ PyObject* pysqlite_connection_executescript(pysqlite_Connection* self, PyObject*
 
     method = PyObject_GetAttrString(cursor, "executescript");
     if (!method) {
-        Py_DECREF(cursor);
-        cursor = 0;
+        Py_CLEAR(cursor);
         goto error;
     }
 
     result = PyObject_CallObject(method, args);
     if (!result) {
-        Py_DECREF(cursor);
-        cursor = 0;
+        Py_CLEAR(cursor);
     }
 
 error:
@@ -1199,6 +1223,52 @@ finally:
     return retval;
 }
 
+/* Function author: Paul Kippes <kippesp@gmail.com>
+ * Class method of Connection to call the Python function _iterdump
+ * of the sqlite3 module.
+ */
+static PyObject *
+pysqlite_connection_iterdump(pysqlite_Connection* self, PyObject* args)
+{
+    PyObject* retval = NULL;
+    PyObject* module = NULL;
+    PyObject* module_dict;
+    PyObject* pyfn_iterdump;
+
+    if (!pysqlite_check_connection(self)) {
+        goto finally;
+    }
+
+    module = PyImport_ImportModule("pysqlite2.dump");
+    if (!module) {
+        goto finally;
+    }
+
+    module_dict = PyModule_GetDict(module);
+    if (!module_dict) {
+        goto finally;
+    }
+
+    pyfn_iterdump = PyDict_GetItemString(module_dict, "_iterdump");
+    if (!pyfn_iterdump) {
+        PyErr_SetString(pysqlite_OperationalError, "Failed to obtain _iterdump() reference");
+        goto finally;
+    }
+
+    args = PyTuple_New(1);
+    if (!args) {
+        goto finally;
+    }
+    Py_INCREF(self);
+    PyTuple_SetItem(args, 0, (PyObject*)self);
+    retval = PyObject_CallObject(pyfn_iterdump, args);
+
+finally:
+    Py_XDECREF(args);
+    Py_XDECREF(module);
+    return retval;
+}
+
 static PyObject *
 pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args)
 {
@@ -1332,6 +1402,10 @@ static PyMethodDef connection_methods[] = {
         PyDoc_STR("Creates a new aggregate. Non-standard.")},
     {"set_authorizer", (PyCFunction)pysqlite_connection_set_authorizer, METH_VARARGS|METH_KEYWORDS,
         PyDoc_STR("Sets authorizer callback. Non-standard.")},
+    #ifdef HAVE_LOAD_EXTENSION
+    {"enable_load_extension", (PyCFunction)pysqlite_enable_load_extension, METH_VARARGS,
+        PyDoc_STR("Enable dynamic loading of SQLite extension modules. Non-standard.")},
+    #endif
     {"set_progress_handler", (PyCFunction)pysqlite_connection_set_progress_handler, METH_VARARGS|METH_KEYWORDS,
         PyDoc_STR("Sets progress handler callback. Non-standard.")},
     {"execute", (PyCFunction)pysqlite_connection_execute, METH_VARARGS,
@@ -1344,6 +1418,8 @@ static PyMethodDef connection_methods[] = {
         PyDoc_STR("Creates a collation function. Non-standard.")},
     {"interrupt", (PyCFunction)pysqlite_connection_interrupt, METH_NOARGS,
         PyDoc_STR("Abort any pending database operation. Non-standard.")},
+    {"iterdump", (PyCFunction)pysqlite_connection_iterdump, METH_NOARGS,
+        PyDoc_STR("Returns iterator to the dump of the database in an SQL text format. Non-standard.")},
     {"__enter__", (PyCFunction)pysqlite_connection_enter, METH_NOARGS,
         PyDoc_STR("For context manager. Non-standard.")},
     {"__exit__", (PyCFunction)pysqlite_connection_exit, METH_VARARGS,
index a9a2815..2dc613e 100644 (file)
@@ -101,10 +101,7 @@ int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs
 
     self->arraysize = 1;
 
-    self->rowcount = PyInt_FromLong(-1L);
-    if (!self->rowcount) {
-        return -1;
-    }
+    self->rowcount = -1L;
 
     Py_INCREF(Py_None);
     self->row_factory = Py_None;
@@ -130,7 +127,6 @@ void pysqlite_cursor_dealloc(pysqlite_Cursor* self)
     Py_XDECREF(self->row_cast_map);
     Py_XDECREF(self->description);
     Py_XDECREF(self->lastrowid);
-    Py_XDECREF(self->rowcount);
     Py_XDECREF(self->row_factory);
     Py_XDECREF(self->next_row);
 
@@ -202,7 +198,11 @@ int pysqlite_build_row_cast_map(pysqlite_Cursor* self)
             decltype = sqlite3_column_decltype(self->statement->st, i);
             if (decltype) {
                 for (pos = decltype;;pos++) {
-                    if (*pos == ' ' || *pos == 0) {
+                    /* Converter names are split at '(' and blanks.
+                     * This allows 'INTEGER NOT NULL' to be treated as 'INTEGER' and
+                     * 'NUMBER(10)' to be treated as 'NUMBER', for example.
+                     * In other words, it will work as people expect it to work.*/
+                    if (*pos == ' ' || *pos == '(' || *pos == 0) {
                         py_decltype = PyString_FromStringAndSize(decltype, pos - decltype);
                         if (!py_decltype) {
                             return -1;
@@ -423,12 +423,16 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
     int statement_type;
     PyObject* descriptor;
     PyObject* second_argument = NULL;
-    long rowcount = 0;
+    int allow_8bit_chars;
 
     if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) {
         return NULL;
     }
 
+    /* Make shooting yourself in the foot with not utf-8 decodable 8-bit-strings harder */
+    allow_8bit_chars = ((self->connection->text_factory != (PyObject*)&PyUnicode_Type) &&
+        (self->connection->text_factory != (PyObject*)&PyUnicode_Type && pysqlite_OptimizedUnicode));
+
     Py_XDECREF(self->next_row);
     self->next_row = NULL;
 
@@ -506,10 +510,11 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
         operation_cstr = PyString_AsString(operation_bytestr);
     }
 
-    /* reset description */
+    /* reset description and rowcount */
     Py_DECREF(self->description);
     Py_INCREF(Py_None);
     self->description = Py_None;
+    self->rowcount = -1L;
 
     func_args = PyTuple_New(1);
     if (!func_args) {
@@ -540,7 +545,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
         }
         rc = pysqlite_statement_create(self->statement, self->connection, operation);
         if (rc != SQLITE_OK) {
-            self->statement = 0;
+            Py_CLEAR(self->statement);
             goto error;
         }
     }
@@ -592,20 +597,15 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
 
         pysqlite_statement_mark_dirty(self->statement);
 
-        pysqlite_statement_bind_parameters(self->statement, parameters);
+        pysqlite_statement_bind_parameters(self->statement, parameters, allow_8bit_chars);
         if (PyErr_Occurred()) {
             goto error;
         }
 
-        if (pysqlite_build_row_cast_map(self) != 0) {
-            PyErr_SetString(pysqlite_OperationalError, "Error while building row_cast_map");
-            goto error;
-        }
-
         /* Keep trying the SQL statement until the schema stops changing. */
         while (1) {
             /* Actually execute the SQL statement. */
-            rc = _sqlite_step_with_busyhandler(self->statement->st, self->connection);
+            rc = pysqlite_step(self->statement->st, self->connection);
             if (rc == SQLITE_DONE ||  rc == SQLITE_ROW) {
                 /* If it worked, let's get out of the loop */
                 break;
@@ -639,6 +639,11 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
             }
         }
 
+        if (pysqlite_build_row_cast_map(self) != 0) {
+            PyErr_SetString(pysqlite_OperationalError, "Error while building row_cast_map");
+            goto error;
+        }
+
         if (rc == SQLITE_ROW || (rc == SQLITE_DONE && statement_type == STATEMENT_SELECT)) {
             if (self->description == Py_None) {
                 Py_BEGIN_ALLOW_THREADS
@@ -676,8 +681,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
             self->next_row = _pysqlite_fetch_one_row(self);
         } else if (rc == SQLITE_DONE && !multiple) {
             pysqlite_statement_reset(self->statement);
-            Py_DECREF(self->statement);
-            self->statement = 0;
+            Py_CLEAR(self->statement);
         }
 
         switch (statement_type) {
@@ -685,7 +689,10 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
             case STATEMENT_DELETE:
             case STATEMENT_INSERT:
             case STATEMENT_REPLACE:
-                rowcount += (long)sqlite3_changes(self->connection->db);
+                if (self->rowcount == -1L) {
+                    self->rowcount = 0L;
+                }
+                self->rowcount += (long)sqlite3_changes(self->connection->db);
         }
 
         Py_DECREF(self->lastrowid);
@@ -720,13 +727,9 @@ error:
     Py_XDECREF(parameters_list);
 
     if (PyErr_Occurred()) {
-        Py_DECREF(self->rowcount);
-        self->rowcount = PyInt_FromLong(-1L);
+        self->rowcount = -1L;
         return NULL;
     } else {
-        Py_DECREF(self->rowcount);
-        self->rowcount = PyInt_FromLong(rowcount);
-
         Py_INCREF(self);
         return (PyObject*)self;
     }
@@ -787,11 +790,13 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
         }
         statement_completed = 1;
 
+        Py_BEGIN_ALLOW_THREADS
         rc = sqlite3_prepare(self->connection->db,
                              script_cstr,
                              -1,
                              &statement,
                              &script_cstr);
+        Py_END_ALLOW_THREADS
         if (rc != SQLITE_OK) {
             _pysqlite_seterror(self->connection->db, NULL);
             goto error;
@@ -800,7 +805,7 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
         /* execute statement, and ignore results of SELECT statements */
         rc = SQLITE_ROW;
         while (rc == SQLITE_ROW) {
-            rc = _sqlite_step_with_busyhandler(statement, self->connection);
+            rc = pysqlite_step(statement, self->connection);
             /* TODO: we probably need more error handling here */
         }
 
@@ -868,7 +873,7 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self)
     }
 
     if (self->statement) {
-        rc = _sqlite_step_with_busyhandler(self->statement->st, self->connection);
+        rc = pysqlite_step(self->statement->st, self->connection);
         if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
             (void)pysqlite_statement_reset(self->statement);
             Py_DECREF(next_row);
@@ -984,8 +989,7 @@ PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args)
 
     if (self->statement) {
         (void)pysqlite_statement_reset(self->statement);
-        Py_DECREF(self->statement);
-        self->statement = 0;
+        Py_CLEAR(self->statement);
     }
 
     Py_INCREF(Py_None);
@@ -1020,7 +1024,7 @@ static struct PyMemberDef cursor_members[] =
     {"description", T_OBJECT, offsetof(pysqlite_Cursor, description), RO},
     {"arraysize", T_INT, offsetof(pysqlite_Cursor, arraysize), 0},
     {"lastrowid", T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), RO},
-    {"rowcount", T_OBJECT, offsetof(pysqlite_Cursor, rowcount), RO},
+    {"rowcount", T_LONG, offsetof(pysqlite_Cursor, rowcount), RO},
     {"row_factory", T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0},
     {NULL}
 };
index d916ca5..54d816d 100644 (file)
@@ -37,7 +37,7 @@ typedef struct
     PyObject* row_cast_map;
     int arraysize;
     PyObject* lastrowid;
-    PyObject* rowcount;
+    long rowcount;
     PyObject* row_factory;
     pysqlite_Statement* statement;
 
index 5a78917..c730afa 100644 (file)
 
 PyObject *psyco_adapters;
 
-/* microprotocols_init - initialize the adapters dictionary */
+/* pysqlite_microprotocols_init - initialize the adapters dictionary */
 
 int
-microprotocols_init(PyObject *dict)
+pysqlite_microprotocols_init(PyObject *dict)
 {
     /* create adapters dictionary and put it in module namespace */
     if ((psyco_adapters = PyDict_New()) == NULL) {
@@ -49,10 +49,10 @@ microprotocols_init(PyObject *dict)
 }
 
 
-/* microprotocols_add - add a reverse type-caster to the dictionary */
+/* pysqlite_microprotocols_add - add a reverse type-caster to the dictionary */
 
 int
-microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
+pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
 {
     PyObject* key;
     int rc;
@@ -70,10 +70,10 @@ microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
     return rc;
 }
 
-/* microprotocols_adapt - adapt an object to the built-in protocol */
+/* pysqlite_microprotocols_adapt - adapt an object to the built-in protocol */
 
 PyObject *
-microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
+pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
 {
     PyObject *adapter, *key;
 
@@ -132,11 +132,11 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
 /** module-level functions **/
 
&nbs