<!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>[14532] CalendarServer/trunk</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/14532">14532</a></dd>
<dt>Author</dt> <dd>cdaboo@apple.com</dd>
<dt>Date</dt> <dd>2015-03-09 12:47:39 -0700 (Mon, 09 Mar 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Support for pg8000 (not currently enabled for use).</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#CalendarServertrunkproject">CalendarServer/trunk/.project</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolscalverifypy">CalendarServer/trunk/calendarserver/tools/calverify.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolstesttest_purge_old_eventspy">CalendarServer/trunk/calendarserver/tools/test/test_purge_old_events.py</a></li>
<li><a href="#CalendarServertrunkrequirementsstabletxt">CalendarServer/trunk/requirements-stable.txt</a></li>
<li><a href="#CalendarServertrunktwistedcaldavdateopspy">CalendarServer/trunk/twistedcaldav/dateops.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavtesttest_dateopspy">CalendarServer/trunk/twistedcaldav/test/test_dateops.py</a></li>
<li><a href="#CalendarServertrunktxdavbasedatastoresubpostgrespy">CalendarServer/trunk/txdav/base/datastore/subpostgres.py</a></li>
<li><a href="#CalendarServertrunktxdavcaldavdatastoreindex_filepy">CalendarServer/trunk/txdav/caldav/datastore/index_file.py</a></li>
<li><a href="#CalendarServertrunktxdavcaldavdatastorequerybuilderpy">CalendarServer/trunk/txdav/caldav/datastore/query/builder.py</a></li>
<li><a href="#CalendarServertrunktxdavcaldavdatastorequerytesttest_filterpy">CalendarServer/trunk/txdav/caldav/datastore/query/test/test_filter.py</a></li>
<li><a href="#CalendarServertrunktxdavcaldavdatastoresqlpy">CalendarServer/trunk/txdav/caldav/datastore/sql.py</a></li>
<li><a href="#CalendarServertrunktxdavcaldavdatastoresql_attachmentpy">CalendarServer/trunk/txdav/caldav/datastore/sql_attachment.py</a></li>
<li><a href="#CalendarServertrunktxdavcaldavdatastoretesttest_index_filepy">CalendarServer/trunk/txdav/caldav/datastore/test/test_index_file.py</a></li>
<li><a href="#CalendarServertrunktxdavcaldavdatastoretesttest_sqlpy">CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py</a></li>
<li><a href="#CalendarServertrunktxdavcarddavdatastoresqlpy">CalendarServer/trunk/txdav/carddav/datastore/sql.py</a></li>
<li><a href="#CalendarServertrunktxdavcarddavdatastoretesttest_sqlpy">CalendarServer/trunk/txdav/carddav/datastore/test/test_sql.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoresqlpy">CalendarServer/trunk/txdav/common/datastore/sql.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoresql_notificationpy">CalendarServer/trunk/txdav/common/datastore/sql_notification.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoresql_tablespy">CalendarServer/trunk/txdav/common/datastore/sql_tables.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoretesttest_sql_tablespy">CalendarServer/trunk/txdav/common/datastore/test/test_sql_tables.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoreupgradesqltesttest_upgradepy">CalendarServer/trunk/txdav/common/datastore/upgrade/sql/test/test_upgrade.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoreupgradesqltesttest_upgrade_with_datapy">CalendarServer/trunk/txdav/common/datastore/upgrade/sql/test/test_upgrade_with_data.py</a></li>
<li><a href="#CalendarServertrunktxdavwhotesttest_group_attendeespy">CalendarServer/trunk/txdav/who/test/test_group_attendees.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalendarServertrunkproject"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/.project (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/.project        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/.project        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -6,6 +6,7 @@
</span><span class="cx">                 &lt;project&gt;CalDAVClientLibrary&lt;/project&gt;
</span><span class="cx">                 &lt;project&gt;cffi&lt;/project&gt;
</span><span class="cx">                 &lt;project&gt;kerberos&lt;/project&gt;
</span><ins>+                &lt;project&gt;pg8000&lt;/project&gt;
</ins><span class="cx">                 &lt;project&gt;psutil&lt;/project&gt;
</span><span class="cx">                 &lt;project&gt;pycalendar&lt;/project&gt;
</span><span class="cx">                 &lt;project&gt;pycparser&lt;/project&gt;
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolscalverifypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/calverify.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/calverify.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/calendarserver/tools/calverify.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -60,7 +60,7 @@
</span><span class="cx"> from twisted.python import usage
</span><span class="cx"> from twisted.python.usage import Options
</span><span class="cx"> from twistedcaldav.datafilters.peruserdata import PerUserDataFilter
</span><del>-from twistedcaldav.dateops import pyCalendarTodatetime
</del><ins>+from twistedcaldav.dateops import pyCalendarToSQLTimestamp
</ins><span class="cx"> from twistedcaldav.ical import Component, InvalidICalendarDataError, Property, PERUSER_COMPONENT
</span><span class="cx"> from twistedcaldav.stdconfig import DEFAULT_CONFIG_FILE
</span><span class="cx"> from twistedcaldav.timezones import TimezoneCache
</span><span class="lines">@@ -530,8 +530,8 @@
</span><span class="cx">         ch = schema.CALENDAR_HOME
</span><span class="cx">         tr = schema.TIME_RANGE
</span><span class="cx">         kwds = {
</span><del>-            &quot;Start&quot; : pyCalendarTodatetime(start),
-            &quot;Max&quot;   : pyCalendarTodatetime(DateTime(1900, 1, 1, 0, 0, 0))
</del><ins>+            &quot;Start&quot; : pyCalendarToSQLTimestamp(start),
+            &quot;Max&quot;   : pyCalendarToSQLTimestamp(DateTime(1900, 1, 1, 0, 0, 0))
</ins><span class="cx">         }
</span><span class="cx">         rows = (yield Select(
</span><span class="cx">             [ch.OWNER_UID, co.RESOURCE_ID, co.ICALENDAR_UID, cb.CALENDAR_RESOURCE_NAME, co.MD5, co.ORGANIZER, co.CREATED, co.MODIFIED],
</span><span class="lines">@@ -583,8 +583,8 @@
</span><span class="cx">         ch = schema.CALENDAR_HOME
</span><span class="cx">         tr = schema.TIME_RANGE
</span><span class="cx">         kwds = {
</span><del>-            &quot;Start&quot; : pyCalendarTodatetime(start),
-            &quot;Max&quot;   : pyCalendarTodatetime(DateTime(1900, 1, 1, 0, 0, 0)),
</del><ins>+            &quot;Start&quot; : pyCalendarToSQLTimestamp(start),
+            &quot;Max&quot;   : pyCalendarToSQLTimestamp(DateTime(1900, 1, 1, 0, 0, 0)),
</ins><span class="cx">             &quot;UUID&quot; : uuid,
</span><span class="cx">         }
</span><span class="cx">         rows = (yield Select(
</span><span class="lines">@@ -613,8 +613,8 @@
</span><span class="cx">             cb.CALENDAR_RESOURCE_NAME != &quot;inbox&quot;)
</span><span class="cx"> 
</span><span class="cx">         kwds = {
</span><del>-            &quot;Start&quot; : pyCalendarTodatetime(start),
-            &quot;Max&quot;   : pyCalendarTodatetime(DateTime(1900, 1, 1, 0, 0, 0)),
</del><ins>+            &quot;Start&quot; : pyCalendarToSQLTimestamp(start),
+            &quot;Max&quot;   : pyCalendarToSQLTimestamp(DateTime(1900, 1, 1, 0, 0, 0)),
</ins><span class="cx">             &quot;UUID&quot; : uuid,
</span><span class="cx">         }
</span><span class="cx">         rows = (yield Select(
</span><span class="lines">@@ -2159,7 +2159,7 @@
</span><span class="cx">         tr = schema.TIME_RANGE
</span><span class="cx">         kwds = {
</span><span class="cx">             &quot;uuid&quot;: uuid,
</span><del>-            &quot;Start&quot; : pyCalendarTodatetime(start),
</del><ins>+            &quot;Start&quot; : pyCalendarToSQLTimestamp(start),
</ins><span class="cx">         }
</span><span class="cx">         rows = (yield Select(
</span><span class="cx">             [co.RESOURCE_ID, ],
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolstesttest_purge_old_eventspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/test/test_purge_old_events.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/test/test_purge_old_events.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/calendarserver/tools/test/test_purge_old_events.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -25,6 +25,7 @@
</span><span class="cx"> )
</span><span class="cx"> from pycalendar.datetime import DateTime
</span><span class="cx"> from twext.enterprise.dal.syntax import Update, Delete
</span><ins>+from twext.enterprise.util import parseSQLTimestamp
</ins><span class="cx"> from twisted.internet import reactor
</span><span class="cx"> from twisted.internet.defer import inlineCallbacks, returnValue, Deferred
</span><span class="cx"> from twistedcaldav.config import config
</span><span class="lines">@@ -458,19 +459,19 @@
</span><span class="cx">         self.assertEquals(
</span><span class="cx">             sorted(results),
</span><span class="cx">             sorted([
</span><del>-                ['home1', 'calendar1', 'old.ics', '1901-01-01 01:00:00'],
-                ['home1', 'calendar1', 'oldattachment1.ics', '1901-01-01 01:00:00'],
-                ['home1', 'calendar1', 'oldattachment2.ics', '1901-01-01 01:00:00'],
-                ['home1', 'calendar1', 'oldmattachment1.ics', '1901-01-01 01:00:00'],
-                ['home1', 'calendar1', 'oldmattachment2.ics', '1901-01-01 01:00:00'],
-                ['home2', 'calendar3', 'repeating_awhile.ics', '1901-01-01 01:00:00'],
-                ['home2', 'calendar2', 'recent.ics', '%s-03-04 22:15:00' % (now,)],
-                ['home2', 'calendar2', 'oldattachment1.ics', '1901-01-01 01:00:00'],
-                ['home2', 'calendar2', 'oldattachment3.ics', '1901-01-01 01:00:00'],
-                ['home2', 'calendar2', 'oldattachment4.ics', '1901-01-01 01:00:00'],
-                ['home2', 'calendar2', 'oldmattachment1.ics', '1901-01-01 01:00:00'],
-                ['home2', 'calendar2', 'oldmattachment3.ics', '1901-01-01 01:00:00'],
-                ['home2', 'calendar2', 'oldmattachment4.ics', '1901-01-01 01:00:00'],
</del><ins>+                ['home1', 'calendar1', 'old.ics', parseSQLTimestamp('1901-01-01 01:00:00')],
+                ['home1', 'calendar1', 'oldattachment1.ics', parseSQLTimestamp('1901-01-01 01:00:00')],
+                ['home1', 'calendar1', 'oldattachment2.ics', parseSQLTimestamp('1901-01-01 01:00:00')],
+                ['home1', 'calendar1', 'oldmattachment1.ics', parseSQLTimestamp('1901-01-01 01:00:00')],
+                ['home1', 'calendar1', 'oldmattachment2.ics', parseSQLTimestamp('1901-01-01 01:00:00')],
+                ['home2', 'calendar3', 'repeating_awhile.ics', parseSQLTimestamp('1901-01-01 01:00:00')],
+                ['home2', 'calendar2', 'recent.ics', parseSQLTimestamp('%s-03-04 22:15:00' % (now,))],
+                ['home2', 'calendar2', 'oldattachment1.ics', parseSQLTimestamp('1901-01-01 01:00:00')],
+                ['home2', 'calendar2', 'oldattachment3.ics', parseSQLTimestamp('1901-01-01 01:00:00')],
+                ['home2', 'calendar2', 'oldattachment4.ics', parseSQLTimestamp('1901-01-01 01:00:00')],
+                ['home2', 'calendar2', 'oldmattachment1.ics', parseSQLTimestamp('1901-01-01 01:00:00')],
+                ['home2', 'calendar2', 'oldmattachment3.ics', parseSQLTimestamp('1901-01-01 01:00:00')],
+                ['home2', 'calendar2', 'oldmattachment4.ics', parseSQLTimestamp('1901-01-01 01:00:00')],
</ins><span class="cx">             ])
</span><span class="cx">         )
</span><span class="cx"> 
</span><span class="lines">@@ -497,7 +498,7 @@
</span><span class="cx">         count = (yield txn.removeOldEvents(cutoff))
</span><span class="cx">         self.assertEquals(count, 12)
</span><span class="cx">         results = (yield txn.eventsOlderThan(cutoff))
</span><del>-        self.assertEquals(results, [])
</del><ins>+        self.assertEquals(list(results), [])
</ins><span class="cx"> 
</span><span class="cx">         # Remove oldest events (none left)
</span><span class="cx">         count = (yield txn.removeOldEvents(cutoff))
</span></span></pre></div>
<a id="CalendarServertrunkrequirementsstabletxt"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/requirements-stable.txt (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/requirements-stable.txt        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/requirements-stable.txt        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -36,7 +36,7 @@
</span><span class="cx">             #pyOpenSSL
</span><span class="cx">         pycrypto==2.6.1
</span><span class="cx"> 
</span><del>-    --editable svn+http://svn.calendarserver.org/repository/calendarserver/twext/trunk@14521#egg=twextpy
</del><ins>+    --editable svn+http://svn.calendarserver.org/repository/calendarserver/twext/trunk@14531#egg=twextpy
</ins><span class="cx">         cffi==0.8.6
</span><span class="cx">             pycparser==2.10
</span><span class="cx">         #twisted
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavdateopspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/dateops.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/dateops.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/twistedcaldav/dateops.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -32,7 +32,7 @@
</span><span class="cx"> from pycalendar.timezone import Timezone
</span><span class="cx"> from pycalendar.period import Period
</span><span class="cx"> 
</span><del>-import datetime
</del><ins>+from datetime import date, datetime
</ins><span class="cx"> import dateutil.tz
</span><span class="cx"> 
</span><span class="cx"> import calendar
</span><span class="lines">@@ -269,19 +269,19 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-def pyCalendarTodatetime(pydt):
</del><ins>+def pyCalendarToSQLTimestamp(pydt):
</ins><span class="cx"> 
</span><span class="cx">     if pydt.isDateOnly():
</span><del>-        return datetime.date(year=pydt.getYear(), month=pydt.getMonth(), day=pydt.getDay())
</del><ins>+        return date(year=pydt.getYear(), month=pydt.getMonth(), day=pydt.getDay())
</ins><span class="cx">     else:
</span><del>-        return datetime.datetime(
</del><ins>+        return datetime(
</ins><span class="cx">             year=pydt.getYear(),
</span><span class="cx">             month=pydt.getMonth(),
</span><span class="cx">             day=pydt.getDay(),
</span><span class="cx">             hour=pydt.getHours(),
</span><span class="cx">             minute=pydt.getMinutes(),
</span><span class="cx">             second=pydt.getSeconds(),
</span><del>-            tzinfo=dateutil.tz.tzutc()
</del><ins>+            tzinfo=None
</ins><span class="cx">         )
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -295,15 +295,25 @@
</span><span class="cx">     @return: L{DateTime} result
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-    # Format is &quot;%Y-%m-%d %H:%M:%S&quot;
-    return DateTime(
-        year=int(ts[0:4]),
-        month=int(ts[5:7]),
-        day=int(ts[8:10]),
-        hours=int(ts[11:13]),
-        minutes=int(ts[14:16]),
-        seconds=int(ts[17:19])
-    )
</del><ins>+    if isinstance(ts, datetime):
+        return DateTime(
+            year=ts.year,
+            month=ts.month,
+            day=ts.day,
+            hours=ts.hour,
+            minutes=ts.minute,
+            seconds=ts.second
+        )
+    else:
+        # Format is &quot;%Y-%m-%d %H:%M:%S&quot;
+        return DateTime(
+            year=int(ts[0:4]),
+            month=int(ts[5:7]),
+            day=int(ts[8:10]),
+            hours=int(ts[11:13]),
+            minutes=int(ts[14:16]),
+            seconds=int(ts[17:19])
+        )
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -316,18 +326,25 @@
</span><span class="cx">     @return: L{DateTime} result
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-    # Format is &quot;%Y-%m-%d&quot;, though Oracle may add zero time which we ignore
-    return DateTime(
-        year=int(ts[0:4]),
-        month=int(ts[5:7]),
-        day=int(ts[8:10])
-    )
</del><ins>+    if isinstance(ts, date):
+        return DateTime(
+            year=ts.year,
+            month=ts.month,
+            day=ts.day,
+        )
+    else:
+        # Format is &quot;%Y-%m-%d&quot;, though Oracle may add zero time which we ignore
+        return DateTime(
+            year=int(ts[0:4]),
+            month=int(ts[5:7]),
+            day=int(ts[8:10])
+        )
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> def datetimeMktime(dt):
</span><span class="cx"> 
</span><del>-    assert isinstance(dt, datetime.date)
</del><ins>+    assert isinstance(dt, date)
</ins><span class="cx"> 
</span><span class="cx">     if dt.tzinfo is None:
</span><span class="cx">         dt.replace(tzinfo=dateutil.tz.tzutc())
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavtesttest_dateopspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/test/test_dateops.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/test/test_dateops.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/twistedcaldav/test/test_dateops.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -19,11 +19,10 @@
</span><span class="cx"> from pycalendar.datetime import DateTime
</span><span class="cx"> 
</span><span class="cx"> from twistedcaldav.dateops import parseSQLTimestampToPyCalendar, \
</span><del>-    parseSQLDateToPyCalendar, pyCalendarTodatetime, \
</del><ins>+    parseSQLDateToPyCalendar, pyCalendarToSQLTimestamp, \
</ins><span class="cx">     normalizeForExpand, normalizeForIndex, normalizeToUTC, timeRangesOverlap
</span><span class="cx"> 
</span><del>-import datetime
-import dateutil
</del><ins>+from datetime import datetime, date
</ins><span class="cx"> from pycalendar.timezone import Timezone
</span><span class="cx"> from twistedcaldav.timezones import TimezoneCache
</span><span class="cx"> 
</span><span class="lines">@@ -249,17 +248,17 @@
</span><span class="cx">         raise SkipTest(&quot;test unimplemented&quot;)
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-    def test_pyCalendarTodatetime(self):
</del><ins>+    def test_pyCalendarToSQLTimestamp(self):
</ins><span class="cx">         &quot;&quot;&quot;
</span><del>-        dateops.pyCalendarTodatetime
</del><ins>+        dateops.pyCalendarToSQLTimestamp
</ins><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         tests = (
</span><del>-            (DateTime(2012, 4, 4, 12, 34, 56), datetime.datetime(2012, 4, 4, 12, 34, 56, tzinfo=dateutil.tz.tzutc())),
-            (DateTime(2012, 12, 31), datetime.date(2012, 12, 31)),
</del><ins>+            (DateTime(2012, 4, 4, 12, 34, 56), datetime(2012, 4, 4, 12, 34, 56, tzinfo=None)),
+            (DateTime(2012, 12, 31), date(2012, 12, 31)),
</ins><span class="cx">         )
</span><span class="cx"> 
</span><span class="cx">         for pycal, result in tests:
</span><del>-            self.assertEqual(pyCalendarTodatetime(pycal), result)
</del><ins>+            self.assertEqual(pyCalendarToSQLTimestamp(pycal), result)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_parseSQLTimestampToPyCalendar(self):
</span><span class="lines">@@ -269,6 +268,8 @@
</span><span class="cx">         tests = (
</span><span class="cx">             (&quot;2012-04-04 12:34:56&quot;, DateTime(2012, 4, 4, 12, 34, 56)),
</span><span class="cx">             (&quot;2012-12-31 01:01:01&quot;, DateTime(2012, 12, 31, 1, 1, 1)),
</span><ins>+            (datetime(2012, 4, 4, 12, 34, 56), DateTime(2012, 4, 4, 12, 34, 56)),
+            (datetime(2012, 12, 31, 1, 1, 1), DateTime(2012, 12, 31, 1, 1, 1)),
</ins><span class="cx">         )
</span><span class="cx"> 
</span><span class="cx">         for sqlStr, result in tests:
</span><span class="lines">@@ -283,6 +284,8 @@
</span><span class="cx">         tests = (
</span><span class="cx">             (&quot;2012-04-04&quot;, DateTime(2012, 4, 4)),
</span><span class="cx">             (&quot;2012-12-31 00:00:00&quot;, DateTime(2012, 12, 31)),
</span><ins>+            (date(2012, 4, 4), DateTime(2012, 4, 4)),
+            (date(2012, 12, 31), DateTime(2012, 12, 31)),
</ins><span class="cx">         )
</span><span class="cx"> 
</span><span class="cx">         for sqlStr, result in tests:
</span></span></pre></div>
<a id="CalendarServertrunktxdavbasedatastoresubpostgrespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/base/datastore/subpostgres.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/base/datastore/subpostgres.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/base/datastore/subpostgres.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -26,11 +26,15 @@
</span><span class="cx"> from hashlib import md5
</span><span class="cx"> from pipes import quote as shell_quote
</span><span class="cx"> 
</span><del>-import pgdb as postgres
</del><ins>+if True:
+    import pgdb as postgres
+else:
+    import pg8000 as postgres
</ins><span class="cx"> 
</span><span class="cx"> from twisted.python.procutils import which
</span><span class="cx"> from twisted.internet.protocol import ProcessProtocol
</span><span class="cx"> 
</span><ins>+from twext.enterprise.dal.parseschema import splitSQLString
</ins><span class="cx"> from twext.python.log import Logger
</span><span class="cx"> from twext.python.filepath import CachingFilePath
</span><span class="cx"> 
</span><span class="lines">@@ -38,7 +42,6 @@
</span><span class="cx"> from twisted.internet.defer import Deferred
</span><span class="cx"> from txdav.base.datastore.dbapiclient import DBAPIConnector
</span><span class="cx"> from txdav.base.datastore.dbapiclient import postgresPreflight
</span><del>-from txdav.common.datastore.sql_tables import splitSQLString
</del><span class="cx"> from txdav.common.icommondatastore import InternalDataStoreError
</span><span class="cx"> 
</span><span class="cx"> from twisted.application.service import MultiService
</span><span class="lines">@@ -388,9 +391,30 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Produce a DB-API 2.0 connection pointed at this database.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        return self._connectorFor(databaseName).connect(label)
</del><ins>+        connection = self._connectorFor(databaseName).connect(label)
</ins><span class="cx"> 
</span><ins>+        if postgres.__name__ == &quot;pg8000&quot;:
+            # Patch pg8000 behavior to match what we need wrt text processing
</ins><span class="cx"> 
</span><ins>+            def my_text_out(v):
+                return v.encode(&quot;utf-8&quot;) if isinstance(v, unicode) else str(v)
+            connection.realConnection.py_types[str] = (705, postgres.core.FC_TEXT, my_text_out)
+            connection.realConnection.py_types[postgres.six.text_type] = (705, postgres.core.FC_TEXT, my_text_out)
+
+            def my_text_recv(data, offset, length):
+                return str(data[offset: offset + length])
+            connection.realConnection.default_factory = lambda: (postgres.core.FC_TEXT, my_text_recv)
+            connection.realConnection.pg_types[19] = (postgres.core.FC_BINARY, my_text_recv)
+            connection.realConnection.pg_types[25] = (postgres.core.FC_BINARY, my_text_recv)
+            connection.realConnection.pg_types[705] = (postgres.core.FC_BINARY, my_text_recv)
+            connection.realConnection.pg_types[829] = (postgres.core.FC_TEXT, my_text_recv)
+            connection.realConnection.pg_types[1042] = (postgres.core.FC_BINARY, my_text_recv)
+            connection.realConnection.pg_types[1043] = (postgres.core.FC_BINARY, my_text_recv)
+            connection.realConnection.pg_types[2275] = (postgres.core.FC_BINARY, my_text_recv)
+
+        return connection
+
+
</ins><span class="cx">     def ready(self, createDatabaseConn, createDatabaseCursor):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Subprocess is ready.  Time to initialize the subservice.
</span></span></pre></div>
<a id="CalendarServertrunktxdavcaldavdatastoreindex_filepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/caldav/datastore/index_file.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/caldav/datastore/index_file.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/caldav/datastore/index_file.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -50,7 +50,7 @@
</span><span class="cx"> from txdav.common.icommondatastore import SyncTokenValidException, \
</span><span class="cx">     ReservationError, IndexedSearchException
</span><span class="cx"> 
</span><del>-from twistedcaldav.dateops import pyCalendarTodatetime
</del><ins>+from twistedcaldav.dateops import pyCalendarToSQLTimestamp
</ins><span class="cx"> from twistedcaldav.ical import Component
</span><span class="cx"> from twistedcaldav.sql import AbstractSQLDatabase
</span><span class="cx"> from twistedcaldav.sql import db_prefix
</span><span class="lines">@@ -658,7 +658,7 @@
</span><span class="cx">         Gives all resources which have not been expanded beyond a given date
</span><span class="cx">         in the index
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        return self._db_values_for_sql(&quot;select NAME from RESOURCE where RECURRANCE_MAX &lt; :1&quot;, pyCalendarTodatetime(minDate))
</del><ins>+        return self._db_values_for_sql(&quot;select NAME from RESOURCE where RECURRANCE_MAX &lt; :1&quot;, pyCalendarToSQLTimestamp(minDate))
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def reExpandResource(self, name, expand_until):
</span><span class="lines">@@ -747,7 +747,7 @@
</span><span class="cx">             &quot;&quot;&quot;
</span><span class="cx">             insert into RESOURCE (NAME, UID, TYPE, RECURRANCE_MAX, ORGANIZER)
</span><span class="cx">             values (:1, :2, :3, :4, :5)
</span><del>-            &quot;&quot;&quot;, name, uid, calendar.resourceType(), pyCalendarTodatetime(recurrenceLimit) if recurrenceLimit else None, organizer
</del><ins>+            &quot;&quot;&quot;, name, uid, calendar.resourceType(), pyCalendarToSQLTimestamp(recurrenceLimit) if recurrenceLimit else None, organizer
</ins><span class="cx">         )
</span><span class="cx">         resourceid = self.lastrowid
</span><span class="cx"> 
</span><span class="lines">@@ -785,8 +785,8 @@
</span><span class="cx">                     &quot;&quot;&quot;,
</span><span class="cx">                     resourceid,
</span><span class="cx">                     float,
</span><del>-                    pyCalendarTodatetime(start),
-                    pyCalendarTodatetime(end),
</del><ins>+                    pyCalendarToSQLTimestamp(start),
+                    pyCalendarToSQLTimestamp(end),
</ins><span class="cx">                     icalfbtype_to_indexfbtype.get(instance.component.getFBType(), 'F'),
</span><span class="cx">                     transp
</span><span class="cx">                 )
</span><span class="lines">@@ -811,7 +811,7 @@
</span><span class="cx">                     &quot;&quot;&quot;
</span><span class="cx">                     insert into TIMESPAN (RESOURCEID, FLOAT, START, END, FBTYPE, TRANSPARENT)
</span><span class="cx">                     values (:1, :2, :3, :4, :5, :6)
</span><del>-                    &quot;&quot;&quot;, resourceid, float, pyCalendarTodatetime(start), pyCalendarTodatetime(end), '?', '?'
</del><ins>+                    &quot;&quot;&quot;, resourceid, float, pyCalendarToSQLTimestamp(start), pyCalendarToSQLTimestamp(end), '?', '?'
</ins><span class="cx">                 )
</span><span class="cx">                 instanceid = self.lastrowid
</span><span class="cx">                 peruserdata = calendar.perUserData(None)
</span></span></pre></div>
<a id="CalendarServertrunktxdavcaldavdatastorequerybuilderpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/caldav/datastore/query/builder.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/caldav/datastore/query/builder.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/caldav/datastore/query/builder.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -14,7 +14,7 @@
</span><span class="cx"> # limitations under the License.
</span><span class="cx"> ##
</span><span class="cx"> 
</span><del>-from twistedcaldav.dateops import floatoffset, pyCalendarTodatetime
</del><ins>+from twistedcaldav.dateops import floatoffset, pyCalendarToSQLTimestamp
</ins><span class="cx"> 
</span><span class="cx"> from txdav.caldav.datastore.query.filter import ComponentFilter, PropertyFilter, TextMatch, TimeRange
</span><span class="cx"> from txdav.common.datastore.query import expression
</span><span class="lines">@@ -220,8 +220,8 @@
</span><span class="cx">     endfloat = floatoffset(end, tzinfo) if end else None
</span><span class="cx"> 
</span><span class="cx">     return (
</span><del>-        pyCalendarTodatetime(start) if start else None,
-        pyCalendarTodatetime(end) if end else None,
-        pyCalendarTodatetime(startfloat) if startfloat else None,
-        pyCalendarTodatetime(endfloat) if endfloat else None,
</del><ins>+        pyCalendarToSQLTimestamp(start) if start else None,
+        pyCalendarToSQLTimestamp(end) if end else None,
+        pyCalendarToSQLTimestamp(startfloat) if startfloat else None,
+        pyCalendarToSQLTimestamp(endfloat) if endfloat else None,
</ins><span class="cx">     )
</span></span></pre></div>
<a id="CalendarServertrunktxdavcaldavdatastorequerytesttest_filterpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/caldav/datastore/query/test/test_filter.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/caldav/datastore/query/test/test_filter.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/caldav/datastore/query/test/test_filter.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -29,7 +29,6 @@
</span><span class="cx"> from txdav.caldav.datastore.query.generator import CalDAVSQLQueryGenerator
</span><span class="cx"> from txdav.common.datastore.sql_tables import schema
</span><span class="cx"> 
</span><del>-from dateutil.tz import tzutc
</del><span class="cx"> import datetime
</span><span class="cx"> from twistedcaldav.ical import Component
</span><span class="cx"> 
</span><span class="lines">@@ -97,7 +96,7 @@
</span><span class="cx"> 
</span><span class="cx">         self.assertEqual(select.toSQL(), SQLFragment(
</span><span class="cx">             &quot;select distinct RESOURCE_NAME, ICALENDAR_UID, ICALENDAR_TYPE from CALENDAR_OBJECT, TIME_RANGE where ICALENDAR_TYPE in (?, ?, ?) and (FLOATING = ? and START_DATE &lt; ? and END_DATE &gt; ? or FLOATING = ? and START_DATE &lt; ? and END_DATE &gt; ?) and CALENDAR_OBJECT_RESOURCE_ID = RESOURCE_ID and TIME_RANGE.CALENDAR_RESOURCE_ID = ?&quot;,
</span><del>-            [Parameter('arg1', 3), False, datetime.datetime(2006, 6, 5, 17, 0, tzinfo=tzutc()), datetime.datetime(2006, 6, 5, 16, 0, tzinfo=tzutc()), True, datetime.datetime(2006, 6, 5, 13, 0, tzinfo=tzutc()), datetime.datetime(2006, 6, 5, 12, 0, tzinfo=tzutc()), 1234]
</del><ins>+            [Parameter('arg1', 3), False, datetime.datetime(2006, 6, 5, 17, 0), datetime.datetime(2006, 6, 5, 16, 0), True, datetime.datetime(2006, 6, 5, 13, 0), datetime.datetime(2006, 6, 5, 12, 0), 1234]
</ins><span class="cx">         ))
</span><span class="cx">         self.assertEqual(args, {&quot;arg1&quot;: (&quot;VEVENT&quot;, &quot;VFREEBUSY&quot;, &quot;VAVAILABILITY&quot;)})
</span><span class="cx">         self.assertEqual(usedtimerange, True)
</span><span class="lines">@@ -126,7 +125,7 @@
</span><span class="cx"> 
</span><span class="cx">         self.assertEqual(select.toSQL(), SQLFragment(
</span><span class="cx">             &quot;select distinct RESOURCE_NAME, ICALENDAR_UID, ICALENDAR_TYPE, ORGANIZER, FLOATING, coalesce(ADJUSTED_START_DATE, START_DATE), coalesce(ADJUSTED_END_DATE, END_DATE), FBTYPE, TIME_RANGE.TRANSPARENT, PERUSER.TRANSPARENT from CALENDAR_OBJECT, TIME_RANGE left outer join PERUSER on INSTANCE_ID = TIME_RANGE_INSTANCE_ID and USER_ID = ? where ICALENDAR_TYPE in (?, ?, ?) and (FLOATING = ? and coalesce(ADJUSTED_START_DATE, START_DATE) &lt; ? and coalesce(ADJUSTED_END_DATE, END_DATE) &gt; ? or FLOATING = ? and coalesce(ADJUSTED_START_DATE, START_DATE) &lt; ? and coalesce(ADJUSTED_END_DATE, END_DATE) &gt; ?) and CALENDAR_OBJECT_RESOURCE_ID = RESOURCE_ID and TIME_RANGE.CALENDAR_RESOURCE_ID = ?&quot;,
</span><del>-            ['user01', Parameter('arg1', 3), False, datetime.datetime(2006, 6, 5, 17, 0, tzinfo=tzutc()), datetime.datetime(2006, 6, 5, 16, 0, tzinfo=tzutc()), True, datetime.datetime(2006, 6, 5, 13, 0, tzinfo=tzutc()), datetime.datetime(2006, 6, 5, 12, 0, tzinfo=tzutc()), 1234]
</del><ins>+            ['user01', Parameter('arg1', 3), False, datetime.datetime(2006, 6, 5, 17, 0), datetime.datetime(2006, 6, 5, 16, 0), True, datetime.datetime(2006, 6, 5, 13, 0), datetime.datetime(2006, 6, 5, 12, 0), 1234]
</ins><span class="cx">         ))
</span><span class="cx">         self.assertEqual(args, {&quot;arg1&quot;: (&quot;VEVENT&quot;, &quot;VFREEBUSY&quot;, &quot;VAVAILABILITY&quot;)})
</span><span class="cx">         self.assertEqual(usedtimerange, True)
</span><span class="lines">@@ -193,7 +192,7 @@
</span><span class="cx"> 
</span><span class="cx">         self.assertEqual(select.toSQL(), SQLFragment(
</span><span class="cx">             &quot;select distinct RESOURCE_NAME, ICALENDAR_UID, ICALENDAR_TYPE from CALENDAR_OBJECT, TIME_RANGE where (ICALENDAR_TYPE = ? and (FLOATING = ? and END_DATE &gt; ? or FLOATING = ? and END_DATE &gt; ?) or ICALENDAR_TYPE = ?) and CALENDAR_OBJECT_RESOURCE_ID = RESOURCE_ID and TIME_RANGE.CALENDAR_RESOURCE_ID = ?&quot;,
</span><del>-            ['VEVENT', False, datetime.datetime(2006, 6, 5, 16, 0, tzinfo=tzutc()), True, datetime.datetime(2006, 6, 5, 12, 0, tzinfo=tzutc()), 'VTODO', 1234]
</del><ins>+            ['VEVENT', False, datetime.datetime(2006, 6, 5, 16, 0), True, datetime.datetime(2006, 6, 5, 12, 0), 'VTODO', 1234]
</ins><span class="cx">         ))
</span><span class="cx">         self.assertEqual(args, {})
</span><span class="cx">         self.assertEqual(usedtimerange, True)
</span></span></pre></div>
<a id="CalendarServertrunktxdavcaldavdatastoresqlpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/caldav/datastore/sql.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/caldav/datastore/sql.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/caldav/datastore/sql.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -14,6 +14,7 @@
</span><span class="cx"> # See the License for the specific language governing permissions and
</span><span class="cx"> # limitations under the License.
</span><span class="cx"> ##
</span><ins>+from twext.enterprise.util import parseSQLTimestamp
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> &quot;&quot;&quot;
</span><span class="lines">@@ -47,7 +48,7 @@
</span><span class="cx"> from twistedcaldav.stdconfig import config
</span><span class="cx"> from twistedcaldav.datafilters.peruserdata import PerUserDataFilter
</span><span class="cx"> from twistedcaldav.dateops import normalizeForIndex, \
</span><del>-    pyCalendarTodatetime, parseSQLDateToPyCalendar
</del><ins>+    pyCalendarToSQLTimestamp, parseSQLDateToPyCalendar
</ins><span class="cx"> from twistedcaldav.ical import Component, InvalidICalendarDataError, Property
</span><span class="cx"> from twistedcaldav.instance import InvalidOverriddenInstanceError
</span><span class="cx"> from twistedcaldav.timezones import TimezoneException
</span><span class="lines">@@ -1622,8 +1623,8 @@
</span><span class="cx">         returnValue([row[0] for row in (
</span><span class="cx">             yield self._notExpandedWithinQuery.on(
</span><span class="cx">                 self._txn,
</span><del>-                minDate=pyCalendarTodatetime(normalizeForIndex(minDate)) if minDate is not None else None,
-                maxDate=pyCalendarTodatetime(normalizeForIndex(maxDate)),
</del><ins>+                minDate=pyCalendarToSQLTimestamp(normalizeForIndex(minDate)) if minDate is not None else None,
+                maxDate=pyCalendarToSQLTimestamp(normalizeForIndex(maxDate)),
</ins><span class="cx">                 resourceID=self._resourceID))]
</span><span class="cx">         )
</span><span class="cx"> 
</span><span class="lines">@@ -3674,8 +3675,8 @@
</span><span class="cx"> 
</span><span class="cx">             # Only needed if indexing being changed
</span><span class="cx">             if instanceIndexingRequired:
</span><del>-                values[co.RECURRANCE_MIN] = pyCalendarTodatetime(normalizeForIndex(recurrenceLowerLimit)) if recurrenceLowerLimit else None
-                values[co.RECURRANCE_MAX] = pyCalendarTodatetime(normalizeForIndex(recurrenceLimit)) if recurrenceLimit else None
</del><ins>+                values[co.RECURRANCE_MIN] = pyCalendarToSQLTimestamp(normalizeForIndex(recurrenceLowerLimit)) if recurrenceLowerLimit else None
+                values[co.RECURRANCE_MAX] = pyCalendarToSQLTimestamp(normalizeForIndex(recurrenceLimit)) if recurrenceLimit else None
</ins><span class="cx"> 
</span><span class="cx">             if inserting:
</span><span class="cx">                 self._resourceID, self._created, self._modified = (
</span><span class="lines">@@ -3684,15 +3685,17 @@
</span><span class="cx">                         Return=(co.RESOURCE_ID, co.CREATED, co.MODIFIED)
</span><span class="cx">                     ).on(txn)
</span><span class="cx">                 )[0]
</span><ins>+                self._created = parseSQLTimestamp(self._created)
+                self._modified = parseSQLTimestamp(self._modified)
</ins><span class="cx">             else:
</span><span class="cx">                 values[co.MODIFIED] = utcNowSQL
</span><del>-                self._modified = (
</del><ins>+                self._modified = parseSQLTimestamp((
</ins><span class="cx">                     yield Update(
</span><span class="cx">                         values,
</span><span class="cx">                         Where=co.RESOURCE_ID == self._resourceID,
</span><span class="cx">                         Return=co.MODIFIED,
</span><span class="cx">                     ).on(txn)
</span><del>-                )[0][0]
</del><ins>+                )[0][0])
</ins><span class="cx"> 
</span><span class="cx">                 # Need to wipe the existing time-range for this and rebuild if required
</span><span class="cx">                 if instanceIndexingRequired:
</span><span class="lines">@@ -3703,8 +3706,8 @@
</span><span class="cx">         else:
</span><span class="cx">             # Keep MODIFIED the same when doing an index-only update
</span><span class="cx">             values = {
</span><del>-                co.RECURRANCE_MIN : pyCalendarTodatetime(normalizeForIndex(recurrenceLowerLimit)) if recurrenceLowerLimit else None,
-                co.RECURRANCE_MAX : pyCalendarTodatetime(normalizeForIndex(recurrenceLimit)) if recurrenceLimit else None,
</del><ins>+                co.RECURRANCE_MIN : pyCalendarToSQLTimestamp(normalizeForIndex(recurrenceLowerLimit)) if recurrenceLowerLimit else None,
+                co.RECURRANCE_MAX : pyCalendarToSQLTimestamp(normalizeForIndex(recurrenceLimit)) if recurrenceLimit else None,
</ins><span class="cx">                 co.MODIFIED : self._modified,
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -3788,8 +3791,8 @@
</span><span class="cx">             tr.CALENDAR_RESOURCE_ID        : self._calendar._resourceID,
</span><span class="cx">             tr.CALENDAR_OBJECT_RESOURCE_ID : self._resourceID,
</span><span class="cx">             tr.FLOATING                    : floating,
</span><del>-            tr.START_DATE                  : pyCalendarTodatetime(start),
-            tr.END_DATE                    : pyCalendarTodatetime(end),
</del><ins>+            tr.START_DATE                  : pyCalendarToSQLTimestamp(start),
+            tr.END_DATE                    : pyCalendarToSQLTimestamp(end),
</ins><span class="cx">             tr.FBTYPE                      : icalfbtype_to_indexfbtype.get(fbtype, icalfbtype_to_indexfbtype[&quot;FREE&quot;]),
</span><span class="cx">             tr.TRANSPARENT                 : transp,
</span><span class="cx">         }, Return=tr.INSTANCE_ID).on(txn))[0][0]
</span><span class="lines">@@ -3801,9 +3804,9 @@
</span><span class="cx"> 
</span><span class="cx">                 def _adjustDateTime(dt, adjustment, add_duration):
</span><span class="cx">                     if isinstance(adjustment, Duration):
</span><del>-                        return pyCalendarTodatetime((dt + adjustment) if add_duration else (dt - adjustment))
</del><ins>+                        return pyCalendarToSQLTimestamp((dt + adjustment) if add_duration else (dt - adjustment))
</ins><span class="cx">                     elif isinstance(adjustment, DateTime):
</span><del>-                        return pyCalendarTodatetime(normalizeForIndex(adjustment))
</del><ins>+                        return pyCalendarToSQLTimestamp(normalizeForIndex(adjustment))
</ins><span class="cx">                     else:
</span><span class="cx">                         return None
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktxdavcaldavdatastoresql_attachmentpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/caldav/datastore/sql_attachment.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/caldav/datastore/sql_attachment.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/caldav/datastore/sql_attachment.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -160,11 +160,6 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-def sqltime(value):
-    return datetimeMktime(parseSQLTimestamp(value))
-
-
-
</del><span class="cx"> class AttachmentLink(object):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     A binding between an L{Attachment} and an L{CalendarObject}.
</span><span class="lines">@@ -306,6 +301,8 @@
</span><span class="cx"> 
</span><span class="cx">         for attr, value in zip(child._rowAttributes(), attachmentData):
</span><span class="cx">             setattr(child, attr, value)
</span><ins>+        child._created = parseSQLTimestamp(child._created)
+        child._modified = parseSQLTimestamp(child._modified)
</ins><span class="cx">         child._contentType = MimeType.fromString(child._contentType)
</span><span class="cx"> 
</span><span class="cx">         return child
</span><span class="lines">@@ -404,6 +401,8 @@
</span><span class="cx">         the attributes may not match exactly and will need to be processed accordingly.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         result = dict([(attr[1:], getattr(self, attr, None)) for attr in self._rowAttributes()])
</span><ins>+        result[&quot;created&quot;] = result[&quot;created&quot;].isoformat(&quot; &quot;)
+        result[&quot;modified&quot;] = result[&quot;modified&quot;].isoformat(&quot; &quot;)
</ins><span class="cx">         result[&quot;contentType&quot;] = generateContentType(result[&quot;contentType&quot;])
</span><span class="cx">         return result
</span><span class="cx"> 
</span><span class="lines">@@ -469,9 +468,9 @@
</span><span class="cx"> 
</span><span class="cx">         for attr, value in zip(self._rowAttributes(), rows[0]):
</span><span class="cx">             setattr(self, attr, value)
</span><ins>+        self._created = parseSQLTimestamp(self._created)
+        self._modified = parseSQLTimestamp(self._modified)
</ins><span class="cx">         self._contentType = MimeType.fromString(self._contentType)
</span><del>-        self._created = sqltime(self._created)
-        self._modified = sqltime(self._modified)
</del><span class="cx"> 
</span><span class="cx">         returnValue(self)
</span><span class="cx"> 
</span><span class="lines">@@ -636,11 +635,11 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def created(self):
</span><del>-        return self._created
</del><ins>+        return datetimeMktime(self._created)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def modified(self):
</span><del>-        return self._modified
</del><ins>+        return datetimeMktime(self._modified)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -680,8 +679,8 @@
</span><span class="cx"> 
</span><span class="cx">         row_iter = iter(rows[0])
</span><span class="cx">         a_id = row_iter.next()
</span><del>-        created = sqltime(row_iter.next())
-        modified = sqltime(row_iter.next())
</del><ins>+        created = parseSQLTimestamp(row_iter.next())
+        modified = parseSQLTimestamp(row_iter.next())
</ins><span class="cx"> 
</span><span class="cx">         attachment = cls(txn, a_id, dropboxID, name, ownerHomeID, True)
</span><span class="cx">         attachment._created = created
</span><span class="lines">@@ -754,7 +753,7 @@
</span><span class="cx"> 
</span><span class="cx">         att = self._attachmentSchema
</span><span class="cx">         self._created, self._modified = map(
</span><del>-            sqltime,
</del><ins>+            parseSQLTimestamp,
</ins><span class="cx">             (yield Update(
</span><span class="cx">                 {
</span><span class="cx">                     att.CONTENT_TYPE    : generateContentType(self._contentType),
</span><span class="lines">@@ -845,8 +844,8 @@
</span><span class="cx"> 
</span><span class="cx">         row_iter = iter(rows[0])
</span><span class="cx">         a_id = row_iter.next()
</span><del>-        created = sqltime(row_iter.next())
-        modified = sqltime(row_iter.next())
</del><ins>+        created = parseSQLTimestamp(row_iter.next())
+        modified = parseSQLTimestamp(row_iter.next())
</ins><span class="cx"> 
</span><span class="cx">         attachment = cls(txn, a_id, &quot;.&quot;, None, ownerHomeID, True)
</span><span class="cx">         attachment._managedID = managedID
</span><span class="lines">@@ -1119,7 +1118,7 @@
</span><span class="cx">         self._size = size
</span><span class="cx">         att = self._attachmentSchema
</span><span class="cx">         self._created, self._modified = map(
</span><del>-            sqltime,
</del><ins>+            parseSQLTimestamp,
</ins><span class="cx">             (yield Update(
</span><span class="cx">                 {
</span><span class="cx">                     att.CONTENT_TYPE    : generateContentType(self._contentType),
</span></span></pre></div>
<a id="CalendarServertrunktxdavcaldavdatastoretesttest_index_filepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/caldav/datastore/test/test_index_file.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/caldav/datastore/test/test_index_file.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/test_index_file.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -512,7 +512,7 @@
</span><span class="cx"> &quot;&quot;&quot;,
</span><span class="cx">                 &quot;20080601T000000Z&quot;, &quot;20080602T000000Z&quot;,
</span><span class="cx">                 &quot;mailto:user1@example.com&quot;,
</span><del>-                (('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'F'),),
</del><ins>+                (('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'F'),),
</ins><span class="cx">             ),
</span><span class="cx">             (
</span><span class="cx">                 &quot;#1.2 Simple component - transparent&quot;,
</span><span class="lines">@@ -534,7 +534,7 @@
</span><span class="cx"> &quot;&quot;&quot;,
</span><span class="cx">                 &quot;20080602T000000Z&quot;, &quot;20080603T000000Z&quot;,
</span><span class="cx">                 &quot;mailto:user1@example.com&quot;,
</span><del>-                (('N', &quot;2008-06-02 12:00:00+00:00&quot;, &quot;2008-06-02 13:00:00+00:00&quot;, 'B', 'T'),),
</del><ins>+                (('N', &quot;2008-06-02 12:00:00&quot;, &quot;2008-06-02 13:00:00&quot;, 'B', 'T'),),
</ins><span class="cx">             ),
</span><span class="cx">             (
</span><span class="cx">                 &quot;#1.3 Simple component - canceled&quot;,
</span><span class="lines">@@ -556,7 +556,7 @@
</span><span class="cx"> &quot;&quot;&quot;,
</span><span class="cx">                 &quot;20080603T000000Z&quot;, &quot;20080604T000000Z&quot;,
</span><span class="cx">                 &quot;mailto:user1@example.com&quot;,
</span><del>-                (('N', &quot;2008-06-03 12:00:00+00:00&quot;, &quot;2008-06-03 13:00:00+00:00&quot;, 'F', 'F'),),
</del><ins>+                (('N', &quot;2008-06-03 12:00:00&quot;, &quot;2008-06-03 13:00:00&quot;, 'F', 'F'),),
</ins><span class="cx">             ),
</span><span class="cx">             (
</span><span class="cx">                 &quot;#1.4 Simple component - tentative&quot;,
</span><span class="lines">@@ -578,7 +578,7 @@
</span><span class="cx"> &quot;&quot;&quot;,
</span><span class="cx">                 &quot;20080604T000000Z&quot;, &quot;20080605T000000Z&quot;,
</span><span class="cx">                 &quot;mailto:user1@example.com&quot;,
</span><del>-                (('N', &quot;2008-06-04 12:00:00+00:00&quot;, &quot;2008-06-04 13:00:00+00:00&quot;, 'T', 'F'),),
</del><ins>+                (('N', &quot;2008-06-04 12:00:00&quot;, &quot;2008-06-04 13:00:00&quot;, 'T', 'F'),),
</ins><span class="cx">             ),
</span><span class="cx">             (
</span><span class="cx">                 &quot;#2.1 Recurring component - busy&quot;,
</span><span class="lines">@@ -601,8 +601,8 @@
</span><span class="cx">                 &quot;20080605T000000Z&quot;, &quot;20080607T000000Z&quot;,
</span><span class="cx">                 &quot;mailto:user1@example.com&quot;,
</span><span class="cx">                 (
</span><del>-                    ('N', &quot;2008-06-05 12:00:00+00:00&quot;, &quot;2008-06-05 13:00:00+00:00&quot;, 'B', 'F'),
-                    ('N', &quot;2008-06-06 12:00:00+00:00&quot;, &quot;2008-06-06 13:00:00+00:00&quot;, 'B', 'F'),
</del><ins>+                    ('N', &quot;2008-06-05 12:00:00&quot;, &quot;2008-06-05 13:00:00&quot;, 'B', 'F'),
+                    ('N', &quot;2008-06-06 12:00:00&quot;, &quot;2008-06-06 13:00:00&quot;, 'B', 'F'),
</ins><span class="cx">                 ),
</span><span class="cx">             ),
</span><span class="cx">             (
</span><span class="lines">@@ -637,8 +637,8 @@
</span><span class="cx">                 &quot;20080607T000000Z&quot;, &quot;20080609T000000Z&quot;,
</span><span class="cx">                 &quot;mailto:user1@example.com&quot;,
</span><span class="cx">                 (
</span><del>-                    ('N', &quot;2008-06-07 12:00:00+00:00&quot;, &quot;2008-06-07 13:00:00+00:00&quot;, 'B', 'F'),
-                    ('N', &quot;2008-06-08 14:00:00+00:00&quot;, &quot;2008-06-08 15:00:00+00:00&quot;, 'B', 'T'),
</del><ins>+                    ('N', &quot;2008-06-07 12:00:00&quot;, &quot;2008-06-07 13:00:00&quot;, 'B', 'F'),
+                    ('N', &quot;2008-06-08 14:00:00&quot;, &quot;2008-06-08 15:00:00&quot;, 'B', 'T'),
</ins><span class="cx">                 ),
</span><span class="cx">             ),
</span><span class="cx">         )
</span><span class="lines">@@ -714,11 +714,11 @@
</span><span class="cx">                 (
</span><span class="cx">                     (
</span><span class="cx">                         &quot;user01&quot;,
</span><del>-                        (('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'T'),),
</del><ins>+                        (('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'T'),),
</ins><span class="cx">                     ),
</span><span class="cx">                     (
</span><span class="cx">                         &quot;user02&quot;,
</span><del>-                        (('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'F'),),
</del><ins>+                        (('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'F'),),
</ins><span class="cx">                     ),
</span><span class="cx">                 ),
</span><span class="cx">             ),
</span><span class="lines">@@ -767,15 +767,15 @@
</span><span class="cx">                 (
</span><span class="cx">                     (
</span><span class="cx">                         &quot;user01&quot;,
</span><del>-                        (('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'T'),),
</del><ins>+                        (('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'T'),),
</ins><span class="cx">                     ),
</span><span class="cx">                     (
</span><span class="cx">                         &quot;user02&quot;,
</span><del>-                        (('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'F'),),
</del><ins>+                        (('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'F'),),
</ins><span class="cx">                     ),
</span><span class="cx">                     (
</span><span class="cx">                         &quot;user03&quot;,
</span><del>-                        (('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'F'),),
</del><ins>+                        (('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'F'),),
</ins><span class="cx">                     ),
</span><span class="cx">                 ),
</span><span class="cx">             ),
</span><span class="lines">@@ -815,15 +815,15 @@
</span><span class="cx">                     (
</span><span class="cx">                         &quot;user01&quot;,
</span><span class="cx">                         (
</span><del>-                            ('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'T'),
-                            ('N', &quot;2008-06-02 12:00:00+00:00&quot;, &quot;2008-06-02 13:00:00+00:00&quot;, 'B', 'T'),
</del><ins>+                            ('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'T'),
+                            ('N', &quot;2008-06-02 12:00:00&quot;, &quot;2008-06-02 13:00:00&quot;, 'B', 'T'),
</ins><span class="cx">                         ),
</span><span class="cx">                     ),
</span><span class="cx">                     (
</span><span class="cx">                         &quot;user02&quot;,
</span><span class="cx">                         (
</span><del>-                            ('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'F'),
-                            ('N', &quot;2008-06-02 12:00:00+00:00&quot;, &quot;2008-06-02 13:00:00+00:00&quot;, 'B', 'F'),
</del><ins>+                            ('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'F'),
+                            ('N', &quot;2008-06-02 12:00:00&quot;, &quot;2008-06-02 13:00:00&quot;, 'B', 'F'),
</ins><span class="cx">                         ),
</span><span class="cx">                     ),
</span><span class="cx">                 ),
</span><span class="lines">@@ -875,22 +875,22 @@
</span><span class="cx">                     (
</span><span class="cx">                         &quot;user01&quot;,
</span><span class="cx">                         (
</span><del>-                            ('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'T'),
-                            ('N', &quot;2008-06-02 12:00:00+00:00&quot;, &quot;2008-06-02 13:00:00+00:00&quot;, 'B', 'T'),
</del><ins>+                            ('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'T'),
+                            ('N', &quot;2008-06-02 12:00:00&quot;, &quot;2008-06-02 13:00:00&quot;, 'B', 'T'),
</ins><span class="cx">                         ),
</span><span class="cx">                     ),
</span><span class="cx">                     (
</span><span class="cx">                         &quot;user02&quot;,
</span><span class="cx">                         (
</span><del>-                            ('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'F'),
-                            ('N', &quot;2008-06-02 12:00:00+00:00&quot;, &quot;2008-06-02 13:00:00+00:00&quot;, 'B', 'F'),
</del><ins>+                            ('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'F'),
+                            ('N', &quot;2008-06-02 12:00:00&quot;, &quot;2008-06-02 13:00:00&quot;, 'B', 'F'),
</ins><span class="cx">                         ),
</span><span class="cx">                     ),
</span><span class="cx">                     (
</span><span class="cx">                         &quot;user03&quot;,
</span><span class="cx">                         (
</span><del>-                            ('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'F'),
-                            ('N', &quot;2008-06-02 12:00:00+00:00&quot;, &quot;2008-06-02 13:00:00+00:00&quot;, 'B', 'F'),
</del><ins>+                            ('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'F'),
+                            ('N', &quot;2008-06-02 12:00:00&quot;, &quot;2008-06-02 13:00:00&quot;, 'B', 'F'),
</ins><span class="cx">                         ),
</span><span class="cx">                     ),
</span><span class="cx">                 ),
</span><span class="lines">@@ -945,17 +945,17 @@
</span><span class="cx">                     (
</span><span class="cx">                         &quot;user01&quot;,
</span><span class="cx">                         (
</span><del>-                            ('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'T'),
-                            ('N', &quot;2008-06-02 13:00:00+00:00&quot;, &quot;2008-06-02 14:00:00+00:00&quot;, 'B', 'F'),
-                            ('N', &quot;2008-06-03 12:00:00+00:00&quot;, &quot;2008-06-03 13:00:00+00:00&quot;, 'B', 'T'),
</del><ins>+                            ('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'T'),
+                            ('N', &quot;2008-06-02 13:00:00&quot;, &quot;2008-06-02 14:00:00&quot;, 'B', 'F'),
+                            ('N', &quot;2008-06-03 12:00:00&quot;, &quot;2008-06-03 13:00:00&quot;, 'B', 'T'),
</ins><span class="cx">                         ),
</span><span class="cx">                     ),
</span><span class="cx">                     (
</span><span class="cx">                         &quot;user02&quot;,
</span><span class="cx">                         (
</span><del>-                            ('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'F'),
-                            ('N', &quot;2008-06-02 13:00:00+00:00&quot;, &quot;2008-06-02 14:00:00+00:00&quot;, 'B', 'F'),
-                            ('N', &quot;2008-06-03 12:00:00+00:00&quot;, &quot;2008-06-03 13:00:00+00:00&quot;, 'B', 'F'),
</del><ins>+                            ('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'F'),
+                            ('N', &quot;2008-06-02 13:00:00&quot;, &quot;2008-06-02 14:00:00&quot;, 'B', 'F'),
+                            ('N', &quot;2008-06-03 12:00:00&quot;, &quot;2008-06-03 13:00:00&quot;, 'B', 'F'),
</ins><span class="cx">                         ),
</span><span class="cx">                     ),
</span><span class="cx">                 ),
</span><span class="lines">@@ -1025,25 +1025,25 @@
</span><span class="cx">                     (
</span><span class="cx">                         &quot;user01&quot;,
</span><span class="cx">                         (
</span><del>-                            ('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'T'),
-                            ('N', &quot;2008-06-02 13:00:00+00:00&quot;, &quot;2008-06-02 14:00:00+00:00&quot;, 'B', 'F'),
-                            ('N', &quot;2008-06-03 12:00:00+00:00&quot;, &quot;2008-06-03 13:00:00+00:00&quot;, 'B', 'T'),
</del><ins>+                            ('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'T'),
+                            ('N', &quot;2008-06-02 13:00:00&quot;, &quot;2008-06-02 14:00:00&quot;, 'B', 'F'),
+                            ('N', &quot;2008-06-03 12:00:00&quot;, &quot;2008-06-03 13:00:00&quot;, 'B', 'T'),
</ins><span class="cx">                         ),
</span><span class="cx">                     ),
</span><span class="cx">                     (
</span><span class="cx">                         &quot;user02&quot;,
</span><span class="cx">                         (
</span><del>-                            ('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'F'),
-                            ('N', &quot;2008-06-02 13:00:00+00:00&quot;, &quot;2008-06-02 14:00:00+00:00&quot;, 'B', 'F'),
-                            ('N', &quot;2008-06-03 12:00:00+00:00&quot;, &quot;2008-06-03 13:00:00+00:00&quot;, 'B', 'T'),
</del><ins>+                            ('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'F'),
+                            ('N', &quot;2008-06-02 13:00:00&quot;, &quot;2008-06-02 14:00:00&quot;, 'B', 'F'),
+                            ('N', &quot;2008-06-03 12:00:00&quot;, &quot;2008-06-03 13:00:00&quot;, 'B', 'T'),
</ins><span class="cx">                         ),
</span><span class="cx">                     ),
</span><span class="cx">                     (
</span><span class="cx">                         &quot;user03&quot;,
</span><span class="cx">                         (
</span><del>-                            ('N', &quot;2008-06-01 12:00:00+00:00&quot;, &quot;2008-06-01 13:00:00+00:00&quot;, 'B', 'F'),
-                            ('N', &quot;2008-06-02 13:00:00+00:00&quot;, &quot;2008-06-02 14:00:00+00:00&quot;, 'B', 'F'),
-                            ('N', &quot;2008-06-03 12:00:00+00:00&quot;, &quot;2008-06-03 13:00:00+00:00&quot;, 'B', 'F'),
</del><ins>+                            ('N', &quot;2008-06-01 12:00:00&quot;, &quot;2008-06-01 13:00:00&quot;, 'B', 'F'),
+                            ('N', &quot;2008-06-02 13:00:00&quot;, &quot;2008-06-02 14:00:00&quot;, 'B', 'F'),
+                            ('N', &quot;2008-06-03 12:00:00&quot;, &quot;2008-06-03 13:00:00&quot;, 'B', 'F'),
</ins><span class="cx">                         ),
</span><span class="cx">                     ),
</span><span class="cx">                 ),
</span></span></pre></div>
<a id="CalendarServertrunktxdavcaldavdatastoretesttest_sqlpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -73,6 +73,7 @@
</span><span class="cx">     Update
</span><span class="cx"> from twext.enterprise.ienterprise import AlreadyFinishedError
</span><span class="cx"> from twext.enterprise.jobqueue import JobItem
</span><ins>+from twext.enterprise.util import parseSQLTimestamp
</ins><span class="cx"> 
</span><span class="cx"> import datetime
</span><span class="cx"> import os
</span><span class="lines">@@ -741,14 +742,14 @@
</span><span class="cx">         txn = calendarStore.newTransaction()
</span><span class="cx">         home = yield txn.homeWithUID(ECALENDARTYPE, &quot;uid1&quot;, create=True)
</span><span class="cx">         cal = yield home.calendarWithName(&quot;calendar&quot;)
</span><del>-        cal._created = &quot;2011-02-05 11:22:47&quot;
-        cal._modified = &quot;2011-02-06 11:22:47&quot;
</del><ins>+        cal._created = parseSQLTimestamp(&quot;2011-02-05 11:22:47&quot;)
+        cal._modified = parseSQLTimestamp(&quot;2011-02-06 11:22:47&quot;)
</ins><span class="cx">         self.assertEqual(cal.created(), datetimeMktime(datetime.datetime(2011, 2, 5, 11, 22, 47)))
</span><span class="cx">         self.assertEqual(cal.modified(), datetimeMktime(datetime.datetime(2011, 2, 6, 11, 22, 47)))
</span><span class="cx"> 
</span><span class="cx">         obj = yield self.calendarObjectUnderTest()
</span><del>-        obj._created = &quot;2011-02-07 11:22:47&quot;
-        obj._modified = &quot;2011-02-08 11:22:47&quot;
</del><ins>+        obj._created = parseSQLTimestamp(&quot;2011-02-07 11:22:47&quot;)
+        obj._modified = parseSQLTimestamp(&quot;2011-02-08 11:22:47&quot;)
</ins><span class="cx">         self.assertEqual(obj.created(), datetimeMktime(datetime.datetime(2011, 2, 7, 11, 22, 47)))
</span><span class="cx">         self.assertEqual(obj.modified(), datetimeMktime(datetime.datetime(2011, 2, 8, 11, 22, 47)))
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktxdavcarddavdatastoresqlpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/carddav/datastore/sql.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/carddav/datastore/sql.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/carddav/datastore/sql.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -14,6 +14,7 @@
</span><span class="cx"> # See the License for the specific language governing permissions and
</span><span class="cx"> # limitations under the License.
</span><span class="cx"> # #
</span><ins>+from twext.enterprise.util import parseSQLTimestamp
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> &quot;&quot;&quot;
</span><span class="lines">@@ -1909,6 +1910,8 @@
</span><span class="cx"> 
</span><span class="cx">         for attr, value in zip(child._rowAttributes(), objectData):
</span><span class="cx">             setattr(child, attr, value)
</span><ins>+        child._created = parseSQLTimestamp(child._created)
+        child._modified = parseSQLTimestamp(child._modified)
</ins><span class="cx"> 
</span><span class="cx">         yield child._loadPropertyStore(propstore)
</span><span class="cx"> 
</span><span class="lines">@@ -2327,7 +2330,7 @@
</span><span class="cx">         if addressbook.owned() or addressbook.fullyShared():
</span><span class="cx">             rows = yield super(AddressBookObject, cls)._allColumnsWithParentAndNames(addressbook, names)
</span><span class="cx">             if addressbook.fullyShared() and addressbook._groupForSharedAddressBookName() in names:
</span><del>-                rows.append(addressbook._groupForSharedAddressBookRow())
</del><ins>+                rows += (addressbook._groupForSharedAddressBookRow(),)
</ins><span class="cx">         else:
</span><span class="cx">             acceptedGroupIDs = yield addressbook.acceptedGroupIDs()
</span><span class="cx">             allowedObjectIDs = yield addressbook.expandGroupIDs(addressbook._txn, acceptedGroupIDs)
</span><span class="lines">@@ -2622,6 +2625,8 @@
</span><span class="cx">                     dataVersion=self._currentDataVersion,
</span><span class="cx">                 )
</span><span class="cx">             )[0]
</span><ins>+            self._created = parseSQLTimestamp(self._created)
+            self._modified = parseSQLTimestamp(self._modified)
</ins><span class="cx"> 
</span><span class="cx">             # delete foreign members table rows for this object
</span><span class="cx">             groupIDRows = yield Delete(
</span><span class="lines">@@ -2653,7 +2658,7 @@
</span><span class="cx">                 )
</span><span class="cx"> 
</span><span class="cx">         else:
</span><del>-            self._modified = (yield Update(
</del><ins>+            self._modified = parseSQLTimestamp((yield Update(
</ins><span class="cx">                 {
</span><span class="cx">                     abo.VCARD_TEXT: self._objectText,
</span><span class="cx">                     abo.MD5: self._md5,
</span><span class="lines">@@ -2661,7 +2666,7 @@
</span><span class="cx">                     abo.MODIFIED: utcNowSQL,
</span><span class="cx">                 },
</span><span class="cx">                 Where=abo.RESOURCE_ID == self._resourceID,
</span><del>-                Return=abo.MODIFIED).on(self._txn))[0][0]
</del><ins>+                Return=abo.MODIFIED).on(self._txn))[0][0])
</ins><span class="cx"> 
</span><span class="cx">         if self._kind == _ABO_KIND_GROUP:
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktxdavcarddavdatastoretesttest_sqlpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/carddav/datastore/test/test_sql.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/carddav/datastore/test/test_sql.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/carddav/datastore/test/test_sql.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -576,7 +576,7 @@
</span><span class="cx"> 
</span><span class="cx">         aboMembers = schema.ABO_MEMBERS
</span><span class="cx">         memberRows = yield Select([aboMembers.GROUP_ID, aboMembers.MEMBER_ID], From=aboMembers, Where=aboMembers.REMOVED == False).on(txn)
</span><del>-        self.assertEqual(memberRows, [])
</del><ins>+        self.assertEqual(list(memberRows), [])
</ins><span class="cx"> 
</span><span class="cx">         aboForeignMembers = schema.ABO_FOREIGN_MEMBERS
</span><span class="cx">         foreignMemberRows = yield Select([aboForeignMembers.GROUP_ID, aboForeignMembers.MEMBER_ADDRESS], From=aboForeignMembers).on(txn)
</span><span class="lines">@@ -607,7 +607,7 @@
</span><span class="cx">         )
</span><span class="cx"> 
</span><span class="cx">         foreignMemberRows = yield Select([aboForeignMembers.GROUP_ID, aboForeignMembers.MEMBER_ADDRESS], From=aboForeignMembers).on(txn)
</span><del>-        self.assertEqual(foreignMemberRows, [])
</del><ins>+        self.assertEqual(list(foreignMemberRows), [])
</ins><span class="cx"> 
</span><span class="cx">         yield subgroupObject.remove()
</span><span class="cx">         memberRows = yield Select([aboMembers.GROUP_ID, aboMembers.MEMBER_ID, aboMembers.REMOVED, aboMembers.REVISION], From=aboMembers).on(txn)
</span></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoresqlpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/sql.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/sql.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> 
</span><span class="cx"> from pycalendar.datetime import DateTime
</span><span class="cx"> 
</span><ins>+from twext.enterprise.dal.parseschema import splitSQLString
</ins><span class="cx"> from twext.enterprise.dal.syntax import (
</span><span class="cx">     Delete, utcNowSQL, Union, Insert, Len, Max, Parameter, SavepointAction,
</span><span class="cx">     Select, Update, Count, ALL_COLUMNS, Sum,
</span><span class="lines">@@ -48,7 +49,7 @@
</span><span class="cx"> from twisted.python.util import FancyEqMixin
</span><span class="cx"> 
</span><span class="cx"> from twistedcaldav.config import config
</span><del>-from twistedcaldav.dateops import datetimeMktime, pyCalendarTodatetime
</del><ins>+from twistedcaldav.dateops import datetimeMktime, pyCalendarToSQLTimestamp
</ins><span class="cx"> 
</span><span class="cx"> from txdav.base.datastore.util import QueryCacher
</span><span class="cx"> from txdav.base.propertystore.none import PropertyStore as NonePropertyStore
</span><span class="lines">@@ -64,7 +65,7 @@
</span><span class="cx"> from txdav.common.datastore.sql_notification import NotificationCollection
</span><span class="cx"> from txdav.common.datastore.sql_tables import _BIND_MODE_OWN, _BIND_STATUS_ACCEPTED, \
</span><span class="cx">     _HOME_STATUS_EXTERNAL, _HOME_STATUS_NORMAL, \
</span><del>-    _HOME_STATUS_PURGING, schema, splitSQLString, _HOME_STATUS_MIGRATING, \
</del><ins>+    _HOME_STATUS_PURGING, schema, _HOME_STATUS_MIGRATING, \
</ins><span class="cx">     _HOME_STATUS_DISABLED
</span><span class="cx"> from txdav.common.datastore.sql_util import _SharedSyncLogic
</span><span class="cx"> from txdav.common.datastore.sql_sharing import SharingHomeMixIn, SharingMixIn
</span><span class="lines">@@ -1058,7 +1059,7 @@
</span><span class="cx">             if cutoff &lt; truncateLowerLimit:
</span><span class="cx">                 raise ValueError(&quot;Cannot query events older than %s&quot; % (truncateLowerLimit.getText(),))
</span><span class="cx"> 
</span><del>-        kwds = {&quot;CutOff&quot;: pyCalendarTodatetime(cutoff)}
</del><ins>+        kwds = {&quot;CutOff&quot;: pyCalendarToSQLTimestamp(cutoff)}
</ins><span class="cx">         return self._oldEventsBase(batchSize).on(self, **kwds)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -1171,7 +1172,7 @@
</span><span class="cx"> 
</span><span class="cx">         Returns a deferred to a list of (calendar_home_owner_uid, quota used, total old size, total old count) tuples.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        kwds = {&quot;CutOff&quot;: pyCalendarTodatetime(cutoff)}
</del><ins>+        kwds = {&quot;CutOff&quot;: pyCalendarToSQLTimestamp(cutoff)}
</ins><span class="cx">         if uuid:
</span><span class="cx">             kwds[&quot;uuid&quot;] = uuid
</span><span class="cx"> 
</span><span class="lines">@@ -1213,7 +1214,7 @@
</span><span class="cx">         # TODO: see if there is a better way to import Attachment
</span><span class="cx">         from txdav.caldav.datastore.sql import DropBoxAttachment
</span><span class="cx"> 
</span><del>-        kwds = {&quot;CutOff&quot;: pyCalendarTodatetime(cutoff)}
</del><ins>+        kwds = {&quot;CutOff&quot;: pyCalendarToSQLTimestamp(cutoff)}
</ins><span class="cx">         if uuid:
</span><span class="cx">             kwds[&quot;uuid&quot;] = uuid
</span><span class="cx"> 
</span><span class="lines">@@ -1258,7 +1259,7 @@
</span><span class="cx"> 
</span><span class="cx">         Returns a deferred to a list of (calendar_home_owner_uid, quota used, total old size, total old count) tuples.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        kwds = {&quot;CutOff&quot;: pyCalendarTodatetime(cutoff)}
</del><ins>+        kwds = {&quot;CutOff&quot;: pyCalendarToSQLTimestamp(cutoff)}
</ins><span class="cx">         if uuid:
</span><span class="cx">             kwds[&quot;uuid&quot;] = uuid
</span><span class="cx"> 
</span><span class="lines">@@ -1301,7 +1302,7 @@
</span><span class="cx">         # TODO: see if there is a better way to import Attachment
</span><span class="cx">         from txdav.caldav.datastore.sql import ManagedAttachment
</span><span class="cx"> 
</span><del>-        kwds = {&quot;CutOff&quot;: pyCalendarTodatetime(cutoff)}
</del><ins>+        kwds = {&quot;CutOff&quot;: pyCalendarToSQLTimestamp(cutoff)}
</ins><span class="cx">         if uuid:
</span><span class="cx">             kwds[&quot;uuid&quot;] = uuid
</span><span class="cx"> 
</span><span class="lines">@@ -1758,6 +1759,8 @@
</span><span class="cx"> 
</span><span class="cx">         for attr, value in zip(self.metadataAttributes(), data):
</span><span class="cx">             setattr(self, attr, value)
</span><ins>+        self._created = parseSQLTimestamp(self._created)
+        self._modified = parseSQLTimestamp(self._modified)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def serialize(self):
</span><span class="lines">@@ -1766,7 +1769,10 @@
</span><span class="cx">         and reconstituted at the other end. Note that the other end may have a different schema so
</span><span class="cx">         the attributes may not match exactly and will need to be processed accordingly.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        return dict([(attr[1:], getattr(self, attr, None)) for attr in self.metadataAttributes()])
</del><ins>+        data = dict([(attr[1:], getattr(self, attr, None)) for attr in self.metadataAttributes()])
+        data[&quot;created&quot;] = data[&quot;created&quot;].isoformat(&quot; &quot;)
+        data[&quot;modified&quot;] = data[&quot;modified&quot;].isoformat(&quot; &quot;)
+        return data
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def deserialize(self, mapping):
</span><span class="lines">@@ -1776,6 +1782,8 @@
</span><span class="cx"> 
</span><span class="cx">         for attr in self.metadataAttributes():
</span><span class="cx">             setattr(self, attr, mapping.get(attr[1:]))
</span><ins>+        self._created = parseSQLTimestamp(self._created)
+        self._modified = parseSQLTimestamp(self._modified)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     @classmethod
</span><span class="lines">@@ -2568,11 +2576,11 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def created(self):
</span><del>-        return datetimeMktime(parseSQLTimestamp(self._created)) if self._created else None
</del><ins>+        return datetimeMktime(self._created) if self._created else None
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def modified(self):
</span><del>-        return datetimeMktime(parseSQLTimestamp(self._modified)) if self._modified else None
</del><ins>+        return datetimeMktime(self._modified) if self._modified else None
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     @classmethod
</span><span class="lines">@@ -2810,9 +2818,9 @@
</span><span class="cx">             returnValue(result)
</span><span class="cx"> 
</span><span class="cx">         try:
</span><del>-            self._modified = (
</del><ins>+            self._modified = parseSQLTimestamp((
</ins><span class="cx">                 yield self._txn.subtransaction(_bumpModified, retries=0, failureOK=True)
</span><del>-            )[0][0]
</del><ins>+            )[0][0])
</ins><span class="cx">             yield self.invalidateQueryCache()
</span><span class="cx"> 
</span><span class="cx">         except AllRetriesFailed:
</span><span class="lines">@@ -2932,6 +2940,8 @@
</span><span class="cx">         if metadataData:
</span><span class="cx">             for attr, value in zip(child.metadataAttributes(), metadataData):
</span><span class="cx">                 setattr(child, attr, value)
</span><ins>+            child._created = parseSQLTimestamp(child._created)
+            child._modified = parseSQLTimestamp(child._modified)
</ins><span class="cx"> 
</span><span class="cx">         # We have to re-adjust the property store object to account for possible shared
</span><span class="cx">         # collections as previously we loaded them all as if they were owned
</span><span class="lines">@@ -3199,7 +3209,8 @@
</span><span class="cx">         resourceID = (yield cls._insertHomeChild.on(home._txn))[0][0]
</span><span class="cx"> 
</span><span class="cx">         # Initialize this object
</span><del>-        _created, _modified = (yield cls._insertHomeChildMetaData.on(home._txn, resourceID=resourceID))[0]
</del><ins>+        yield cls._insertHomeChildMetaData.on(home._txn, resourceID=resourceID)
+
</ins><span class="cx">         # Bind table needs entry
</span><span class="cx">         yield cls._bindInsertQuery.on(
</span><span class="cx">             home._txn, homeID=home._resourceID, resourceID=resourceID, bindUID=bindUID,
</span><span class="lines">@@ -3267,6 +3278,8 @@
</span><span class="cx">         data[&quot;bindData&quot;] = dict([(attr[1:], getattr(self, attr, None)) for attr in self.bindAttributes()])
</span><span class="cx">         data[&quot;additionalBindData&quot;] = dict([(attr[1:], getattr(self, attr, None)) for attr in self.additionalBindAttributes()])
</span><span class="cx">         data[&quot;metadataData&quot;] = dict([(attr[1:], getattr(self, attr, None)) for attr in self.metadataAttributes()])
</span><ins>+        data[&quot;metadataData&quot;][&quot;created&quot;] = data[&quot;metadataData&quot;][&quot;created&quot;].isoformat(&quot; &quot;)
+        data[&quot;metadataData&quot;][&quot;modified&quot;] = data[&quot;metadataData&quot;][&quot;modified&quot;].isoformat(&quot; &quot;)
</ins><span class="cx">         return data
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -3930,11 +3943,11 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def created(self):
</span><del>-        return datetimeMktime(parseSQLTimestamp(self._created)) if self._created else None
</del><ins>+        return datetimeMktime(self._created) if self._created else None
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def modified(self):
</span><del>-        return datetimeMktime(parseSQLTimestamp(self._modified)) if self._modified else None
</del><ins>+        return datetimeMktime(self._modified) if self._modified else None
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def addNotifier(self, factory_name, notifier):
</span><span class="lines">@@ -4050,11 +4063,11 @@
</span><span class="cx">             returnValue(result)
</span><span class="cx"> 
</span><span class="cx">         try:
</span><del>-            self._modified = (
</del><ins>+            self._modified = parseSQLTimestamp((
</ins><span class="cx">                 yield self._txn.subtransaction(
</span><span class="cx">                     _bumpModified, retries=0, failureOK=True
</span><span class="cx">                 )
</span><del>-            )[0][0]
</del><ins>+            )[0][0])
</ins><span class="cx"> 
</span><span class="cx">             queryCacher = self._txn._queryCacher
</span><span class="cx">             if queryCacher is not None:
</span><span class="lines">@@ -4119,6 +4132,8 @@
</span><span class="cx"> 
</span><span class="cx">         for attr, value in zip(child._rowAttributes(), objectData):
</span><span class="cx">             setattr(child, attr, value)
</span><ins>+        child._created = parseSQLTimestamp(child._created)
+        child._modified = parseSQLTimestamp(child._modified)
</ins><span class="cx"> 
</span><span class="cx">         yield child._loadPropertyStore(propstore)
</span><span class="cx"> 
</span><span class="lines">@@ -4520,7 +4535,10 @@
</span><span class="cx">         and reconstituted at the other end. Note that the other end may have a different schema so
</span><span class="cx">         the attributes may not match exactly and will need to be processed accordingly.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        return dict([(attr[1:], getattr(self, attr, None)) for attr in itertools.chain(self._rowAttributes(), self._otherSerializedAttributes())])
</del><ins>+        data = dict([(attr[1:], getattr(self, attr, None)) for attr in itertools.chain(self._rowAttributes(), self._otherSerializedAttributes())])
+        data[&quot;created&quot;] = data[&quot;created&quot;].isoformat(&quot; &quot;)
+        data[&quot;modified&quot;] = data[&quot;modified&quot;].isoformat(&quot; &quot;)
+        return data
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     @classmethod
</span><span class="lines">@@ -4757,11 +4775,11 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def created(self):
</span><del>-        return datetimeMktime(parseSQLTimestamp(self._created))
</del><ins>+        return datetimeMktime(self._created)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def modified(self):
</span><del>-        return datetimeMktime(parseSQLTimestamp(self._modified))
</del><ins>+        return datetimeMktime(self._modified)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     @classproperty
</span></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoresql_notificationpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/sql_notification.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/sql_notification.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/common/datastore/sql_notification.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -683,6 +683,8 @@
</span><span class="cx">              child._notificationType,
</span><span class="cx">              child._created,
</span><span class="cx">              child._modified,) = tuple(row)
</span><ins>+            child._created = parseSQLTimestamp(child._created)
+            child._modified = parseSQLTimestamp(child._modified)
</ins><span class="cx">             try:
</span><span class="cx">                 child._notificationType = json.loads(child._notificationType)
</span><span class="cx">             except ValueError:
</span><span class="lines">@@ -733,6 +735,8 @@
</span><span class="cx">              self._notificationType,
</span><span class="cx">              self._created,
</span><span class="cx">              self._modified,) = tuple(rows[0])
</span><ins>+            self._created = parseSQLTimestamp(self._created)
+            self._modified = parseSQLTimestamp(self._modified)
</ins><span class="cx">             try:
</span><span class="cx">                 self._notificationType = json.loads(self._notificationType)
</span><span class="cx">             except ValueError:
</span><span class="lines">@@ -828,7 +832,11 @@
</span><span class="cx">                 notificationType=json.dumps(self._notificationType),
</span><span class="cx">                 notificationData=notificationtext, md5=self._md5
</span><span class="cx">             )
</span><del>-            self._resourceID, self._created, self._modified = rows[0]
</del><ins>+            self._resourceID, self._created, self._modified = (
+                rows[0][0],
+                parseSQLTimestamp(rows[0][1]),
+                parseSQLTimestamp(rows[0][2]),
+            )
</ins><span class="cx">             self._loadPropertyStore()
</span><span class="cx">         else:
</span><span class="cx">             rows = yield self._updateNotificationQuery.on(
</span><span class="lines">@@ -836,7 +844,7 @@
</span><span class="cx">                 notificationType=json.dumps(self._notificationType),
</span><span class="cx">                 notificationData=notificationtext, md5=self._md5
</span><span class="cx">             )
</span><del>-            self._modified = rows[0][0]
</del><ins>+            self._modified = parseSQLTimestamp(rows[0][0])
</ins><span class="cx">         self._notificationData = notificationdata
</span><span class="cx"> 
</span><span class="cx">     _notificationDataFromID = Select(
</span><span class="lines">@@ -877,8 +885,8 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def created(self):
</span><del>-        return datetimeMktime(parseSQLTimestamp(self._created))
</del><ins>+        return datetimeMktime(self._created)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def modified(self):
</span><del>-        return datetimeMktime(parseSQLTimestamp(self._modified))
</del><ins>+        return datetimeMktime(self._modified)
</ins></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoresql_tablespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/sql_tables.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/sql_tables.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/common/datastore/sql_tables.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -23,13 +23,11 @@
</span><span class="cx"> from twext.enterprise.dal.syntax import SchemaSyntax, QueryGenerator
</span><span class="cx"> from twext.enterprise.dal.model import NO_DEFAULT
</span><span class="cx"> from twext.enterprise.dal.model import Sequence, ProcedureCall
</span><ins>+from twext.enterprise.dal.parseschema import schemaFromPath
</ins><span class="cx"> from twext.enterprise.dal.syntax import FixedPlaceholder
</span><span class="cx"> from twext.enterprise.ienterprise import ORACLE_DIALECT, POSTGRES_DIALECT
</span><span class="cx"> from twext.enterprise.dal.syntax import Insert
</span><span class="cx"> from twext.enterprise.ienterprise import ORACLE_TABLE_NAME_MAX
</span><del>-from twext.enterprise.dal.parseschema import schemaFromPath, significant
-from sqlparse import parse
-from re import compile
</del><span class="cx"> import hashlib
</span><span class="cx"> import itertools
</span><span class="cx"> 
</span><span class="lines">@@ -436,44 +434,6 @@
</span><span class="cx">         out.write(&quot;-- Skipped Function {}\n&quot;.format(function.name))
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-
-def splitSQLString(sqlString):
-    &quot;&quot;&quot;
-    Strings which mix zero or more sql statements with zero or more pl/sql
-    statements need to be split into individual sql statements for execution.
-    This function was written to allow execution of pl/sql during Oracle schema
-    upgrades.
-    &quot;&quot;&quot;
-    aggregated = ''
-    inPlSQL = None
-    parsed = parse(sqlString)
-    for stmt in parsed:
-        while stmt.tokens and not significant(stmt.tokens[0]):
-            stmt.tokens.pop(0)
-        if not stmt.tokens:
-            continue
-        if inPlSQL is not None:
-            agg = str(stmt).strip()
-            if &quot;end;&quot;.lower() in agg.lower():
-                inPlSQL = None
-                aggregated += agg
-                rex = compile(&quot;\n +&quot;)
-                aggregated = rex.sub('\n', aggregated)
-                yield aggregated.strip()
-                continue
-            aggregated += agg
-            continue
-        if inPlSQL is None:
-            # if 'begin'.lower() in str(stmt).split()[0].lower():
-            if str(stmt).lower().strip().startswith('begin'):
-                inPlSQL = True
-                aggregated += str(stmt)
-                continue
-        else:
-            continue
-        yield str(stmt).rstrip().rstrip(&quot;;&quot;)
-
-
</del><span class="cx"> if __name__ == '__main__':
</span><span class="cx">     import sys
</span><span class="cx">     version = sys.argv[1] if len(sys.argv) == 2 else None
</span></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoretesttest_sql_tablespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/test/test_sql_tables.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/test/test_sql_tables.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/common/datastore/test/test_sql_tables.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -31,8 +31,9 @@
</span><span class="cx"> from twext.enterprise.dal.syntax import SchemaSyntax
</span><span class="cx"> 
</span><span class="cx"> from txdav.common.datastore.sql_tables import schema, _translateSchema
</span><del>-from txdav.common.datastore.sql_tables import SchemaBroken, splitSQLString
</del><ins>+from txdav.common.datastore.sql_tables import SchemaBroken
</ins><span class="cx"> 
</span><ins>+from twext.enterprise.dal.parseschema import splitSQLString
</ins><span class="cx"> from twext.enterprise.dal.test.test_parseschema import SchemaTestHelper
</span><span class="cx"> 
</span><span class="cx"> from textwrap import dedent
</span></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoreupgradesqltesttest_upgradepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/upgrade/sql/test/test_upgrade.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/upgrade/sql/test/test_upgrade.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/common/datastore/upgrade/sql/test/test_upgrade.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -163,7 +163,7 @@
</span><span class="cx">             startTxn = store.newTransaction(&quot;test_dbUpgrades&quot;)
</span><span class="cx">             yield startTxn.execSQL(&quot;create schema test_dbUpgrades;&quot;)
</span><span class="cx">             yield startTxn.execSQL(&quot;set search_path to test_dbUpgrades;&quot;)
</span><del>-            yield startTxn.execSQL(path.getContent())
</del><ins>+            yield startTxn.execSQLBlock(path.getContent())
</ins><span class="cx">             yield startTxn.commit()
</span><span class="cx"> 
</span><span class="cx">         @inlineCallbacks
</span><span class="lines">@@ -269,7 +269,7 @@
</span><span class="cx">             startTxn = store.newTransaction(&quot;test_dbUpgrades&quot;)
</span><span class="cx">             yield startTxn.execSQL(&quot;create schema test_dbUpgrades;&quot;)
</span><span class="cx">             yield startTxn.execSQL(&quot;set search_path to test_dbUpgrades;&quot;)
</span><del>-            yield startTxn.execSQL(path.getContent())
</del><ins>+            yield startTxn.execSQLBlock(path.getContent())
</ins><span class="cx">             yield startTxn.execSQL(&quot;update CALENDARSERVER set VALUE = '%s' where NAME = '%s';&quot; % (oldVersion, versionKey,))
</span><span class="cx">             yield startTxn.commit()
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoreupgradesqltesttest_upgrade_with_datapy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/upgrade/sql/test/test_upgrade_with_data.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/upgrade/sql/test/test_upgrade_with_data.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/common/datastore/upgrade/sql/test/test_upgrade_with_data.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -82,7 +82,7 @@
</span><span class="cx">         startTxn = self.store.newTransaction(&quot;test_dbUpgrades&quot;)
</span><span class="cx">         yield startTxn.execSQL(&quot;create schema test_dbUpgrades;&quot;)
</span><span class="cx">         yield startTxn.execSQL(&quot;set search_path to test_dbUpgrades;&quot;)
</span><del>-        yield startTxn.execSQL(path.getContent())
</del><ins>+        yield startTxn.execSQLBlock(path.getContent())
</ins><span class="cx">         yield startTxn.commit()
</span><span class="cx"> 
</span><span class="cx">         self.addCleanup(self.cleanUp)
</span></span></pre></div>
<a id="CalendarServertrunktxdavwhotesttest_group_attendeespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/who/test/test_group_attendees.py (14531 => 14532)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/who/test/test_group_attendees.py        2015-03-09 19:43:14 UTC (rev 14531)
+++ CalendarServer/trunk/txdav/who/test/test_group_attendees.py        2015-03-09 19:47:39 UTC (rev 14532)
</span><span class="lines">@@ -875,7 +875,7 @@
</span><span class="cx">             self.transactionUnderTest(),
</span><span class="cx">             resourceID=cobj._resourceID,
</span><span class="cx">             groupID=group.groupID,
</span><del>-            membershipHash=-1,
</del><ins>+            membershipHash=&quot;None&quot;,
</ins><span class="cx">         )
</span><span class="cx">         wps = yield groupCacher.refreshGroup(self.transactionUnderTest(), &quot;group01&quot;)
</span><span class="cx">         self.assertEqual(len(wps), 1)
</span><span class="lines">@@ -1034,7 +1034,7 @@
</span><span class="cx">             self.transactionUnderTest(),
</span><span class="cx">             resourceID=cobj._resourceID,
</span><span class="cx">             groupID=group.groupID,
</span><del>-            membershipHash=-1,
</del><ins>+            membershipHash=&quot;None&quot;,
</ins><span class="cx">         )
</span><span class="cx">         wps = yield groupCacher.refreshGroup(self.transactionUnderTest(), &quot;group01&quot;)
</span><span class="cx">         self.assertEqual(len(wps), 1)
</span></span></pre>
</div>
</div>

</body>
</html>