<!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>[11845] CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades</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/11845">11845</a></dd>
<dt>Author</dt> <dd>cdaboo@apple.com</dd>
<dt>Date</dt> <dd>2013-10-29 17:05:49 -0700 (Tue, 29 Oct 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add progress/error logging for store data upgrades.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#CalendarServertrunktxdavcommondatastoreupgradesqlupgradesaddressbook_upgrade_from_1_to_2py">CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/addressbook_upgrade_from_1_to_2.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoreupgradesqlupgradescalendar_upgrade_from_1_to_2py">CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_1_to_2.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoreupgradesqlupgradescalendar_upgrade_from_3_to_4py">CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_3_to_4.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoreupgradesqlupgradescalendar_upgrade_from_4_to_5py">CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_4_to_5.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoreupgradesqlupgradesutilpy">CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/util.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalendarServertrunktxdavcommondatastoreupgradesqlupgradesaddressbook_upgrade_from_1_to_2py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/addressbook_upgrade_from_1_to_2.py (11844 => 11845)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/addressbook_upgrade_from_1_to_2.py        2013-10-29 23:59:02 UTC (rev 11844)
+++ CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/addressbook_upgrade_from_1_to_2.py        2013-10-30 00:05:49 UTC (rev 11845)
</span><span class="lines">@@ -22,7 +22,8 @@
</span><span class="cx"> from txdav.base.propertystore.base import PropertyName
</span><span class="cx"> from txdav.common.datastore.sql_tables import _ABO_KIND_GROUP, schema
</span><span class="cx"> from txdav.common.datastore.upgrade.sql.upgrades.util import updateAddressBookDataVersion, \
</span><del>-    doToEachHomeNotAtVersion, removeProperty, cleanPropertyStore
</del><ins>+    doToEachHomeNotAtVersion, removeProperty, cleanPropertyStore, \
+    logUpgradeStatus
</ins><span class="cx"> from txdav.xml import element
</span><span class="cx"> 
</span><span class="cx"> &quot;&quot;&quot;
</span><span class="lines">@@ -73,14 +74,20 @@
</span><span class="cx">                 #update rest
</span><span class="cx">                 yield abObject.setComponent(component)
</span><span class="cx"> 
</span><ins>+    logUpgradeStatus(&quot;Starting Addressbook Populate Members&quot;)
+
</ins><span class="cx">     # Do this to each calendar home not already at version 2
</span><del>-    yield doToEachHomeNotAtVersion(sqlStore, schema.ADDRESSBOOK_HOME, UPGRADE_TO_VERSION, doIt)
</del><ins>+    yield doToEachHomeNotAtVersion(sqlStore, schema.ADDRESSBOOK_HOME, UPGRADE_TO_VERSION, doIt, &quot;Populate Members&quot;)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> @inlineCallbacks
</span><span class="cx"> def removeResourceType(sqlStore):
</span><ins>+    logUpgradeStatus(&quot;Starting Addressbook Remove Resource Type&quot;)
+
</ins><span class="cx">     sqlTxn = sqlStore.newTransaction()
</span><span class="cx">     yield removeProperty(sqlTxn, PropertyName.fromElement(element.ResourceType))
</span><span class="cx">     yield sqlTxn.commit()
</span><span class="cx">     yield cleanPropertyStore()
</span><ins>+
+    logUpgradeStatus(&quot;End Addressbook Remove Resource Type&quot;)
</ins></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoreupgradesqlupgradescalendar_upgrade_from_1_to_2py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_1_to_2.py (11844 => 11845)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_1_to_2.py        2013-10-29 23:59:02 UTC (rev 11844)
+++ CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_1_to_2.py        2013-10-30 00:05:49 UTC (rev 11845)
</span><span class="lines">@@ -16,12 +16,16 @@
</span><span class="cx"> ##
</span><span class="cx"> 
</span><span class="cx"> from twext.enterprise.dal.syntax import Update
</span><del>-from txdav.xml.parser import WebDAVDocument
</del><ins>+
</ins><span class="cx"> from twisted.internet.defer import inlineCallbacks
</span><ins>+
</ins><span class="cx"> from twistedcaldav import caldavxml
</span><ins>+
</ins><span class="cx"> from txdav.common.datastore.sql_tables import schema
</span><span class="cx"> from txdav.common.datastore.upgrade.sql.upgrades.util import rowsForProperty,\
</span><del>-    removeProperty, updateCalendarDataVersion, doToEachHomeNotAtVersion
</del><ins>+    removeProperty, updateCalendarDataVersion, doToEachHomeNotAtVersion, \
+    logUpgradeStatus, logUpgradeError
+from txdav.xml.parser import WebDAVDocument
</ins><span class="cx"> 
</span><span class="cx"> &quot;&quot;&quot;
</span><span class="cx"> Calendar data upgrade from database version 1 to 2
</span><span class="lines">@@ -50,9 +54,14 @@
</span><span class="cx">     extracting the new format value from the XML property.
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><ins>+    logUpgradeStatus(&quot;Starting Move supported-component-set&quot;)
+
</ins><span class="cx">     sqlTxn = sqlStore.newTransaction()
</span><span class="cx">     try:
</span><ins>+        calendar_rid = None
</ins><span class="cx">         rows = (yield rowsForProperty(sqlTxn, caldavxml.SupportedCalendarComponentSet))
</span><ins>+        total = len(rows)
+        count = 0
</ins><span class="cx">         for calendar_rid, value in rows:
</span><span class="cx">             prop = WebDAVDocument.fromString(value).root_element
</span><span class="cx">             supported_components = &quot;,&quot;.join(sorted([comp.attributes[&quot;name&quot;].upper() for comp in prop.children]))
</span><span class="lines">@@ -63,11 +72,19 @@
</span><span class="cx">                 },
</span><span class="cx">                 Where=(meta.RESOURCE_ID == calendar_rid)
</span><span class="cx">             ).on(sqlTxn)
</span><ins>+            count += 1
+            logUpgradeStatus(&quot;Move supported-component-set&quot;, count, total)
</ins><span class="cx"> 
</span><span class="cx">         yield removeProperty(sqlTxn, caldavxml.SupportedCalendarComponentSet)
</span><span class="cx">         yield sqlTxn.commit()
</span><ins>+
+        logUpgradeStatus(&quot;End Move supported-component-set&quot;)
</ins><span class="cx">     except RuntimeError:
</span><span class="cx">         yield sqlTxn.abort()
</span><ins>+        logUpgradeError(
+            &quot;Move supported-component-set&quot;,
+            &quot;Last calendar: {}&quot;.format(calendar_rid)
+        )
</ins><span class="cx">         raise
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -86,5 +103,7 @@
</span><span class="cx">         home = yield txn.calendarHomeWithResourceID(homeResourceID)
</span><span class="cx">         yield home.splitCalendars()
</span><span class="cx"> 
</span><ins>+    logUpgradeStatus(&quot;Starting Split Calendars&quot;)
+
</ins><span class="cx">     # Do this to each calendar home not already at version 2
</span><del>-    yield doToEachHomeNotAtVersion(sqlStore, schema.CALENDAR_HOME, UPGRADE_TO_VERSION, doIt)
</del><ins>+    yield doToEachHomeNotAtVersion(sqlStore, schema.CALENDAR_HOME, UPGRADE_TO_VERSION, doIt, &quot;Split Calendars&quot;)
</ins></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoreupgradesqlupgradescalendar_upgrade_from_3_to_4py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_3_to_4.py (11844 => 11845)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_3_to_4.py        2013-10-29 23:59:02 UTC (rev 11844)
+++ CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_3_to_4.py        2013-10-30 00:05:49 UTC (rev 11845)
</span><span class="lines">@@ -25,7 +25,8 @@
</span><span class="cx"> from txdav.caldav.icalendarstore import InvalidDefaultCalendar
</span><span class="cx"> from txdav.common.datastore.sql_tables import schema, _BIND_MODE_OWN
</span><span class="cx"> from txdav.common.datastore.upgrade.sql.upgrades.util import rowsForProperty, updateCalendarDataVersion, \
</span><del>-    updateAllCalendarHomeDataVersions, removeProperty, cleanPropertyStore
</del><ins>+    updateAllCalendarHomeDataVersions, removeProperty, countProperty, cleanPropertyStore, \
+    logUpgradeStatus, logUpgradeError
</ins><span class="cx"> from txdav.xml.parser import WebDAVDocument
</span><span class="cx"> from txdav.xml import element
</span><span class="cx"> from twisted.python.failure import Failure
</span><span class="lines">@@ -78,13 +79,22 @@
</span><span class="cx">     cb = schema.CALENDAR_BIND
</span><span class="cx">     rp = schema.RESOURCE_PROPERTY
</span><span class="cx"> 
</span><ins>+    logUpgradeStatus(&quot;Starting Process {}&quot;.format(propname.qname()))
+
+    sqlTxn = sqlStore.newTransaction()
+    total = (yield countProperty(sqlTxn, propname))
+    yield sqlTxn.commit()
+    count = 0
+
</ins><span class="cx">     try:
</span><ins>+        inbox_rid = None
</ins><span class="cx">         while True:
</span><span class="cx">             sqlTxn = sqlStore.newTransaction()
</span><span class="cx">             rows = (yield rowsForProperty(sqlTxn, propname, batch=BATCH_SIZE))
</span><span class="cx">             if len(rows) == 0:
</span><span class="cx">                 yield sqlTxn.commit()
</span><span class="cx">                 break
</span><ins>+
</ins><span class="cx">             delete_ids = []
</span><span class="cx">             for inbox_rid, value in rows:
</span><span class="cx">                 delete_ids.append(inbox_rid)
</span><span class="lines">@@ -127,10 +137,22 @@
</span><span class="cx"> 
</span><span class="cx">             yield sqlTxn.commit()
</span><span class="cx"> 
</span><ins>+            count += len(rows)
+            logUpgradeStatus(
+                &quot;Process {}&quot;.format(propname.qname()),
+                count,
+                total
+            )
+
</ins><span class="cx">         yield cleanPropertyStore()
</span><ins>+        logUpgradeStatus(&quot;End Process {}&quot;.format(propname.qname()))
</ins><span class="cx"> 
</span><del>-    except RuntimeError:
</del><ins>+    except RuntimeError as e:
</ins><span class="cx">         f = Failure()
</span><ins>+        logUpgradeError(
+            &quot;Process {}&quot;.format(propname.qname()),
+            &quot;Inbox: {}, error: {}&quot;.format(inbox_rid, e),
+        )
</ins><span class="cx">         yield sqlTxn.abort()
</span><span class="cx">         f.raiseException()
</span><span class="cx"> 
</span><span class="lines">@@ -147,14 +169,24 @@
</span><span class="cx">     cb = schema.CALENDAR_BIND
</span><span class="cx">     rp = schema.RESOURCE_PROPERTY
</span><span class="cx"> 
</span><ins>+    propname = caldavxml.ScheduleCalendarTransp
+    logUpgradeStatus(&quot;Starting Process {}&quot;.format(propname.qname()))
+
+    sqlTxn = sqlStore.newTransaction()
+    total = (yield countProperty(sqlTxn, propname))
+    yield sqlTxn.commit()
+    count = 0
+
</ins><span class="cx">     try:
</span><ins>+        calendar_rid = None
</ins><span class="cx">         calendars_for_id = {}
</span><span class="cx">         while True:
</span><span class="cx">             sqlTxn = sqlStore.newTransaction()
</span><del>-            rows = (yield rowsForProperty(sqlTxn, caldavxml.ScheduleCalendarTransp, with_uid=True, batch=BATCH_SIZE))
</del><ins>+            rows = (yield rowsForProperty(sqlTxn, propname, with_uid=True, batch=BATCH_SIZE))
</ins><span class="cx">             if len(rows) == 0:
</span><span class="cx">                 yield sqlTxn.commit()
</span><span class="cx">                 break
</span><ins>+
</ins><span class="cx">             delete_ids = []
</span><span class="cx">             for calendar_rid, value, viewer in rows:
</span><span class="cx">                 delete_ids.append(calendar_rid)
</span><span class="lines">@@ -191,13 +223,25 @@
</span><span class="cx"> 
</span><span class="cx">             yield sqlTxn.commit()
</span><span class="cx"> 
</span><ins>+            count += len(rows)
+            logUpgradeStatus(
+                &quot;Process {}&quot;.format(propname.qname()),
+                count,
+                total,
+            )
+
</ins><span class="cx">         sqlTxn = sqlStore.newTransaction()
</span><span class="cx">         yield removeProperty(sqlTxn, PropertyName.fromElement(caldavxml.CalendarFreeBusySet))
</span><span class="cx">         yield sqlTxn.commit()
</span><span class="cx">         yield cleanPropertyStore()
</span><ins>+        logUpgradeStatus(&quot;End Process {}&quot;.format(propname.qname()))
</ins><span class="cx"> 
</span><del>-    except RuntimeError:
</del><ins>+    except RuntimeError as e:
</ins><span class="cx">         f = Failure()
</span><ins>+        logUpgradeError(
+            &quot;Process {}&quot;.format(propname.qname()),
+            &quot;Inbox: {}, error: {}&quot;.format(calendar_rid, e),
+        )
</ins><span class="cx">         yield sqlTxn.abort()
</span><span class="cx">         f.raiseException()
</span><span class="cx"> 
</span><span class="lines">@@ -250,7 +294,15 @@
</span><span class="cx">     cb = schema.CALENDAR_BIND
</span><span class="cx">     rp = schema.RESOURCE_PROPERTY
</span><span class="cx"> 
</span><ins>+    logUpgradeStatus(&quot;Starting Process {} {}&quot;.format(propname.qname(), vevent))
+
+    sqlTxn = sqlStore.newTransaction()
+    total = (yield countProperty(sqlTxn, propname))
+    yield sqlTxn.commit()
+    count = 0
+
</ins><span class="cx">     try:
</span><ins>+        rid = None
</ins><span class="cx">         calendars_for_id = {}
</span><span class="cx">         while True:
</span><span class="cx">             sqlTxn = sqlStore.newTransaction()
</span><span class="lines">@@ -258,6 +310,7 @@
</span><span class="cx">             if len(rows) == 0:
</span><span class="cx">                 yield sqlTxn.commit()
</span><span class="cx">                 break
</span><ins>+
</ins><span class="cx">             delete_ids = []
</span><span class="cx">             for rid, value, viewer in rows:
</span><span class="cx">                 delete_ids.append(rid)
</span><span class="lines">@@ -311,10 +364,22 @@
</span><span class="cx"> 
</span><span class="cx">             yield sqlTxn.commit()
</span><span class="cx"> 
</span><ins>+            count += len(rows)
+            logUpgradeStatus(
+                &quot;Process {} {}&quot;.format(propname.qname(), vevent),
+                count,
+                total,
+            )
+
</ins><span class="cx">         yield cleanPropertyStore()
</span><ins>+        logUpgradeStatus(&quot;End Process {} {}&quot;.format(propname.qname(), vevent))
</ins><span class="cx"> 
</span><del>-    except RuntimeError:
</del><ins>+    except RuntimeError as e:
</ins><span class="cx">         f = Failure()
</span><ins>+        logUpgradeError(
+            &quot;Process {} {}&quot;.format(propname.qname(), vevent),
+            &quot;Rid: {}, error: {}&quot;.format(rid, e),
+        )
</ins><span class="cx">         yield sqlTxn.abort()
</span><span class="cx">         f.raiseException()
</span><span class="cx"> 
</span><span class="lines">@@ -322,7 +387,11 @@
</span><span class="cx"> 
</span><span class="cx"> @inlineCallbacks
</span><span class="cx"> def removeResourceType(sqlStore):
</span><ins>+    logUpgradeStatus(&quot;Starting Calendar Remove Resource Type&quot;)
+
</ins><span class="cx">     sqlTxn = sqlStore.newTransaction()
</span><span class="cx">     yield removeProperty(sqlTxn, PropertyName.fromElement(element.ResourceType))
</span><span class="cx">     yield sqlTxn.commit()
</span><span class="cx">     yield cleanPropertyStore()
</span><ins>+
+    logUpgradeStatus(&quot;End Calendar Remove Resource Type&quot;)
</ins></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoreupgradesqlupgradescalendar_upgrade_from_4_to_5py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_4_to_5.py (11844 => 11845)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_4_to_5.py        2013-10-29 23:59:02 UTC (rev 11844)
+++ CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_4_to_5.py        2013-10-30 00:05:49 UTC (rev 11845)
</span><span class="lines">@@ -25,7 +25,8 @@
</span><span class="cx"> from txdav.base.propertystore.base import PropertyName
</span><span class="cx"> from txdav.common.datastore.sql_tables import schema, _BIND_MODE_OWN
</span><span class="cx"> from txdav.common.datastore.upgrade.sql.upgrades.util import rowsForProperty, updateCalendarDataVersion, \
</span><del>-    updateAllCalendarHomeDataVersions, removeProperty, cleanPropertyStore
</del><ins>+    updateAllCalendarHomeDataVersions, removeProperty, cleanPropertyStore, \
+    logUpgradeStatus, countProperty, logUpgradeError
</ins><span class="cx"> from txdav.xml import element
</span><span class="cx"> from txdav.xml.parser import WebDAVDocument
</span><span class="cx"> from twext.web2.dav.resource import TwistedQuotaUsedProperty, \
</span><span class="lines">@@ -64,14 +65,24 @@
</span><span class="cx">     cb = schema.CALENDAR_BIND
</span><span class="cx">     rp = schema.RESOURCE_PROPERTY
</span><span class="cx"> 
</span><ins>+    propname = caldavxml.CalendarTimeZone
+    logUpgradeStatus(&quot;Starting Process {}&quot;.format(propname.qname()))
+
+    sqlTxn = sqlStore.newTransaction()
+    total = (yield countProperty(sqlTxn, propname))
+    yield sqlTxn.commit()
+    count = 0
+
</ins><span class="cx">     try:
</span><ins>+        calendar_rid = None
</ins><span class="cx">         calendars_for_id = {}
</span><span class="cx">         while True:
</span><span class="cx">             sqlTxn = sqlStore.newTransaction()
</span><del>-            rows = (yield rowsForProperty(sqlTxn, caldavxml.CalendarTimeZone, with_uid=True, batch=BATCH_SIZE))
</del><ins>+            rows = (yield rowsForProperty(sqlTxn, propname, with_uid=True, batch=BATCH_SIZE))
</ins><span class="cx">             if len(rows) == 0:
</span><span class="cx">                 yield sqlTxn.commit()
</span><span class="cx">                 break
</span><ins>+
</ins><span class="cx">             delete_ids = []
</span><span class="cx">             for calendar_rid, value, viewer in rows:
</span><span class="cx">                 delete_ids.append(calendar_rid)
</span><span class="lines">@@ -107,11 +118,22 @@
</span><span class="cx">             ).on(sqlTxn, ids=delete_ids)
</span><span class="cx"> 
</span><span class="cx">             yield sqlTxn.commit()
</span><ins>+            count += len(rows)
+            logUpgradeStatus(
+                &quot;Process {}&quot;.format(propname.qname()),
+                count,
+                total,
+            )
</ins><span class="cx"> 
</span><span class="cx">         yield cleanPropertyStore()
</span><ins>+        logUpgradeStatus(&quot;End Process {}&quot;.format(propname.qname()))
</ins><span class="cx"> 
</span><del>-    except RuntimeError:
</del><ins>+    except RuntimeError as e:
</ins><span class="cx">         f = Failure()
</span><ins>+        logUpgradeError(
+            &quot;Process {}&quot;.format(propname.qname()),
+            &quot;Rid: {}, error: {}&quot;.format(calendar_rid, e),
+        )
</ins><span class="cx">         yield sqlTxn.abort()
</span><span class="cx">         f.raiseException()
</span><span class="cx"> 
</span><span class="lines">@@ -128,10 +150,19 @@
</span><span class="cx">     cb = schema.CALENDAR_BIND
</span><span class="cx">     rp = schema.RESOURCE_PROPERTY
</span><span class="cx"> 
</span><ins>+    propname = customxml.CalendarAvailability
+    logUpgradeStatus(&quot;Starting Process {}&quot;.format(propname.qname()))
+
+    sqlTxn = sqlStore.newTransaction()
+    total = (yield countProperty(sqlTxn, propname))
+    yield sqlTxn.commit()
+    count = 0
+
</ins><span class="cx">     try:
</span><ins>+        calendar_rid = None
</ins><span class="cx">         while True:
</span><span class="cx">             sqlTxn = sqlStore.newTransaction()
</span><del>-            rows = (yield rowsForProperty(sqlTxn, customxml.CalendarAvailability, batch=BATCH_SIZE))
</del><ins>+            rows = (yield rowsForProperty(sqlTxn, propname, batch=BATCH_SIZE))
</ins><span class="cx">             if len(rows) == 0:
</span><span class="cx">                 yield sqlTxn.commit()
</span><span class="cx">                 break
</span><span class="lines">@@ -164,10 +195,22 @@
</span><span class="cx"> 
</span><span class="cx">             yield sqlTxn.commit()
</span><span class="cx"> 
</span><ins>+            count += len(rows)
+            logUpgradeStatus(
+                &quot;Process {}&quot;.format(propname.qname()),
+                count,
+                total,
+            )
+
</ins><span class="cx">         yield cleanPropertyStore()
</span><ins>+        logUpgradeStatus(&quot;End Process {}&quot;.format(propname.qname()))
</ins><span class="cx"> 
</span><del>-    except RuntimeError:
</del><ins>+    except RuntimeError as e:
</ins><span class="cx">         f = Failure()
</span><ins>+        logUpgradeError(
+            &quot;Process {}&quot;.format(propname.qname()),
+            &quot;Rid: {}, error: {}&quot;.format(calendar_rid, e),
+        )
</ins><span class="cx">         yield sqlTxn.abort()
</span><span class="cx">         f.raiseException()
</span><span class="cx"> 
</span><span class="lines">@@ -190,6 +233,8 @@
</span><span class="cx">     {http://twistedmatrix.com/xml_namespace/dav/}schedule-auto-respond
</span><span class="cx"> 
</span><span class="cx">     &quot;&quot;&quot;
</span><ins>+    logUpgradeStatus(&quot;Starting Calendar Remove Other Properties&quot;)
+
</ins><span class="cx">     sqlTxn = sqlStore.newTransaction()
</span><span class="cx"> 
</span><span class="cx">     yield removeProperty(sqlTxn, PropertyName.fromElement(element.ACL))
</span><span class="lines">@@ -205,3 +250,5 @@
</span><span class="cx"> 
</span><span class="cx">     yield sqlTxn.commit()
</span><span class="cx">     yield cleanPropertyStore()
</span><ins>+
+    logUpgradeStatus(&quot;End Calendar Remove Other Properties&quot;)
</ins></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoreupgradesqlupgradesutilpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/util.py (11844 => 11845)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/util.py        2013-10-29 23:59:02 UTC (rev 11844)
+++ CalendarServer/trunk/txdav/common/datastore/upgrade/sql/upgrades/util.py        2013-10-30 00:05:49 UTC (rev 11845)
</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 twext.enterprise.dal.syntax import Select, Delete, Update
</del><ins>+from twext.enterprise.dal.syntax import Select, Delete, Update, Count
</ins><span class="cx"> from twext.python.log import Logger
</span><span class="cx"> from twisted.internet.defer import inlineCallbacks, returnValue
</span><span class="cx"> from txdav.base.propertystore.base import PropertyName
</span><span class="lines">@@ -44,6 +44,21 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> @inlineCallbacks
</span><ins>+def countProperty(txn, propelement):
+    pname = PropertyName.fromElement(propelement)
+
+    rp = schema.RESOURCE_PROPERTY
+    count = (yield Select(
+        [Count(rp.RESOURCE_ID), ],
+        From=rp,
+        Where=rp.NAME == pname.toString(),
+    ).on(txn))[0][0]
+
+    returnValue(count)
+
+
+
+@inlineCallbacks
</ins><span class="cx"> def cleanPropertyStore():
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     We have manually manipulated the SQL property store by-passing the underlying implementation's caching
</span><span class="lines">@@ -114,14 +129,25 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> @inlineCallbacks
</span><del>-def doToEachHomeNotAtVersion(store, homeSchema, version, doIt):
</del><ins>+def doToEachHomeNotAtVersion(store, homeSchema, version, doIt, logStr):
</ins><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Do something to each home whose version column indicates it is older
</span><span class="cx">     than the specified version. Do this in batches as there may be a lot of work to do.
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><ins>+    txn = store.newTransaction(&quot;updateDataVersion&quot;)
+    total = (yield Select(
+        [Count(homeSchema.RESOURCE_ID), ],
+        From=homeSchema,
+        Where=homeSchema.DATAVERSION &lt; version,
+    ).on(txn))[0][0]
+    yield txn.commit()
+    count = 0
+
</ins><span class="cx">     while True:
</span><span class="cx"> 
</span><ins>+        logUpgradeStatus(logStr, count, total)
+
</ins><span class="cx">         # Get the next home with an old version
</span><span class="cx">         txn = store.newTransaction(&quot;updateDataVersion&quot;)
</span><span class="cx">         try:
</span><span class="lines">@@ -135,6 +161,7 @@
</span><span class="cx"> 
</span><span class="cx">             if len(rows) == 0:
</span><span class="cx">                 yield txn.commit()
</span><ins>+                logUpgradeStatus(&quot;End {}&quot;.format(logStr), count, total)
</ins><span class="cx">                 returnValue(None)
</span><span class="cx"> 
</span><span class="cx">             # Apply to the home
</span><span class="lines">@@ -149,6 +176,26 @@
</span><span class="cx">             yield txn.commit()
</span><span class="cx">         except RuntimeError, e:
</span><span class="cx">             f = Failure()
</span><del>-            log.error(&quot;Failed to upgrade %s to %s: %s&quot; % (homeSchema, version, e))
</del><ins>+            logUpgradeError(
+                logStr,
+                &quot;Failed to upgrade {} to {}: {}&quot;.format(homeSchema, version, e)
+            )
</ins><span class="cx">             yield txn.abort()
</span><span class="cx">             f.raiseException()
</span><ins>+
+        count += 1
+
+
+
+def logUpgradeStatus(title, count=None, total=None):
+    if total is None:
+        log.info(&quot;Database upgrade {title}&quot;, title=title)
+    else:
+        divisor = 1000 if total &gt; 1000 else 100
+        if (divmod(count, divisor)[1] == 0) or (count == total):
+            log.info(&quot;Database upgrade {title}: {count} of {total}&quot;, title=title, count=count, total=total)
+
+
+
+def logUpgradeError(title, details):
+    log.error(&quot;Database upgrade {title} failed: {details}&quot;, title=title, details=details)
</ins></span></pre>
</div>
</div>

</body>
</html>