]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- rework the sphinx customizations into distinct modules
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 19 Oct 2012 23:20:18 +0000 (19:20 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 19 Oct 2012 23:20:18 +0000 (19:20 -0400)
- build a new Sphinx extension that allows dialect info
to be entered as directives which is then rendered consistently
throughout all dialect/dbapi sections
- break out the "empty_strings" requirement for oracle test

54 files changed:
CHANGES
doc/build/builder/__init__.py
doc/build/builder/autodoc_mods.py [new file with mode: 0644]
doc/build/builder/builders.py [deleted file]
doc/build/builder/dialect_info.py [new file with mode: 0644]
doc/build/builder/mako.py [new file with mode: 0644]
doc/build/builder/sqlformatter.py [new file with mode: 0644]
doc/build/conf.py
doc/build/dialects/drizzle.rst
doc/build/dialects/firebird.rst
doc/build/dialects/informix.rst
doc/build/dialects/mssql.rst
doc/build/dialects/mysql.rst
doc/build/dialects/oracle.rst
doc/build/dialects/postgresql.rst
doc/build/dialects/sybase.rst
lib/sqlalchemy/dialects/drizzle/base.py
lib/sqlalchemy/dialects/drizzle/mysqldb.py
lib/sqlalchemy/dialects/firebird/base.py
lib/sqlalchemy/dialects/firebird/fdb.py
lib/sqlalchemy/dialects/firebird/kinterbasdb.py
lib/sqlalchemy/dialects/informix/base.py
lib/sqlalchemy/dialects/informix/informixdb.py
lib/sqlalchemy/dialects/mssql/adodbapi.py
lib/sqlalchemy/dialects/mssql/base.py
lib/sqlalchemy/dialects/mssql/mxodbc.py
lib/sqlalchemy/dialects/mssql/pymssql.py
lib/sqlalchemy/dialects/mssql/pyodbc.py
lib/sqlalchemy/dialects/mssql/zxjdbc.py
lib/sqlalchemy/dialects/mysql/base.py
lib/sqlalchemy/dialects/mysql/gaerdbms.py
lib/sqlalchemy/dialects/mysql/mysqlconnector.py
lib/sqlalchemy/dialects/mysql/mysqldb.py
lib/sqlalchemy/dialects/mysql/oursql.py
lib/sqlalchemy/dialects/mysql/pymysql.py
lib/sqlalchemy/dialects/mysql/pyodbc.py
lib/sqlalchemy/dialects/mysql/zxjdbc.py
lib/sqlalchemy/dialects/oracle/base.py
lib/sqlalchemy/dialects/oracle/cx_oracle.py
lib/sqlalchemy/dialects/oracle/zxjdbc.py
lib/sqlalchemy/dialects/postgresql/base.py
lib/sqlalchemy/dialects/postgresql/pg8000.py
lib/sqlalchemy/dialects/postgresql/psycopg2.py
lib/sqlalchemy/dialects/postgresql/pypostgresql.py
lib/sqlalchemy/dialects/postgresql/zxjdbc.py
lib/sqlalchemy/dialects/sqlite/base.py
lib/sqlalchemy/dialects/sqlite/pysqlite.py
lib/sqlalchemy/dialects/sybase/base.py
lib/sqlalchemy/dialects/sybase/mxodbc.py
lib/sqlalchemy/dialects/sybase/pyodbc.py
lib/sqlalchemy/dialects/sybase/pysybase.py
lib/sqlalchemy/testing/requirements.py
lib/sqlalchemy/testing/suite/test_types.py
test/requirements.py

diff --git a/CHANGES b/CHANGES
index 89f62ffd84689e9b353f8d1e9662f78b65b4b372..f1301ba281f1091aaaeae0236f7feb6702358baf 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -288,9 +288,10 @@ underneath "0.7.xx".
     without producing history events. [ticket:2582]
 
   - [feature] ORM entities can be passed
-    to select() as well as the select_from(),
+    to the core select() construct as well
+    as to the select_from(),
     correlate(), and correlate_except()
-    methods, where they will be unwrapped
+    methods of select(), where they will be unwrapped
     into selectables. [ticket:2245]
 
   - [feature] Some support for auto-rendering of a
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0e29e69c46e5b6f6ef698ee5daee3b7248df880c 100644 (file)
@@ -0,0 +1,12 @@
+
+
+from . import autodoc_mods, dialect_info, sqlformatter, mako
+
+def setup(app):
+    app.add_config_value('release_date', "", True)
+    app.add_config_value('site_base', "", True)
+    app.add_config_value('build_number', "", 1)
+    mako.setup(app)
+    autodoc_mods.setup(app)
+    dialect_info.setup(app)
+    sqlformatter.setup(app)
diff --git a/doc/build/builder/autodoc_mods.py b/doc/build/builder/autodoc_mods.py
new file mode 100644 (file)
index 0000000..8c687fb
--- /dev/null
@@ -0,0 +1,47 @@
+import re
+
+def autodoc_skip_member(app, what, name, obj, skip, options):
+    if what == 'class' and skip and \
+        name in ('__init__', '__eq__', '__ne__', '__lt__',
+                    '__le__', '__call__') and \
+        obj.__doc__:
+        return False
+    else:
+        return skip
+
+# im sure this is in the app somewhere, but I don't really
+# know where, so we're doing it here.
+_track_autodoced = {}
+def autodoc_process_docstring(app, what, name, obj, options, lines):
+    if what == "class":
+        _track_autodoced[name] = obj
+    elif what in ("attribute", "method") and \
+        options.get("inherited-members"):
+        m = re.match(r'(.*?)\.([\w_]+)$', name)
+        if m:
+            clsname, attrname = m.group(1, 2)
+            if clsname in _track_autodoced:
+                cls = _track_autodoced[clsname]
+                for supercls in cls.__mro__:
+                    if attrname in supercls.__dict__:
+                        break
+                if supercls is not cls:
+                    lines[:0] = [
+                        ".. container:: inherited_member",
+                        "",
+                        "    *inherited from the* :%s:`.%s.%s` *%s of* :class:`.%s`" % (
+                                    "attr" if what == "attribute"
+                                    else "meth",
+                                    supercls.__name__,
+                                    attrname,
+                                    what,
+                                    supercls.__name__
+                                ),
+                        ""
+                    ]
+
+
+def setup(app):
+    app.connect('autodoc-skip-member', autodoc_skip_member)
+    app.connect('autodoc-process-docstring', autodoc_process_docstring)
+
diff --git a/doc/build/builder/builders.py b/doc/build/builder/builders.py
deleted file mode 100644 (file)
index 0776bd4..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-from sphinx.application import TemplateBridge
-from sphinx.builders.html import StandaloneHTMLBuilder
-from sphinx.highlighting import PygmentsBridge
-from sphinx.jinja2glue import BuiltinTemplateLoader
-from pygments import highlight
-from pygments.lexer import RegexLexer, bygroups, using
-from pygments.token import *
-from pygments.filter import Filter, apply_filters
-from pygments.lexers import PythonLexer, PythonConsoleLexer
-from pygments.formatters import HtmlFormatter, LatexFormatter
-import re
-from mako.lookup import TemplateLookup
-from mako.template import Template
-from mako import __version__
-import os
-
-rtd = os.environ.get('READTHEDOCS', None) == 'True'
-
-class MakoBridge(TemplateBridge):
-    def init(self, builder, *args, **kw):
-        self.jinja2_fallback = BuiltinTemplateLoader()
-        self.jinja2_fallback.init(builder, *args, **kw)
-
-        builder.config.html_context['release_date'] = builder.config['release_date']
-        builder.config.html_context['site_base'] = builder.config['site_base']
-
-        self.lookup = TemplateLookup(directories=builder.config.templates_path,
-            #format_exceptions=True,
-            imports=[
-                "from builder import util"
-            ]
-        )
-
-        if rtd:
-            import urllib2
-            template_url = builder.config['site_base'] + "/docs_base.mako"
-            template = urllib2.urlopen(template_url).read()
-            self.lookup.put_string("/rtd_base.mako", template)
-
-    def render(self, template, context):
-        template = template.replace(".html", ".mako")
-        context['prevtopic'] = context.pop('prev', None)
-        context['nexttopic'] = context.pop('next', None)
-        version = context['version']
-        pathto = context['pathto']
-
-        # RTD layout
-        if rtd:
-            # add variables if not present, such
-            # as if local test of READTHEDOCS variable
-            if 'MEDIA_URL' not in context:
-                context['MEDIA_URL'] = "http://media.readthedocs.org/"
-            if 'slug' not in context:
-                context['slug'] = context['project'].lower()
-            if 'url' not in context:
-                context['url'] = "/some/test/url"
-            if 'current_version' not in context:
-                context['current_version'] = "latest"
-
-            if 'name' not in context:
-                context['name'] = context['project'].lower()
-
-            context['rtd'] = True
-            context['toolbar'] = True
-            context['layout'] = "rtd_layout.mako"
-            context['base'] = "rtd_base.mako"
-            context['pdf_url'] = "%spdf/%s/%s/%s.pdf" % (
-                    context['MEDIA_URL'],
-                    context['slug'],
-                    context['current_version'],
-                    context['slug']
-            )
-        # local docs layout
-        else:
-            context['rtd'] = False
-            context['toolbar'] = False
-            context['layout'] = "layout.mako"
-            context['base'] = "static_base.mako"
-
-        context.setdefault('_', lambda x:x)
-        return self.lookup.get_template(template).render_unicode(**context)
-
-    def render_string(self, template, context):
-        # this is used for  .js, .css etc. and we don't have
-        # local copies of that stuff here so use the jinja render.
-        return self.jinja2_fallback.render_string(template, context)
-
-class StripDocTestFilter(Filter):
-    def filter(self, lexer, stream):
-        for ttype, value in stream:
-            if ttype is Token.Comment and re.match(r'#\s*doctest:', value):
-                continue
-            yield ttype, value
-
-class PyConWithSQLLexer(RegexLexer):
-    name = 'PyCon+SQL'
-    aliases = ['pycon+sql']
-
-    flags = re.IGNORECASE | re.DOTALL
-
-    tokens = {
-            'root': [
-                (r'{sql}', Token.Sql.Link, 'sqlpopup'),
-                (r'{opensql}', Token.Sql.Open, 'opensqlpopup'),
-                (r'.*?\n', using(PythonConsoleLexer))
-            ],
-            'sqlpopup':[
-                (
-                    r'(.*?\n)((?:PRAGMA|BEGIN|SELECT|INSERT|DELETE|ROLLBACK|COMMIT|ALTER|UPDATE|CREATE|DROP|PRAGMA|DESCRIBE).*?(?:{stop}\n?|$))',
-                    bygroups(using(PythonConsoleLexer), Token.Sql.Popup),
-                    "#pop"
-                )
-            ],
-            'opensqlpopup':[
-                (
-                    r'.*?(?:{stop}\n*|$)',
-                    Token.Sql,
-                    "#pop"
-                )
-            ]
-        }
-
-
-class PythonWithSQLLexer(RegexLexer):
-    name = 'Python+SQL'
-    aliases = ['pycon+sql']
-
-    flags = re.IGNORECASE | re.DOTALL
-
-    tokens = {
-            'root': [
-                (r'{sql}', Token.Sql.Link, 'sqlpopup'),
-                (r'{opensql}', Token.Sql.Open, 'opensqlpopup'),
-                (r'.*?\n', using(PythonLexer))
-            ],
-            'sqlpopup':[
-                (
-                    r'(.*?\n)((?:PRAGMA|BEGIN|SELECT|INSERT|DELETE|ROLLBACK|COMMIT|ALTER|UPDATE|CREATE|DROP|PRAGMA|DESCRIBE).*?(?:{stop}\n?|$))',
-                    bygroups(using(PythonLexer), Token.Sql.Popup),
-                    "#pop"
-                )
-            ],
-            'opensqlpopup':[
-                (
-                    r'.*?(?:{stop}\n*|$)',
-                    Token.Sql,
-                    "#pop"
-                )
-            ]
-        }
-
-
-def _strip_trailing_whitespace(iter_):
-    buf = list(iter_)
-    if buf:
-        buf[-1] = (buf[-1][0], buf[-1][1].rstrip())
-    for t, v in buf:
-        yield t, v
-
-class PopupSQLFormatter(HtmlFormatter):
-    def _format_lines(self, tokensource):
-        buf = []
-        for ttype, value in apply_filters(tokensource, [StripDocTestFilter()]):
-            if ttype in Token.Sql:
-                for t, v in HtmlFormatter._format_lines(self, iter(buf)):
-                    yield t, v
-                buf = []
-
-                if ttype is Token.Sql:
-                    yield 1, "<div class='show_sql'>%s</div>" % re.sub(r'(?:[{stop}|\n]*)$', '', value)
-                elif ttype is Token.Sql.Link:
-                    yield 1, "<a href='#' class='sql_link'>sql</a>"
-                elif ttype is Token.Sql.Popup:
-                    yield 1, "<div class='popup_sql'>%s</div>" % re.sub(r'(?:[{stop}|\n]*)$', '', value)
-            else:
-                buf.append((ttype, value))
-
-        for t, v in _strip_trailing_whitespace(HtmlFormatter._format_lines(self, iter(buf))):
-            yield t, v
-
-class PopupLatexFormatter(LatexFormatter):
-    def _filter_tokens(self, tokensource):
-        for ttype, value in apply_filters(tokensource, [StripDocTestFilter()]):
-            if ttype in Token.Sql:
-                if ttype is not Token.Sql.Link and ttype is not Token.Sql.Open:
-                    yield Token.Literal, re.sub(r'{stop}', '', value)
-                else:
-                    continue
-            else:
-                yield ttype, value
-
-    def format(self, tokensource, outfile):
-        LatexFormatter.format(self, self._filter_tokens(tokensource), outfile)
-
-def autodoc_skip_member(app, what, name, obj, skip, options):
-    if what == 'class' and skip and \
-        name in ('__init__', '__eq__', '__ne__', '__lt__', '__le__', '__call__') and \
-        obj.__doc__:
-        return False
-    else:
-        return skip
-
-# im sure this is in the app somewhere, but I don't really
-# know where, so we're doing it here.
-_track_autodoced = {}
-def autodoc_process_docstring(app, what, name, obj, options, lines):
-    if what == "class":
-        _track_autodoced[name] = obj
-    elif what in ("attribute", "method") and \
-        options.get("inherited-members"):
-        m = re.match(r'(.*?)\.([\w_]+)$', name)
-        if m:
-            clsname, attrname = m.group(1, 2)
-            if clsname in _track_autodoced:
-                cls = _track_autodoced[clsname]
-                for supercls in cls.__mro__:
-                    if attrname in supercls.__dict__:
-                        break
-                if supercls is not cls:
-                    lines[:0] = [
-                        ".. container:: inherited_member",
-                        "",
-                        "    *inherited from the* :%s:`.%s.%s` *%s of* :class:`.%s`" % (
-                                    "attr" if what == "attribute"
-                                    else "meth",
-                                    supercls.__name__,
-                                    attrname,
-                                    what,
-                                    supercls.__name__
-                                ),
-                        ""
-                    ]
-
-def setup(app):
-    app.add_lexer('pycon+sql', PyConWithSQLLexer())
-    app.add_lexer('python+sql', PythonWithSQLLexer())
-    app.add_config_value('release_date', "", True)
-    app.add_config_value('site_base', "", True)
-    app.add_config_value('build_number', "", 1)
-    app.connect('autodoc-skip-member', autodoc_skip_member)
-    app.connect('autodoc-process-docstring', autodoc_process_docstring)
-    PygmentsBridge.html_formatter = PopupSQLFormatter
-    PygmentsBridge.latex_formatter = PopupLatexFormatter
-
diff --git a/doc/build/builder/dialect_info.py b/doc/build/builder/dialect_info.py
new file mode 100644 (file)
index 0000000..808b3cd
--- /dev/null
@@ -0,0 +1,175 @@
+import re
+from sphinx.util.compat import Directive
+from docutils import nodes
+
+class DialectDirective(Directive):
+    has_content = True
+
+    _dialects = {}
+
+    def _parse_content(self):
+        d = {}
+        d['default'] = self.content[0]
+        d['text'] = []
+        idx = 0
+        for line in self.content[1:]:
+            idx += 1
+            m = re.match(r'\:(.+?)\: +(.+)', line)
+            if m:
+                attrname, value = m.group(1, 2)
+                d[attrname] = value
+            else:
+                break
+        d["text"] = self.content[idx + 1:]
+        return d
+
+    def _dbapi_node(self):
+
+        dialect_name, dbapi_name = self.dialect_name.split("+")
+
+        try:
+            dialect_directive = self._dialects[dialect_name]
+        except KeyError:
+            raise Exception("No .. dialect:: %s directive has been established"
+                                    % dialect_name)
+
+        output = []
+
+        content = self._parse_content()
+
+        parent_section_ref = self.state.parent.children[0]['ids'][0]
+        self._append_dbapi_bullet(dialect_name, dbapi_name,
+                                        content['name'], parent_section_ref)
+
+        p = nodes.paragraph('', '',
+                    nodes.Text(
+                        "Support for the %s database via the %s driver." % (
+                                dialect_directive.database_name,
+                                content['name']
+                        ),
+                        "Support for the %s database via the %s driver." % (
+                                dialect_directive.database_name,
+                                content['name']
+                        )
+                    ),
+        )
+
+        self.state.nested_parse(content['text'], 0, p)
+        output.append(p)
+
+        if "url" in content or "driverurl" in content:
+            sec = nodes.section(
+                    '',
+                    nodes.title("DBAPI", "DBAPI"),
+                    ids=["dialect-%s-%s-url" % (dialect_name, dbapi_name)]
+            )
+            if "url" in content:
+                text = "%s is available at:\n" % dbapi_name
+                uri = content['url']
+                sec.append(
+                    nodes.paragraph('', '',
+                        nodes.Text(text, text),
+                        nodes.reference('', '',
+                            nodes.Text(uri, uri),
+                            refuri=uri,
+                        )
+                    )
+                )
+            if "driverurl" in content:
+                text = "Drivers for this database are available at:\n"
+                sec.append(
+                    nodes.paragraph('', '',
+                        nodes.Text(text, text),
+                        nodes.reference('', '',
+                            nodes.Text(content['driverurl'], content['driverurl']),
+                            refuri=content['driverurl']
+                        )
+                    )
+                )
+            output.append(sec)
+
+
+        if "connectstring" in content:
+            # TODO: wish I knew how to just embed RST here and parse it into
+            # nodes
+            sec = nodes.section(
+                    '',
+                    nodes.title("Connecting", "Connecting"),
+                    nodes.paragraph('', '',
+                        nodes.Text("Connect String:", "Connect String:"),
+                        nodes.literal_block(content['connectstring'],
+                            content['connectstring'])
+                    ),
+                    ids=["dialect-%s-%s-connect" % (dialect_name, dbapi_name)]
+            )
+            output.append(sec)
+
+        return output
+
+    def _dialect_node(self):
+        self._dialects[self.dialect_name] = self
+
+        content = self._parse_content()
+        self.database_name = content['name']
+
+        self.bullets = nodes.bullet_list()
+        text = "The following dialect/DBAPI options are available.  "\
+                "Please refer to individual DBAPI sections for connect information."
+        sec = nodes.section('',
+                nodes.paragraph('', '',
+                    nodes.Text(
+                        "Support for the %s database." % content['name'],
+                        "Support for the %s database." % content['name']
+                    ),
+                ),
+                nodes.title("DBAPI Support", "DBAPI Support"),
+                nodes.paragraph('', '',
+                    nodes.Text(text, text),
+                    self.bullets
+                ),
+                ids=["dialect-%s" % self.dialect_name]
+            )
+
+        return [sec]
+
+    def _append_dbapi_bullet(self, dialect_name, dbapi_name, name, idname):
+        env = self.state.document.settings.env
+        dialect_directive = self._dialects[dialect_name]
+
+        list_node = nodes.list_item('',
+                nodes.paragraph('', '',
+                    nodes.reference('', '',
+                                nodes.Text(name, name),
+                                refdocname=self.docname,
+                                refuri=env.app.builder.get_relative_uri(
+                                        dialect_directive.docname, self.docname) +
+                                            "#" + idname
+                            ),
+                    #nodes.Text(" ", " "),
+                    #nodes.reference('', '',
+                    #            nodes.Text("(connectstring)", "(connectstring)"),
+                    #            refdocname=self.docname,
+                    #            refuri=env.app.builder.get_relative_uri(
+                    #                    dialect_directive.docname, self.docname) +
+                    ##                        "#" + ("dialect-%s-%s-connect" %
+                    #                                (dialect_name, dbapi_name))
+                    #        )
+                    )
+            )
+        dialect_directive.bullets.append(list_node)
+
+    def run(self):
+        env = self.state.document.settings.env
+        self.docname = env.docname
+
+        self.dialect_name = dialect_name = self.content[0]
+
+        has_dbapi = "+" in dialect_name
+        if has_dbapi:
+            return self._dbapi_node()
+        else:
+            return self._dialect_node()
+
+def setup(app):
+    app.add_directive('dialect', DialectDirective)
+
diff --git a/doc/build/builder/mako.py b/doc/build/builder/mako.py
new file mode 100644 (file)
index 0000000..0a69551
--- /dev/null
@@ -0,0 +1,79 @@
+from __future__ import absolute_import
+
+from sphinx.application import TemplateBridge
+from sphinx.jinja2glue import BuiltinTemplateLoader
+from mako.lookup import TemplateLookup
+import os
+
+rtd = os.environ.get('READTHEDOCS', None) == 'True'
+
+class MakoBridge(TemplateBridge):
+    def init(self, builder, *args, **kw):
+        self.jinja2_fallback = BuiltinTemplateLoader()
+        self.jinja2_fallback.init(builder, *args, **kw)
+
+        builder.config.html_context['release_date'] = builder.config['release_date']
+        builder.config.html_context['site_base'] = builder.config['site_base']
+
+        self.lookup = TemplateLookup(directories=builder.config.templates_path,
+            #format_exceptions=True,
+            imports=[
+                "from builder import util"
+            ]
+        )
+
+        if rtd:
+            import urllib2
+            template_url = builder.config['site_base'] + "/docs_base.mako"
+            template = urllib2.urlopen(template_url).read()
+            self.lookup.put_string("/rtd_base.mako", template)
+
+    def render(self, template, context):
+        template = template.replace(".html", ".mako")
+        context['prevtopic'] = context.pop('prev', None)
+        context['nexttopic'] = context.pop('next', None)
+
+        # RTD layout
+        if rtd:
+            # add variables if not present, such
+            # as if local test of READTHEDOCS variable
+            if 'MEDIA_URL' not in context:
+                context['MEDIA_URL'] = "http://media.readthedocs.org/"
+            if 'slug' not in context:
+                context['slug'] = context['project'].lower()
+            if 'url' not in context:
+                context['url'] = "/some/test/url"
+            if 'current_version' not in context:
+                context['current_version'] = "latest"
+
+            if 'name' not in context:
+                context['name'] = context['project'].lower()
+
+            context['rtd'] = True
+            context['toolbar'] = True
+            context['layout'] = "rtd_layout.mako"
+            context['base'] = "rtd_base.mako"
+            context['pdf_url'] = "%spdf/%s/%s/%s.pdf" % (
+                    context['MEDIA_URL'],
+                    context['slug'],
+                    context['current_version'],
+                    context['slug']
+            )
+        # local docs layout
+        else:
+            context['rtd'] = False
+            context['toolbar'] = False
+            context['layout'] = "layout.mako"
+            context['base'] = "static_base.mako"
+
+        context.setdefault('_', lambda x: x)
+        return self.lookup.get_template(template).render_unicode(**context)
+
+    def render_string(self, template, context):
+        # this is used for  .js, .css etc. and we don't have
+        # local copies of that stuff here so use the jinja render.
+        return self.jinja2_fallback.render_string(template, context)
+
+def setup(app):
+    app.config['template_bridge'] = "builder.mako.MakoBridge"
+
diff --git a/doc/build/builder/sqlformatter.py b/doc/build/builder/sqlformatter.py
new file mode 100644 (file)
index 0000000..2d80749
--- /dev/null
@@ -0,0 +1,132 @@
+from pygments.lexer import RegexLexer, bygroups, using
+from pygments.token import Token
+from pygments.filter import Filter
+from pygments.filter import apply_filters
+from pygments.lexers import PythonLexer, PythonConsoleLexer
+from sphinx.highlighting import PygmentsBridge
+from pygments.formatters import HtmlFormatter, LatexFormatter
+
+import re
+
+
+def _strip_trailing_whitespace(iter_):
+    buf = list(iter_)
+    if buf:
+        buf[-1] = (buf[-1][0], buf[-1][1].rstrip())
+    for t, v in buf:
+        yield t, v
+
+
+class StripDocTestFilter(Filter):
+    def filter(self, lexer, stream):
+        for ttype, value in stream:
+            if ttype is Token.Comment and re.match(r'#\s*doctest:', value):
+                continue
+            yield ttype, value
+
+class PyConWithSQLLexer(RegexLexer):
+    name = 'PyCon+SQL'
+    aliases = ['pycon+sql']
+
+    flags = re.IGNORECASE | re.DOTALL
+
+    tokens = {
+            'root': [
+                (r'{sql}', Token.Sql.Link, 'sqlpopup'),
+                (r'{opensql}', Token.Sql.Open, 'opensqlpopup'),
+                (r'.*?\n', using(PythonConsoleLexer))
+            ],
+            'sqlpopup': [
+                (
+                    r'(.*?\n)((?:PRAGMA|BEGIN|SELECT|INSERT|DELETE|ROLLBACK|'
+                        'COMMIT|ALTER|UPDATE|CREATE|DROP|PRAGMA'
+                        '|DESCRIBE).*?(?:{stop}\n?|$))',
+                    bygroups(using(PythonConsoleLexer), Token.Sql.Popup),
+                    "#pop"
+                )
+            ],
+            'opensqlpopup': [
+                (
+                    r'.*?(?:{stop}\n*|$)',
+                    Token.Sql,
+                    "#pop"
+                )
+            ]
+        }
+
+
+class PythonWithSQLLexer(RegexLexer):
+    name = 'Python+SQL'
+    aliases = ['pycon+sql']
+
+    flags = re.IGNORECASE | re.DOTALL
+
+    tokens = {
+            'root': [
+                (r'{sql}', Token.Sql.Link, 'sqlpopup'),
+                (r'{opensql}', Token.Sql.Open, 'opensqlpopup'),
+                (r'.*?\n', using(PythonLexer))
+            ],
+            'sqlpopup': [
+                (
+                    r'(.*?\n)((?:PRAGMA|BEGIN|SELECT|INSERT|DELETE|ROLLBACK'
+                        '|COMMIT|ALTER|UPDATE|CREATE|DROP'
+                        '|PRAGMA|DESCRIBE).*?(?:{stop}\n?|$))',
+                    bygroups(using(PythonLexer), Token.Sql.Popup),
+                    "#pop"
+                )
+            ],
+            'opensqlpopup': [
+                (
+                    r'.*?(?:{stop}\n*|$)',
+                    Token.Sql,
+                    "#pop"
+                )
+            ]
+        }
+
+class PopupSQLFormatter(HtmlFormatter):
+    def _format_lines(self, tokensource):
+        buf = []
+        for ttype, value in apply_filters(tokensource, [StripDocTestFilter()]):
+            if ttype in Token.Sql:
+                for t, v in HtmlFormatter._format_lines(self, iter(buf)):
+                    yield t, v
+                buf = []
+
+                if ttype is Token.Sql:
+                    yield 1, "<div class='show_sql'>%s</div>" % \
+                                        re.sub(r'(?:[{stop}|\n]*)$', '', value)
+                elif ttype is Token.Sql.Link:
+                    yield 1, "<a href='#' class='sql_link'>sql</a>"
+                elif ttype is Token.Sql.Popup:
+                    yield 1, "<div class='popup_sql'>%s</div>" % \
+                                        re.sub(r'(?:[{stop}|\n]*)$', '', value)
+            else:
+                buf.append((ttype, value))
+
+        for t, v in _strip_trailing_whitespace(
+                        HtmlFormatter._format_lines(self, iter(buf))):
+            yield t, v
+
+class PopupLatexFormatter(LatexFormatter):
+    def _filter_tokens(self, tokensource):
+        for ttype, value in apply_filters(tokensource, [StripDocTestFilter()]):
+            if ttype in Token.Sql:
+                if ttype is not Token.Sql.Link and ttype is not Token.Sql.Open:
+                    yield Token.Literal, re.sub(r'{stop}', '', value)
+                else:
+                    continue
+            else:
+                yield ttype, value
+
+    def format(self, tokensource, outfile):
+        LatexFormatter.format(self, self._filter_tokens(tokensource), outfile)
+
+def setup(app):
+    app.add_lexer('pycon+sql', PyConWithSQLLexer())
+    app.add_lexer('python+sql', PythonWithSQLLexer())
+
+    PygmentsBridge.html_formatter = PopupSQLFormatter
+    PygmentsBridge.latex_formatter = PopupLatexFormatter
+
index 9079232d512ac92ac2b1e796ce9d5ced37242461..73cd47e6be942e3c2bcdb51b2b4fd34bf69c905f 100644 (file)
@@ -30,10 +30,10 @@ import sqlalchemy
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
 #extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode',
-#                'sphinx.ext.doctest', 'builder.builders']
+#                'sphinx.ext.doctest', 'builder']
 
 extensions = ['sphinx.ext.autodoc',
-                'sphinx.ext.doctest', 'builder.builders']
+                'sphinx.ext.doctest', 'builder']
 
 # Add any paths that contain templates here, relative to this directory.
 # not sure why abspath() is needed here, some users
@@ -45,7 +45,6 @@ nitpicky = True
 # The suffix of source filenames.
 source_suffix = '.rst'
 
-template_bridge = "builder.builders.MakoBridge"
 
 # The encoding of source files.
 #source_encoding = 'utf-8-sig'
index ec0af93ce0a324cc85aeaafe26d98c638d1b7ede..99ff596d7feac371b6e2c2d648df6ebb2d45cdc8 100644 (file)
@@ -70,9 +70,7 @@ construction arguments, are as follows:
     :show-inheritance:
 
 
-.. _drizzle_mysqldb:
-
-MySQL-Python Notes
---------------------
+MySQL-Python
+------------
 
 .. automodule:: sqlalchemy.dialects.drizzle.mysqldb
index 2ec0103eff71a4b0fd435d7e49ae25861e30b927..d5b6b2ffdd6ebb66fec6039f46b3a9d558c63640 100644 (file)
@@ -5,8 +5,6 @@ Firebird
 
 .. automodule:: sqlalchemy.dialects.firebird.base
 
-.. _kinterbasdb:
-
 kinterbasdb
 -----------
 
index 12eaa04381b2011372478eeeaf0482687a88fc52..f37ae6cf566b49453b2155cb4b6ef66050d9551c 100644 (file)
@@ -5,7 +5,7 @@ Informix
 
 .. automodule:: sqlalchemy.dialects.informix.base
 
-informixdb Notes
---------------------
+informixdb
+----------
 
 .. automodule:: sqlalchemy.dialects.informix.informixdb
\ No newline at end of file
index f969983328215283afb023e00d1553c2720134fc..615d1a11dd18a6b7da770c995dbfdac8c2e4d97e 100644 (file)
@@ -19,7 +19,7 @@ they originate from :mod:`sqlalchemy.types` or from the local dialect::
         SMALLINT, SMALLMONEY, SQL_VARIANT, TEXT, TIME, \
         TIMESTAMP, TINYINT, UNIQUEIDENTIFIER, VARBINARY, VARCHAR
 
-Types which are specific to SQL Server, or have SQL Server-specific 
+Types which are specific to SQL Server, or have SQL Server-specific
 construction arguments, are as follows:
 
 .. currentmodule:: sqlalchemy.dialects.mssql
@@ -109,7 +109,7 @@ pymssql
 -------
 .. automodule:: sqlalchemy.dialects.mssql.pymssql
 
-zxjdbc Notes
+zxjdbc
 --------------
 
 .. automodule:: sqlalchemy.dialects.mssql.zxjdbc
index 2110e375afed08f6e60eeec2f81ea92cfceda901..b5119f23fba58f9b7b05f247a9b1180040a97579 100644 (file)
@@ -155,50 +155,36 @@ construction arguments, are as follows:
     :members: __init__
     :show-inheritance:
 
-.. _mysqldb:
-
 MySQL-Python
 --------------------
 
 .. automodule:: sqlalchemy.dialects.mysql.mysqldb
 
-.. _oursql:
-
 OurSQL
 --------------
 
 .. automodule:: sqlalchemy.dialects.mysql.oursql
 
-.. _pymysql:
-
 pymysql
 -------------
 
 .. automodule:: sqlalchemy.dialects.mysql.pymysql
 
-.. _mysqlconnector:
-
 MySQL-Connector
 ----------------------
 
 .. automodule:: sqlalchemy.dialects.mysql.mysqlconnector
 
-.. _gaerdbms:
-
 Google App Engine
 -----------------------
 
 .. automodule:: sqlalchemy.dialects.mysql.gaerdbms
 
-.. _mysql_pyodbc:
-
 pyodbc
---------------
+------
 
 .. automodule:: sqlalchemy.dialects.mysql.pyodbc
 
-.. _mysql_zxjdbc:
-
 zxjdbc
 --------------
 
index 5e259ead76c9d3df17e10db32622fdee9b0891f7..4be8c5b5136f6ef23b8116afedd789dfc3a4f685 100644 (file)
@@ -18,7 +18,7 @@ they originate from :mod:`sqlalchemy.types` or from the local dialect::
                 NUMBER, NVARCHAR, NVARCHAR2, RAW, TIMESTAMP, VARCHAR, \
                 VARCHAR2
 
-Types which are specific to Oracle, or have Oracle-specific 
+Types which are specific to Oracle, or have Oracle-specific
 construction arguments, are as follows:
 
 .. currentmodule:: sqlalchemy.dialects.oracle
@@ -51,12 +51,12 @@ construction arguments, are as follows:
   :members: __init__
   :show-inheritance:
 
-cx_Oracle Notes
----------------
+cx_Oracle
+----------
 
 .. automodule:: sqlalchemy.dialects.oracle.cx_oracle
 
-zxjdbc Notes
---------------
+zxjdbc
+-------
 
 .. automodule:: sqlalchemy.dialects.oracle.zxjdbc
index cf6f277f56ea394f926521eca50d0fd3a561d218..55705a037a6a744fd51e6230f580cf5992f411c1 100644 (file)
@@ -76,23 +76,16 @@ psycopg2
 
 .. automodule:: sqlalchemy.dialects.postgresql.psycopg2
 
-
-.. _pypostgresql:
-
 py-postgresql
 --------------------
 
 .. automodule:: sqlalchemy.dialects.postgresql.pypostgresql
 
-.. _pg8000:
-
 pg8000
 --------------
 
 .. automodule:: sqlalchemy.dialects.postgresql.pg8000
 
-.. _zxjdbc:
-
 zxjdbc
 --------------
 
index 8200f223dc726f1925da4879039c8a0c2ce0ef76..8e9695325a3c102dd0a9009a25ce9a776de4d41b 100644 (file)
@@ -5,17 +5,17 @@ Sybase
 
 .. automodule:: sqlalchemy.dialects.sybase.base
 
-python-sybase notes
+python-sybase
 -------------------
 
 .. automodule:: sqlalchemy.dialects.sybase.pysybase
 
-pyodbc notes
+pyodbc
 ------------
 
 .. automodule:: sqlalchemy.dialects.sybase.pyodbc
 
-mxodbc notes
+mxodbc
 ------------
 
 .. automodule:: sqlalchemy.dialects.sybase.mxodbc
index d32240c38249773c64b469562cff5c77e801a819..2b5df38601301a1f511fc5e0713f8125381bd969 100644 (file)
@@ -6,7 +6,10 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 
-"""Support for the Drizzle database.
+"""
+
+.. dialect:: drizzle
+    :name: Drizzle
 
 Drizzle is a variant of MySQL. Unlike MySQL, Drizzle's default storage engine
 is InnoDB (transactions, foreign-keys) rather than MyISAM. For more
@@ -16,14 +19,6 @@ the `Drizzle Documentation <http://docs.drizzle.org/index.html>`_.
 The SQLAlchemy Drizzle dialect leans heavily on the MySQL dialect, so much of
 the :doc:`SQLAlchemy MySQL <mysql>` documentation is also relevant.
 
-DBAPI Support
--------------
-
-The following dialect/driver options are available:
-
-``drizzle://``- uses mysqldb_
-
-``drizzle+mysqldb://`` - uses mysqldb_
 
 """
 
index ce9518a8111617887b81b9788946f8bfe2ed756c..7d91cc368be3622e873363b926e4d535fe7d5bfb 100644 (file)
@@ -1,15 +1,10 @@
-"""Support for the Drizzle database via the mysql-python adapter.
-
-MySQL-Python is available at:
-
-    http://sourceforge.net/projects/mysql-python
-
-Connecting
------------
-
-Connect string format::
+"""
+.. dialect:: drizzle+mysqldb
+    :name: MySQL-Python
+    :dbapi: mysqldb
+    :connectstring: drizzle+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
+    :url: http://sourceforge.net/projects/mysql-python
 
-    drizzle+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
 
 """
 
index b990400389889d88956d12e69a42c174b8470615..df20060e58276d8d3f3242d71aa34bcca531889b 100644 (file)
@@ -5,18 +5,9 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 """
-Support for the Firebird database.
 
-DBAPI Support
--------------
-
-The following dialect/driver options are available:
-
-``firebird://``- uses kinterbasdb_
-
-``firebird+kinterbasdb://`` - uses kinterbasdb_
-
-``firebird+fdb://`` - uses fdb_
+.. dialect:: firebird
+    :name: Firebird
 
 Firebird Dialects
 -----------------
index 3601b391b127adee74114f53f1563f12c588bbc0..aac3579d6f1c6fae94a2f1776b37c595ebee9cea 100644 (file)
@@ -5,21 +5,15 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 """
-fdb is a kinterbasdb compatible DBAPI for Firebird.
+.. dialect:: firebird+fdb
+    :name: fdb
+    :dbapi: pyodbc
+    :connectstring: firebird+fdb://user:password@host:port/path/to/db[?key=value&key=value...]
+    :url: http://pypi.python.org/pypi/fdb/
 
-.. versionadded:: 0.8 - Support for the fdb Firebird driver.
+    fdb is a kinterbasdb compatible DBAPI for Firebird.
 
-DBAPI
------
-
-http://pypi.python.org/pypi/fdb/
-
-Connecting
------------
-
-Connect string format::
-
-    firebird+fdb://user:password@host:port/path/to/db[?key=value&key=value...]
+    .. versionadded:: 0.8 - Support for the fdb Firebird driver.
 
 Status
 ------
index 78fffd647156102039062e77a6bfd9dc12a873cb..90fadde50b76a1fc246c50730c4c426508ce673f 100644 (file)
@@ -5,18 +5,11 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 """
-
-DBAPI
------
-
-http://firebirdsql.org/index.php?op=devel&sub=python
-
-Connecting
------------
-
-Connect string format::
-
-    firebird+kinterbasdb://user:password@host:port/path/to/db[?key=value&key=value...]
+.. dialect:: firebird+kinterbasdb
+    :name: kinterbasdb
+    :dbapi: kinterbasdb
+    :connectstring: firebird+kinterbasdb://user:password@host:port/path/to/db[?key=value&key=value...]
+    :url: http://firebirdsql.org/index.php?op=devel&sub=python
 
 Arguments
 ----------
index eff563a1d1808e26231532981451ad2277e3da22..f54bf6d37b991432aa883cac792af7970c77f24a 100644 (file)
@@ -5,7 +5,9 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the Informix database.
+"""
+.. dialect:: informix
+    :name: Informix
 
 .. note::
 
index b771e15017c4aa113a59b82edf96becc8868c426..474bc5f11b2710b8b308ac47cf256f4966d3fbf6 100644 (file)
@@ -5,18 +5,12 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 """
-Support for the informixdb DBAPI.
 
-informixdb is available at:
-
-    http://informixdb.sourceforge.net/
-
-Connecting
-^^^^^^^^^^
-
-Sample informix connection::
-
-    engine = create_engine('informix+informixdb://user:password@host/dbname')
+.. dialect:: informix+informixdb
+    :name: informixdb
+    :dbapi: informixdb
+    :connectstring: informix+informixdb://user:password@host/dbname
+    :url: http://informixdb.sourceforge.net/
 
 """
 
index 5b23282692ff4742dbec2bfd2f6e24fe99e6bc6c..747ea17db7420c5f87433d64a99a05558ff78ae5 100644 (file)
@@ -5,7 +5,16 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 """
-The adodbapi dialect is not implemented for 0.6 at this time.
+.. dialect:: mssql+adodbapi
+    :name: adodbapi
+    :dbapi: adodbapi
+    :connectstring: mssql+adodbapi://<username>:<password>@<dsnname>
+    :url: http://adodbapi.sourceforge.net/
+
+.. note::
+
+    The adodbapi dialect is not implemented SQLAlchemy versions 0.6 and
+    above at this time.
 
 """
 import datetime
index e8f0385b4abe082cd1da93450206fb826080a8ee..51884247f9174fc0ff477369540886baac377d1f 100644 (file)
@@ -4,7 +4,9 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the Microsoft SQL Server database.
+"""
+.. dialect:: mssql
+    :name: Microsoft SQL Server
 
 
 Auto Increment Behavior
index 4e0af2d39683399ceede463bec87fd139c72a195..91922a442a931a1bf9c2d7498cbd26d466dc93d4 100644 (file)
@@ -5,24 +5,14 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 """
-Support for MS-SQL via mxODBC.
-
-mxODBC is available at:
-
-    http://www.egenix.com/
-
-This was tested with mxODBC 3.1.2 and the SQL Server Native
-Client connected to MSSQL 2005 and 2008 Express Editions.
-
-Connecting
-~~~~~~~~~~
-
-Connection is via DSN::
-
-    mssql+mxodbc://<username>:<password>@<dsnname>
+.. dialect:: mssql+mxodbc
+    :name: mxODBC
+    :dbapi: mxodbc
+    :connectstring: mssql+mxodbc://<username>:<password>@<dsnname>
+    :url: http://www.egenix.com/
 
 Execution Modes
-~~~~~~~~~~~~~~~
+---------------
 
 mxODBC features two styles of statement execution, using the
 ``cursor.execute()`` and ``cursor.executedirect()`` methods (the second being
index 96b1511bd7d55303edf7f77f67b781139de450d0..881893422bfeed5d7aac4f3c05c16de40e8ba719 100644 (file)
@@ -5,28 +5,14 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 """
-Support for the pymssql dialect.
-
-This dialect supports pymssql 1.0 and greater.
-
-pymssql is available at:
-
-    http://pymssql.sourceforge.net/
-
-Connecting
-^^^^^^^^^^
-
-Sample connect string::
-
-    mssql+pymssql://<username>:<password>@<freetds_name>
-
-Adding "?charset=utf8" or similar will cause pymssql to return
-strings as Python unicode objects.   This can potentially improve
-performance in some scenarios as decoding of strings is
-handled natively.
+.. dialect:: mssql+pymssql
+    :name: pymssql
+    :dbapi: pymssql
+    :connectstring: mssql+pymssql://<username>:<password>@<freetds_name>?charset=utf8
+    :url: http://pymssql.sourceforge.net/
 
 Limitations
-^^^^^^^^^^^
+-----------
 
 pymssql inherits a lot of limitations from FreeTDS, including:
 
index 10149689afa9d95654869341399fc72af9e82fe1..47a4851b009399deef05fad318e63bb10a024f88 100644 (file)
@@ -5,14 +5,14 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 """
-Support for MS-SQL via pyodbc.
+.. dialect:: mssql+pyodbc
+    :name: PyODBC
+    :dbapi: pyodbc
+    :connectstring: mssql+pyodbc://<username>:<password>@<dsnname>
+    :url: http://pypi.python.org/pypi/pyodbc/
 
-pyodbc is available at:
-
-    http://pypi.python.org/pypi/pyodbc/
-
-Connecting
-^^^^^^^^^^
+Additional Connection Examples
+-------------------------------
 
 Examples of pyodbc connection string URLs:
 
@@ -81,7 +81,7 @@ the python shell. For example::
     'dsn%3Dmydsn%3BDatabase%3Ddb'
 
 Unicode Binds
-^^^^^^^^^^^^^
+-------------
 
 The current state of PyODBC on a unix backend with FreeTDS and/or
 EasySoft is poor regarding unicode; different OS platforms and versions of UnixODBC
index 38deacfd6bf78d6b437b5a0366f5f8731ffbc302..1b36075b07bd957216b4e51b5181dbd0057a1f8d 100644 (file)
@@ -4,24 +4,13 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the Microsoft SQL Server database via the zxjdbc JDBC
-connector.
-
-JDBC Driver
------------
-
-Requires the jTDS driver, available from: http://jtds.sourceforge.net/
-
-Connecting
-----------
-
-URLs are of the standard form of
-``mssql+zxjdbc://user:pass@host:port/dbname[?key=value&key=value...]``.
+"""
+.. dialect:: mssql+zxjdbc
+    :name: zxJDBC for Jython
+    :dbapi: zxjdbc
+    :connectstring: mssql+zxjdbc://user:pass@host:port/dbname[?key=value&key=value...]
+    :driverurl: http://jtds.sourceforge.net/
 
-Additional arguments which may be specified either as query string
-arguments on the URL, or as keyword arguments to
-:func:`~sqlalchemy.create_engine()` will be passed as Connection
-properties to the underlying JDBC driver.
 
 """
 from ...connectors.zxJDBC import ZxJDBCConnector
index 7f67d78261cf26945ac2f4a2584e5c6561cf3348..92c6f58a0aec473dd1af0d95c4b229b361ffb42a 100644 (file)
@@ -4,27 +4,10 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the MySQL database.
-
-DBAPI Support
--------------
-
-The following dialect/driver options are available:
-
-* :ref:`mysqldb`
-
-* :ref:`mysqlconnector`
-
-* :ref:`oursql`
-
-* :ref:`gaerdbms`
-
-* :ref:`pymysql`
-
-* :ref:`mysql_pyodbc`
-
-* :ref:`mysql_zxjdbc`
+"""
 
+.. dialect:: mysql
+    :name: MySQL
 
 Supported Versions and Features
 -------------------------------
@@ -55,11 +38,6 @@ Nested Transactions                    5.0.3
 See the official MySQL documentation for detailed information about features
 supported in any given server release.
 
-Connecting
-----------
-
-See the API documentation on individual drivers for details on connecting.
-
 Connection Timeouts
 -------------------
 
index 29a67a540be78624c0e8de034d56be62bbd2d266..66180e233abc8b1d24390fe83223a79d822a36f6 100644 (file)
@@ -3,29 +3,18 @@
 #
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
-"""Support for Google Cloud SQL on Google App Engine.
-
-This dialect is based primarily on the :mod:`.mysql.mysqldb` dialect with minimal
-changes.
-
-.. versionadded:: 0.7.8
-
-DBAPI
------
-
-    https://developers.google.com/appengine/docs/python/cloud-sql/developers-guide
-
-Connecting
-----------
-
-Connect string format::
+"""
+.. dialect:: mysql+gaerdbms
+    :name: Google Cloud SQL
+    :dbapi: rdbms
+    :connectstring: mysql+gaerdbms:///<dbname>?instance=instancename
+    :url: https://developers.google.com/appengine/docs/python/cloud-sql/developers-guide
 
-    mysql+gaerdbms:///<dbname>
+    This dialect is based primarily on the :mod:`.mysql.mysqldb` dialect with minimal
+    changes.
 
-E.g.::
+    .. versionadded:: 0.7.8
 
-  create_engine('mysql+gaerdbms:///mydb',
-                 connect_args={"instance":"instancename"})
 
 Pooling
 -------
index ea8d9322c08a764b87ce25d7d2d7c1719640ec92..82d9067855906fad8339baddf4a1f6f8c5950419 100644 (file)
@@ -4,21 +4,13 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the MySQL database via the MySQL Connector/Python adapter.
-
-DBAPI
------
-
-MySQL Connector/Python is available at:
-
-    https://launchpad.net/myconnpy
-
-Connecting
------------
-
-Connect string format::
+"""
+.. dialect:: mysql+mysqlconnector
+    :name: MySQL Connector/Python
+    :dbapi: myconnpy
+    :connectstring: mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>
+    :url: https://launchpad.net/myconnpy
 
-    mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>
 
 """
 
index add0c00ee8f3435183ef0bc6f9ae1f4b37f4e724..7385f6e60d9b4b70e20e523715643f72e04622a5 100644 (file)
@@ -4,21 +4,14 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the MySQL database via the MySQL-python adapter.
-
-DBAPI
------
-
-MySQL-Python is available at:
-
-    http://sourceforge.net/projects/mysql-python
-
-Connecting
------------
+"""
 
-Connect string format::
+.. dialect:: mysql+mysqldb
+    :name: MySQL-Python
+    :dbapi: mysqldb
+    :connectstring: mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
+    :url: http://sourceforge.net/projects/mysql-python
 
-    mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
 
 Unicode
 -------
index ca713a068fdf3d3b8efdacc75fbbed78d6a4de0f..cc4e3b5f23c4ecea57e8fe638c270b406cc7472d 100644 (file)
@@ -4,21 +4,13 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the MySQL database via the oursql adapter.
-
-DBAPI
------
-
-OurSQL is available at:
-
-    http://packages.python.org/oursql/
-
-Connecting
------------
-
-Connect string format::
+"""
 
-    mysql+oursql://<user>:<password>@<host>[:<port>]/<dbname>
+.. dialect:: mysql+oursql
+    :name: OurSQL
+    :dbapi: oursql
+    :connectstring: mysql+oursql://<user>:<password>@<host>[:<port>]/<dbname>
+    :url: http://packages.python.org/oursql/
 
 Unicode
 -------
index b6f2d4384f19871d92d2ce664bf32447919efb54..36b49ba3b847b956482103ed28e81d7a6a550d9f 100644 (file)
@@ -4,21 +4,13 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the MySQL database via the pymysql adapter.
-
-DBAPI
------
-
-pymysql is available at:
-
-    http://code.google.com/p/pymysql/
-
-Connecting
-----------
-
-Connect string::
+"""
 
-    mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
+.. dialect:: mysql+pymysql
+    :name: PyMySQL
+    :dbapi: pymysql
+    :connectstring: mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
+    :url: http://code.google.com/p/pymysql/
 
 MySQL-Python Compatibility
 --------------------------
index 20cc53be7f1cf4e7c5d63eb7123b504330e8e5b4..2736ef7a4ba3bd3285821c5cb23c65c0cdb1118e 100644 (file)
@@ -4,21 +4,15 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the MySQL database via the pyodbc adapter.
-
-DBAPI
------
-
-pyodbc is available at:
-
-    http://pypi.python.org/pypi/pyodbc/
+"""
 
-Connecting
-----------
 
-Connect string::
+.. dialect:: mysql+pyodbc
+    :name: PyODBC
+    :dbapi: pyodbc
+    :connectstring: mysql+pyodbc://<username>:<password>@<dsnname>
+    :url: http://pypi.python.org/pypi/pyodbc/
 
-    mysql+pyodbc://<username>:<password>@<dsnname>
 
 Limitations
 -----------
index 82e7dca8d013f4ed8e490dc7149c2d8a9329bf53..955044a58773f8dedcdc81c248729eaaa8488ce5 100644 (file)
@@ -4,20 +4,13 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the MySQL database via Jython's zxjdbc JDBC connector.
-
-DBAPI
------
-
-The official MySQL JDBC driver is at
-http://dev.mysql.com/downloads/connector/j/.
-
-Connecting
-----------
-
-Connect string::
+"""
 
-    mysql+zxjdbc://<user>:<password>@<hostname>[:<port>]/<database>
+.. dialect:: mysql+zxjdbc
+    :name: zxjdbc for Jython
+    :dbapi: zxjdbc
+    :connectstring: mysql+zxjdbc://<user>:<password>@<hostname>[:<port>]/<database>
+    :driverurl: http://dev.mysql.com/downloads/connector/j/
 
 Character Sets
 --------------
index ee4a82115c7d32709c6c882f6085dcceb0f26af6..7b1470f63652a9a2fe99eee5528634a88b8b33dc 100644 (file)
@@ -4,9 +4,11 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the Oracle database.
+"""
+.. dialect:: oracle
+    :name: Oracle
 
-Oracle version 8 through current (11g at the time of this writing) are supported.
+    Oracle version 8 through current (11g at the time of this writing) are supported.
 
 Connect Arguments
 -----------------
index ddd61e5a97ef6421ab33be4a633cfac637a90ffe..233f3cb271af20a4a539cc285d4335379f820c72 100644 (file)
@@ -4,24 +4,19 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the Oracle database via the cx_oracle driver.
-
-Driver
-------
+"""
 
-The Oracle dialect uses the cx_oracle driver, available at
-http://cx-oracle.sourceforge.net/ .   The dialect has several behaviors
-which are specifically tailored towards compatibility with this module.
-Version 5.0 or greater is **strongly** recommended, as SQLAlchemy makes
-extensive use of the cx_oracle output converters for numeric and
-string conversions.
+.. dialect:: oracle+cx_oracle
+    :name: cx-Oracle
+    :dbapi: cx_oracle
+    :connectstring: oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]
+    :url: http://cx-oracle.sourceforge.net/
 
-Connecting
-----------
+Additional Connect Arguments
+----------------------------
 
-Connecting with create_engine() uses the standard URL approach of
-``oracle://user:pass@host:port/dbname[?key=value&key=value...]``.  If dbname is
-present, the host, port, and dbname tokens are converted to a TNS name using
+When connecting with ``dbname`` present, the host, port, and dbname tokens are
+converted to a TNS name using
 the cx_oracle :func:`makedsn()` function.  Otherwise, the host token is taken
 directly as a TNS name.
 
index 3a0f45665645f83774b72979ab462619b3948765..54608969bb3d729566cfeec093109eea82d75d47 100644 (file)
@@ -4,13 +4,12 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the Oracle database via the zxjdbc JDBC connector.
-
-JDBC Driver
------------
-
-The official Oracle JDBC driver is at
-http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html.
+"""
+.. dialect:: oracle+zxjdbc
+    :name: zxJDBC for Jython
+    :dbapi: zxjdbc
+    :connectstring: oracle+zxjdbc://user:pass@host/dbname
+    :driverurl: http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html.
 
 """
 import decimal
index 0d2cb3c8ff68e845a4286eb9874cbd24df3d8541..625ece6a131bb9d0ded36873793cdd8741bfda29 100644 (file)
@@ -4,20 +4,10 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the PostgreSQL database.
-
-DBAPI Support
--------------
-
-The following dialect/driver options are available:
-
-* :ref:`psycopg2`
-
-* :ref:`pg8000`
-
-* :ref:`pypostgresql`
+"""
+.. dialect:: postgresql
+    :name: PostgreSQL
 
-* :ref:`zxjdbc`
 
 Sequences/SERIAL
 ----------------
index e19d84b51ade8e4bb89f40c12aa8271aaa909d6a..6a7c5cecb7db9ce9f8e3964fe6480d16847a4cbc 100644 (file)
@@ -4,19 +4,12 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the PostgreSQL database via the pg8000 driver.
-
-DBAPI
-------
-
-    http://pybrary.net/pg8000/
-
-Connecting
-----------
-
-Connect string format::
-
-    postgresql+pg8000://user:password@host:port/dbname[?key=value&key=value...]
+"""
+.. dialect:: postgresql+pg8000
+    :name: pg8000
+    :dbapi: pg8000
+    :connectstring: postgresql+pg8000://user:password@host:port/dbname[?key=value&key=value...]
+    :url: http://pybrary.net/pg8000/
 
 Unicode
 -------
index 14fb35456873906ad7f67303cb570276a7b02aea..700f76793afc0c4f524e48befaf6697ed3c1fdcc 100644 (file)
@@ -4,23 +4,12 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the PostgreSQL database via the psycopg2 driver.
-
-DBAPI
-------
-
-The psycopg2 driver is available at http://pypi.python.org/pypi/psycopg2/ .
-The dialect has several behaviors  which are specifically tailored towards compatibility
-with this module.
-
-Note that psycopg1 is **not** supported.
-
-Connecting
-----------
-
-Connect string format::
-
-    postgresql+psycopg2://user:password@host:port/dbname[?key=value&key=value...]
+"""
+.. dialect:: postgresql+psycopg2
+    :name: psycopg2
+    :dbapi: psycopg2
+    :connectstring: postgresql+psycopg2://user:password@host:port/dbname[?key=value&key=value...]
+    :url: http://pypi.python.org/pypi/psycopg2/
 
 psycopg2 Connect Arguments
 -----------------------------------
index cf091b3115648fc38735fbbc429d3236b99e6b42..e7023610bef11b4378034060ee3165b62d41083f 100644 (file)
@@ -4,19 +4,12 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the PostgreSQL database via py-postgresql.
-
-DBAPI
------
-
-    http://python.projects.pgfoundry.org/
-
-Connecting
-----------
-
-Connect string format::
-
-    postgresql+pypostgresql://user:password@host:port/dbname[?key=value&key=value...]
+"""
+.. dialect:: postgresql+pypostgresql
+    :name: py-postgresql
+    :dbapi: pypostgresql
+    :connectstring: postgresql+pypostgresql://user:password@host:port/dbname[?key=value&key=value...]
+    :url: http://python.projects.pgfoundry.org/
 
 
 """
index 381424c7f04a0e9c759f0233e53152ca1e2f4896..196d77aaaa1ff0f2df579855d2a1833631c92895 100644 (file)
@@ -4,19 +4,12 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the PostgreSQL database via the zxjdbc JDBC connector.
-
-DBAPI
------------
-
-The official Postgresql JDBC driver is at http://jdbc.postgresql.org/.
-
-Connecting
-----------
-
-Connect string format::
-
-    postgresql+zxjdbc://scott:tiger@localhost/db
+"""
+.. dialect:: postgresql+zxjdbc
+    :name: zxJDBC for Jython
+    :dbapi: zxjdbc
+    :connectstring: postgresql+zxjdbc://scott:tiger@localhost/db
+    :driverurl: http://jdbc.postgresql.org/
 
 
 """
index eb03a55c40b4f79d93463d24d15a0cd8988e62ac..c7ac2bba43db6e03b5bdb9543a76ca02fbb4650c 100644 (file)
@@ -4,7 +4,10 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the SQLite database.
+"""
+.. dialect:: sqlite
+    :name: SQLite
+
 
 Date and Time Types
 -------------------
index 648867094db89f012ac0ea43447f1c1566f1e4d9..558f1016b3951b88363bcbf1af39076688d010d6 100644 (file)
@@ -4,10 +4,15 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for the SQLite database via pysqlite.
+"""
+.. dialect:: sqlite+pysqlite
+    :name: pysqlite
+    :dbapi: sqlite3
+    :connectstring: sqlite+pysqlite:///file_path
+    :url: http://docs.python.org/library/sqlite3.html
 
-Note that pysqlite is the same driver as the ``sqlite3``
-module included with the Python distribution.
+    Note that ``pysqlite`` is the same driver as the ``sqlite3``
+    module included with the Python distribution.
 
 Driver
 ------
@@ -26,14 +31,12 @@ this explicitly::
     from sqlite3 import dbapi2 as sqlite
     e = create_engine('sqlite+pysqlite:///file.db', module=sqlite)
 
-Full documentation on pysqlite is available at:
-`<http://www.initd.org/pub/software/pysqlite/doc/usage-guide.html>`_
 
 Connect Strings
 ---------------
 
 The file specification for the SQLite database is taken as the "database" portion of
-the URL.  Note that the format of a url is::
+the URL.  Note that the format of a SQLAlchemy url is::
 
     driver://user:pass@host/database
 
index 9a1a5bdf381e2898c302f486e67da71d81b75c54..2d213ed5b2d6a6eabb1cbb4b592466a5f87327cb 100644 (file)
@@ -8,7 +8,10 @@
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
-"""Support for Sybase Adaptive Server Enterprise (ASE).
+"""
+
+.. dialect:: sybase
+    :name: Sybase
 
 .. note::
 
index f88b1ed3c6421b1ef4c4c2f16d94620e45152c4f..2bf4071ddc1e70fb2c05e6b55b2d6247a07d3772 100644 (file)
@@ -3,11 +3,17 @@
 #
 # This module is part of SQLAlchemy and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
-
 """
-Support for Sybase via mxodbc.
 
-This dialect is a stub only and is likely non functional at this time.
+.. dialect:: sybase+mxodbc
+    :name: mxODBC
+    :dbapi: mxodbc
+    :connectstring: sybase+mxodbc://<username>:<password>@<dsnname>
+    :url: http://www.egenix.com/
+
+.. note::
+
+    This dialect is a stub only and is likely non functional at this time.
 
 
 """
index 70bdd71a26f1133e3b23aedebdbb2a35fd709b66..c4badd3e5e9921e24f0e3c9a0373525feeb9fac2 100644 (file)
@@ -5,14 +5,12 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 """
-Support for Sybase via pyodbc.
+.. dialect:: sybase+pyodbc
+    :name: PyODBC
+    :dbapi: pyodbc
+    :connectstring: sybase+pyodbc://<username>:<password>@<dsnname>[/<database>]
+    :url: http://pypi.python.org/pypi/pyodbc/
 
-http://pypi.python.org/pypi/pyodbc/
-
-Connect strings are of the form::
-
-    sybase+pyodbc://<username>:<password>@<dsn>/
-    sybase+pyodbc://<username>:<password>@<host>/<database>
 
 Unicode Support
 ---------------
index bf8c2096b8cfb8c373c552558bb80cdfe99e64e2..58a669be0e5352c10c3d755c9345e0b3b6f01e76 100644 (file)
@@ -5,13 +5,11 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 """
-Support for Sybase via the python-sybase driver.
-
-http://python-sybase.sourceforge.net/
-
-Connect strings are of the form::
-
-    sybase+pysybase://<username>:<password>@<dsn>/[database name]
+.. dialect:: sybase+pysybase
+    :name: Python-Sybase
+    :dbapi: Sybase
+    :connectstring: sybase+pysybase://<username>:<password>@<dsn>/[database name]
+    :url: http://python-sybase.sourceforge.net/
 
 Unicode Support
 ---------------
index ade1fd241cb04266f4e66c1709cc0b3b02b92c3c..163e0494708146fa60f995511b2db560c0fdf9da 100644 (file)
@@ -186,8 +186,15 @@ class SuiteRequirements(Requirements):
         return exclusions.open()
 
     @property
-    def empty_strings(self):
-        """target database can persist/return an empty string."""
+    def empty_strings_varchar(self):
+        """target database can persist/return an empty string with a varchar."""
+
+        return exclusions.open()
+
+    @property
+    def empty_strings_text(self):
+        """target database can persist/return an empty string with an
+        unbounded text."""
 
         return exclusions.open()
 
index 361d784b8b599d27bdeef7ac9fdc8ce91a7f49c2..cd7b61f42405bfed8a40f31f8df9bc3590f9eff3 100644 (file)
@@ -70,8 +70,7 @@ class _UnicodeFixture(object):
             assert isinstance(row[0], unicode)
 
 
-    @requirements.empty_strings
-    def test_empty_strings(self):
+    def _test_empty_strings(self):
         unicode_table = self.tables.unicode_table
 
         config.db.execute(
@@ -89,9 +88,17 @@ class UnicodeVarcharTest(_UnicodeFixture, fixtures.TablesTest):
     datatype = Unicode(255)
 
 
+    @requirements.empty_strings_varchar
+    def test_empty_strings(self):
+        self._test_empty_strings()
+
 class UnicodeTextTest(_UnicodeFixture, fixtures.TablesTest):
     __requires__ = 'unicode_data', 'text_type'
 
     datatype = UnicodeText()
 
+    @requirements.empty_strings_text
+    def test_empty_strings(self):
+        self._test_empty_strings()
+
 __all__ = ('UnicodeVarcharTest', 'UnicodeTextTest')
\ No newline at end of file
index ca245eb3077d9a29996dfb80adefea4c10342f1c..b88b774322f60e6f33add88af21182df091cf138 100644 (file)
@@ -290,8 +290,16 @@ class DefaultRequirements(SuiteRequirements):
         return skip_if("drizzle", "no VIEW support")
 
     @property
-    def empty_strings(self):
-        """target database can persist/return an empty string."""
+    def empty_strings_varchar(self):
+        """target database can persist/return an empty string with a varchar."""
+
+        return fails_if("oracle", 'oracle converts empty '
+                                'strings to a blank space')
+
+    @property
+    def empty_strings_text(self):
+        """target database can persist/return an empty string with an
+        unbounded text."""
 
         return fails_if("oracle", 'oracle converts empty '
                                 'strings to a blank space')