<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[15734] twext/trunk/twext/enterprise</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.calendarserver.org//changeset/15734">15734</a></dd>
<dt>Author</dt> <dd>cdaboo@apple.com</dd>
<dt>Date</dt> <dd>2016-07-05 12:32:22 -0700 (Tue, 05 Jul 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Wrap database parameters into a single class that also supports optional features. Allow SKIP LOCKED optional feature with postgres.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#twexttrunktwextenterpriseadbapi2py">twext/trunk/twext/enterprise/adbapi2.py</a></li>
<li><a href="#twexttrunktwextenterprisedalrecordpy">twext/trunk/twext/enterprise/dal/record.py</a></li>
<li><a href="#twexttrunktwextenterprisedalsyntaxpy">twext/trunk/twext/enterprise/dal/syntax.py</a></li>
<li><a href="#twexttrunktwextenterprisedaltesttest_sqlsyntaxpy">twext/trunk/twext/enterprise/dal/test/test_sqlsyntax.py</a></li>
<li><a href="#twexttrunktwextenterprisefixturespy">twext/trunk/twext/enterprise/fixtures.py</a></li>
<li><a href="#twexttrunktwextenterpriseienterprisepy">twext/trunk/twext/enterprise/ienterprise.py</a></li>
<li><a href="#twexttrunktwextenterprisejobsjobitempy">twext/trunk/twext/enterprise/jobs/jobitem.py</a></li>
<li><a href="#twexttrunktwextenterprisetesttest_adbapi2py">twext/trunk/twext/enterprise/test/test_adbapi2.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="twexttrunktwextenterpriseadbapi2py"></a>
<div class="modfile"><h4>Modified: twext/trunk/twext/enterprise/adbapi2.py (15733 => 15734)</h4>
<pre class="diff"><span>
<span class="info">--- twext/trunk/twext/enterprise/adbapi2.py        2016-07-01 16:33:47 UTC (rev 15733)
+++ twext/trunk/twext/enterprise/adbapi2.py        2016-07-05 19:32:22 UTC (rev 15734)
</span><span class="lines">@@ -60,7 +60,8 @@
</span><span class="cx"> from twisted.internet.defer import fail
</span><span class="cx"> 
</span><span class="cx"> from twext.enterprise.ienterprise import (
</span><del>-    AlreadyFinishedError, IAsyncTransaction, POSTGRES_DIALECT, ICommandBlock
</del><ins>+    AlreadyFinishedError, IAsyncTransaction, ICommandBlock,
+    DatabaseType, POSTGRES_DIALECT,
</ins><span class="cx"> )
</span><span class="cx"> 
</span><span class="cx"> from twext.python.log import Logger
</span><span class="lines">@@ -74,8 +75,8 @@
</span><span class="cx"> 
</span><span class="cx"> DEFAULT_PARAM_STYLE = &quot;pyformat&quot;
</span><span class="cx"> DEFAULT_DIALECT = POSTGRES_DIALECT
</span><ins>+DEFAULT_DBTYPE = DatabaseType(DEFAULT_DIALECT, DEFAULT_PARAM_STYLE)
</ins><span class="cx"> 
</span><del>-
</del><span class="cx"> def _forward(thunk):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Forward an attribute to the connection pool.
</span><span class="lines">@@ -172,17 +173,11 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     @_forward
</span><del>-    def paramstyle(self):
</del><ins>+    def dbtype(self):
</ins><span class="cx">         &quot;&quot;&quot;
</span><del>-        The paramstyle attribute is mirrored from the connection pool.
</del><ins>+        The dbtype attribute is mirrored from the connection pool.
</ins><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-    @_forward
-    def dialect(self):
-        &quot;&quot;&quot;
-        The dialect attribute is mirrored from the connection pool.
-        &quot;&quot;&quot;
-
</del><span class="cx">     def _reallyExecSQL(self, sql, args=None, raiseOnZeroRowCount=None):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Execute the given SQL on a thread, using a DB-API 2.0 cursor.
</span><span class="lines">@@ -528,8 +523,7 @@
</span><span class="cx">     implements(IAsyncTransaction)
</span><span class="cx"> 
</span><span class="cx">     def __init__(self, pool, reason, label=None):
</span><del>-        self.paramstyle = pool.paramstyle
-        self.dialect = pool.dialect
</del><ins>+        self.dbtype = pool.dbtype
</ins><span class="cx">         self.reason = reason
</span><span class="cx">         self._label = label
</span><span class="cx"> 
</span><span class="lines">@@ -563,12 +557,11 @@
</span><span class="cx">     def __init__(self, pool, label=None):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Initialize a L{_WaitingTxn} based on a L{ConnectionPool}.  (The C{pool}
</span><del>-        is used only to reflect C{dialect} and C{paramstyle} attributes; not
</del><ins>+        is used only to reflect C{dbtype} attribute; not
</ins><span class="cx">         remembered or modified in any way.)
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         self._spool = []
</span><del>-        self.paramstyle = pool.paramstyle
-        self.dialect = pool.dialect
</del><ins>+        self.dbtype = pool.dbtype
</ins><span class="cx">         self._label = label
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -931,8 +924,7 @@
</span><span class="cx"> 
</span><span class="cx">     def __init__(self, singleTxn):
</span><span class="cx">         self._singleTxn = singleTxn
</span><del>-        self.paramstyle = singleTxn.paramstyle
-        self.dialect = singleTxn.dialect
</del><ins>+        self.dbtype = singleTxn.dbtype
</ins><span class="cx">         self._spool = _WaitingTxn(singleTxn._pool, label=singleTxn._label)
</span><span class="cx">         self._started = False
</span><span class="cx">         self._ended = False
</span><span class="lines">@@ -1129,15 +1121,14 @@
</span><span class="cx">     def __init__(
</span><span class="cx">         self,
</span><span class="cx">         connectionFactory, maxConnections=10,
</span><del>-        paramstyle=DEFAULT_PARAM_STYLE, dialect=DEFAULT_DIALECT,
</del><ins>+        dbtype=None,
</ins><span class="cx">         name=None,
</span><span class="cx">     ):
</span><span class="cx"> 
</span><span class="cx">         super(ConnectionPool, self).__init__()
</span><span class="cx">         self.connectionFactory = connectionFactory
</span><span class="cx">         self.maxConnections = maxConnections
</span><del>-        self.paramstyle = paramstyle
-        self.dialect = dialect
</del><ins>+        self.dbtype = dbtype if dbtype is not None else DEFAULT_DBTYPE.copyreplace()
</ins><span class="cx">         if name is not None:
</span><span class="cx">             self.name = name
</span><span class="cx"> 
</span><span class="lines">@@ -1674,15 +1665,14 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx">     def __init__(
</span><del>-        self, dialect=POSTGRES_DIALECT, paramstyle=DEFAULT_PARAM_STYLE
</del><ins>+        self, dbtype=DEFAULT_DBTYPE,
</ins><span class="cx">     ):
</span><span class="cx">         # See DEFAULT_PARAM_STYLE FIXME above.
</span><span class="cx">         super(ConnectionPoolClient, self).__init__()
</span><span class="cx">         self._nextID = count().next
</span><span class="cx">         self._txns = weakref.WeakValueDictionary()
</span><span class="cx">         self._queries = {}
</span><del>-        self.dialect = dialect
-        self.paramstyle = paramstyle
</del><ins>+        self.dbtype = dbtype if dbtype is not None else DEFAULT_DBTYPE.copyreplace()
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def unhandledError(self, failure):
</span><span class="lines">@@ -1813,21 +1803,13 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     @property
</span><del>-    def paramstyle(self):
</del><ins>+    def dbtype(self):
</ins><span class="cx">         &quot;&quot;&quot;
</span><del>-        Forward C{paramstyle} attribute to the client.
</del><ins>+        Forward C{dbtype} attribute to the client.
</ins><span class="cx">         &quot;&quot;&quot;
</span><del>-        return self._client.paramstyle
</del><ins>+        return self._client.dbtype
</ins><span class="cx"> 
</span><span class="cx"> 
</span><del>-    @property
-    def dialect(self):
-        &quot;&quot;&quot;
-        Forward C{dialect} attribute to the client.
-        &quot;&quot;&quot;
-        return self._client.dialect
-
-
</del><span class="cx">     def execSQL(self, sql, args=None, raiseOnZeroRowCount=None, blockID=&quot;&quot;):
</span><span class="cx">         if not blockID:
</span><span class="cx">             if self._completed:
</span><span class="lines">@@ -1912,21 +1894,13 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     @property
</span><del>-    def paramstyle(self):
</del><ins>+    def dbtype(self):
</ins><span class="cx">         &quot;&quot;&quot;
</span><del>-        Forward C{paramstyle} attribute to the transaction.
</del><ins>+        Forward C{dbtype} attribute to the transaction.
</ins><span class="cx">         &quot;&quot;&quot;
</span><del>-        return self._transaction.paramstyle
</del><ins>+        return self._transaction.dbtype
</ins><span class="cx"> 
</span><span class="cx"> 
</span><del>-    @property
-    def dialect(self):
-        &quot;&quot;&quot;
-        Forward C{dialect} attribute to the transaction.
-        &quot;&quot;&quot;
-        return self._transaction.dialect
-
-
</del><span class="cx">     def execSQL(self, sql, args=None, raiseOnZeroRowCount=None):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Execute some SQL on this command block.
</span></span></pre></div>
<a id="twexttrunktwextenterprisedalrecordpy"></a>
<div class="modfile"><h4>Modified: twext/trunk/twext/enterprise/dal/record.py (15733 => 15734)</h4>
<pre class="diff"><span>
<span class="info">--- twext/trunk/twext/enterprise/dal/record.py        2016-07-01 16:33:47 UTC (rev 15733)
+++ twext/trunk/twext/enterprise/dal/record.py        2016-07-05 19:32:22 UTC (rev 15734)
</span><span class="lines">@@ -649,7 +649,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Delete all rows matching the where expression from the table that corresponds to C{cls}.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        if transaction.dialect == ORACLE_DIALECT and returnCols is not None:
</del><ins>+        if transaction.dbtype.dialect == ORACLE_DIALECT and returnCols is not None:
</ins><span class="cx">             # Oracle cannot return multiple rows in the RETURNING clause so
</span><span class="cx">             # we have to split this into a SELECT followed by a DELETE
</span><span class="cx">             if not isinstance(returnCols, (tuple, list)):
</span></span></pre></div>
<a id="twexttrunktwextenterprisedalsyntaxpy"></a>
<div class="modfile"><h4>Modified: twext/trunk/twext/enterprise/dal/syntax.py (15733 => 15734)</h4>
<pre class="diff"><span>
<span class="info">--- twext/trunk/twext/enterprise/dal/syntax.py        2016-07-01 16:33:47 UTC (rev 15733)
+++ twext/trunk/twext/enterprise/dal/syntax.py        2016-07-05 19:32:22 UTC (rev 15734)
</span><span class="lines">@@ -80,7 +80,7 @@
</span><span class="cx"> 
</span><span class="cx"> from twext.enterprise.dal.model import Schema, Table, Column, Sequence, SQLType
</span><span class="cx"> from twext.enterprise.ienterprise import (
</span><del>-    POSTGRES_DIALECT, ORACLE_DIALECT, SQLITE_DIALECT, IDerivedParameter
</del><ins>+    POSTGRES_DIALECT, ORACLE_DIALECT, SQLITE_DIALECT, DatabaseType, IDerivedParameter
</ins><span class="cx"> )
</span><span class="cx"> from twext.enterprise.util import mapOracleOutputType
</span><span class="cx"> 
</span><span class="lines">@@ -158,8 +158,8 @@
</span><span class="cx">     and automated id generator.
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-    def __init__(self, dialect=None, placeholder=None):
-        self.dialect = dialect if dialect else POSTGRES_DIALECT
</del><ins>+    def __init__(self, dbtype=None, placeholder=None):
+        self.dbtype = dbtype if dbtype else DatabaseType(POSTGRES_DIALECT, &quot;qmark&quot;)
</ins><span class="cx">         if placeholder is None:
</span><span class="cx">             placeholder = defaultPlaceholder()
</span><span class="cx">         self.placeholder = placeholder
</span><span class="lines">@@ -172,7 +172,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def shouldQuote(self, name):
</span><del>-        return (self.dialect == ORACLE_DIALECT and name.lower() in _KEYWORDS)
</del><ins>+        return (self.dbtype.dialect == ORACLE_DIALECT and name.lower() in _KEYWORDS)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -261,7 +261,7 @@
</span><span class="cx">             C{list}s)
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         queryGenerator = QueryGenerator(
</span><del>-            txn.dialect, self._paramstyles[txn.paramstyle]()
</del><ins>+            txn.dbtype, self._paramstyles[txn.dbtype.paramstyle]()
</ins><span class="cx">         )
</span><span class="cx">         outvars = self._extraVars(txn, queryGenerator)
</span><span class="cx">         kw.update(outvars)
</span><span class="lines">@@ -270,7 +270,7 @@
</span><span class="cx">             fragment.text, fragment.parameters, raiseOnZeroRowCount
</span><span class="cx">         )
</span><span class="cx">         result = self._extraResult(result, outvars, queryGenerator)
</span><del>-        if queryGenerator.dialect == ORACLE_DIALECT and result:
</del><ins>+        if queryGenerator.dbtype.dialect == ORACLE_DIALECT and result:
</ins><span class="cx">             result.addCallback(self._fixOracleNulls)
</span><span class="cx">         return result
</span><span class="cx"> 
</span><span class="lines">@@ -590,7 +590,7 @@
</span><span class="cx"> 
</span><span class="cx">     def nameFor(self, queryGenerator):
</span><span class="cx">         if (
</span><del>-            queryGenerator.dialect == ORACLE_DIALECT and
</del><ins>+            queryGenerator.dbtype.dialect == ORACLE_DIALECT and
</ins><span class="cx">             self.oracleName is not None
</span><span class="cx">         ):
</span><span class="cx">             return self.oracleName
</span><span class="lines">@@ -668,7 +668,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Convert to an SQL fragment.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        if queryGenerator.dialect == ORACLE_DIALECT:
</del><ins>+        if queryGenerator.dbtype.dialect == ORACLE_DIALECT:
</ins><span class="cx">             fmt = &quot;%s.nextval&quot;
</span><span class="cx">         else:
</span><span class="cx">             fmt = &quot;nextval('%s')&quot;
</span><span class="lines">@@ -723,7 +723,7 @@
</span><span class="cx">         # XXX maybe there should be a specific method which is only invoked
</span><span class="cx">         # from the FROM clause, that only tables and joins would implement?
</span><span class="cx">         return SQLFragment(
</span><del>-            _nameForDialect(self.model.name, queryGenerator.dialect)
</del><ins>+            _nameForDialect(self.model.name, queryGenerator.dbtype.dialect)
</ins><span class="cx">         )
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -1110,7 +1110,7 @@
</span><span class="cx"> 
</span><span class="cx">     def subSQL(self, queryGenerator, allTables):
</span><span class="cx">         if (
</span><del>-            queryGenerator.dialect == ORACLE_DIALECT and
</del><ins>+            queryGenerator.dbtype.dialect == ORACLE_DIALECT and
</ins><span class="cx">             isinstance(self.b, Constant) and
</span><span class="cx">             self.b.value == &quot;&quot; and self.op in (&quot;=&quot;, &quot;!=&quot;)
</span><span class="cx">         ):
</span><span class="lines">@@ -1382,9 +1382,9 @@
</span><span class="cx">     An EXCEPT construct used inside a SELECT.
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     def setOpSQL(self, queryGenerator):
</span><del>-        if queryGenerator.dialect == POSTGRES_DIALECT:
</del><ins>+        if queryGenerator.dbtype.dialect == POSTGRES_DIALECT:
</ins><span class="cx">             return SQLFragment(&quot; EXCEPT &quot;)
</span><del>-        elif queryGenerator.dialect == ORACLE_DIALECT:
</del><ins>+        elif queryGenerator.dbtype.dialect == ORACLE_DIALECT:
</ins><span class="cx">             return SQLFragment(&quot; MINUS &quot;)
</span><span class="cx">         else:
</span><span class="cx">             raise NotImplementedError(&quot;Unsupported dialect&quot;)
</span><span class="lines">@@ -1506,11 +1506,11 @@
</span><span class="cx">         if self.ForUpdate:
</span><span class="cx">             # FOR UPDATE not supported with sqlite - but that is probably not relevant
</span><span class="cx">             # given that sqlite does file level locking of the DB
</span><del>-            if queryGenerator.dialect != SQLITE_DIALECT:
</del><ins>+            if queryGenerator.dbtype.dialect != SQLITE_DIALECT:
</ins><span class="cx">                 # Oracle turns this statement into a sub-select if Limit is non-zero, but we can't have
</span><span class="cx">                 # the &quot;for update&quot; in the sub-select. So suppress it here and add it in the outer limit
</span><span class="cx">                 # select later.
</span><del>-                if self.Limit is None or queryGenerator.dialect != ORACLE_DIALECT:
</del><ins>+                if self.Limit is None or queryGenerator.dbtype.dialect != ORACLE_DIALECT:
</ins><span class="cx">                     stmt.text += &quot; for update&quot;
</span><span class="cx">                     if self.NoWait:
</span><span class="cx">                         stmt.text += &quot; nowait&quot;
</span><span class="lines">@@ -1519,7 +1519,7 @@
</span><span class="cx"> 
</span><span class="cx">         if self.Limit is not None:
</span><span class="cx">             limitConst = Constant(self.Limit).subSQL(queryGenerator, allTables)
</span><del>-            if queryGenerator.dialect == ORACLE_DIALECT:
</del><ins>+            if queryGenerator.dbtype.dialect == ORACLE_DIALECT:
</ins><span class="cx">                 wrapper = SQLFragment(&quot;select * from (&quot;)
</span><span class="cx">                 wrapper.append(stmt)
</span><span class="cx">                 wrapper.append(SQLFragment(&quot;) where ROWNUM &lt;= &quot;))
</span><span class="lines">@@ -1529,7 +1529,7 @@
</span><span class="cx">             stmt.append(limitConst)
</span><span class="cx"> 
</span><span class="cx">             # Add in any Oracle &quot;for update&quot;
</span><del>-            if self.ForUpdate and queryGenerator.dialect == ORACLE_DIALECT:
</del><ins>+            if self.ForUpdate and queryGenerator.dbtype.dialect == ORACLE_DIALECT:
</ins><span class="cx">                 stmt.text += &quot; for update&quot;
</span><span class="cx">                 if self.NoWait:
</span><span class="cx">                     stmt.text += &quot; nowait&quot;
</span><span class="lines">@@ -1620,7 +1620,7 @@
</span><span class="cx">         @rtype: L{SQLFragment}
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-        if queryGenerator.dialect != ORACLE_DIALECT:
</del><ins>+        if queryGenerator.dbtype.dialect != ORACLE_DIALECT:
</ins><span class="cx">             raise NotImplementedError(&quot;CALL statement only available with Oracle DB&quot;)
</span><span class="cx">         args = (self.ReturnType,) + self.Args
</span><span class="cx">         stmt = SQLFragment(&quot;call &quot;, args)
</span><span class="lines">@@ -1724,14 +1724,14 @@
</span><span class="cx">         if isinstance(retclause, (tuple, list)):
</span><span class="cx">             retclause = _CommaList(retclause)
</span><span class="cx"> 
</span><del>-        if queryGenerator.dialect == SQLITE_DIALECT:
</del><ins>+        if queryGenerator.dbtype.dialect == SQLITE_DIALECT:
</ins><span class="cx">             # sqlite does this another way.
</span><span class="cx">             return stmt
</span><span class="cx"> 
</span><span class="cx">         if retclause is not None:
</span><span class="cx">             stmt.text += &quot; returning &quot;
</span><span class="cx">             stmt.append(retclause.subSQL(queryGenerator, allTables))
</span><del>-            if queryGenerator.dialect == ORACLE_DIALECT:
</del><ins>+            if queryGenerator.dbtype.dialect == ORACLE_DIALECT:
</ins><span class="cx">                 stmt.text += &quot; into &quot;
</span><span class="cx">                 params = []
</span><span class="cx">                 retvals = self._returnAsList()
</span><span class="lines">@@ -1757,7 +1757,7 @@
</span><span class="cx">             return []
</span><span class="cx">         result = []
</span><span class="cx">         rvars = self._returnAsList()
</span><del>-        if queryGenerator.dialect == ORACLE_DIALECT:
</del><ins>+        if queryGenerator.dbtype.dialect == ORACLE_DIALECT:
</ins><span class="cx">             for n, v in enumerate(rvars):
</span><span class="cx">                 result.append((&quot;oracle_out_&quot; + str(n), _OracleOutParam(v)))
</span><span class="cx">         return result
</span><span class="lines">@@ -1765,7 +1765,7 @@
</span><span class="cx"> 
</span><span class="cx">     def _extraResult(self, result, outvars, queryGenerator):
</span><span class="cx">         if (
</span><del>-            queryGenerator.dialect == ORACLE_DIALECT and
</del><ins>+            queryGenerator.dbtype.dialect == ORACLE_DIALECT and
</ins><span class="cx">             self.Return is not None
</span><span class="cx">         ):
</span><span class="cx">             def processIt(emptyListResult):
</span><span class="lines">@@ -1841,7 +1841,7 @@
</span><span class="cx">         tableModel = columnsAndValues[0][0].model.table
</span><span class="cx">         specifiedColumnModels = [x.model for x in self.columnMap.keys()]
</span><span class="cx"> 
</span><del>-        if queryGenerator.dialect == ORACLE_DIALECT:
</del><ins>+        if queryGenerator.dbtype.dialect == ORACLE_DIALECT:
</ins><span class="cx">             # See test_nextSequenceDefaultImplicitExplicitOracle.
</span><span class="cx">             for column in tableModel.columns:
</span><span class="cx">                 if isinstance(column.default, Sequence):
</span><span class="lines">@@ -1881,7 +1881,7 @@
</span><span class="cx">         behavior.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         result = yield super(_DMLStatement, self).on(txn, *a, **kw)
</span><del>-        if self.Return is not None and txn.dialect == SQLITE_DIALECT:
</del><ins>+        if self.Return is not None and txn.dbtype.dialect == SQLITE_DIALECT:
</ins><span class="cx">             table = self._returnAsList()[0].model.table
</span><span class="cx">             result = yield Select(
</span><span class="cx">                 self._returnAsList(),
</span><span class="lines">@@ -1936,7 +1936,7 @@
</span><span class="cx">         databases that don't provide return values as part of their C{UPDATE}
</span><span class="cx">         behavior.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        doExtra = self.Return is not None and txn.dialect == SQLITE_DIALECT
</del><ins>+        doExtra = self.Return is not None and txn.dbtype.dialect == SQLITE_DIALECT
</ins><span class="cx">         upcall = lambda: super(_DMLStatement, self).on(txn, *a, **kw)
</span><span class="cx"> 
</span><span class="cx">         if doExtra:
</span><span class="lines">@@ -2024,7 +2024,7 @@
</span><span class="cx">     @inlineCallbacks
</span><span class="cx">     def on(self, txn, *a, **kw):
</span><span class="cx">         upcall = lambda: super(Delete, self).on(txn, *a, **kw)
</span><del>-        if txn.dialect == SQLITE_DIALECT and self.Return is not None:
</del><ins>+        if txn.dbtype.dialect == SQLITE_DIALECT and self.Return is not None:
</ins><span class="cx">             result = yield Select(
</span><span class="cx">                 self._returnAsList(),
</span><span class="cx">                 From=self.From, Where=self.Where
</span><span class="lines">@@ -2064,7 +2064,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def _toSQL(self, queryGenerator):
</span><del>-        if queryGenerator.dialect == SQLITE_DIALECT:
</del><ins>+        if queryGenerator.dbtype.dialect == SQLITE_DIALECT:
</ins><span class="cx">             # FIXME - this is only stubbed out for testing right now, actual
</span><span class="cx">             # concurrency would require some kind of locking statement here.
</span><span class="cx">             # BEGIN IMMEDIATE maybe, if that's okay in the middle of a
</span><span class="lines">@@ -2085,7 +2085,7 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx">     def _toSQL(self, queryGenerator):
</span><del>-        assert(queryGenerator.dialect == POSTGRES_DIALECT)
</del><ins>+        assert(queryGenerator.dbtype.dialect == POSTGRES_DIALECT)
</ins><span class="cx">         return SQLFragment(&quot;select pg_advisory_lock(1)&quot;)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -2093,7 +2093,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Override on() to only execute on Postgres
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        if txn.dialect == POSTGRES_DIALECT:
</del><ins>+        if txn.dbtype.dialect == POSTGRES_DIALECT:
</ins><span class="cx">             return super(DatabaseLock, self).on(txn, *a, **kw)
</span><span class="cx"> 
</span><span class="cx">         return succeed(None)
</span><span class="lines">@@ -2106,7 +2106,7 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx">     def _toSQL(self, queryGenerator):
</span><del>-        assert(queryGenerator.dialect == POSTGRES_DIALECT)
</del><ins>+        assert(queryGenerator.dbtype.dialect == POSTGRES_DIALECT)
</ins><span class="cx">         return SQLFragment(&quot;select pg_advisory_unlock(1)&quot;)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -2114,7 +2114,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Override on() to only execute on Postgres
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        if txn.dialect == POSTGRES_DIALECT:
</del><ins>+        if txn.dbtype.dialect == POSTGRES_DIALECT:
</ins><span class="cx">             return super(DatabaseUnlock, self).on(txn, *a, **kw)
</span><span class="cx"> 
</span><span class="cx">         return succeed(None)
</span><span class="lines">@@ -2170,7 +2170,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def _safeName(self, txn):
</span><del>-        if txn.dialect == ORACLE_DIALECT:
</del><ins>+        if txn.dbtype.dialect == ORACLE_DIALECT:
</ins><span class="cx">             # Oracle limits the length of identifiers
</span><span class="cx">             return self._name[:30]
</span><span class="cx">         else:
</span><span class="lines">@@ -2186,7 +2186,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def release(self, txn):
</span><del>-        if txn.dialect == ORACLE_DIALECT:
</del><ins>+        if txn.dbtype.dialect == ORACLE_DIALECT:
</ins><span class="cx">             # There is no &quot;release savepoint&quot; statement in oracle, but then, we
</span><span class="cx">             # don't need it because there's no resource to manage.  Just don't
</span><span class="cx">             # do anything.
</span></span></pre></div>
<a id="twexttrunktwextenterprisedaltesttest_sqlsyntaxpy"></a>
<div class="modfile"><h4>Modified: twext/trunk/twext/enterprise/dal/test/test_sqlsyntax.py (15733 => 15734)</h4>
<pre class="diff"><span>
<span class="info">--- twext/trunk/twext/enterprise/dal/test/test_sqlsyntax.py        2016-07-01 16:33:47 UTC (rev 15733)
+++ twext/trunk/twext/enterprise/dal/test/test_sqlsyntax.py        2016-07-05 19:32:22 UTC (rev 15734)
</span><span class="lines">@@ -21,6 +21,7 @@
</span><span class="cx"> from twisted.internet.defer import succeed
</span><span class="cx"> from twisted.trial.unittest import TestCase, SkipTest
</span><span class="cx"> 
</span><ins>+from twext.enterprise.adbapi2 import DEFAULT_PARAM_STYLE
</ins><span class="cx"> from twext.enterprise.dal import syntax
</span><span class="cx"> try:
</span><span class="cx">     from twext.enterprise.dal.parseschema import addSQLToSchema
</span><span class="lines">@@ -40,7 +41,7 @@
</span><span class="cx"> from twext.enterprise.dal.syntax import SchemaSyntax
</span><span class="cx"> from twext.enterprise.dal.test.test_parseschema import SchemaTestHelper
</span><span class="cx"> from twext.enterprise.ienterprise import (
</span><del>-    POSTGRES_DIALECT, ORACLE_DIALECT, SQLITE_DIALECT
</del><ins>+    POSTGRES_DIALECT, ORACLE_DIALECT, SQLITE_DIALECT, DatabaseType
</ins><span class="cx"> )
</span><span class="cx"> from twext.enterprise.test.test_adbapi2 import ConnectionPoolHelper
</span><span class="cx"> from twext.enterprise.test.test_adbapi2 import NetworkedPoolHelper
</span><span class="lines">@@ -56,8 +57,8 @@
</span><span class="cx">     generation.
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-    def __init__(self, paramstyle):
-        self.paramstyle = &quot;qmark&quot;
</del><ins>+    def __init__(self):
+        self.dbtype = DatabaseType(POSTGRES_DIALECT, &quot;qmark&quot;)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -75,11 +76,10 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     counter = 0
</span><span class="cx"> 
</span><del>-    def __init__(self, dialect=SQLITE_DIALECT, paramstyle=&quot;numeric&quot;):
</del><ins>+    def __init__(self, dbtype=DatabaseType(SQLITE_DIALECT, &quot;numeric&quot;)):
</ins><span class="cx">         self.execed = []
</span><span class="cx">         self.pendingResults = []
</span><del>-        self.dialect = SQLITE_DIALECT
-        self.paramstyle = &quot;numeric&quot;
</del><ins>+        self.dbtype = dbtype
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def nextResult(self, result):
</span><span class="lines">@@ -110,8 +110,7 @@
</span><span class="cx">     Fake transaction for testing oracle NULL behavior.
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-    dialect = ORACLE_DIALECT
-    paramstyle = &quot;numeric&quot;
</del><ins>+    dbtype = DatabaseType(ORACLE_DIALECT, &quot;numeric&quot;)
</ins><span class="cx"> 
</span><span class="cx">     def execSQL(self, text, params, exc):
</span><span class="cx">         return succeed([[None, None]])
</span><span class="lines">@@ -192,7 +191,9 @@
</span><span class="cx">             Select(
</span><span class="cx">                 From=self.schema.FOO,
</span><span class="cx">                 Where=self.schema.FOO.BAR == 1
</span><del>-            ).toSQL(QueryGenerator(POSTGRES_DIALECT, FixedPlaceholder(&quot;$$&quot;))),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(POSTGRES_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;$$&quot;)
+            )),
</ins><span class="cx">             SQLFragment(&quot;select * from FOO where BAR = $$&quot;, [1])
</span><span class="cx">         )
</span><span class="cx"> 
</span><span class="lines">@@ -270,14 +271,18 @@
</span><span class="cx">             Select(
</span><span class="cx">                 From=self.schema.FOO,
</span><span class="cx">                 Where=self.schema.FOO.BAR == &quot;&quot;
</span><del>-            ).toSQL(QueryGenerator(ORACLE_DIALECT, NumericPlaceholder())),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(ORACLE_DIALECT, &quot;numeric&quot;), NumericPlaceholder()
+            )),
</ins><span class="cx">             SQLFragment(&quot;select * from FOO where BAR is null&quot;, [])
</span><span class="cx">         )
</span><span class="cx">         self.assertEquals(
</span><span class="cx">             Select(
</span><span class="cx">                 From=self.schema.FOO,
</span><span class="cx">                 Where=self.schema.FOO.BAR != &quot;&quot;
</span><del>-            ).toSQL(QueryGenerator(ORACLE_DIALECT, NumericPlaceholder())),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(ORACLE_DIALECT, &quot;numeric&quot;), NumericPlaceholder()
+            )),
</ins><span class="cx">             SQLFragment(&quot;select * from FOO where BAR is not null&quot;, [])
</span><span class="cx">         )
</span><span class="cx"> 
</span><span class="lines">@@ -698,7 +703,9 @@
</span><span class="cx">                         Where=(self.schema.FOO.BAR == 2),
</span><span class="cx">                     ),
</span><span class="cx">                 ),
</span><del>-            ).toSQL(QueryGenerator(POSTGRES_DIALECT, FixedPlaceholder(&quot;?&quot;))),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(POSTGRES_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;?&quot;)
+            )),
</ins><span class="cx">             SQLFragment(
</span><span class="cx">                 &quot;(select * from FOO where BAR = ?) &quot;
</span><span class="cx">                 &quot;UNION (select * from FOO where BAR = ?)&quot;, [1, 2]
</span><span class="lines">@@ -717,7 +724,9 @@
</span><span class="cx">                     ),
</span><span class="cx">                     optype=SetExpression.OPTYPE_ALL
</span><span class="cx">                 ),
</span><del>-            ).toSQL(QueryGenerator(POSTGRES_DIALECT, FixedPlaceholder(&quot;?&quot;))),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(POSTGRES_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;?&quot;)
+            )),
</ins><span class="cx">             SQLFragment(
</span><span class="cx">                 &quot;(select * from FOO where BAR = ?) &quot;
</span><span class="cx">                 &quot;INTERSECT ALL (select * from FOO where BAR = ?)&quot;, [1, 2]
</span><span class="lines">@@ -741,7 +750,9 @@
</span><span class="cx">                     ),
</span><span class="cx">                     optype=SetExpression.OPTYPE_DISTINCT,
</span><span class="cx">                 ),
</span><del>-            ).toSQL(QueryGenerator(POSTGRES_DIALECT, FixedPlaceholder(&quot;?&quot;))),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(POSTGRES_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;?&quot;)
+            )),
</ins><span class="cx">             SQLFragment(
</span><span class="cx">                 &quot;(select * from FOO) &quot;
</span><span class="cx">                 &quot;EXCEPT DISTINCT (select * from FOO where BAR = ?) &quot;
</span><span class="lines">@@ -765,7 +776,9 @@
</span><span class="cx">                         ),
</span><span class="cx">                     ),
</span><span class="cx">                 ),
</span><del>-            ).toSQL(QueryGenerator(ORACLE_DIALECT, FixedPlaceholder(&quot;?&quot;))),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(ORACLE_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;?&quot;)
+            )),
</ins><span class="cx">             SQLFragment(
</span><span class="cx">                 &quot;(select * from FOO) MINUS ((select * from FOO where BAR = ?) &quot;
</span><span class="cx">                 &quot;MINUS (select * from FOO where BAR = ?))&quot;, [2, 3]
</span><span class="lines">@@ -784,7 +797,9 @@
</span><span class="cx">                     ),
</span><span class="cx">                 ),
</span><span class="cx">                 OrderBy=self.schema.FOO.BAR,
</span><del>-            ).toSQL(QueryGenerator(POSTGRES_DIALECT, FixedPlaceholder(&quot;?&quot;))),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(POSTGRES_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;?&quot;)
+            )),
</ins><span class="cx">             SQLFragment(
</span><span class="cx">                 &quot;(select * from FOO where BAR = ?) &quot;
</span><span class="cx">                 &quot;UNION (select * from FOO where BAR = ?) order by BAR&quot;, [1, 2]
</span><span class="lines">@@ -1417,7 +1432,9 @@
</span><span class="cx">             Insert(
</span><span class="cx">                 {self.schema.FOO.BAR: 40, self.schema.FOO.BAZ: 50},
</span><span class="cx">                 Return=(self.schema.FOO.BAR, self.schema.FOO.BAZ)
</span><del>-            ).toSQL(QueryGenerator(ORACLE_DIALECT, NumericPlaceholder())),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(ORACLE_DIALECT, &quot;numeric&quot;), NumericPlaceholder()
+            )),
</ins><span class="cx">             SQLFragment(
</span><span class="cx">                 &quot;insert into FOO (BAR, BAZ) values (:1, :2) &quot;
</span><span class="cx">                 &quot;returning BAR, BAZ into :3, :4&quot;,
</span><span class="lines">@@ -1439,7 +1456,9 @@
</span><span class="cx">             {self.schema.FOO.BAR: 39, self.schema.FOO.BAZ: 82},
</span><span class="cx">             Return=(self.schema.FOO.BAR, self.schema.FOO.BAZ)
</span><span class="cx">         )
</span><del>-        qg = lambda: QueryGenerator(SQLITE_DIALECT, NumericPlaceholder())
</del><ins>+        qg = lambda: QueryGenerator(
+            DatabaseType(SQLITE_DIALECT, &quot;numeric&quot;), NumericPlaceholder()
+        )
</ins><span class="cx">         self.assertEquals(
</span><span class="cx">             insertStatement.toSQL(qg()),
</span><span class="cx">             SQLFragment(&quot;insert into FOO (BAR, BAZ) values (:1, :2)&quot;, [39, 82])
</span><span class="lines">@@ -1609,7 +1628,9 @@
</span><span class="cx">                     self.schema.LEVELS.ACCESS: 1,
</span><span class="cx">                     self.schema.LEVELS.USERNAME: &quot;hi&quot;
</span><span class="cx">                 }
</span><del>-            ).toSQL(QueryGenerator(ORACLE_DIALECT, FixedPlaceholder(&quot;?&quot;))),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(ORACLE_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;?&quot;)
+            )),
</ins><span class="cx">             SQLFragment(
</span><span class="cx">                 &quot;&quot;&quot;insert into LEVELS (&quot;ACCESS&quot;, USERNAME) values (?, ?)&quot;&quot;&quot;,
</span><span class="cx">                 [1, &quot;hi&quot;]
</span><span class="lines">@@ -1621,7 +1642,9 @@
</span><span class="cx">                     self.schema.LEVELS.ACCESS: 1,
</span><span class="cx">                     self.schema.LEVELS.USERNAME: &quot;hi&quot;
</span><span class="cx">                 }
</span><del>-            ).toSQL(QueryGenerator(POSTGRES_DIALECT, FixedPlaceholder(&quot;?&quot;))),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(POSTGRES_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;?&quot;)
+            )),
</ins><span class="cx">             SQLFragment(
</span><span class="cx">                 &quot;insert into LEVELS (ACCESS, USERNAME) values (?, ?)&quot;,
</span><span class="cx">                 [1, &quot;hi&quot;]
</span><span class="lines">@@ -1832,7 +1855,9 @@
</span><span class="cx">                 [self.schema.FOO.BAR],
</span><span class="cx">                 From=self.schema.FOO,
</span><span class="cx">                 Limit=123
</span><del>-            ).toSQL(QueryGenerator(ORACLE_DIALECT, FixedPlaceholder(&quot;?&quot;))),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(ORACLE_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;?&quot;)
+            )),
</ins><span class="cx">             SQLFragment(
</span><span class="cx">                 &quot;select * from (select BAR from FOO) &quot;
</span><span class="cx">                 &quot;where ROWNUM &lt;= ?&quot;, [123]
</span><span class="lines">@@ -1891,7 +1916,9 @@
</span><span class="cx">         self.assertEquals(
</span><span class="cx">             Insert(
</span><span class="cx">                 {self.schema.BOZ.QUX: self.schema.A_SEQ}
</span><del>-            ).toSQL(QueryGenerator(ORACLE_DIALECT, FixedPlaceholder(&quot;?&quot;))),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(ORACLE_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;?&quot;)
+            )),
</ins><span class="cx">             SQLFragment(&quot;insert into BOZ (QUX) values (A_SEQ.nextval)&quot;, [])
</span><span class="cx">         )
</span><span class="cx"> 
</span><span class="lines">@@ -1911,7 +1938,9 @@
</span><span class="cx">         )
</span><span class="cx">         self.assertEquals(
</span><span class="cx">             Insert({self.schema.DFLTR.a: &quot;hello&quot;}).toSQL(
</span><del>-                QueryGenerator(ORACLE_DIALECT, FixedPlaceholder(&quot;?&quot;))
</del><ins>+                QueryGenerator(
+                    DatabaseType(ORACLE_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;?&quot;)
+                )
</ins><span class="cx">             ),
</span><span class="cx">             SQLFragment(&quot;insert into DFLTR (a, b) values &quot;
</span><span class="cx">                         &quot;(?, A_SEQ.nextval)&quot;, [&quot;hello&quot;]),
</span><span class="lines">@@ -1924,7 +1953,9 @@
</span><span class="cx">                     self.schema.DFLTR.b: self.schema.A_SEQ
</span><span class="cx">                 }
</span><span class="cx">             ).toSQL(
</span><del>-                QueryGenerator(ORACLE_DIALECT, FixedPlaceholder(&quot;?&quot;))
</del><ins>+                QueryGenerator(
+                    DatabaseType(ORACLE_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;?&quot;)
+                )
</ins><span class="cx">             ),
</span><span class="cx">             SQLFragment(
</span><span class="cx">                 &quot;insert into DFLTR (a, b) values (?, A_SEQ.nextval)&quot;, [&quot;hello&quot;]
</span><span class="lines">@@ -1943,8 +1974,7 @@
</span><span class="cx">         class FakeOracleTxn(object):
</span><span class="cx">             def execSQL(self, text, params, exc):
</span><span class="cx">                 stmts.append((text, params))
</span><del>-            dialect = ORACLE_DIALECT
-            paramstyle = &quot;numeric&quot;
</del><ins>+            dbtype = DatabaseType(ORACLE_DIALECT, &quot;numeric&quot;)
</ins><span class="cx"> 
</span><span class="cx">         Select(
</span><span class="cx">             [self.schema.FOO.BAR],
</span><span class="lines">@@ -2171,7 +2201,9 @@
</span><span class="cx">         vvl = self.schema.veryveryveryveryveryveryveryverylong
</span><span class="cx">         self.assertEquals(
</span><span class="cx">             Insert({vvl.foo: 1}).toSQL(
</span><del>-                QueryGenerator(ORACLE_DIALECT, FixedPlaceholder(&quot;?&quot;))
</del><ins>+                QueryGenerator(
+                    DatabaseType(ORACLE_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;?&quot;)
+                )
</ins><span class="cx">             ),
</span><span class="cx">             SQLFragment(
</span><span class="cx">                 &quot;insert into veryveryveryveryveryveryveryve (foo) values (?)&quot;,
</span><span class="lines">@@ -2245,7 +2277,7 @@
</span><span class="cx">         self.assertEquals(
</span><span class="cx">             Call(
</span><span class="cx">                 &quot;procedure&quot;
</span><del>-            ).toSQL(QueryGenerator(ORACLE_DIALECT)),
</del><ins>+            ).toSQL(QueryGenerator(DatabaseType(ORACLE_DIALECT, &quot;qmark&quot;))),
</ins><span class="cx">             SQLFragment(&quot;call procedure()&quot;, (None,))
</span><span class="cx">         )
</span><span class="cx"> 
</span><span class="lines">@@ -2253,7 +2285,7 @@
</span><span class="cx">             Call(
</span><span class="cx">                 &quot;procedure&quot;,
</span><span class="cx">                 1, &quot;2&quot;
</span><del>-            ).toSQL(QueryGenerator(ORACLE_DIALECT)),
</del><ins>+            ).toSQL(QueryGenerator(DatabaseType(ORACLE_DIALECT, &quot;qmark&quot;))),
</ins><span class="cx">             SQLFragment(&quot;call procedure()&quot;, (None, 1, &quot;2&quot;))
</span><span class="cx">         )
</span><span class="cx"> 
</span><span class="lines">@@ -2261,7 +2293,7 @@
</span><span class="cx">             Call(
</span><span class="cx">                 &quot;function&quot;,
</span><span class="cx">                 returnType=int
</span><del>-            ).toSQL(QueryGenerator(ORACLE_DIALECT)),
</del><ins>+            ).toSQL(QueryGenerator(DatabaseType(ORACLE_DIALECT, &quot;qmark&quot;))),
</ins><span class="cx">             SQLFragment(&quot;call function()&quot;, (int,))
</span><span class="cx">         )
</span><span class="cx"> 
</span><span class="lines">@@ -2270,14 +2302,14 @@
</span><span class="cx">                 &quot;function&quot;,
</span><span class="cx">                 1, &quot;2&quot;,
</span><span class="cx">                 returnType=int
</span><del>-            ).toSQL(QueryGenerator(ORACLE_DIALECT)),
</del><ins>+            ).toSQL(QueryGenerator(DatabaseType(ORACLE_DIALECT, &quot;qmark&quot;))),
</ins><span class="cx">             SQLFragment(&quot;call function()&quot;, (int, 1, &quot;2&quot;))
</span><span class="cx">         )
</span><span class="cx"> 
</span><span class="cx">         self.assertRaises(
</span><span class="cx">             NotImplementedError,
</span><span class="cx">             Call(&quot;procedure&quot;).toSQL,
</span><del>-            QueryGenerator(POSTGRES_DIALECT)
</del><ins>+            QueryGenerator(DatabaseType(POSTGRES_DIALECT, &quot;qmark&quot;))
</ins><span class="cx">         )
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -2292,7 +2324,9 @@
</span><span class="cx">         self.assertEquals(
</span><span class="cx">             Insert(
</span><span class="cx">                 {schema.FOO.BAR: 1, schema.FOO.UID: &quot;test&quot;},
</span><del>-            ).toSQL(QueryGenerator(ORACLE_DIALECT, FixedPlaceholder(&quot;?&quot;))),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(ORACLE_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;?&quot;)
+            )),
</ins><span class="cx">             SQLFragment(
</span><span class="cx">                 &quot;insert into FOO (BAR, \&quot;UID\&quot;) values (?, ?)&quot;, [1, &quot;test&quot;]
</span><span class="cx">             )
</span><span class="lines">@@ -2301,7 +2335,9 @@
</span><span class="cx">             Update(
</span><span class="cx">                 {schema.FOO.BAR: 1, schema.FOO.UID: &quot;test&quot;},
</span><span class="cx">                 Where=(schema.FOO.BAR == 2),
</span><del>-            ).toSQL(QueryGenerator(ORACLE_DIALECT, FixedPlaceholder(&quot;?&quot;))),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(ORACLE_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;?&quot;)
+            )),
</ins><span class="cx">             SQLFragment(
</span><span class="cx">                 &quot;update FOO set BAR = ?, \&quot;UID\&quot; = ? where BAR = ?&quot;, [1, &quot;test&quot;, 2]
</span><span class="cx">             )
</span><span class="lines">@@ -2311,7 +2347,9 @@
</span><span class="cx">                 [schema.FOO.BAR, schema.FOO.UID],
</span><span class="cx">                 From=schema.FOO,
</span><span class="cx">                 Where=(schema.FOO.UID == &quot;test&quot;),
</span><del>-            ).toSQL(QueryGenerator(ORACLE_DIALECT, FixedPlaceholder(&quot;?&quot;))),
</del><ins>+            ).toSQL(QueryGenerator(
+                DatabaseType(ORACLE_DIALECT, &quot;pyformat&quot;), FixedPlaceholder(&quot;?&quot;)
+            )),
</ins><span class="cx">             SQLFragment(
</span><span class="cx">                 &quot;select BAR, \&quot;UID\&quot; from FOO where \&quot;UID\&quot; = ?&quot;, [&quot;test&quot;]
</span><span class="cx">             )
</span><span class="lines">@@ -2388,7 +2426,7 @@
</span><span class="cx">     Tests which use an oracle connection.
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-    dialect = ORACLE_DIALECT
</del><ins>+    dbtype = DatabaseType(ORACLE_DIALECT, DEFAULT_PARAM_STYLE)
</ins><span class="cx"> 
</span><span class="cx">     def setUp(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="lines">@@ -2406,10 +2444,10 @@
</span><span class="cx">     TestCase
</span><span class="cx"> ):
</span><span class="cx"> 
</span><del>-    dialect = ORACLE_DIALECT
</del><ins>+    dbtype = DatabaseType(ORACLE_DIALECT, DEFAULT_PARAM_STYLE)
</ins><span class="cx"> 
</span><span class="cx">     def setUp(self):
</span><span class="cx">         self.patch(syntax, &quot;cx_Oracle&quot;, FakeCXOracleModule)
</span><span class="cx">         super(OracleNetConnectionTests, self).setUp()
</span><span class="cx">         ExampleSchemaHelper.setUp(self)
</span><del>-        self.pump.client.dialect = ORACLE_DIALECT
</del><ins>+        self.pump.client.dbtypedialect = ORACLE_DIALECT
</ins></span></pre></div>
<a id="twexttrunktwextenterprisefixturespy"></a>
<div class="modfile"><h4>Modified: twext/trunk/twext/enterprise/fixtures.py (15733 => 15734)</h4>
<pre class="diff"><span>
<span class="info">--- twext/trunk/twext/enterprise/fixtures.py        2016-07-01 16:33:47 UTC (rev 15733)
+++ twext/trunk/twext/enterprise/fixtures.py        2016-07-05 19:32:22 UTC (rev 15734)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> from twisted.python.threadpool import ThreadPool
</span><span class="cx"> 
</span><span class="cx"> from twext.enterprise.adbapi2 import ConnectionPool
</span><ins>+from twext.enterprise.ienterprise import DatabaseType
</ins><span class="cx"> from twext.enterprise.ienterprise import SQLITE_DIALECT
</span><span class="cx"> from twext.enterprise.ienterprise import POSTGRES_DIALECT
</span><span class="cx"> from twext.enterprise.adbapi2 import DEFAULT_PARAM_STYLE
</span><span class="lines">@@ -39,7 +40,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-def buildConnectionPool(testCase, schemaText=&quot;&quot;, dialect=SQLITE_DIALECT):
</del><ins>+def buildConnectionPool(testCase, schemaText=&quot;&quot;, dbtype=DatabaseType(SQLITE_DIALECT, &quot;numeric&quot;)):
</ins><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Build a L{ConnectionPool} for testing purposes, with the given C{testCase}.
</span><span class="cx"> 
</span><span class="lines">@@ -71,8 +72,7 @@
</span><span class="cx">     con = connectionFactory()
</span><span class="cx">     con.executescript(schemaText)
</span><span class="cx">     con.commit()
</span><del>-    pool = ConnectionPool(connectionFactory, paramstyle=&quot;numeric&quot;,
-                          dialect=SQLITE_DIALECT)
</del><ins>+    pool = ConnectionPool(connectionFactory, dbtype=dbtype)
</ins><span class="cx">     pool.startService()
</span><span class="cx">     testCase.addCleanup(pool.stopService)
</span><span class="cx">     return pool
</span><span class="lines">@@ -227,8 +227,7 @@
</span><span class="cx">     L{ConnectionPool}.
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-    dialect = POSTGRES_DIALECT
-    paramstyle = DEFAULT_PARAM_STYLE
</del><ins>+    dbtype = DatabaseType(POSTGRES_DIALECT, DEFAULT_PARAM_STYLE)
</ins><span class="cx"> 
</span><span class="cx">     def setUp(self, test=None, connect=None):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="lines">@@ -245,8 +244,7 @@
</span><span class="cx">         self.pool = ConnectionPool(
</span><span class="cx">             connect,
</span><span class="cx">             maxConnections=2,
</span><del>-            dialect=self.dialect,
-            paramstyle=self.paramstyle
</del><ins>+            dbtype=self.dbtype,
</ins><span class="cx">         )
</span><span class="cx">         self.pool._createHolder = self.makeAHolder
</span><span class="cx">         self.clock = self.pool.reactor = ClockWithThreads()
</span><span class="lines">@@ -301,8 +299,7 @@
</span><span class="cx">     capable of firing all its L{Deferred}s on demand, synchronously, by using
</span><span class="cx">     SQLite.
</span><span class="cx">     &quot;&quot;&quot;
</span><del>-    dialect = SQLITE_DIALECT
-    paramstyle = sqlite3.paramstyle
</del><ins>+    dbtype = DatabaseType(SQLITE_DIALECT, sqlite3.paramstyle)
</ins><span class="cx"> 
</span><span class="cx">     def __init__(self, schema):
</span><span class="cx">         self.schema = schema
</span></span></pre></div>
<a id="twexttrunktwextenterpriseienterprisepy"></a>
<div class="modfile"><h4>Modified: twext/trunk/twext/enterprise/ienterprise.py (15733 => 15734)</h4>
<pre class="diff"><span>
<span class="info">--- twext/trunk/twext/enterprise/ienterprise.py        2016-07-01 16:33:47 UTC (rev 15733)
+++ twext/trunk/twext/enterprise/ienterprise.py        2016-07-05 19:32:22 UTC (rev 15734)
</span><span class="lines">@@ -56,26 +56,61 @@
</span><span class="cx"> ORACLE_TABLE_NAME_MAX = 30
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+&quot;&quot;&quot;
+Holds details about the database in use. The C{dialect} attribute is
+one of the C{*_DIALECT} constants in this module. The C{paramstyle}
+attribute is a copy of the DB-API 2.0 module attribute. The C{options}
+attribute is a set of optional features for the DB in use.
+&quot;&quot;&quot;
+class DatabaseType(object):
+    def __init__(self, dialect, paramstyle, options=()):
+        &quot;&quot;&quot;
+        @param dialect: database dialect to use
+        @type dialect: L{str}
+        @param paramstyle: parameter style for SQL statements
+        @type paramstyle: L[str}
+        @param options: set of optional features
+        @type options: L{iterable}
+        &quot;&quot;&quot;
+        self.dialect = dialect
+        self.paramstyle = paramstyle
+        self.options = frozenset(options)
</ins><span class="cx"> 
</span><ins>+
+    def copyreplace(self, dialect=None, paramstyle=None, options=None):
+        &quot;&quot;&quot;
+        Create a copy of this L{DatabaseType} and modify the supplied properties in
+        the new copy.
+
+        @param dialect: new value for C{dialect} or None for no change
+        @type dialect: L{str}
+        @param paramstyle: new value for C{paramstyle} or None for no change
+        @type paramstyle: L{str}
+        @param options: new value for C{options} or None for no change
+        @type options: L{iterable}
+        &quot;&quot;&quot;
+
+        return DatabaseType(
+            self.dialect if dialect is None else dialect,
+            self.paramstyle if paramstyle is None else paramstyle,
+            self.options if options is None else options,
+        )
+
+
+
</ins><span class="cx"> class ISQLExecutor(Interface):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Base SQL-execution interface, for a group of commands or a transaction.
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-    paramstyle = Attribute(
</del><ins>+    dbtype = Attribute(
</ins><span class="cx">         &quot;&quot;&quot;
</span><del>-        A copy of the C{paramstyle} attribute from a DB-API 2.0 module.
</del><ins>+        A copy of the C{dbtype} attribute from the connection pool. It is
+        a L{DatabaseType}.
</ins><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">     )
</span><span class="cx"> 
</span><del>-    dialect = Attribute(
-        &quot;&quot;&quot;
-        A copy of the C{dialect} attribute from the connection pool.  One of
-        the C{*_DIALECT} constants in this module, such as L{POSTGRES_DIALECT}.
-        &quot;&quot;&quot;
-    )
</del><span class="cx"> 
</span><del>-
</del><span class="cx">     def execSQL(sql, args=(), raiseOnZeroRowCount=None):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Execute some SQL.
</span></span></pre></div>
<a id="twexttrunktwextenterprisejobsjobitempy"></a>
<div class="modfile"><h4>Modified: twext/trunk/twext/enterprise/jobs/jobitem.py (15733 => 15734)</h4>
<pre class="diff"><span>
<span class="info">--- twext/trunk/twext/enterprise/jobs/jobitem.py        2016-07-01 16:33:47 UTC (rev 15733)
+++ twext/trunk/twext/enterprise/jobs/jobitem.py        2016-07-05 19:32:22 UTC (rev 15734)
</span><span class="lines">@@ -376,7 +376,7 @@
</span><span class="cx">         @rtype: L{JobItem}
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-        if txn.dialect == ORACLE_DIALECT:
</del><ins>+        if txn.dbtype.dialect == ORACLE_DIALECT:
</ins><span class="cx"> 
</span><span class="cx">             # For Oracle we need a multi-app server solution that only locks the
</span><span class="cx">             # (one) row being returned by the query, and allows other app servers
</span><span class="lines">@@ -409,6 +409,9 @@
</span><span class="cx">             elif minPriority == JOB_PRIORITY_HIGH:
</span><span class="cx">                 queryExpr = (cls.priority == JOB_PRIORITY_HIGH).And(queryExpr)
</span><span class="cx"> 
</span><ins>+            extra_kwargs = {}
+            if &quot;skip-locked&quot; in txn.dbtype.options:
+                extra_kwargs[&quot;skipLocked&quot;] = True
</ins><span class="cx">             jobs = yield cls.query(
</span><span class="cx">                 txn,
</span><span class="cx">                 queryExpr,
</span><span class="lines">@@ -417,6 +420,7 @@
</span><span class="cx">                 forUpdate=True,
</span><span class="cx">                 noWait=False,
</span><span class="cx">                 limit=1,
</span><ins>+                **extra_kwargs
</ins><span class="cx">             )
</span><span class="cx">             job = jobs[0] if jobs else None
</span><span class="cx"> 
</span><span class="lines">@@ -438,19 +442,23 @@
</span><span class="cx">         @rtype: L{JobItem}
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-        if txn.dialect == ORACLE_DIALECT:
</del><ins>+        if txn.dbtype.dialect == ORACLE_DIALECT:
</ins><span class="cx">             # See L{nextjob} for why Oracle is different
</span><span class="cx">             job = None
</span><span class="cx">             jobID = yield Call(&quot;overdue_job&quot;, now, returnType=int).on(txn)
</span><span class="cx">             if jobID:
</span><span class="cx">                 job = yield cls.load(txn, jobID)
</span><span class="cx">         else:
</span><ins>+            extra_kwargs = {}
+            if &quot;skip-locked&quot; in txn.dbtype.options:
+                extra_kwargs[&quot;skipLocked&quot;] = True
</ins><span class="cx">             jobs = yield cls.query(
</span><span class="cx">                 txn,
</span><span class="cx">                 (cls.assigned != None).And(cls.overdue &lt; now),
</span><span class="cx">                 forUpdate=True,
</span><span class="cx">                 noWait=False,
</span><span class="cx">                 limit=1,
</span><ins>+                **extra_kwargs
</ins><span class="cx">             )
</span><span class="cx">             job = jobs[0] if jobs else None
</span><span class="cx"> 
</span></span></pre></div>
<a id="twexttrunktwextenterprisetesttest_adbapi2py"></a>
<div class="modfile"><h4>Modified: twext/trunk/twext/enterprise/test/test_adbapi2.py (15733 => 15734)</h4>
<pre class="diff"><span>
<span class="info">--- twext/trunk/twext/enterprise/test/test_adbapi2.py        2016-07-01 16:33:47 UTC (rev 15733)
+++ twext/trunk/twext/enterprise/test/test_adbapi2.py        2016-07-05 19:32:22 UTC (rev 15734)
</span><span class="lines">@@ -676,7 +676,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Change the paramstyle of the transaction under test.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        self.pool.paramstyle = paramstyle
</del><ins>+        self.pool.dbtype = self.pool.dbtype.copyreplace(paramstyle=paramstyle)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_propagateParamstyle(self):
</span><span class="lines">@@ -687,24 +687,24 @@
</span><span class="cx">         TEST_PARAMSTYLE = &quot;justtesting&quot;
</span><span class="cx">         self.setParamstyle(TEST_PARAMSTYLE)
</span><span class="cx">         normaltxn = self.createTransaction()
</span><del>-        self.assertEquals(normaltxn.paramstyle, TEST_PARAMSTYLE)
-        self.assertEquals(normaltxn.commandBlock().paramstyle, TEST_PARAMSTYLE)
</del><ins>+        self.assertEquals(normaltxn.dbtype.paramstyle, TEST_PARAMSTYLE)
+        self.assertEquals(normaltxn.commandBlock().dbtype.paramstyle, TEST_PARAMSTYLE)
</ins><span class="cx">         self.pauseHolders()
</span><span class="cx">         extra = []
</span><span class="cx">         extra.append(self.createTransaction())
</span><span class="cx">         waitingtxn = self.createTransaction()
</span><del>-        self.assertEquals(waitingtxn.paramstyle, TEST_PARAMSTYLE)
</del><ins>+        self.assertEquals(waitingtxn.dbtype.paramstyle, TEST_PARAMSTYLE)
</ins><span class="cx">         self.flushHolders()
</span><span class="cx">         self.pool.stopService()
</span><span class="cx">         notxn = self.createTransaction()
</span><del>-        self.assertEquals(notxn.paramstyle, TEST_PARAMSTYLE)
</del><ins>+        self.assertEquals(notxn.dbtype.paramstyle, TEST_PARAMSTYLE)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def setDialect(self, dialect):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Change the dialect of the transaction under test.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        self.pool.dialect = dialect
</del><ins>+        self.pool.dbtype = self.pool.dbtype.copyreplace(dialect=dialect)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_propagateDialect(self):
</span><span class="lines">@@ -715,17 +715,17 @@
</span><span class="cx">         TEST_DIALECT = &quot;otherdialect&quot;
</span><span class="cx">         self.setDialect(TEST_DIALECT)
</span><span class="cx">         normaltxn = self.createTransaction()
</span><del>-        self.assertEquals(normaltxn.dialect, TEST_DIALECT)
-        self.assertEquals(normaltxn.commandBlock().dialect, TEST_DIALECT)
</del><ins>+        self.assertEquals(normaltxn.dbtype.dialect, TEST_DIALECT)
+        self.assertEquals(normaltxn.commandBlock().dbtype.dialect, TEST_DIALECT)
</ins><span class="cx">         self.pauseHolders()
</span><span class="cx">         extra = []
</span><span class="cx">         extra.append(self.createTransaction())
</span><span class="cx">         waitingtxn = self.createTransaction()
</span><del>-        self.assertEquals(waitingtxn.dialect, TEST_DIALECT)
</del><ins>+        self.assertEquals(waitingtxn.dbtype.dialect, TEST_DIALECT)
</ins><span class="cx">         self.flushHolders()
</span><span class="cx">         self.pool.stopService()
</span><span class="cx">         notxn = self.createTransaction()
</span><del>-        self.assertEquals(notxn.dialect, TEST_DIALECT)
</del><ins>+        self.assertEquals(notxn.dbtype.dialect, TEST_DIALECT)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_reConnectWhenFirstExecFails(self):
</span><span class="lines">@@ -1330,8 +1330,7 @@
</span><span class="cx">         super(NetworkedPoolHelper, self).setUp()
</span><span class="cx">         self.pump = IOPump(
</span><span class="cx">             ConnectionPoolClient(
</span><del>-                dialect=self.dialect,
-                paramstyle=self.paramstyle
</del><ins>+                dbtype=self.dbtype,
</ins><span class="cx">             ),
</span><span class="cx">             ConnectionPoolConnection(self.pool)
</span><span class="cx">         )
</span><span class="lines">@@ -1384,7 +1383,7 @@
</span><span class="cx">         Change the paramstyle on both the pool and the client.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         super(NetworkedConnectionPoolTests, self).setParamstyle(paramstyle)
</span><del>-        self.pump.client.paramstyle = paramstyle
</del><ins>+        self.pump.client.dbtype = self.pump.client.dbtype.copyreplace(paramstyle=paramstyle)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def setDialect(self, dialect):
</span><span class="lines">@@ -1392,7 +1391,7 @@
</span><span class="cx">         Change the dialect on both the pool and the client.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         super(NetworkedConnectionPoolTests, self).setDialect(dialect)
</span><del>-        self.pump.client.dialect = dialect
</del><ins>+        self.pump.client.dbtype = self.pump.client.dbtype.copyreplace(dialect=dialect)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_newTransaction(self):
</span></span></pre>
</div>
</div>

</body>
</html>