[CalendarServer-changes] [12666] CalendarServer/trunk/txdav

source_changes at macosforge.org source_changes at macosforge.org
Wed Mar 12 11:24:58 PDT 2014


Revision: 12666
          http://trac.calendarserver.org//changeset/12666
Author:   cdaboo at apple.com
Date:     2014-02-11 19:22:49 -0800 (Tue, 11 Feb 2014)
Log Message:
-----------
Make sure a missing home child revision does not cause an exception.

Modified Paths:
--------------
    CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py
    CalendarServer/trunk/txdav/common/datastore/sql.py

Modified: CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py	2014-02-12 02:17:03 UTC (rev 12665)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py	2014-02-12 03:22:49 UTC (rev 12666)
@@ -1898,7 +1898,39 @@
         self.assertNotEqual(caldata4, None)
 
 
+    @inlineCallbacks
+    def test_calendarMissingRevision(self):
+        """
+        Test that two concurrent attempts to add resources in two separate
+        calendar homes does not deadlock on the revision table update.
+        """
 
+        # Get details
+        home = yield self.homeUnderTest(name="user01", create=True)
+        self.assertNotEqual(home, None)
+        calendar = yield home.childWithName("calendar")
+        self.assertNotEqual(calendar, None)
+
+        rev = calendar._revisionsSchema
+        yield Delete(
+            From=rev,
+            Where=(rev.HOME_RESOURCE_ID == Parameter("homeID")).And(
+                   rev.COLLECTION_NAME == Parameter("collectionName"))
+        ).on(self.transactionUnderTest(), homeID=home.id(), collectionName="calendar")
+
+        yield self.commit()
+
+        home = yield self.homeUnderTest(name="user01")
+        children = yield home.loadChildren()
+        self.assertEqual(len(children), 3)
+        yield self.commit()
+
+        calendar = yield self.calendarUnderTest(home="user01", name="calendar")
+        token = yield calendar.syncToken()
+        self.assertTrue(token is not None)
+
+
+
 class SchedulingTests(CommonCommonTests, unittest.TestCase):
     """
     CalendarObject splitting tests

Modified: CalendarServer/trunk/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql.py	2014-02-12 02:17:03 UTC (rev 12665)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py	2014-02-12 03:22:49 UTC (rev 12666)
@@ -1417,7 +1417,6 @@
         """
         delegates = set()
 
-
         # First get the direct delegates
         results = (
             yield self._selectDelegatesQuery.on(
@@ -2213,15 +2212,15 @@
 
 class _EmptyCacher(object):
 
-    def set(self, key, value): #@UnusedVariable
+    def set(self, key, value):
         return succeed(True)
 
 
-    def get(self, key, withIdentifier=False): #@UnusedVariable
+    def get(self, key, withIdentifier=False):
         return succeed(None)
 
 
-    def delete(self, key): #@UnusedVariable
+    def delete(self, key):
         return succeed(True)
 
 
@@ -3579,7 +3578,8 @@
     @classproperty
     def _deleteSyncTokenQuery(cls):
         """
-        DAL query to update a sync revision to be a tombstone instead.
+        DAL query to remove all child revision information. The revision for the collection
+        itself is not touched.
         """
         rev = cls._revisionsSchema
         return Delete(
@@ -3593,7 +3593,7 @@
     @classproperty
     def _sharedRemovalQuery(cls):
         """
-        DAL query to update the sync token for a shared collection.
+        DAL query to indicate a shared collection has been deleted.
         """
         rev = cls._revisionsSchema
         return Update({rev.RESOURCE_ID: None,
@@ -3608,7 +3608,7 @@
     @classproperty
     def _unsharedRemovalQuery(cls):
         """
-        DAL query to update the sync token for an owned collection.
+        DAL query to indicate an owned collection has been deleted.
         """
         rev = cls._revisionsSchema
         return Update({rev.RESOURCE_ID: None,
@@ -3621,6 +3621,14 @@
 
     @inlineCallbacks
     def _deletedSyncToken(self, sharedRemoval=False):
+        """
+        When a collection is deleted we remove all the revision information for its child resources.
+        We update the collection's sync token to indicate it has been deleted - that way a sync on
+        the home collection can report the deletion of the collection.
+
+        @param sharedRemoval: indicates whether the collection being removed is shared
+        @type sharedRemoval: L{bool}
+        """
         # Remove all child entries
         yield self._deleteSyncTokenQuery.on(self._txn,
                                             homeID=self._home._resourceID,
@@ -4431,7 +4439,7 @@
         )
 
         result = []
-        for homeUID, homeRID, resourceID, resourceName, bindMode, bindStatus, bindMessage in acceptedRows: #@UnusedVariable
+        for homeUID, homeRID, _ignore_resourceID, resourceName, bindMode, bindStatus, bindMessage in acceptedRows:
             invite = SharingInvitation(
                 resourceName,
                 self.ownerHome().name(),
@@ -4914,7 +4922,7 @@
             self._notifiers = None
 
 
-    def memoMe(self, key, memo): #@UnusedVariable
+    def memoMe(self, key, memo):
         """
         Add this object to the memo dictionary in whatever fashion is appropriate.
 
@@ -4972,14 +4980,14 @@
 
         # Create the actual objects merging in properties
         for dataRow in dataRows:
-            bindData = dataRow[:cls.bindColumnCount] #@UnusedVariable
+            bindData = dataRow[:cls.bindColumnCount]
             resourceID = bindData[cls.bindColumns().index(cls._bindSchema.RESOURCE_ID)]
             additionalBindData = dataRow[cls.bindColumnCount:cls.bindColumnCount + len(cls.additionalBindColumns())]
             metadataData = dataRow[cls.bindColumnCount + len(cls.additionalBindColumns()):]
             propstore = propertyStores.get(resourceID, None)
 
             child = yield cls.makeClass(home, bindData, additionalBindData, metadataData, propstore)
-            child._syncTokenRevision = revisions.get(resourceID)
+            child._syncTokenRevision = revisions.get(resourceID, 0)
             results.append(child)
 
         returnValue(results)
@@ -5480,7 +5488,7 @@
         )
 
 
-    def _movedObjectResource(self, child, newparent): #@UnusedVariable
+    def _movedObjectResource(self, child, newparent):
         """
         Method that subclasses can override to do an extra DB adjustments when a resource
         is moved.
@@ -6014,7 +6022,7 @@
         returnValue(rows[0] if rows else None)
 
 
-    def __init__(self, parent, name, uid, resourceID=None, options=None): #@UnusedVariable
+    def __init__(self, parent, name, uid, resourceID=None, options=None):
         self._parentCollection = parent
         self._resourceID = resourceID
         self._name = name
@@ -7096,7 +7104,7 @@
             returnValue(None)
 
 
-    def _loadPropertyStore(self, props=None, created=False): #@UnusedVariable
+    def _loadPropertyStore(self, props=None, created=False):
         if props is None:
             props = NonePropertyStore(self._home.uid())
         self._propertyStore = props
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140312/32d0bd51/attachment.html>


More information about the calendarserver-changes mailing list