[CalendarServer-changes] [9219] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Wed May 2 08:47:10 PDT 2012
Revision: 9219
http://trac.macosforge.org/projects/calendarserver/changeset/9219
Author: glyph at apple.com
Date: 2012-05-02 08:47:09 -0700 (Wed, 02 May 2012)
Log Message:
-----------
if the calendar is already shared, change the sharing mode when shareWith is called again.
Modified Paths:
--------------
CalendarServer/trunk/txdav/caldav/datastore/test/common.py
CalendarServer/trunk/txdav/common/datastore/sql.py
Property Changed:
----------------
CalendarServer/trunk/
Modified: CalendarServer/trunk/txdav/caldav/datastore/test/common.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/test/common.py 2012-05-01 21:05:31 UTC (rev 9218)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/common.py 2012-05-02 15:47:09 UTC (rev 9219)
@@ -43,7 +43,7 @@
from txdav.common.icommondatastore import ObjectResourceNameAlreadyExistsError
from txdav.common.inotifications import INotificationObject
from txdav.common.datastore.test.util import CommonCommonTests
-from txdav.common.datastore.sql_tables import _BIND_MODE_WRITE
+from txdav.common.datastore.sql_tables import _BIND_MODE_WRITE, _BIND_MODE_READ
from txdav.caldav.icalendarstore import (
ICalendarObject, ICalendarHome,
@@ -1014,6 +1014,28 @@
@inlineCallbacks
+ def test_shareAgainChangesMode(self):
+ """
+ If a calendar is already shared with a given calendar home,
+ L{ICalendar.shareWith} will change the sharing mode.
+ """
+ yield self.test_shareWith()
+ # yield self.commit() # txn is none? why?
+ OTHER_HOME_UID = "home_splits"
+ cal = yield self.calendarUnderTest()
+ other = yield self.homeUnderTest(name=OTHER_HOME_UID)
+ newName = yield cal.shareWith(other, _BIND_MODE_READ)
+ otherCal = yield other.sharedChildWithName(newName)
+ self.assertNotIdentical(otherCal, None)
+
+ # FIXME: permission information should be visible on the retrieved
+ # calendar object, we shoudln't need to go via the legacy API.
+ invites = yield cal.retrieveOldInvites().allRecords()
+ self.assertEqual(len(invites), 1)
+ self.assertEqual(invites[0].access, "read-only")
+
+
+ @inlineCallbacks
def test_hasCalendarResourceUIDSomewhereElse(self):
"""
L{ICalendarHome.hasCalendarResourceUIDSomewhereElse} will determine if
Modified: CalendarServer/trunk/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql.py 2012-05-01 21:05:31 UTC (rev 9218)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py 2012-05-02 15:47:09 UTC (rev 9219)
@@ -552,16 +552,22 @@
object to execute SQL on.
@param thunk: a 1-argument callable which returns a Deferred when it is
- done. If this Deferred fails,
+ done. If this Deferred fails, the sub-transaction will be rolled
+ back.
+ @type thunk: L{callable}
@param retries: the number of times to re-try C{thunk} before deciding
that it's legitimately failed.
+ @type retries: L{int}
@param failureOK: it is OK if this subtransaction fails so do not log.
+ @type failureOK: L{bool}
@return: a L{Deferred} which fires or fails according to the logic in
C{thunk}. If it succeeds, it will return the value that C{thunk}
- returned.
+ returned. If C{thunk} fails or raises an exception more than
+ C{retries} times, then the L{Deferred} resulting from
+ C{subtransaction} will fail with L{AllRetriesFailed}.
"""
# Right now this code is covered mostly by the automated property store
# tests. It should have more direct test coverage.
@@ -1958,6 +1964,18 @@
)
+ @classproperty
+ def _updateBindQuery(cls): #@NoSelf
+ bind = cls._bindSchema
+ return Update({bind.BIND_MODE: Parameter("mode"),
+ bind.BIND_STATUS: Parameter("status"),
+ bind.MESSAGE: Parameter("message")},
+ Where=
+ (bind.RESOURCE_ID == Parameter("resourceID"))
+ .And(bind.HOME_RESOURCE_ID == Parameter("homeID")),
+ Return=bind.RESOURCE_NAME)
+
+
@inlineCallbacks
def shareWith(self, shareeHome, mode):
"""
@@ -1977,22 +1995,37 @@
dnprop = (self.properties().get(dn) or
DisplayName.fromString(self.name()))
# FIXME: honor current home type
- newName = str(uuid4())
- yield self._bindInsertQuery.on(
- self._txn, homeID=shareeHome._resourceID,
- resourceID=self._resourceID, name=newName, mode=mode,
- seenByOwner=True, seenBySharee=True,
- bindStatus=_BIND_STATUS_ACCEPTED,
- )
- yield self._insertInviteQuery.on(
- self._txn, uid=newName, name=str(dnprop),
- homeID=shareeHome._resourceID, resourceID=self._resourceID,
- recipient=shareeHome.uid()
- )
+ @inlineCallbacks
+ def doInsert(subt):
+ newName = str(uuid4())
+ yield self._bindInsertQuery.on(
+ subt, homeID=shareeHome._resourceID,
+ resourceID=self._resourceID, name=newName, mode=mode,
+ seenByOwner=True, seenBySharee=True,
+ bindStatus=_BIND_STATUS_ACCEPTED,
+ )
+ yield self._insertInviteQuery.on(
+ subt, uid=newName, name=str(dnprop),
+ homeID=shareeHome._resourceID, resourceID=self._resourceID,
+ recipient=shareeHome.uid()
+ )
+ returnValue(newName)
+ try:
+ sharedName = yield self._txn.subtransaction(doInsert)
+ except AllRetriesFailed:
+ # FIXME: catch more specific exception
+ sharedName = (yield self._updateBindQuery.on(
+ self._txn,
+ mode=mode, status=_BIND_STATUS_ACCEPTED, message=None,
+ resourceID=self._resourceID, homeID=shareeHome._resourceID
+ ))[0][0]
+ # Invite already exists; no need to update it, since the name will
+ # remain the same.
+
shareeProps = yield PropertyStore.load(shareeHome.uid(), self._txn,
self._resourceID)
shareeProps[dn] = dnprop
- returnValue(newName)
+ returnValue(sharedName)
@classmethod
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120502/2c05e2e6/attachment.html>
More information about the calendarserver-changes
mailing list