[CalendarServer-changes] [10939] CalendarServer/branches/users/gaya/sharedgroups/txdav

source_changes at macosforge.org source_changes at macosforge.org
Sat Mar 16 16:47:46 PDT 2013


Revision: 10939
          http://trac.calendarserver.org//changeset/10939
Author:   gaya at apple.com
Date:     2013-03-16 16:47:46 -0700 (Sat, 16 Mar 2013)
Log Message:
-----------
CommonHomeChild.shareWith() tries insert first.  Add AddressBookObject.shareWith()

Modified Paths:
--------------
    CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py
    CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py

Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py	2013-03-16 23:46:55 UTC (rev 10938)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py	2013-03-16 23:47:46 UTC (rev 10939)
@@ -25,11 +25,11 @@
     "AddressBookObject",
 ]
 
+from uuid import uuid4
+
 from twext.enterprise.dal.syntax import Delete, Insert, Len, Parameter, \
     Update, Union, Max, Select, utcNowSQL
-
 from twext.python.clsprop import classproperty
-
 from twext.web2.http import HTTPError
 from twext.web2.http_headers import MimeType
 from twext.web2.responsecode import FORBIDDEN
@@ -54,7 +54,8 @@
     _ABO_KIND_GROUP, _ABO_KIND_RESOURCE, _ABO_KIND_LOCATION, schema, \
     _BIND_MODE_OWN, _BIND_MODE_WRITE, _BIND_STATUS_ACCEPTED, \
     _BIND_STATUS_DECLINED, _BIND_STATUS_INVITED
-from txdav.common.icommondatastore import InternalDataStoreError
+from txdav.common.icommondatastore import InternalDataStoreError, \
+    AllRetriesFailed
 from txdav.xml.rfc2518 import ResourceType
 
 from zope.interface.declarations import implements
@@ -1285,9 +1286,6 @@
             elif self.shareUID():
                 raise SharedGroupDeleteNotAllowedError
 
-        aboMembers = schema.ABO_MEMBERS
-        aboForeignMembers = schema.ABO_FOREIGN_MEMBERS
-
         if not self.owned() and not self._addressbook.fullyShared():
             # convert delete in sharee shared group address book to remove of memberships
             # that make this object visible to the sharee
@@ -1304,6 +1302,9 @@
 
         else:
             # delete members table rows for this object,...
+            aboMembers = schema.ABO_MEMBERS
+            aboForeignMembers = schema.ABO_FOREIGN_MEMBERS
+
             groupIDRows = yield Delete(
                 aboMembers,
                 Where=aboMembers.MEMBER_ID == self._resourceID,
@@ -2105,6 +2106,64 @@
 
 
     @inlineCallbacks
+    def shareWith(self, shareeHome, mode, status=None, message=None):
+        """
+        Share this (owned) L{AddressBookObject} with another home.
+
+        @param shareeHome: The home of the sharee.
+        @type shareeHome: L{CommonHome}
+
+        @param mode: The sharing mode; L{_BIND_MODE_READ} or
+            L{_BIND_MODE_WRITE} or L{_BIND_MODE_DIRECT}
+        @type mode: L{str}
+
+        @param status: The sharing status; L{_BIND_STATUS_INVITED} or
+            L{_BIND_STATUS_ACCEPTED}
+        @type mode: L{str}
+
+        @param message: The proposed message to go along with the share, which
+            will be used as the default display name.
+        @type mode: L{str}
+
+        @return: the name of the shared group in the sharee home.
+        @rtype: L{str}
+        """
+
+        if status is None:
+            status = _BIND_STATUS_ACCEPTED
+
+        @inlineCallbacks
+        def doInsert(subt):
+            newName = str(uuid4())
+            yield self._bindInsertQuery.on(
+                subt, homeID=shareeHome._resourceID,
+                resourceID=self._resourceID, name=newName,
+                mode=mode, bindStatus=status, message=message
+            )
+            returnValue(newName)
+        try:
+            bindName = yield self._txn.subtransaction(doInsert)
+        except AllRetriesFailed:
+            # FIXME: catch more specific exception
+            groupBindRows = yield self._bindForResourceIDAndHomeID.on(
+                self._txn, resourceID=self._resourceID, homeID=shareeHome._resourceID
+            )
+            bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = groupBindRows[0] #@UnusedVariable
+            if bindStatus == _BIND_STATUS_ACCEPTED:
+                group = yield shareeHome.objectForShareUID(bindName)
+            else:
+                group = yield shareeHome.invitedObjectForShareUID(bindName)
+            bindName = yield self.updateShare(
+                group, mode=mode, status=status,
+                message=message
+            )
+
+        # Must send notification to ensure cache invalidation occurs
+        yield self.notifyChanged()
+
+        returnValue(bindName)
+
+    @inlineCallbacks
     #TODO:  This is almost the same as AddressBook.updateShare(): combine
     def updateShare(self, shareeView, mode=None, status=None, message=None, name=None):
         """

Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py	2013-03-16 23:46:55 UTC (rev 10938)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py	2013-03-16 23:47:46 UTC (rev 10939)
@@ -2473,6 +2473,15 @@
         })
 
 
+    @classmethod
+    def _updateBindColumnsQuery(cls, columnMap):
+        bind = cls._bindSchema
+        return Update(columnMap,
+                      Where=(bind.RESOURCE_ID == Parameter("resourceID"))
+                      .And(bind.HOME_RESOURCE_ID == Parameter("homeID")),
+                      Return=bind.RESOURCE_NAME)
+
+
     @classproperty
     def _updateBindQuery(cls): #@NoSelf
         bind = cls._bindSchema
@@ -2482,6 +2491,17 @@
                      bind.MESSAGE: Parameter("message")})
 
 
+    @classproperty
+    def _deleteBindWithResourceIDAndHomeID(cls): #@NoSelf
+        bind = cls._bindSchema
+        return Delete(
+            From=bind,
+            Where=(bind.RESOURCE_ID == Parameter("resourceID"))
+                  .And(bind.HOME_RESOURCE_ID == Parameter("homeID")),
+            Return=bind.RESOURCE_NAME,
+        )
+
+
     @classmethod
     def _bindColumns(cls):
         bind = cls._bindSchema
@@ -2577,19 +2597,26 @@
         if status is None:
             status = _BIND_STATUS_ACCEPTED
 
-        child = yield shareeHome.childWithID(self._resourceID)
-        if child:
+        @inlineCallbacks
+        def doInsert(subt):
+            newName = str(uuid4())
+            yield self._bindInsertQuery.on(
+                subt, homeID=shareeHome._resourceID,
+                resourceID=self._resourceID, name=newName,
+                mode=mode, bindStatus=status, message=message
+            )
+            returnValue(newName)
+        try:
+            bindName = yield self._txn.subtransaction(doInsert)
+        except AllRetriesFailed:
+            # FIXME: catch more specific exception
+            child = yield shareeHome.childWithID(self._resourceID)
+            if not child:
+                child = yield shareeHome.objectWithID(shareeHome, self._resourceID, accepted=False)
             bindName = yield self.updateShare(
                 child, mode=mode, status=status,
                 message=message
             )
-        else:
-            bindName = str(uuid4())
-            yield self._bindInsertQuery.on(
-                self._txn, homeID=shareeHome._resourceID,
-                resourceID=self._resourceID, name=bindName,
-                mode=mode, bindStatus=status, message=message
-            )
 
         # Must send notification to ensure cache invalidation occurs
         yield self.notifyChanged()
@@ -2597,15 +2624,6 @@
         returnValue(bindName)
 
 
-    @classmethod
-    def _updateBindColumnsQuery(cls, columnMap):
-        bind = cls._bindSchema
-        return Update(columnMap,
-                      Where=(bind.RESOURCE_ID == Parameter("resourceID"))
-                      .And(bind.HOME_RESOURCE_ID == Parameter("homeID")),
-                      Return=bind.RESOURCE_NAME)
-
-
     @inlineCallbacks
     def updateShare(self, shareeView, mode=None, status=None, message=None, name=None):
         """
@@ -2684,17 +2702,6 @@
         returnValue(shareeView._name)
 
 
-    @classproperty
-    def _deleteBindWithResourceIDAndHomeID(cls): #@NoSelf
-        bind = cls._bindSchema
-        return Delete(
-            From=bind,
-            Where=(bind.RESOURCE_ID == Parameter("resourceID"))
-                  .And(bind.HOME_RESOURCE_ID == Parameter("homeID")),
-            Return=bind.RESOURCE_NAME,
-        )
-
-
     @inlineCallbacks
     def unshareWith(self, shareeHome):
         """
@@ -2921,7 +2928,7 @@
         self._index = None  # Derived classes need to set this
 
 
-    def memoMe(self, key, memo):
+    def memoMe(self, key, memo): #@UnusedVariable
         """
         Add this object to the memo dictionary in whatever fashion is appropriate.
 
@@ -3107,7 +3114,10 @@
         if not rows:
             returnValue(None)
 
-        bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = rows[0] #@UnusedVariable
+        bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = rows[0] #@UnusedVariable]
+        if (bindStatus == _BIND_STATUS_ACCEPTED) != bool(accepted):
+            returnValue(None)
+
         if accepted:
             returnValue((yield home.objectWithShareUID(bindName)))
         else:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130316/74c311c0/attachment-0001.html>


More information about the calendarserver-changes mailing list