[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