<!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>[15748] twext/branches/users/cdaboo/better-next-job</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/15748">15748</a></dd>
<dt>Author</dt> <dd>cdaboo@apple.com</dd>
<dt>Date</dt> <dd>2016-07-07 09:12:19 -0700 (Thu, 07 Jul 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Merge from trunk.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#twextbranchesuserscdaboobetternextjobbin_buildsh">twext/branches/users/cdaboo/better-next-job/bin/_build.sh</a></li>
<li><a href="#twextbranchesuserscdaboobetternextjobsetuppy">twext/branches/users/cdaboo/better-next-job/setup.py</a></li>
<li><a href="#twextbranchesuserscdaboobetternextjobtwextenterpriseadbapi2py">twext/branches/users/cdaboo/better-next-job/twext/enterprise/adbapi2.py</a></li>
<li><a href="#twextbranchesuserscdaboobetternextjobtwextenterprisedalrecordpy">twext/branches/users/cdaboo/better-next-job/twext/enterprise/dal/record.py</a></li>
<li><a href="#twextbranchesuserscdaboobetternextjobtwextenterprisedalsyntaxpy">twext/branches/users/cdaboo/better-next-job/twext/enterprise/dal/syntax.py</a></li>
<li><a href="#twextbranchesuserscdaboobetternextjobtwextenterprisedaltesttest_sqlsyntaxpy">twext/branches/users/cdaboo/better-next-job/twext/enterprise/dal/test/test_sqlsyntax.py</a></li>
<li><a href="#twextbranchesuserscdaboobetternextjobtwextenterprisefixturespy">twext/branches/users/cdaboo/better-next-job/twext/enterprise/fixtures.py</a></li>
<li><a href="#twextbranchesuserscdaboobetternextjobtwextenterpriseienterprisepy">twext/branches/users/cdaboo/better-next-job/twext/enterprise/ienterprise.py</a></li>
<li><a href="#twextbranchesuserscdaboobetternextjobtwextenterprisejobsjobitempy">twext/branches/users/cdaboo/better-next-job/twext/enterprise/jobs/jobitem.py</a></li>
<li><a href="#twextbranchesuserscdaboobetternextjobtwextenterprisetesttest_adbapi2py">twext/branches/users/cdaboo/better-next-job/twext/enterprise/test/test_adbapi2.py</a></li>
<li><a href="#twextbranchesuserscdaboobetternextjobtwextpythonlogpy">twext/branches/users/cdaboo/better-next-job/twext/python/log.py</a></li>
</ul>
<h3>Property Changed</h3>
<ul>
<li><a href="#twextbranchesuserscdaboobetternextjob">twext/branches/users/cdaboo/better-next-job/</a></li>
<li><a href="#twextbranchesuserscdaboobetternextjobtwext">twext/branches/users/cdaboo/better-next-job/twext/</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="twextbranchesuserscdaboobetternextjob"></a>
<div class="propset"><h4>Property changes: twext/branches/users/cdaboo/better-next-job</h4>
<pre class="diff"><span>
</span></pre></div>
<a id="svnmergeinfo"></a>
<div class="modfile"><h4>Modified: svn:mergeinfo</h4></div>
<span class="cx">/twext/branches/users/cdaboo/jobs:12742-12780
</span><span class="cx">/twext/branches/users/cdaboo/pod2pod-migration:14416-14520
</span><span class="cx">/twext/branches/users/sagen/recordtypes:13647-13658
</span><span class="cx">/twext/branches/users/sagen/recordtypes-2:13659
</span><span class="cx"> + /twext/branches/users/cdaboo/jobqueue-3:13444-13471
</span><span class="cx">/twext/branches/users/cdaboo/jobs:12742-12780
</span><span class="cx">/twext/branches/users/cdaboo/pod2pod-migration:14416-14520
</span><span class="cx">/twext/branches/users/sagen/recordtypes:13647-13658
</span><span class="cx">/twext/branches/users/sagen/recordtypes-2:13659
</span><span class="cx">/twext/trunk:15734-15744
</span><a id="twextbranchesuserscdaboobetternextjobbin_buildsh"></a>
<div class="modfile"><h4>Modified: twext/branches/users/cdaboo/better-next-job/bin/_build.sh (15747 => 15748)</h4>
<pre class="diff"><span>
<span class="info">--- twext/branches/users/cdaboo/better-next-job/bin/_build.sh        2016-07-07 15:59:44 UTC (rev 15747)
+++ twext/branches/users/cdaboo/better-next-job/bin/_build.sh        2016-07-07 16:12:19 UTC (rev 15748)
</span><span class="lines">@@ -594,37 +594,15 @@
</span><span class="cx">
</span><span class="cx"> bootstrap_virtualenv () {
</span><span class="cx"> mkdir -p "${py_ve_tools}";
</span><del>- mkdir -p "${py_ve_tools}/lib";
- mkdir -p "${py_ve_tools}/junk";
</del><ins>+ export PYTHONUSERBASE="${py_ve_tools}"
</ins><span class="cx">
</span><span class="cx"> for pkg in \
</span><del>- setuptools-17.0 \
- pip-7.0.3 \
- virtualenv-13.0.3 \
</del><ins>+ setuptools==18.5 \
+ pip==8.1.2 \
+ virtualenv==15.0.2 \
</ins><span class="cx"> ; do
</span><del>- local name="${pkg%-*}";
- local version="${pkg#*-}";
- local first="$(echo "${name}" | sed 's|^\(.\).*$|\1|')";
- local url="https://pypi.python.org/packages/source/${first}/${name}/${pkg}.tar.gz";
-
- ruler "Downloading ${pkg}";
-
- local tmp="$(mktemp -d -t ccsXXXXX)";
-
- curl -L "${url}" | tar -C "${tmp}" -xvzf -;
-
- cd "${tmp}/$(basename "${pkg}")";
- PYTHONPATH="${py_ve_tools}/lib" \
- "${bootstrap_python}" setup.py install \
- --install-base="${py_ve_tools}" \
- --install-lib="${py_ve_tools}/lib" \
- --install-headers="${py_ve_tools}/junk" \
- --install-scripts="${py_ve_tools}/junk" \
- --install-data="${py_ve_tools}/junk" \
- ; \
- cd "${wd}";
-
- rm -rf "${tmp}";
</del><ins>+ ruler "Installing ${pkg}";
+ "${bootstrap_python}" -m pip install -I --user "${pkg}";
</ins><span class="cx"> done;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="twextbranchesuserscdaboobetternextjobsetuppy"></a>
<div class="modfile"><h4>Modified: twext/branches/users/cdaboo/better-next-job/setup.py (15747 => 15748)</h4>
<pre class="diff"><span>
<span class="info">--- twext/branches/users/cdaboo/better-next-job/setup.py        2016-07-07 15:59:44 UTC (rev 15747)
+++ twext/branches/users/cdaboo/better-next-job/setup.py        2016-07-07 16:12:19 UTC (rev 15748)
</span><span class="lines">@@ -240,7 +240,7 @@
</span><span class="cx">
</span><span class="cx"> install_requirements = [
</span><span class="cx"> "cffi",
</span><del>- "twisted>=15.4",
</del><ins>+ "twisted>=16.3",
</ins><span class="cx"> ]
</span><span class="cx">
</span><span class="cx"> extras_requirements = {
</span></span></pre></div>
<a id="twextbranchesuserscdaboobetternextjobtwext"></a>
<div class="propset"><h4>Property changes: twext/branches/users/cdaboo/better-next-job/twext</h4>
<pre class="diff"><span>
</span></pre></div>
<a id="svnmergeinfo"></a>
<div class="modfile"><h4>Modified: svn:mergeinfo</h4></div>
<span class="cx">/CalendarServer/branches/config-separation/twext:4379-4443
</span><span class="cx">/CalendarServer/branches/egg-info-351/twext:4589-4625
</span><span class="cx">/CalendarServer/branches/generic-sqlstore/twext:6167-6191
</span><span class="cx">/CalendarServer/branches/new-store/twext:5594-5934
</span><span class="cx">/CalendarServer/branches/new-store-no-caldavfile/twext:5911-5935
</span><span class="cx">/CalendarServer/branches/new-store-no-caldavfile-2/twext:5936-5981
</span><span class="cx">/CalendarServer/branches/release/CalendarServer-4.3-dev/twext:10180-10190,10192
</span><span class="cx">/CalendarServer/branches/release/CalendarServer-5.1-dev/twext:11846
</span><span class="cx">/CalendarServer/branches/users/cdaboo/batchupload-6699/twext:6700-7198
</span><span class="cx">/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/twext:5693-5702
</span><span class="cx">/CalendarServer/branches/users/cdaboo/component-set-fixes/twext:8130-8346
</span><span class="cx">/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twext:3628-3644
</span><span class="cx">/CalendarServer/branches/users/cdaboo/fix-no-ischedule/twext:11607-11871
</span><span class="cx">/CalendarServer/branches/users/cdaboo/implicituidrace/twext:8137-8141
</span><span class="cx">/CalendarServer/branches/users/cdaboo/ischedule-dkim/twext:9747-9979
</span><span class="cx">/CalendarServer/branches/users/cdaboo/json/twext:11622-11912
</span><span class="cx">/CalendarServer/branches/users/cdaboo/managed-attachments/twext:9985-10145
</span><span class="cx">/CalendarServer/branches/users/cdaboo/more-sharing-5591/twext:5592-5601
</span><span class="cx">/CalendarServer/branches/users/cdaboo/partition-4464/twext:4465-4957
</span><span class="cx">/CalendarServer/branches/users/cdaboo/performance-tweaks/twext:11824-11836
</span><span class="cx">/CalendarServer/branches/users/cdaboo/pods/twext:7297-7377
</span><span class="cx">/CalendarServer/branches/users/cdaboo/pycalendar/twext:7085-7206
</span><span class="cx">/CalendarServer/branches/users/cdaboo/pycard/twext:7227-7237
</span><span class="cx">/CalendarServer/branches/users/cdaboo/queued-attendee-refreshes/twext:7740-8287
</span><span class="cx">/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/twext:5071-5105
</span><span class="cx">/CalendarServer/branches/users/cdaboo/reverse-proxy-pods/twext:11875-11900
</span><span class="cx">/CalendarServer/branches/users/cdaboo/shared-calendars-5187/twext:5188-5440
</span><span class="cx">/CalendarServer/branches/users/cdaboo/sharing-in-the-store/twext:11935-12016
</span><span class="cx">/CalendarServer/branches/users/cdaboo/store-scheduling/twext:10876-11129
</span><span class="cx">/CalendarServer/branches/users/cdaboo/timezones/twext:7443-7699
</span><span class="cx">/CalendarServer/branches/users/cdaboo/txn-debugging/twext:8730-8743
</span><span class="cx">/CalendarServer/branches/users/gaya/sharedgroups-3/twext:11088-11204
</span><span class="cx">/CalendarServer/branches/users/glyph/always-abort-txn-on-error/twext:9958-9969
</span><span class="cx">/CalendarServer/branches/users/glyph/case-insensitive-uid/twext:8772-8805
</span><span class="cx">/CalendarServer/branches/users/glyph/conn-limit/twext:6574-6577
</span><span class="cx">/CalendarServer/branches/users/glyph/contacts-server-merge/twext:4971-5080
</span><span class="cx">/CalendarServer/branches/users/glyph/dalify/twext:6932-7023
</span><span class="cx">/CalendarServer/branches/users/glyph/db-reconnect/twext:6824-6876
</span><span class="cx">/CalendarServer/branches/users/glyph/deploybuild/twext:7563-7572
</span><span class="cx">/CalendarServer/branches/users/glyph/digest-auth-redux/twext:10624-10635
</span><span class="cx">/CalendarServer/branches/users/glyph/disable-quota/twext:7718-7727
</span><span class="cx">/CalendarServer/branches/users/glyph/dont-start-postgres/twext:6592-6614
</span><span class="cx">/CalendarServer/branches/users/glyph/enforce-max-requests/twext:11640-11643
</span><span class="cx">/CalendarServer/branches/users/glyph/hang-fix/twext:11465-11491
</span><span class="cx">/CalendarServer/branches/users/glyph/imip-and-admin-html/twext:7866-7984
</span><span class="cx">/CalendarServer/branches/users/glyph/ipv6-client/twext:9054-9105
</span><span class="cx">/CalendarServer/branches/users/glyph/launchd-wrapper-bis/twext:11413-11436
</span><span class="cx">/CalendarServer/branches/users/glyph/linux-tests/twext:6893-6900
</span><span class="cx">/CalendarServer/branches/users/glyph/log-cleanups/twext:11691-11731
</span><span class="cx">/CalendarServer/branches/users/glyph/migrate-merge/twext:8690-8713
</span><span class="cx">/CalendarServer/branches/users/glyph/misc-portability-fixes/twext:7365-7374
</span><span class="cx">/CalendarServer/branches/users/glyph/more-deferreds-6/twext:6322-6368
</span><span class="cx">/CalendarServer/branches/users/glyph/more-deferreds-7/twext:6369-6445
</span><span class="cx">/CalendarServer/branches/users/glyph/multiget-delete/twext:8321-8330
</span><span class="cx">/CalendarServer/branches/users/glyph/new-export/twext:7444-7485
</span><span class="cx">/CalendarServer/branches/users/glyph/one-home-list-api/twext:10048-10073
</span><span class="cx">/CalendarServer/branches/users/glyph/oracle/twext:7106-7155
</span><span class="cx">/CalendarServer/branches/users/glyph/oracle-nulls/twext:7340-7351
</span><span class="cx">/CalendarServer/branches/users/glyph/other-html/twext:8062-8091
</span><span class="cx">/CalendarServer/branches/users/glyph/parallel-sim/twext:8240-8251
</span><span class="cx">/CalendarServer/branches/users/glyph/parallel-upgrade/twext:8376-8400
</span><span class="cx">/CalendarServer/branches/users/glyph/parallel-upgrade_to_1/twext:8571-8583
</span><span class="cx">/CalendarServer/branches/users/glyph/q/twext:9560-9688
</span><span class="cx">/CalendarServer/branches/users/glyph/queue-locking-and-timing/twext:10204-10289
</span><span class="cx">/CalendarServer/branches/users/glyph/quota/twext:7604-7637
</span><span class="cx">/CalendarServer/branches/users/glyph/sendfdport/twext:5388-5424
</span><span class="cx">/CalendarServer/branches/users/glyph/shared-pool-fixes/twext:8436-8443
</span><span class="cx">/CalendarServer/branches/users/glyph/shared-pool-take2/twext:8155-8174
</span><span class="cx">/CalendarServer/branches/users/glyph/sharedpool/twext:6490-6550
</span><span class="cx">/CalendarServer/branches/users/glyph/sharing-api/twext:9192-9205
</span><span class="cx">/CalendarServer/branches/users/glyph/skip-lonely-vtimezones/twext:8524-8535
</span><span class="cx">/CalendarServer/branches/users/glyph/sql-store/twext:5929-6073
</span><span class="cx">/CalendarServer/branches/users/glyph/start-service-start-loop/twext:11060-11065
</span><span class="cx">/CalendarServer/branches/users/glyph/subtransactions/twext:7248-7258
</span><span class="cx">/CalendarServer/branches/users/glyph/table-alias/twext:8651-8664
</span><span class="cx">/CalendarServer/branches/users/glyph/uidexport/twext:7673-7676
</span><span class="cx">/CalendarServer/branches/users/glyph/unshare-when-access-revoked/twext:10562-10595
</span><span class="cx">/CalendarServer/branches/users/glyph/use-system-twisted/twext:5084-5149
</span><span class="cx">/CalendarServer/branches/users/glyph/uuid-normalize/twext:9268-9296
</span><span class="cx">/CalendarServer/branches/users/glyph/warning-cleanups/twext:11347-11357
</span><span class="cx">/CalendarServer/branches/users/glyph/whenNotProposed/twext:11881-11897
</span><span class="cx">/CalendarServer/branches/users/glyph/xattrs-from-files/twext:7757-7769
</span><span class="cx">/CalendarServer/branches/users/sagen/applepush/twext:8126-8184
</span><span class="cx">/CalendarServer/branches/users/sagen/inboxitems/twext:7380-7381
</span><span class="cx">/CalendarServer/branches/users/sagen/locations-resources/twext:5032-5051
</span><span class="cx">/CalendarServer/branches/users/sagen/locations-resources-2/twext:5052-5061
</span><span class="cx">/CalendarServer/branches/users/sagen/purge_old_events/twext:6735-6746
</span><span class="cx">/CalendarServer/branches/users/sagen/resource-delegates-4038/twext:4040-4067
</span><span class="cx">/CalendarServer/branches/users/sagen/resource-delegates-4066/twext:4068-4075
</span><span class="cx">/CalendarServer/branches/users/sagen/resources-2/twext:5084-5093
</span><span class="cx">/CalendarServer/branches/users/sagen/testing/twext:10827-10851,10853-10855
</span><span class="cx">/CalendarServer/branches/users/wsanchez/transations/twext:5515-5593
</span><span class="cx">/twext/branches/users/cdaboo/jobqueue-3/twext:13444-13471
</span><span class="cx">/twext/branches/users/cdaboo/jobs/twext:12742-12780
</span><span class="cx">/twext/branches/users/cdaboo/pod2pod-migration/twext:14416-14520
</span><span class="cx">/twext/branches/users/sagen/recordtypes/twext:13647-13658
</span><span class="cx">/twext/branches/users/sagen/recordtypes-2/twext:13659
</span><span class="cx"> + /CalDAVTester/trunk/twext:11193-11198
</span><span class="cx">/CalendarServer/branches/config-separation/twext:4379-4443
</span><span class="cx">/CalendarServer/branches/egg-info-351/twext:4589-4625
</span><span class="cx">/CalendarServer/branches/generic-sqlstore/twext:6167-6191
</span><span class="cx">/CalendarServer/branches/new-store-no-caldavfile-2/twext:5936-5981
</span><span class="cx">/CalendarServer/branches/new-store-no-caldavfile/twext:5911-5935
</span><span class="cx">/CalendarServer/branches/new-store/twext:5594-5934
</span><span class="cx">/CalendarServer/branches/release/CalendarServer-4.3-dev/twext:10180-10190,10192
</span><span class="cx">/CalendarServer/branches/release/CalendarServer-5.1-dev/twext:11846
</span><span class="cx">/CalendarServer/branches/users/cdaboo/batchupload-6699/twext:6700-7198
</span><span class="cx">/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/twext:5693-5702
</span><span class="cx">/CalendarServer/branches/users/cdaboo/component-set-fixes/twext:8130-8346
</span><span class="cx">/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twext:3628-3644
</span><span class="cx">/CalendarServer/branches/users/cdaboo/fix-no-ischedule/twext:11607-11871
</span><span class="cx">/CalendarServer/branches/users/cdaboo/implicituidrace/twext:8137-8141
</span><span class="cx">/CalendarServer/branches/users/cdaboo/ischedule-dkim/twext:9747-9979
</span><span class="cx">/CalendarServer/branches/users/cdaboo/json/twext:11622-11912
</span><span class="cx">/CalendarServer/branches/users/cdaboo/managed-attachments/twext:9985-10145
</span><span class="cx">/CalendarServer/branches/users/cdaboo/more-sharing-5591/twext:5592-5601
</span><span class="cx">/CalendarServer/branches/users/cdaboo/partition-4464/twext:4465-4957
</span><span class="cx">/CalendarServer/branches/users/cdaboo/performance-tweaks/twext:11824-11836
</span><span class="cx">/CalendarServer/branches/users/cdaboo/pods/twext:7297-7377
</span><span class="cx">/CalendarServer/branches/users/cdaboo/pycalendar/twext:7085-7206
</span><span class="cx">/CalendarServer/branches/users/cdaboo/pycard/twext:7227-7237
</span><span class="cx">/CalendarServer/branches/users/cdaboo/queued-attendee-refreshes/twext:7740-8287
</span><span class="cx">/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/twext:5071-5105
</span><span class="cx">/CalendarServer/branches/users/cdaboo/reverse-proxy-pods/twext:11875-11900
</span><span class="cx">/CalendarServer/branches/users/cdaboo/shared-calendars-5187/twext:5188-5440
</span><span class="cx">/CalendarServer/branches/users/cdaboo/sharing-in-the-store/twext:11935-12016
</span><span class="cx">/CalendarServer/branches/users/cdaboo/store-scheduling/twext:10876-11129
</span><span class="cx">/CalendarServer/branches/users/cdaboo/timezones/twext:7443-7699
</span><span class="cx">/CalendarServer/branches/users/cdaboo/txn-debugging/twext:8730-8743
</span><span class="cx">/CalendarServer/branches/users/gaya/sharedgroups-3/twext:11088-11204
</span><span class="cx">/CalendarServer/branches/users/glyph/always-abort-txn-on-error/twext:9958-9969
</span><span class="cx">/CalendarServer/branches/users/glyph/case-insensitive-uid/twext:8772-8805
</span><span class="cx">/CalendarServer/branches/users/glyph/conn-limit/twext:6574-6577
</span><span class="cx">/CalendarServer/branches/users/glyph/contacts-server-merge/twext:4971-5080
</span><span class="cx">/CalendarServer/branches/users/glyph/dalify/twext:6932-7023
</span><span class="cx">/CalendarServer/branches/users/glyph/db-reconnect/twext:6824-6876
</span><span class="cx">/CalendarServer/branches/users/glyph/deploybuild/twext:7563-7572
</span><span class="cx">/CalendarServer/branches/users/glyph/digest-auth-redux/twext:10624-10635
</span><span class="cx">/CalendarServer/branches/users/glyph/disable-quota/twext:7718-7727
</span><span class="cx">/CalendarServer/branches/users/glyph/dont-start-postgres/twext:6592-6614
</span><span class="cx">/CalendarServer/branches/users/glyph/enforce-max-requests/twext:11640-11643
</span><span class="cx">/CalendarServer/branches/users/glyph/hang-fix/twext:11465-11491
</span><span class="cx">/CalendarServer/branches/users/glyph/imip-and-admin-html/twext:7866-7984
</span><span class="cx">/CalendarServer/branches/users/glyph/ipv6-client/twext:9054-9105
</span><span class="cx">/CalendarServer/branches/users/glyph/launchd-wrapper-bis/twext:11413-11436
</span><span class="cx">/CalendarServer/branches/users/glyph/linux-tests/twext:6893-6900
</span><span class="cx">/CalendarServer/branches/users/glyph/log-cleanups/twext:11691-11731
</span><span class="cx">/CalendarServer/branches/users/glyph/migrate-merge/twext:8690-8713
</span><span class="cx">/CalendarServer/branches/users/glyph/misc-portability-fixes/twext:7365-7374
</span><span class="cx">/CalendarServer/branches/users/glyph/more-deferreds-6/twext:6322-6368
</span><span class="cx">/CalendarServer/branches/users/glyph/more-deferreds-7/twext:6369-6445
</span><span class="cx">/CalendarServer/branches/users/glyph/multiget-delete/twext:8321-8330
</span><span class="cx">/CalendarServer/branches/users/glyph/new-export/twext:7444-7485
</span><span class="cx">/CalendarServer/branches/users/glyph/one-home-list-api/twext:10048-10073
</span><span class="cx">/CalendarServer/branches/users/glyph/oracle-nulls/twext:7340-7351
</span><span class="cx">/CalendarServer/branches/users/glyph/oracle/twext:7106-7155
</span><span class="cx">/CalendarServer/branches/users/glyph/other-html/twext:8062-8091
</span><span class="cx">/CalendarServer/branches/users/glyph/parallel-sim/twext:8240-8251
</span><span class="cx">/CalendarServer/branches/users/glyph/parallel-upgrade/twext:8376-8400
</span><span class="cx">/CalendarServer/branches/users/glyph/parallel-upgrade_to_1/twext:8571-8583
</span><span class="cx">/CalendarServer/branches/users/glyph/q/twext:9560-9688
</span><span class="cx">/CalendarServer/branches/users/glyph/queue-locking-and-timing/twext:10204-10289
</span><span class="cx">/CalendarServer/branches/users/glyph/quota/twext:7604-7637
</span><span class="cx">/CalendarServer/branches/users/glyph/sendfdport/twext:5388-5424
</span><span class="cx">/CalendarServer/branches/users/glyph/shared-pool-fixes/twext:8436-8443
</span><span class="cx">/CalendarServer/branches/users/glyph/shared-pool-take2/twext:8155-8174
</span><span class="cx">/CalendarServer/branches/users/glyph/sharedpool/twext:6490-6550
</span><span class="cx">/CalendarServer/branches/users/glyph/sharing-api/twext:9192-9205
</span><span class="cx">/CalendarServer/branches/users/glyph/skip-lonely-vtimezones/twext:8524-8535
</span><span class="cx">/CalendarServer/branches/users/glyph/sql-store/twext:5929-6073
</span><span class="cx">/CalendarServer/branches/users/glyph/start-service-start-loop/twext:11060-11065
</span><span class="cx">/CalendarServer/branches/users/glyph/subtransactions/twext:7248-7258
</span><span class="cx">/CalendarServer/branches/users/glyph/table-alias/twext:8651-8664
</span><span class="cx">/CalendarServer/branches/users/glyph/uidexport/twext:7673-7676
</span><span class="cx">/CalendarServer/branches/users/glyph/unshare-when-access-revoked/twext:10562-10595
</span><span class="cx">/CalendarServer/branches/users/glyph/use-system-twisted/twext:5084-5149
</span><span class="cx">/CalendarServer/branches/users/glyph/uuid-normalize/twext:9268-9296
</span><span class="cx">/CalendarServer/branches/users/glyph/warning-cleanups/twext:11347-11357
</span><span class="cx">/CalendarServer/branches/users/glyph/whenNotProposed/twext:11881-11897
</span><span class="cx">/CalendarServer/branches/users/glyph/xattrs-from-files/twext:7757-7769
</span><span class="cx">/CalendarServer/branches/users/sagen/applepush/twext:8126-8184
</span><span class="cx">/CalendarServer/branches/users/sagen/inboxitems/twext:7380-7381
</span><span class="cx">/CalendarServer/branches/users/sagen/locations-resources-2/twext:5052-5061
</span><span class="cx">/CalendarServer/branches/users/sagen/locations-resources/twext:5032-5051
</span><span class="cx">/CalendarServer/branches/users/sagen/purge_old_events/twext:6735-6746
</span><span class="cx">/CalendarServer/branches/users/sagen/resource-delegates-4038/twext:4040-4067
</span><span class="cx">/CalendarServer/branches/users/sagen/resource-delegates-4066/twext:4068-4075
</span><span class="cx">/CalendarServer/branches/users/sagen/resources-2/twext:5084-5093
</span><span class="cx">/CalendarServer/branches/users/sagen/testing/twext:10827-10851,10853-10855
</span><span class="cx">/CalendarServer/branches/users/wsanchez/transations/twext:5515-5593
</span><span class="cx">/twext/branches/users/cdaboo/jobqueue-3/twext:13444-13471
</span><span class="cx">/twext/branches/users/cdaboo/jobs/twext:12742-12780
</span><span class="cx">/twext/branches/users/cdaboo/pod2pod-migration/twext:14416-14520
</span><span class="cx">/twext/branches/users/sagen/recordtypes-2/twext:13659
</span><span class="cx">/twext/branches/users/sagen/recordtypes/twext:13647-13658
</span><span class="cx">/twext/trunk/twext:15734-15744
</span><a id="twextbranchesuserscdaboobetternextjobtwextenterpriseadbapi2py"></a>
<div class="modfile"><h4>Modified: twext/branches/users/cdaboo/better-next-job/twext/enterprise/adbapi2.py (15747 => 15748)</h4>
<pre class="diff"><span>
<span class="info">--- twext/branches/users/cdaboo/better-next-job/twext/enterprise/adbapi2.py        2016-07-07 15:59:44 UTC (rev 15747)
+++ twext/branches/users/cdaboo/better-next-job/twext/enterprise/adbapi2.py        2016-07-07 16:12:19 UTC (rev 15748)
</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 = "pyformat"
</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"> """
</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"> """
</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"> """
</span><span class="cx">
</span><del>- @_forward
- def dialect(self):
- """
- The dialect attribute is mirrored from the connection pool.
- """
-
</del><span class="cx"> def _reallyExecSQL(self, sql, args=None, raiseOnZeroRowCount=None):
</span><span class="cx"> """
</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"> """
</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"> """
</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"> """
</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">@@ -1706,7 +1696,7 @@
</span><span class="cx">
</span><span class="cx"> @rtype: L{IAsyncTransaction}
</span><span class="cx"> """
</span><del>- txnid = str(self._nextID())
</del><ins>+ txnid = self._nextID()
</ins><span class="cx"> txn = _NetTransaction(client=self, transactionID=txnid)
</span><span class="cx"> self._txns[txnid] = txn
</span><span class="cx"> self.callRemote(StartTxn, transactionID=txnid)
</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"> """
</span><del>- Forward C{paramstyle} attribute to the client.
</del><ins>+ Forward C{dbtype} attribute to the client.
</ins><span class="cx"> """
</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):
- """
- Forward C{dialect} attribute to the client.
- """
- return self._client.dialect
-
-
</del><span class="cx"> def execSQL(self, sql, args=None, raiseOnZeroRowCount=None, blockID=""):
</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"> """
</span><del>- Forward C{paramstyle} attribute to the transaction.
</del><ins>+ Forward C{dbtype} attribute to the transaction.
</ins><span class="cx"> """
</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):
- """
- Forward C{dialect} attribute to the transaction.
- """
- return self._transaction.dialect
-
-
</del><span class="cx"> def execSQL(self, sql, args=None, raiseOnZeroRowCount=None):
</span><span class="cx"> """
</span><span class="cx"> Execute some SQL on this command block.
</span></span></pre></div>
<a id="twextbranchesuserscdaboobetternextjobtwextenterprisedalrecordpy"></a>
<div class="modfile"><h4>Modified: twext/branches/users/cdaboo/better-next-job/twext/enterprise/dal/record.py (15747 => 15748)</h4>
<pre class="diff"><span>
<span class="info">--- twext/branches/users/cdaboo/better-next-job/twext/enterprise/dal/record.py        2016-07-07 15:59:44 UTC (rev 15747)
+++ twext/branches/users/cdaboo/better-next-job/twext/enterprise/dal/record.py        2016-07-07 16:12:19 UTC (rev 15748)
</span><span class="lines">@@ -649,7 +649,7 @@
</span><span class="cx"> """
</span><span class="cx"> Delete all rows matching the where expression from the table that corresponds to C{cls}.
</span><span class="cx"> """
</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="twextbranchesuserscdaboobetternextjobtwextenterprisedalsyntaxpy"></a>
<div class="modfile"><h4>Modified: twext/branches/users/cdaboo/better-next-job/twext/enterprise/dal/syntax.py (15747 => 15748)</h4>
<pre class="diff"><span>
<span class="info">--- twext/branches/users/cdaboo/better-next-job/twext/enterprise/dal/syntax.py        2016-07-07 15:59:44 UTC (rev 15747)
+++ twext/branches/users/cdaboo/better-next-job/twext/enterprise/dal/syntax.py        2016-07-07 16:12:19 UTC (rev 15748)
</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"> """
</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, "qmark")
</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"> """
</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"> """
</span><span class="cx"> Convert to an SQL fragment.
</span><span class="cx"> """
</span><del>- if queryGenerator.dialect == ORACLE_DIALECT:
</del><ins>+ if queryGenerator.dbtype.dialect == ORACLE_DIALECT:
</ins><span class="cx"> fmt = "%s.nextval"
</span><span class="cx"> else:
</span><span class="cx"> fmt = "nextval('%s')"
</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 == "" and self.op in ("=", "!=")
</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"> """
</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(" EXCEPT ")
</span><del>- elif queryGenerator.dialect == ORACLE_DIALECT:
</del><ins>+ elif queryGenerator.dbtype.dialect == ORACLE_DIALECT:
</ins><span class="cx"> return SQLFragment(" MINUS ")
</span><span class="cx"> else:
</span><span class="cx"> raise NotImplementedError("Unsupported dialect")
</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 "for update" 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 += " for update"
</span><span class="cx"> if self.NoWait:
</span><span class="cx"> stmt.text += " nowait"
</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("select * from (")
</span><span class="cx"> wrapper.append(stmt)
</span><span class="cx"> wrapper.append(SQLFragment(") where ROWNUM <= "))
</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 "for update"
</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 += " for update"
</span><span class="cx"> if self.NoWait:
</span><span class="cx"> stmt.text += " nowait"
</span><span class="lines">@@ -1620,7 +1620,7 @@
</span><span class="cx"> @rtype: L{SQLFragment}
</span><span class="cx"> """
</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("CALL statement only available with Oracle DB")
</span><span class="cx"> args = (self.ReturnType,) + self.Args
</span><span class="cx"> stmt = SQLFragment("call ", 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 += " returning "
</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 += " into "
</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(("oracle_out_" + 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"> """
</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"> """
</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"> """
</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("select pg_advisory_lock(1)")
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -2093,7 +2093,7 @@
</span><span class="cx"> """
</span><span class="cx"> Override on() to only execute on Postgres
</span><span class="cx"> """
</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"> """
</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("select pg_advisory_unlock(1)")
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -2114,7 +2114,7 @@
</span><span class="cx"> """
</span><span class="cx"> Override on() to only execute on Postgres
</span><span class="cx"> """
</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 "release savepoint" 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="twextbranchesuserscdaboobetternextjobtwextenterprisedaltesttest_sqlsyntaxpy"></a>
<div class="modfile"><h4>Modified: twext/branches/users/cdaboo/better-next-job/twext/enterprise/dal/test/test_sqlsyntax.py (15747 => 15748)</h4>
<pre class="diff"><span>
<span class="info">--- twext/branches/users/cdaboo/better-next-job/twext/enterprise/dal/test/test_sqlsyntax.py        2016-07-07 15:59:44 UTC (rev 15747)
+++ twext/branches/users/cdaboo/better-next-job/twext/enterprise/dal/test/test_sqlsyntax.py        2016-07-07 16:12:19 UTC (rev 15748)
</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"> """
</span><span class="cx">
</span><del>- def __init__(self, paramstyle):
- self.paramstyle = "qmark"
</del><ins>+ def __init__(self):
+ self.dbtype = DatabaseType(POSTGRES_DIALECT, "qmark")
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -75,11 +76,10 @@
</span><span class="cx"> """
</span><span class="cx"> counter = 0
</span><span class="cx">
</span><del>- def __init__(self, dialect=SQLITE_DIALECT, paramstyle="numeric"):
</del><ins>+ def __init__(self, dbtype=DatabaseType(SQLITE_DIALECT, "numeric")):
</ins><span class="cx"> self.execed = []
</span><span class="cx"> self.pendingResults = []
</span><del>- self.dialect = SQLITE_DIALECT
- self.paramstyle = "numeric"
</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"> """
</span><span class="cx">
</span><del>- dialect = ORACLE_DIALECT
- paramstyle = "numeric"
</del><ins>+ dbtype = DatabaseType(ORACLE_DIALECT, "numeric")
</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("$$"))),
</del><ins>+ ).toSQL(QueryGenerator(
+ DatabaseType(POSTGRES_DIALECT, "pyformat"), FixedPlaceholder("$$")
+ )),
</ins><span class="cx"> SQLFragment("select * from FOO where BAR = $$", [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 == ""
</span><del>- ).toSQL(QueryGenerator(ORACLE_DIALECT, NumericPlaceholder())),
</del><ins>+ ).toSQL(QueryGenerator(
+ DatabaseType(ORACLE_DIALECT, "numeric"), NumericPlaceholder()
+ )),
</ins><span class="cx"> SQLFragment("select * from FOO where BAR is null", [])
</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 != ""
</span><del>- ).toSQL(QueryGenerator(ORACLE_DIALECT, NumericPlaceholder())),
</del><ins>+ ).toSQL(QueryGenerator(
+ DatabaseType(ORACLE_DIALECT, "numeric"), NumericPlaceholder()
+ )),
</ins><span class="cx"> SQLFragment("select * from FOO where BAR is not null", [])
</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("?"))),
</del><ins>+ ).toSQL(QueryGenerator(
+ DatabaseType(POSTGRES_DIALECT, "pyformat"), FixedPlaceholder("?")
+ )),
</ins><span class="cx"> SQLFragment(
</span><span class="cx"> "(select * from FOO where BAR = ?) "
</span><span class="cx"> "UNION (select * from FOO where BAR = ?)", [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("?"))),
</del><ins>+ ).toSQL(QueryGenerator(
+ DatabaseType(POSTGRES_DIALECT, "pyformat"), FixedPlaceholder("?")
+ )),
</ins><span class="cx"> SQLFragment(
</span><span class="cx"> "(select * from FOO where BAR = ?) "
</span><span class="cx"> "INTERSECT ALL (select * from FOO where BAR = ?)", [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("?"))),
</del><ins>+ ).toSQL(QueryGenerator(
+ DatabaseType(POSTGRES_DIALECT, "pyformat"), FixedPlaceholder("?")
+ )),
</ins><span class="cx"> SQLFragment(
</span><span class="cx"> "(select * from FOO) "
</span><span class="cx"> "EXCEPT DISTINCT (select * from FOO where BAR = ?) "
</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("?"))),
</del><ins>+ ).toSQL(QueryGenerator(
+ DatabaseType(ORACLE_DIALECT, "pyformat"), FixedPlaceholder("?")
+ )),
</ins><span class="cx"> SQLFragment(
</span><span class="cx"> "(select * from FOO) MINUS ((select * from FOO where BAR = ?) "
</span><span class="cx"> "MINUS (select * from FOO where BAR = ?))", [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("?"))),
</del><ins>+ ).toSQL(QueryGenerator(
+ DatabaseType(POSTGRES_DIALECT, "pyformat"), FixedPlaceholder("?")
+ )),
</ins><span class="cx"> SQLFragment(
</span><span class="cx"> "(select * from FOO where BAR = ?) "
</span><span class="cx"> "UNION (select * from FOO where BAR = ?) order by BAR", [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, "numeric"), NumericPlaceholder()
+ )),
</ins><span class="cx"> SQLFragment(
</span><span class="cx"> "insert into FOO (BAR, BAZ) values (:1, :2) "
</span><span class="cx"> "returning BAR, BAZ into :3, :4",
</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, "numeric"), NumericPlaceholder()
+ )
</ins><span class="cx"> self.assertEquals(
</span><span class="cx"> insertStatement.toSQL(qg()),
</span><span class="cx"> SQLFragment("insert into FOO (BAR, BAZ) values (:1, :2)", [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: "hi"
</span><span class="cx"> }
</span><del>- ).toSQL(QueryGenerator(ORACLE_DIALECT, FixedPlaceholder("?"))),
</del><ins>+ ).toSQL(QueryGenerator(
+ DatabaseType(ORACLE_DIALECT, "pyformat"), FixedPlaceholder("?")
+ )),
</ins><span class="cx"> SQLFragment(
</span><span class="cx"> """insert into LEVELS ("ACCESS", USERNAME) values (?, ?)""",
</span><span class="cx"> [1, "hi"]
</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: "hi"
</span><span class="cx"> }
</span><del>- ).toSQL(QueryGenerator(POSTGRES_DIALECT, FixedPlaceholder("?"))),
</del><ins>+ ).toSQL(QueryGenerator(
+ DatabaseType(POSTGRES_DIALECT, "pyformat"), FixedPlaceholder("?")
+ )),
</ins><span class="cx"> SQLFragment(
</span><span class="cx"> "insert into LEVELS (ACCESS, USERNAME) values (?, ?)",
</span><span class="cx"> [1, "hi"]
</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("?"))),
</del><ins>+ ).toSQL(QueryGenerator(
+ DatabaseType(ORACLE_DIALECT, "pyformat"), FixedPlaceholder("?")
+ )),
</ins><span class="cx"> SQLFragment(
</span><span class="cx"> "select * from (select BAR from FOO) "
</span><span class="cx"> "where ROWNUM <= ?", [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("?"))),
</del><ins>+ ).toSQL(QueryGenerator(
+ DatabaseType(ORACLE_DIALECT, "pyformat"), FixedPlaceholder("?")
+ )),
</ins><span class="cx"> SQLFragment("insert into BOZ (QUX) values (A_SEQ.nextval)", [])
</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: "hello"}).toSQL(
</span><del>- QueryGenerator(ORACLE_DIALECT, FixedPlaceholder("?"))
</del><ins>+ QueryGenerator(
+ DatabaseType(ORACLE_DIALECT, "pyformat"), FixedPlaceholder("?")
+ )
</ins><span class="cx"> ),
</span><span class="cx"> SQLFragment("insert into DFLTR (a, b) values "
</span><span class="cx"> "(?, A_SEQ.nextval)", ["hello"]),
</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("?"))
</del><ins>+ QueryGenerator(
+ DatabaseType(ORACLE_DIALECT, "pyformat"), FixedPlaceholder("?")
+ )
</ins><span class="cx"> ),
</span><span class="cx"> SQLFragment(
</span><span class="cx"> "insert into DFLTR (a, b) values (?, A_SEQ.nextval)", ["hello"]
</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 = "numeric"
</del><ins>+ dbtype = DatabaseType(ORACLE_DIALECT, "numeric")
</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("?"))
</del><ins>+ QueryGenerator(
+ DatabaseType(ORACLE_DIALECT, "pyformat"), FixedPlaceholder("?")
+ )
</ins><span class="cx"> ),
</span><span class="cx"> SQLFragment(
</span><span class="cx"> "insert into veryveryveryveryveryveryveryve (foo) values (?)",
</span><span class="lines">@@ -2245,7 +2277,7 @@
</span><span class="cx"> self.assertEquals(
</span><span class="cx"> Call(
</span><span class="cx"> "procedure"
</span><del>- ).toSQL(QueryGenerator(ORACLE_DIALECT)),
</del><ins>+ ).toSQL(QueryGenerator(DatabaseType(ORACLE_DIALECT, "qmark"))),
</ins><span class="cx"> SQLFragment("call procedure()", (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"> "procedure",
</span><span class="cx"> 1, "2"
</span><del>- ).toSQL(QueryGenerator(ORACLE_DIALECT)),
</del><ins>+ ).toSQL(QueryGenerator(DatabaseType(ORACLE_DIALECT, "qmark"))),
</ins><span class="cx"> SQLFragment("call procedure()", (None, 1, "2"))
</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"> "function",
</span><span class="cx"> returnType=int
</span><del>- ).toSQL(QueryGenerator(ORACLE_DIALECT)),
</del><ins>+ ).toSQL(QueryGenerator(DatabaseType(ORACLE_DIALECT, "qmark"))),
</ins><span class="cx"> SQLFragment("call function()", (int,))
</span><span class="cx"> )
</span><span class="cx">
</span><span class="lines">@@ -2270,14 +2302,14 @@
</span><span class="cx"> "function",
</span><span class="cx"> 1, "2",
</span><span class="cx"> returnType=int
</span><del>- ).toSQL(QueryGenerator(ORACLE_DIALECT)),
</del><ins>+ ).toSQL(QueryGenerator(DatabaseType(ORACLE_DIALECT, "qmark"))),
</ins><span class="cx"> SQLFragment("call function()", (int, 1, "2"))
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx"> self.assertRaises(
</span><span class="cx"> NotImplementedError,
</span><span class="cx"> Call("procedure").toSQL,
</span><del>- QueryGenerator(POSTGRES_DIALECT)
</del><ins>+ QueryGenerator(DatabaseType(POSTGRES_DIALECT, "qmark"))
</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: "test"},
</span><del>- ).toSQL(QueryGenerator(ORACLE_DIALECT, FixedPlaceholder("?"))),
</del><ins>+ ).toSQL(QueryGenerator(
+ DatabaseType(ORACLE_DIALECT, "pyformat"), FixedPlaceholder("?")
+ )),
</ins><span class="cx"> SQLFragment(
</span><span class="cx"> "insert into FOO (BAR, \"UID\") values (?, ?)", [1, "test"]
</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: "test"},
</span><span class="cx"> Where=(schema.FOO.BAR == 2),
</span><del>- ).toSQL(QueryGenerator(ORACLE_DIALECT, FixedPlaceholder("?"))),
</del><ins>+ ).toSQL(QueryGenerator(
+ DatabaseType(ORACLE_DIALECT, "pyformat"), FixedPlaceholder("?")
+ )),
</ins><span class="cx"> SQLFragment(
</span><span class="cx"> "update FOO set BAR = ?, \"UID\" = ? where BAR = ?", [1, "test", 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 == "test"),
</span><del>- ).toSQL(QueryGenerator(ORACLE_DIALECT, FixedPlaceholder("?"))),
</del><ins>+ ).toSQL(QueryGenerator(
+ DatabaseType(ORACLE_DIALECT, "pyformat"), FixedPlaceholder("?")
+ )),
</ins><span class="cx"> SQLFragment(
</span><span class="cx"> "select BAR, \"UID\" from FOO where \"UID\" = ?", ["test"]
</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"> """
</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"> """
</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, "cx_Oracle", 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="twextbranchesuserscdaboobetternextjobtwextenterprisefixturespy"></a>
<div class="modfile"><h4>Modified: twext/branches/users/cdaboo/better-next-job/twext/enterprise/fixtures.py (15747 => 15748)</h4>
<pre class="diff"><span>
<span class="info">--- twext/branches/users/cdaboo/better-next-job/twext/enterprise/fixtures.py        2016-07-07 15:59:44 UTC (rev 15747)
+++ twext/branches/users/cdaboo/better-next-job/twext/enterprise/fixtures.py        2016-07-07 16:12:19 UTC (rev 15748)
</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="", dialect=SQLITE_DIALECT):
</del><ins>+def buildConnectionPool(testCase, schemaText="", dbtype=DatabaseType(SQLITE_DIALECT, "numeric")):
</ins><span class="cx"> """
</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="numeric",
- 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"> """
</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"> """
</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"> """
</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="twextbranchesuserscdaboobetternextjobtwextenterpriseienterprisepy"></a>
<div class="modfile"><h4>Modified: twext/branches/users/cdaboo/better-next-job/twext/enterprise/ienterprise.py (15747 => 15748)</h4>
<pre class="diff"><span>
<span class="info">--- twext/branches/users/cdaboo/better-next-job/twext/enterprise/ienterprise.py        2016-07-07 15:59:44 UTC (rev 15747)
+++ twext/branches/users/cdaboo/better-next-job/twext/enterprise/ienterprise.py        2016-07-07 16:12:19 UTC (rev 15748)
</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>+"""
+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.
+"""
+class DatabaseType(object):
+ def __init__(self, dialect, paramstyle, options=()):
+ """
+ @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}
+ """
+ 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):
+ """
+ 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}
+ """
+
+ 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"> """
</span><span class="cx"> Base SQL-execution interface, for a group of commands or a transaction.
</span><span class="cx"> """
</span><span class="cx">
</span><del>- paramstyle = Attribute(
</del><ins>+ dbtype = Attribute(
</ins><span class="cx"> """
</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"> """
</span><span class="cx"> )
</span><span class="cx">
</span><del>- dialect = Attribute(
- """
- 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}.
- """
- )
</del><span class="cx">
</span><del>-
</del><span class="cx"> def execSQL(sql, args=(), raiseOnZeroRowCount=None):
</span><span class="cx"> """
</span><span class="cx"> Execute some SQL.
</span></span></pre></div>
<a id="twextbranchesuserscdaboobetternextjobtwextenterprisejobsjobitempy"></a>
<div class="modfile"><h4>Modified: twext/branches/users/cdaboo/better-next-job/twext/enterprise/jobs/jobitem.py (15747 => 15748)</h4>
<pre class="diff"><span>
<span class="info">--- twext/branches/users/cdaboo/better-next-job/twext/enterprise/jobs/jobitem.py        2016-07-07 15:59:44 UTC (rev 15747)
+++ twext/branches/users/cdaboo/better-next-job/twext/enterprise/jobs/jobitem.py        2016-07-07 16:12:19 UTC (rev 15748)
</span><span class="lines">@@ -384,7 +384,7 @@
</span><span class="cx"> @rtype: L{JobItem}
</span><span class="cx"> """
</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">@@ -417,6 +417,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 "skip-locked" in txn.dbtype.options:
+ extra_kwargs["skipLocked"] = True
</ins><span class="cx"> jobs = yield cls.query(
</span><span class="cx"> txn,
</span><span class="cx"> queryExpr,
</span><span class="lines">@@ -425,6 +428,7 @@
</span><span class="cx"> forUpdate=True,
</span><span class="cx"> noWait=False,
</span><span class="cx"> limit=rowLimit,
</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">@@ -452,19 +456,23 @@
</span><span class="cx"> @rtype: L{JobItem}
</span><span class="cx"> """
</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("overdue_job", now, rowLimit, 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 "skip-locked" in txn.dbtype.options:
+ extra_kwargs["skipLocked"] = True
</ins><span class="cx"> jobs = yield cls.query(
</span><span class="cx"> txn,
</span><span class="cx"> (cls.assigned != None).And(cls.overdue < now),
</span><span class="cx"> forUpdate=True,
</span><span class="cx"> noWait=False,
</span><span class="cx"> limit=rowLimit,
</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="twextbranchesuserscdaboobetternextjobtwextenterprisetesttest_adbapi2py"></a>
<div class="modfile"><h4>Modified: twext/branches/users/cdaboo/better-next-job/twext/enterprise/test/test_adbapi2.py (15747 => 15748)</h4>
<pre class="diff"><span>
<span class="info">--- twext/branches/users/cdaboo/better-next-job/twext/enterprise/test/test_adbapi2.py        2016-07-07 15:59:44 UTC (rev 15747)
+++ twext/branches/users/cdaboo/better-next-job/twext/enterprise/test/test_adbapi2.py        2016-07-07 16:12:19 UTC (rev 15748)
</span><span class="lines">@@ -676,7 +676,7 @@
</span><span class="cx"> """
</span><span class="cx"> Change the paramstyle of the transaction under test.
</span><span class="cx"> """
</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 = "justtesting"
</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"> """
</span><span class="cx"> Change the dialect of the transaction under test.
</span><span class="cx"> """
</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 = "otherdialect"
</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"> """
</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"> """
</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>
<a id="twextbranchesuserscdaboobetternextjobtwextpythonlogpy"></a>
<div class="modfile"><h4>Modified: twext/branches/users/cdaboo/better-next-job/twext/python/log.py (15747 => 15748)</h4>
<pre class="diff"><span>
<span class="info">--- twext/branches/users/cdaboo/better-next-job/twext/python/log.py        2016-07-07 15:59:44 UTC (rev 15747)
+++ twext/branches/users/cdaboo/better-next-job/twext/python/log.py        2016-07-07 16:12:19 UTC (rev 15748)
</span><span class="lines">@@ -19,6 +19,7 @@
</span><span class="cx"> FileLogObserver, FilteringLogObserver, LogLevelFilterPredicate, \
</span><span class="cx"> formatEventAsClassicLogText, formatTime
</span><span class="cx"> from twisted.python import log
</span><ins>+from twisted import logger
</ins><span class="cx">
</span><span class="cx"> class Logger(_Logger):
</span><span class="cx"> """
</span><span class="lines">@@ -108,4 +109,4 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> Logger.logBeginner = FilteringLogBeginnerWrapper(log.theLogPublisher._logBeginner)
</span><del>-log.theLogPublisher._logBeginner = Logger.logBeginner
</del><ins>+logger.globalLogBeginner = Logger.logBeginner
</ins></span></pre>
</div>
</div>
</body>
</html>