[CalendarServer-changes] [9320] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Thu May 31 15:50:07 PDT 2012


Revision: 9320
          http://trac.macosforge.org/projects/calendarserver/changeset/9320
Author:   glyph at apple.com
Date:     2012-05-31 15:50:07 -0700 (Thu, 31 May 2012)
Log Message:
-----------
Fix and test for denormalized notification home UUIDs.  Test for denormalized addressbook UUIDs, just in case.

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

Property Changed:
----------------
    CalendarServer/trunk/

Modified: CalendarServer/trunk/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql.py	2012-05-31 21:04:04 UTC (rev 9319)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py	2012-05-31 22:50:07 UTC (rev 9320)
@@ -438,11 +438,11 @@
 
 
     @memoizedKey("uid", "_notificationHomes")
-    def notificationsWithUID(self, uid):
+    def notificationsWithUID(self, uid, create=True):
         """
         Implement notificationsWithUID.
         """
-        return NotificationCollection.notificationsWithUID(self, uid)
+        return NotificationCollection.notificationsWithUID(self, uid, create)
 
     @classproperty
     def _insertAPNSubscriptionQuery(cls): #@NoSelf
@@ -3443,15 +3443,15 @@
 
     @classmethod
     @inlineCallbacks
-    def notificationsWithUID(cls, txn, uid):
+    def notificationsWithUID(cls, txn, uid, create):
         rows = yield cls._resourceIDFromUIDQuery.on(txn, uid=uid)
 
         if rows:
             resourceID = rows[0][0]
             created = False
-        else:
-            # Use savepoint so we can do a partial rollback if there is a race condition
-            # where this row has already been inserted
+        elif create:
+            # Use savepoint so we can do a partial rollback if there is a race
+            # condition where this row has already been inserted
             savepoint = SavepointAction("notificationsWithUID")
             yield savepoint.acquire(txn)
 
@@ -3459,9 +3459,11 @@
                 resourceID = str((
                     yield cls._provisionNewNotificationsQuery.on(txn, uid=uid)
                 )[0][0])
-            except Exception: # FIXME: Really want to trap the pg.DatabaseError but in a non-DB specific manner
+            except Exception:
+                # FIXME: Really want to trap the pg.DatabaseError but in a non-
+                # DB specific manner
                 yield savepoint.rollback(txn)
-                
+
                 # Retry the query - row may exist now, if not re-raise
                 rows = yield cls._resourceIDFromUIDQuery.on(txn, uid=uid)
                 if rows:
@@ -3472,7 +3474,8 @@
             else:
                 created = True
                 yield savepoint.release(txn)
-                
+        else:
+            returnValue(None)
         collection = cls(txn, uid, resourceID)
         yield collection._loadPropertyStore()
         if created:
@@ -4137,10 +4140,7 @@
             homeType=homeTypeName
         )
         other = None
-        if homeType == ENOTIFICATIONTYPE:
-            this = yield t.notificationsWithUID(UID)
-        else:
-            this = yield t.homeWithUID(homeType, UID)
+        this = yield _getHome(t, homeType, UID)
         if homeType == ECALENDARTYPE:
             fixedThisHome = yield fixOneCalendarHome(this)
         else:
@@ -4159,7 +4159,7 @@
                 log_msg(format="Detected case variance: %(uid)s %(newuid)s"
                         "[%(homeType)s]",
                         uid=UID, newuid=newname, homeType=homeTypeName)
-                other = yield t.homeWithUID(homeType, newname)
+                other = yield _getHome(t, homeType, newname)
                 if other is None:
                     # No duplicate: just fix the name.
                     yield _renameHome(t, homeTable, UID, newname)
@@ -4181,6 +4181,30 @@
 
 
 
+def _getHome(txn, homeType, uid):
+    """
+    Like L{CommonHome.homeWithUID} but also honoring ENOTIFICATIONTYPE which
+    isn't I{really} a type of home.
+
+    @param txn: the transaction to retrieve the home from
+    @type txn: L{CommonStoreTransaction}
+
+    @param homeType: L{ENOTIFICATIONTYPE}, L{ECALENDARTYPE}, or
+        L{EADDRESSBOOKTYPE}.
+
+    @param uid: the UID of the home to retrieve.
+    @type uid: L{str}
+
+    @return: a L{Deferred} that fires with the L{CommonHome} or
+        L{NotificationHome} when it has been retrieved.
+    """
+    if homeType == ENOTIFICATIONTYPE:
+        return txn.notificationsWithUID(uid, create=False)
+    else:
+        return txn.homeWithUID(homeType, uid)
+
+
+
 @inlineCallbacks
 def _normalizeColumnUUIDs(txn, column):
     """
@@ -4241,7 +4265,8 @@
     # a lower-case OWNER_UID.  If there are none, then we can early-out and
     # avoid the tedious and potentially expensive inspection of oodles of
     # calendar data.
-    for x in [schema.CALENDAR_HOME, schema.ADDRESSBOOK_HOME]:
+    for x in [schema.CALENDAR_HOME, schema.ADDRESSBOOK_HOME,
+              schema.NOTIFICATION_HOME]:
         slct = Select([x.OWNER_UID], From=x,
                       Where=x.OWNER_UID != Upper(x.OWNER_UID))
         rows = yield slct.on(t)

Modified: CalendarServer/trunk/txdav/common/datastore/test/test_sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/test/test_sql.py	2012-05-31 21:04:04 UTC (rev 9319)
+++ CalendarServer/trunk/txdav/common/datastore/test/test_sql.py	2012-05-31 22:50:07 UTC (rev 9320)
@@ -339,13 +339,12 @@
 
 
     @inlineCallbacks
-    def allHomeUIDs(self):
+    def allHomeUIDs(self, table=schema.CALENDAR_HOME):
         """
         Get a listing of all UIDs in the current store.
         """
-        results = yield Select(
-            [schema.CALENDAR_HOME.OWNER_UID],
-            From=schema.CALENDAR_HOME).on(self.transactionUnderTest())
+        results = yield (Select([table.OWNER_UID], From=table)
+                         .on(self.transactionUnderTest()))
         yield self.commit()
         returnValue(results)
 
@@ -364,6 +363,37 @@
         self.assertEqual((yield self.allHomeUIDs()), [[normalizedUID]])
 
 
+    @inlineCallbacks
+    def test_fixUUIDNormalization_lowerToUpper_notification(self):
+        """
+        L{fixUUIDNormalization} will fix the normalization of UUIDs.  If a home
+        is found with the wrong case but no duplicate, it will simply be
+        upper-cased.
+        """
+        t1 = self.transactionUnderTest()
+        yield t1.notificationsWithUID(denormalizedUID, create=True)
+        yield self.commit()
+        yield fixUUIDNormalization(self.storeUnderTest())
+        self.assertEqual((yield self.allHomeUIDs(schema.NOTIFICATION_HOME)),
+                         [[normalizedUID]])
+
+
+    @inlineCallbacks
+    def test_fixUUIDNormalization_lowerToUpper_addressbook(self):
+        """
+        L{fixUUIDNormalization} will fix the normalization of UUIDs.  If a home
+        is found with the wrong case but no duplicate, it will simply be
+        upper-cased.
+        """
+        t1 = self.transactionUnderTest()
+        yield t1.addressbookHomeWithUID(denormalizedUID, create=True)
+        yield self.commit()
+        yield fixUUIDNormalization(self.storeUnderTest())
+        self.assertEqual((yield self.allHomeUIDs(schema.ADDRESSBOOK_HOME)),
+                         [[normalizedUID]])
+
+
+
 from uuid import UUID
 exampleUID = UUID("a"*32)
 denormalizedUID = str(exampleUID)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120531/367756d4/attachment-0001.html>


More information about the calendarserver-changes mailing list