[CalendarServer-changes] [11193] CalendarServer/branches/users/gaya/sharedgroups-3
source_changes at macosforge.org
source_changes at macosforge.org
Wed May 15 15:34:00 PDT 2013
Revision: 11193
http://trac.calendarserver.org//changeset/11193
Author: gaya at apple.com
Date: 2013-05-15 15:34:00 -0700 (Wed, 15 May 2013)
Log Message:
-----------
merge from 11192
Modified Paths:
--------------
CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/customxml.py
CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/extensions.py
CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/method/report_sync_collection.py
CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/resource.py
CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/stdconfig.py
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/base/propertystore/sql.py
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/sql.py
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/test/common.py
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/test/test_attachments.py
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/test/test_sql.py
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/carddav/datastore/sql.py
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/file.py
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql.py
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/current-oracle-dialect.sql
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/current.sql
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/old/oracle-dialect/v19.sql
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/old/postgres-dialect/v19.sql
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_18_to_19.sql
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/upgrades/postgres-dialect/upgrade_from_18_to_19.sql
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/upgrade/sql/upgrade.py
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_3_to_4.py
Property Changed:
----------------
CalendarServer/branches/users/gaya/sharedgroups-3/
CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql.py
Property changes on: CalendarServer/branches/users/gaya/sharedgroups-3
___________________________________________________________________
Modified: svn:mergeinfo
- /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/generic-sqlstore:6167-6191
/CalendarServer/branches/new-store:5594-5934
/CalendarServer/branches/new-store-no-caldavfile:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2:5936-5981
/CalendarServer/branches/release/CalendarServer-4.3-dev:10180-10190,10192
/CalendarServer/branches/users/cdaboo/batchupload-6699:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692:5693-5702
/CalendarServer/branches/users/cdaboo/component-set-fixes:8130-8346
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/implicituidrace:8137-8141
/CalendarServer/branches/users/cdaboo/ischedule-dkim:9747-9979
/CalendarServer/branches/users/cdaboo/managed-attachments:9985-10145
/CalendarServer/branches/users/cdaboo/more-sharing-5591:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/cdaboo/pods:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar:7085-7206
/CalendarServer/branches/users/cdaboo/pycard:7227-7237
/CalendarServer/branches/users/cdaboo/queued-attendee-refreshes:7740-8287
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187:5188-5440
/CalendarServer/branches/users/cdaboo/store-scheduling:10876-11129
/CalendarServer/branches/users/cdaboo/timezones:7443-7699
/CalendarServer/branches/users/cdaboo/txn-debugging:8730-8743
/CalendarServer/branches/users/glyph/always-abort-txn-on-error:9958-9969
/CalendarServer/branches/users/glyph/case-insensitive-uid:8772-8805
/CalendarServer/branches/users/glyph/conn-limit:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge:4971-5080
/CalendarServer/branches/users/glyph/dalify:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect:6824-6876
/CalendarServer/branches/users/glyph/deploybuild:7563-7572
/CalendarServer/branches/users/glyph/digest-auth-redux:10624-10635
/CalendarServer/branches/users/glyph/disable-quota:7718-7727
/CalendarServer/branches/users/glyph/dont-start-postgres:6592-6614
/CalendarServer/branches/users/glyph/imip-and-admin-html:7866-7984
/CalendarServer/branches/users/glyph/ipv6-client:9054-9105
/CalendarServer/branches/users/glyph/linux-tests:6893-6900
/CalendarServer/branches/users/glyph/migrate-merge:8690-8713
/CalendarServer/branches/users/glyph/misc-portability-fixes:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7:6369-6445
/CalendarServer/branches/users/glyph/multiget-delete:8321-8330
/CalendarServer/branches/users/glyph/new-export:7444-7485
/CalendarServer/branches/users/glyph/one-home-list-api:10048-10073
/CalendarServer/branches/users/glyph/oracle:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls:7340-7351
/CalendarServer/branches/users/glyph/other-html:8062-8091
/CalendarServer/branches/users/glyph/parallel-sim:8240-8251
/CalendarServer/branches/users/glyph/parallel-upgrade:8376-8400
/CalendarServer/branches/users/glyph/parallel-upgrade_to_1:8571-8583
/CalendarServer/branches/users/glyph/q:9560-9688
/CalendarServer/branches/users/glyph/queue-locking-and-timing:10204-10289
/CalendarServer/branches/users/glyph/quota:7604-7637
/CalendarServer/branches/users/glyph/sendfdport:5388-5424
/CalendarServer/branches/users/glyph/shared-pool-fixes:8436-8443
/CalendarServer/branches/users/glyph/shared-pool-take2:8155-8174
/CalendarServer/branches/users/glyph/sharedpool:6490-6550
/CalendarServer/branches/users/glyph/sharing-api:9192-9205
/CalendarServer/branches/users/glyph/skip-lonely-vtimezones:8524-8535
/CalendarServer/branches/users/glyph/sql-store:5929-6073
/CalendarServer/branches/users/glyph/start-service-start-loop:11060-11065
/CalendarServer/branches/users/glyph/subtransactions:7248-7258
/CalendarServer/branches/users/glyph/table-alias:8651-8664
/CalendarServer/branches/users/glyph/uidexport:7673-7676
/CalendarServer/branches/users/glyph/unshare-when-access-revoked:10562-10595
/CalendarServer/branches/users/glyph/use-system-twisted:5084-5149
/CalendarServer/branches/users/glyph/uuid-normalize:9268-9296
/CalendarServer/branches/users/glyph/xattrs-from-files:7757-7769
/CalendarServer/branches/users/sagen/applepush:8126-8184
/CalendarServer/branches/users/sagen/inboxitems:7380-7381
/CalendarServer/branches/users/sagen/locations-resources:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
/CalendarServer/branches/users/sagen/resources-2:5084-5093
/CalendarServer/branches/users/sagen/testing:10827-10851,10853-10855
/CalendarServer/branches/users/wsanchez/transations:5515-5593
/CalendarServer/trunk:11090-11095,11097-11111,11115-11174
+ /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/generic-sqlstore:6167-6191
/CalendarServer/branches/new-store:5594-5934
/CalendarServer/branches/new-store-no-caldavfile:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2:5936-5981
/CalendarServer/branches/release/CalendarServer-4.3-dev:10180-10190,10192
/CalendarServer/branches/users/cdaboo/batchupload-6699:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692:5693-5702
/CalendarServer/branches/users/cdaboo/component-set-fixes:8130-8346
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/implicituidrace:8137-8141
/CalendarServer/branches/users/cdaboo/ischedule-dkim:9747-9979
/CalendarServer/branches/users/cdaboo/managed-attachments:9985-10145
/CalendarServer/branches/users/cdaboo/more-sharing-5591:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/cdaboo/pods:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar:7085-7206
/CalendarServer/branches/users/cdaboo/pycard:7227-7237
/CalendarServer/branches/users/cdaboo/queued-attendee-refreshes:7740-8287
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187:5188-5440
/CalendarServer/branches/users/cdaboo/store-scheduling:10876-11129
/CalendarServer/branches/users/cdaboo/timezones:7443-7699
/CalendarServer/branches/users/cdaboo/txn-debugging:8730-8743
/CalendarServer/branches/users/glyph/always-abort-txn-on-error:9958-9969
/CalendarServer/branches/users/glyph/case-insensitive-uid:8772-8805
/CalendarServer/branches/users/glyph/conn-limit:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge:4971-5080
/CalendarServer/branches/users/glyph/dalify:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect:6824-6876
/CalendarServer/branches/users/glyph/deploybuild:7563-7572
/CalendarServer/branches/users/glyph/digest-auth-redux:10624-10635
/CalendarServer/branches/users/glyph/disable-quota:7718-7727
/CalendarServer/branches/users/glyph/dont-start-postgres:6592-6614
/CalendarServer/branches/users/glyph/imip-and-admin-html:7866-7984
/CalendarServer/branches/users/glyph/ipv6-client:9054-9105
/CalendarServer/branches/users/glyph/linux-tests:6893-6900
/CalendarServer/branches/users/glyph/migrate-merge:8690-8713
/CalendarServer/branches/users/glyph/misc-portability-fixes:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7:6369-6445
/CalendarServer/branches/users/glyph/multiget-delete:8321-8330
/CalendarServer/branches/users/glyph/new-export:7444-7485
/CalendarServer/branches/users/glyph/one-home-list-api:10048-10073
/CalendarServer/branches/users/glyph/oracle:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls:7340-7351
/CalendarServer/branches/users/glyph/other-html:8062-8091
/CalendarServer/branches/users/glyph/parallel-sim:8240-8251
/CalendarServer/branches/users/glyph/parallel-upgrade:8376-8400
/CalendarServer/branches/users/glyph/parallel-upgrade_to_1:8571-8583
/CalendarServer/branches/users/glyph/q:9560-9688
/CalendarServer/branches/users/glyph/queue-locking-and-timing:10204-10289
/CalendarServer/branches/users/glyph/quota:7604-7637
/CalendarServer/branches/users/glyph/sendfdport:5388-5424
/CalendarServer/branches/users/glyph/shared-pool-fixes:8436-8443
/CalendarServer/branches/users/glyph/shared-pool-take2:8155-8174
/CalendarServer/branches/users/glyph/sharedpool:6490-6550
/CalendarServer/branches/users/glyph/sharing-api:9192-9205
/CalendarServer/branches/users/glyph/skip-lonely-vtimezones:8524-8535
/CalendarServer/branches/users/glyph/sql-store:5929-6073
/CalendarServer/branches/users/glyph/start-service-start-loop:11060-11065
/CalendarServer/branches/users/glyph/subtransactions:7248-7258
/CalendarServer/branches/users/glyph/table-alias:8651-8664
/CalendarServer/branches/users/glyph/uidexport:7673-7676
/CalendarServer/branches/users/glyph/unshare-when-access-revoked:10562-10595
/CalendarServer/branches/users/glyph/use-system-twisted:5084-5149
/CalendarServer/branches/users/glyph/uuid-normalize:9268-9296
/CalendarServer/branches/users/glyph/xattrs-from-files:7757-7769
/CalendarServer/branches/users/sagen/applepush:8126-8184
/CalendarServer/branches/users/sagen/inboxitems:7380-7381
/CalendarServer/branches/users/sagen/locations-resources:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
/CalendarServer/branches/users/sagen/resources-2:5084-5093
/CalendarServer/branches/users/sagen/testing:10827-10851,10853-10855
/CalendarServer/branches/users/wsanchez/transations:5515-5593
/CalendarServer/trunk:11090-11095,11097-11111,11115-11192
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/customxml.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/customxml.py 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/customxml.py 2013-05-15 22:34:00 UTC (rev 11193)
@@ -72,7 +72,11 @@
"calendarserver-partstat-changes",
)
+calendarserver_home_sync_compliance = (
+ "calendarserver-home-sync",
+)
+
@registerElement
class TwistedCalendarSupportedComponents (WebDAVTextElement):
"""
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/extensions.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/extensions.py 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/extensions.py 2013-05-15 22:34:00 UTC (rev 11193)
@@ -535,24 +535,6 @@
-def updateCacheTokenOnCallback(f):
- def wrapper(self, *args, **kwargs):
- if hasattr(self, "notifyChanged"):
- def updateToken(response):
- d = self.notifyChanged()
- d.addCallback(lambda _: response)
- return d
-
- d = maybeDeferred(f, self, *args, **kwargs)
- d.addCallback(updateToken)
- return d
- else:
- return f(self, *args, **kwargs)
-
- return wrapper
-
-
-
class DAVResource (DirectoryPrincipalPropertySearchMixIn,
SuperDAVResource, LoggingMixIn,
DirectoryRenderingMixIn, StaticRenderMixin):
@@ -563,20 +545,6 @@
that is currently in static.py but is actually applicable to any type of resource.
"""
- @updateCacheTokenOnCallback
- def http_PROPPATCH(self, request):
- return super(DAVResource, self).http_PROPPATCH(request)
-
-
- @updateCacheTokenOnCallback
- def http_DELETE(self, request):
- return super(DAVResource, self).http_DELETE(request)
-
-
- @updateCacheTokenOnCallback
- def http_ACL(self, request):
- return super(DAVResource, self).http_ACL(request)
-
http_REPORT = http_REPORT
def davComplianceClasses(self):
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/method/report_sync_collection.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/method/report_sync_collection.py 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/method/report_sync_collection.py 2013-05-15 22:34:00 UTC (rev 11193)
@@ -46,7 +46,7 @@
"""
Generate a sync-collection REPORT.
"""
-
+
# These resource support the report
if not config.EnableSyncReport or element.Report(element.SyncCollection(),) not in self.supportedReports():
log.err("sync-collection report is only allowed on calendar/inbox/addressbook/notification collection resources %s" % (self,))
@@ -55,24 +55,26 @@
element.SupportedReport(),
"Report not supported on this resource",
))
-
+
responses = []
# Process Depth and sync-level for backwards compatibility
# Use sync-level if present and ignore Depth, else use Depth
if sync_collection.sync_level:
depth = sync_collection.sync_level
+ if depth == "infinite":
+ depth = "infinity"
descriptor = "DAV:sync-level"
else:
depth = request.headers.getHeader("depth", None)
descriptor = "Depth header without DAV:sync-level"
-
+
if depth not in ("1", "infinity"):
log.err("sync-collection report with invalid depth header: %s" % (depth,))
raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, "Invalid %s value" % (descriptor,)))
-
- propertyreq = sync_collection.property.children if sync_collection.property else None
-
+
+ propertyreq = sync_collection.property.children if sync_collection.property else None
+
@inlineCallbacks
def _namedPropertiesForResource(request, props, resource, forbidden=False):
"""
@@ -87,7 +89,7 @@
responsecode.FORBIDDEN : [],
responsecode.NOT_FOUND : [],
}
-
+
for property in props:
if isinstance(property, element.WebDAVElement):
qname = property.qname()
@@ -106,13 +108,14 @@
f = Failure()
log.err("Error reading property %r for resource %s: %s" % (qname, request.uri, f.value))
status = statusForFailure(f, "getting property: %s" % (qname,))
- if status not in properties_by_status: properties_by_status[status] = []
+ if status not in properties_by_status:
+ properties_by_status[status] = []
properties_by_status[status].append(propertyName(qname))
else:
properties_by_status[responsecode.NOT_FOUND].append(propertyName(qname))
-
+
returnValue(properties_by_status)
-
+
# Do some optimization of access control calculation by determining any inherited ACLs outside of
# the child resource loop and supply those to the checkPrivileges on each child.
filteredaces = (yield self.inheritedACEsforChildren(request))
@@ -173,11 +176,11 @@
for name in removed:
href = element.HRef.fromString(joinURL(request.uri, name))
responses.append(element.StatusResponse(element.HRef.fromString(href), element.Status.fromResponseCode(responsecode.NOT_FOUND)))
-
+
for name in notallowed:
href = element.HRef.fromString(joinURL(request.uri, name))
responses.append(element.StatusResponse(element.HRef.fromString(href), element.Status.fromResponseCode(responsecode.NOT_ALLOWED)))
-
+
if not hasattr(request, "extendedLogItems"):
request.extendedLogItems = {}
request.extendedLogItems["responses"] = len(responses)
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/resource.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/resource.py 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/resource.py 2013-05-15 22:34:00 UTC (rev 11193)
@@ -202,22 +202,7 @@
calendarPrivilegeSet = _calendarPrivilegeSet()
-def updateCacheTokenOnCallback(f):
- def fun(self, *args, **kwargs):
- def _updateToken(response):
- return self.notifyChanged().addCallback(lambda _: response)
- d = maybeDeferred(f, self, *args, **kwargs)
-
- if hasattr(self, 'notifyChanged'):
- d.addCallback(_updateToken)
-
- return d
-
- return fun
-
-
-
class CalDAVResource (
CalDAVComplianceMixIn, SharedResourceMixin,
DAVResourceWithChildrenMixin, DAVResource, LoggingMixIn
@@ -391,21 +376,6 @@
# End transitional new-store interface
- @updateCacheTokenOnCallback
- def http_PROPPATCH(self, request):
- return super(CalDAVResource, self).http_PROPPATCH(request)
-
-
- @updateCacheTokenOnCallback
- def http_DELETE(self, request):
- return super(CalDAVResource, self).http_DELETE(request)
-
-
- @updateCacheTokenOnCallback
- def http_ACL(self, request):
- return super(CalDAVResource, self).http_ACL(request)
-
-
##
# WebDAV
##
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/stdconfig.py 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/twistedcaldav/stdconfig.py 2013-05-15 22:34:00 UTC (rev 11193)
@@ -1542,6 +1542,9 @@
compliance += customxml.calendarserver_principal_property_search_compliance
compliance += customxml.calendarserver_principal_search_compliance
+ # Home Depth:1 sync report will include WebDAV property changes on home child resources
+ compliance += customxml.calendarserver_home_sync_compliance
+
configDict.CalDAVComplianceClasses = compliance
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/base/propertystore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/base/propertystore/sql.py 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/base/propertystore/sql.py 2013-05-15 22:34:00 UTC (rev 11193)
@@ -250,9 +250,12 @@
name=key_str, uid=uid)
self._cacher.delete(str(self._resourceID))
- # Call the registered notification callback
+ # Call the registered notification callback - we need to do this as a preCommit since it involves
+ # a bunch of deferred operations, but this propstore api is not deferred. preCommit will execute
+ # the deferreds properly, and it is fine to wait until everything else is done before sending the
+ # notifications.
if hasattr(self, "_notifyCallback") and self._notifyCallback is not None:
- self._notifyCallback()
+ self._txn.preCommit(self._notifyCallback)
def justLogIt(f):
f.trap(AllRetriesFailed)
@@ -278,6 +281,14 @@
name=key_str, uid=uid
)
self._cacher.delete(str(self._resourceID))
+
+ # Call the registered notification callback - we need to do this as a preCommit since it involves
+ # a bunch of deferred operations, but this propstore api is not deferred. preCommit will execute
+ # the deferreds properly, and it is fine to wait until everything else is done before sending the
+ # notifications.
+ if hasattr(self, "_notifyCallback") and self._notifyCallback is not None:
+ self._txn.preCommit(self._notifyCallback)
+
def justLogIt(f):
f.trap(AllRetriesFailed)
self.log_error("setting a property failed; probably nothing.")
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/sql.py 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/sql.py 2013-05-15 22:34:00 UTC (rev 11193)
@@ -624,11 +624,8 @@
pick another from the calendar home.
"""
- chm = self._homeMetaDataSchema
componentType = "VTODO" if tasks else "VEVENT"
test_name = "tasks" if tasks else "calendar"
- attribute_to_test = "_default_tasks" if tasks else "_default_events"
- column_to_set = chm.DEFAULT_TASKS if tasks else chm.DEFAULT_EVENTS
defaultCalendar = (yield self.calendarWithName(test_name))
if defaultCalendar is None or not defaultCalendar.owned():
@@ -657,13 +654,7 @@
# Failed to even create a default - bad news...
raise RuntimeError("No valid calendars to use as a default %s calendar." % (componentType,))
- setattr(self, attribute_to_test, defaultCalendar._resourceID)
- yield Update(
- {column_to_set: defaultCalendar._resourceID},
- Where=chm.RESOURCE_ID == self._resourceID,
- ).on(self._txn)
- yield self.invalidateQueryCache()
- yield self.notifyChanged()
+ yield self.setDefaultCalendar(defaultCalendar, tasks)
returnValue(defaultCalendar)
@@ -701,7 +692,12 @@
yield self.invalidateQueryCache()
yield self.notifyChanged()
+ # CalDAV stores the default calendar properties on the inbox so we also need to send a changed notification on that
+ inbox = (yield self.calendarWithName("inbox"))
+ if inbox is not None:
+ yield inbox.notifyChanged()
+
@inlineCallbacks
def defaultCalendar(self, componentType, create=True):
"""
@@ -761,14 +757,7 @@
yield default.setSupportedComponents(componentType.upper())
# Update the metadata
- chm = self._homeMetaDataSchema
- column_to_set = chm.DEFAULT_TASKS if componentType == "VTODO" else chm.DEFAULT_EVENTS
- setattr(self, attribute_to_test, default._resourceID)
- yield Update(
- {column_to_set: default._resourceID},
- Where=chm.RESOURCE_ID == self._resourceID,
- ).on(self._txn)
- yield self.invalidateQueryCache()
+ yield self.setDefaultCalendar(default, componentType == "VTODO")
returnValue(default)
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/test/common.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/test/common.py 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/test/common.py 2013-05-15 22:34:00 UTC (rev 11193)
@@ -1733,15 +1733,16 @@
home = yield self.homeUnderTest()
changed, deleted = yield home.resourceNamesSinceToken(
- self.token2revision(st), "depth_is_ignored")
+ self.token2revision(st), "infinity")
- self.assertEquals(set(changed), set(["calendar_1/new.ics",
+ self.assertEquals(set(changed), set(["calendar_1/",
+ "calendar_1/new.ics",
"calendar_1/2.ics",
"other-calendar/"]))
self.assertEquals(set(deleted), set(["calendar_1/2.ics"]))
changed, deleted = yield home.resourceNamesSinceToken(
- self.token2revision(st2), "depth_is_ignored")
+ self.token2revision(st2), "infinity")
self.assertEquals(changed, [])
self.assertEquals(deleted, [])
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/test/test_attachments.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/test/test_attachments.py 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/test/test_attachments.py 2013-05-15 22:34:00 UTC (rev 11193)
@@ -14,7 +14,7 @@
# limitations under the License.
##
-from calendarserver.tap.util import getRootResource, directoryFromConfig
+from calendarserver.tap.util import directoryFromConfig
from pycalendar.datetime import PyCalendarDateTime
from pycalendar.value import PyCalendarValue
@@ -1404,10 +1404,7 @@
self._sqlCalendarStore = yield buildCalendarStore(self, self.notifierFactory, directoryFromConfig(config))
yield self.populate()
- self.rootResource = getRootResource(config, self._sqlCalendarStore)
- self.directory = self._sqlCalendarStore.directoryService()
-
@inlineCallbacks
def populate(self):
yield populateCalendarsFrom(self.requirements, self.storeUnderTest())
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/test/test_sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/test/test_sql.py 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/caldav/datastore/test/test_sql.py 2013-05-15 22:34:00 UTC (rev 11193)
@@ -38,8 +38,9 @@
from twistedcaldav.query import calendarqueryfilter
from txdav.base.propertystore.base import PropertyName
+from txdav.caldav.datastore.sql import Calendar
from txdav.caldav.datastore.test.common import CommonTests as CalendarCommonTests, \
- test_event_text
+ test_event_text, OTHER_HOME_UID
from txdav.caldav.datastore.test.test_file import setUpCalendarStore
from txdav.caldav.datastore.test.util import buildCalendarStore
from txdav.caldav.datastore.util import _migrateCalendar, migrateHome
@@ -47,7 +48,7 @@
from txdav.common.datastore.sql import ECALENDARTYPE, CommonObjectResource
from txdav.common.datastore.sql_legacy import PostgresLegacyIndexEmulator
from txdav.common.datastore.sql_tables import schema, _BIND_MODE_DIRECT, \
- _BIND_STATUS_ACCEPTED
+ _BIND_STATUS_ACCEPTED, _BIND_MODE_WRITE, _BIND_STATUS_INVITED
from txdav.common.datastore.test.util import populateCalendarsFrom
from txdav.common.icommondatastore import NoSuchObjectResourceError
from txdav.xml.rfc2518 import GETContentLanguage, ResourceType
@@ -1046,7 +1047,7 @@
children = yield calendar1.listCalendarObjects()
self.assertEqual(len(children), 3)
new_sync_token1 = yield calendar1.syncToken()
- self.assertEqual(new_sync_token1, original_sync_token1)
+ self.assertNotEqual(new_sync_token1, original_sync_token1)
result = yield calendar1.getSupportedComponents()
self.assertEquals(result, "VEVENT")
@@ -1692,3 +1693,87 @@
self.assertEquals(alarm_result, None)
yield self.commit()
+
+
+ @inlineCallbacks
+ def test_shareWithRevision(self):
+ """
+ Verify that bindRevision on calendars and shared calendars has the correct value.
+ """
+ cal = yield self.calendarUnderTest()
+ self.assertEqual(cal._bindRevision, 0)
+ other = yield self.homeUnderTest(name=OTHER_HOME_UID)
+ newCalName = yield cal.shareWith(other, _BIND_MODE_WRITE)
+ yield self.commit()
+
+ normalCal = yield self.calendarUnderTest()
+ self.assertEqual(normalCal._bindRevision, 0)
+ otherHome = yield self.homeUnderTest(name=OTHER_HOME_UID)
+ otherCal = yield otherHome.childWithName(newCalName)
+ self.assertNotEqual(otherCal._bindRevision, 0)
+
+
+ @inlineCallbacks
+ def test_updateShareRevision(self):
+ """
+ Verify that bindRevision on calendars and shared calendars has the correct value.
+ """
+ cal = yield self.calendarUnderTest()
+ self.assertEqual(cal._bindRevision, 0)
+ other = yield self.homeUnderTest(name=OTHER_HOME_UID)
+ newCalName = yield cal.shareWith(other, _BIND_MODE_WRITE, status=_BIND_STATUS_INVITED)
+ yield self.commit()
+
+ normalCal = yield self.calendarUnderTest()
+ self.assertEqual(normalCal._bindRevision, 0)
+ otherHome = yield self.homeUnderTest(name=OTHER_HOME_UID)
+ otherCal = yield otherHome.invitedObjectWithShareUID(newCalName)
+ self.assertEqual(otherCal._bindRevision, 0)
+ yield self.commit()
+
+ normalCal = yield self.calendarUnderTest()
+ otherHome = yield self.homeUnderTest(name=OTHER_HOME_UID)
+ otherCal = yield otherHome.invitedObjectWithShareUID(newCalName)
+ yield normalCal.updateShare(otherCal, status=_BIND_STATUS_ACCEPTED)
+ yield self.commit()
+
+ normalCal = yield self.calendarUnderTest()
+ self.assertEqual(normalCal._bindRevision, 0)
+ otherHome = yield self.homeUnderTest(name=OTHER_HOME_UID)
+ otherCal = yield otherHome.childWithName(newCalName)
+ self.assertNotEqual(otherCal._bindRevision, 0)
+
+
+ @inlineCallbacks
+ def test_sharedRevisions(self):
+ """
+ Verify that resourceNamesSinceRevision returns all resources after initial bind and sync.
+ """
+ cal = yield self.calendarUnderTest()
+ self.assertEqual(cal._bindRevision, 0)
+ other = yield self.homeUnderTest(name=OTHER_HOME_UID)
+ newCalName = yield cal.shareWith(other, _BIND_MODE_WRITE)
+ yield self.commit()
+
+ normalCal = yield self.calendarUnderTest()
+ self.assertEqual(normalCal._bindRevision, 0)
+ otherHome = yield self.homeUnderTest(name=OTHER_HOME_UID)
+ otherCal = yield otherHome.childWithName(newCalName)
+ self.assertNotEqual(otherCal._bindRevision, 0)
+
+ changed, deleted = yield otherCal.resourceNamesSinceRevision(otherCal._bindRevision - 1)
+ self.assertNotEqual(len(changed), 0)
+ self.assertEqual(len(deleted), 0)
+
+ changed, deleted = yield otherCal.resourceNamesSinceRevision(otherCal._bindRevision)
+ self.assertEqual(len(changed), 0)
+ self.assertEqual(len(deleted), 0)
+
+ for depth in ("1", "infinity",):
+ changed, deleted = yield otherHome.resourceNamesSinceRevision(otherCal._bindRevision - 1, depth)
+ self.assertNotEqual(len(changed), 0)
+ self.assertEqual(len(deleted), 0)
+
+ changed, deleted = yield otherHome.resourceNamesSinceRevision(otherCal._bindRevision, depth)
+ self.assertEqual(len(changed), 0)
+ self.assertEqual(len(deleted), 0)
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/carddav/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/carddav/datastore/sql.py 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/carddav/datastore/sql.py 2013-05-15 22:34:00 UTC (rev 11193)
@@ -195,6 +195,7 @@
def createdHome(self):
# initialize synctoken
yield self.addressbook()._initSyncToken()
+ yield self.addressbook()._initBindRevision()
@inlineCallbacks
@@ -317,17 +318,17 @@
rev.RESOURCE_NAME,
rev.DELETED],
From=rev,
- Where=(rev.REVISION > Parameter("token")).And(
+ Where=(rev.REVISION > Parameter("revision")).And(
rev.HOME_RESOURCE_ID == Parameter("resourceID")).And(
rev.RESOURCE_ID == rev.HOME_RESOURCE_ID)
)
@inlineCallbacks
- def doChangesQuery(self, token):
+ def doChangesQuery(self, revision):
rows = yield self._changesQuery.on(self._txn,
resourceID=self._resourceID,
- token=token)
+ revision=revision)
bindName = self.addressbook().name()
result = [[bindName] + row for row in rows]
@@ -657,7 +658,7 @@
)
# get ownerHomeIDs
for dataRow in dataRows:
- bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = dataRow[:6] #@UnusedVariable
+ bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = dataRow[:cls.bindColumnCount] #@UnusedVariable
ownerHome = yield home.ownerHomeWithChildID(resourceID)
ownerHomeToDataRowMap[ownerHome] = dataRow
@@ -666,7 +667,7 @@
home._txn, homeID=home._resourceID
)
for groupBindRow in groupBindRows:
- bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = groupBindRow[:6] #@UnusedVariable
+ bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = groupBindRow[:cls.bindColumnCount] #@UnusedVariable
ownerAddressBookID = yield AddressBookObject.ownerAddressBookFromGroupID(home._txn, resourceID)
ownerHome = yield home.ownerHomeWithChildID(ownerAddressBookID)
if ownerHome not in ownerHomeToDataRowMap:
@@ -688,14 +689,15 @@
# Create the actual objects merging in properties
for ownerHome, dataRow in ownerHomeToDataRowMap.iteritems():
- bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = dataRow[:6] #@UnusedVariable
- metadata = dataRow[6:]
+ bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = dataRow[:cls.bindColumnCount] #@UnusedVariable
+ metadata = dataRow[cls.bindColumnCount:]
child = cls(
home=home,
name=ownerHome.shareeAddressBookName(),
resourceID=ownerHome._resourceID,
mode=bindMode, status=bindStatus,
+ revision=bindRevision,
message=bindMessage, ownerHome=ownerHome,
bindName=bindName
)
@@ -777,7 +779,7 @@
if not rows:
returnValue(None)
- bindMode, homeID, resourceID, bindName, bindStatus, bindMessage, ownerAddressBookID, cachedBindStatus = rows[0] #@UnusedVariable
+ bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage, ownerAddressBookID, cachedBindStatus = rows[0] #@UnusedVariable
# if wrong status, exit here. Item is in queryCache
if (cachedBindStatus == _BIND_STATUS_ACCEPTED) != bool(accepted):
returnValue(None)
@@ -788,6 +790,7 @@
home=home,
name=ownerAddressBook.shareeAddressBookName(), resourceID=ownerAddressBookID,
mode=bindMode, status=bindStatus,
+ revision=bindRevision,
message=bindMessage, ownerHome=ownerHome,
bindName=bindName,
)
@@ -811,7 +814,7 @@
"""
bindRows = yield cls._bindForNameAndHomeID.on(home._txn, name=name, homeID=home._resourceID)
if bindRows:
- bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = bindRows[0] #@UnusedVariable
+ bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = bindRows[0] #@UnusedVariable
if (bindStatus == _BIND_STATUS_ACCEPTED) != bool(accepted):
returnValue(None)
@@ -827,7 +830,7 @@
home._txn, name=name, homeID=home._resourceID
)
if groupBindRows:
- bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = groupBindRows[0] #@UnusedVariable
+ bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = groupBindRows[0] #@UnusedVariable
if (bindStatus == _BIND_STATUS_ACCEPTED) != bool(accepted):
returnValue(None)
@@ -868,7 +871,7 @@
home._txn, resourceID=resourceID, homeID=home._resourceID
)
if bindRows:
- bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = bindRows[0] #@UnusedVariable
+ bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = bindRows[0] #@UnusedVariable
if (bindStatus == _BIND_STATUS_ACCEPTED) != bool(accepted):
returnValue(None)
@@ -882,7 +885,7 @@
home._txn, homeID=home._resourceID, addressbookID=resourceID
)
if groupBindRows:
- bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = groupBindRows[0] #@UnusedVariable
+ bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = groupBindRows[0] #@UnusedVariable
if (bindStatus == _BIND_STATUS_ACCEPTED) != bool(accepted):
returnValue(None)
@@ -929,9 +932,11 @@
Where=(bind.RESOURCE_ID == Parameter("resourceID"))
.And(bind.HOME_RESOURCE_ID == Parameter("homeID")),
).on(self._txn, resourceID=self._resourceID, homeID=self.viewerHome()._resourceID)
- '''
+
yield self.invalidateQueryCache()
yield self.notifyChanged()
+ '''
+ yield None
@classmethod
@@ -950,7 +955,7 @@
rows.extend((yield AddressBookObject._acceptedBindForHomeID.on(
home._txn, homeID=home._resourceID
)))
- for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in rows: #@UnusedVariable
+ for bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage in rows: #@UnusedVariable
ownerHome = yield home._txn.homeWithResourceID(home._homeType, homeID)
names |= set([ownerHome.shareeAddressBookName()])
returnValue(tuple(names))
@@ -995,7 +1000,7 @@
groupBindRows = yield AddressBookObject._unacceptedBindWithHomeIDAndAddressBookID.on(
self._txn, homeID=self._home._resourceID, addressbookID=self._resourceID
)
- #for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in groupBindRows: #@UnusedVariable
+ #for bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage in groupBindRows: #@UnusedVariable
returnValue([groupBindRow[2] for groupBindRow in groupBindRows])
@@ -1007,7 +1012,7 @@
groupBindRows = yield AddressBookObject._acceptedBindWithHomeIDAndAddressBookID.on(
self._txn, homeID=self._home._resourceID, addressbookID=self._resourceID
)
- #for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in groupBindRows: #@UnusedVariable
+ #for bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage in groupBindRows: #@UnusedVariable
returnValue([groupBindRow[2] for groupBindRow in groupBindRows])
@@ -1021,7 +1026,7 @@
)
readWriteGroupIDs = []
readOnlyGroupIDs = []
- for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in groupBindRows: #@UnusedVariable
+ for bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage in groupBindRows: #@UnusedVariable
if bindMode == _BIND_MODE_WRITE:
readWriteGroupIDs.append(resourceID)
else:
@@ -1067,7 +1072,7 @@
)
readWriteGroupIDs = []
readOnlyGroupIDs = []
- for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in groupBindRows: #@UnusedVariable
+ for bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage in groupBindRows: #@UnusedVariable
if bindMode == _BIND_MODE_WRITE:
readWriteGroupIDs.append(resourceID)
else:
@@ -1162,6 +1167,7 @@
if shareeView._bindStatus == _BIND_STATUS_ACCEPTED:
if 0 == previouslyAcceptedBindCount:
yield shareeView._initSyncToken()
+ yield shareeView._initBindRevision()
shareeView._home._children[shareeView._name] = shareeView
shareeView._home._children[shareeView._resourceID] = shareeView
elif shareeView._bindStatus == _BIND_STATUS_DECLINED:
@@ -1205,7 +1211,7 @@
bindRows = yield self._sharedBindForResourceID.on(
self._txn, resourceID=self._resourceID, homeID=self._home._resourceID
)
- for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in bindRows: #@UnusedVariable
+ for bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage in bindRows: #@UnusedVariable
home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
new = yield home.childWithName(self.shareeAddressBookName())
result.append(new)
@@ -1231,7 +1237,7 @@
bindRows = yield self._unacceptedBindForResourceID.on(
self._txn, resourceID=self._resourceID
)
- for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in bindRows: #@UnusedVariable
+ for bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage in bindRows: #@UnusedVariable
home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
new = yield self.objectWithName(home, self.shareeAddressBookName(), accepted=False)
result.append(new)
@@ -1532,7 +1538,7 @@
)
if groupBindRows:
- bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = groupBindRows[0] #@UnusedVariable
+ bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = groupBindRows[0] #@UnusedVariable
self._bindMode = bindMode
self._bindStatus = bindStatus
self._bindMessage = bindMessage
@@ -2115,9 +2121,11 @@
Where=(bind.RESOURCE_ID == Parameter("resourceID"))
.And(bind.HOME_RESOURCE_ID == Parameter("homeID")),
).on(self._txn, resourceID=self._resourceID, homeID=self.viewerHome()._resourceID)
- '''
+
yield self.invalidateQueryCache()
yield self.notifyChanged()
+ '''
+ yield None
@classmethod
def metadataColumns(cls):
@@ -2138,7 +2146,7 @@
def _childrenAndMetadataForHomeID(cls): #@NoSelf
bind = cls._bindSchema
child = cls._objectSchema
- columns = cls._bindColumns() + cls.metadataColumns()
+ columns = cls.bindColumns() + cls.metadataColumns()
return Select(columns,
From=child.join(
bind, child.RESOURCE_ID == bind.RESOURCE_ID,
@@ -2171,7 +2179,7 @@
groupBindRows = yield self._sharedBindForResourceID.on(
self._txn, resourceID=self._resourceID, homeID=self._home._resourceID
)
- for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in groupBindRows: #@UnusedVariable
+ for bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage in groupBindRows: #@UnusedVariable
home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
addressbook = yield home.childWithName(self._home.shareeAddressBookName())
new = yield addressbook.objectResourceWithID(resourceID)
@@ -2199,7 +2207,7 @@
groupBindRows = yield self._unacceptedBindForResourceID.on(
self._txn, resourceID=self._resourceID
)
- for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in groupBindRows: #@UnusedVariable
+ for bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage in groupBindRows: #@UnusedVariable
home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
addressbook = yield home.childWithName(self._home.shareeAddressBookName())
if not addressbook:
@@ -2330,16 +2338,21 @@
returnValue(newName)
try:
bindName = yield self._txn.subtransaction(doInsert)
+ if status == _BIND_STATUS_ACCEPTED:
+ shareeView = yield shareeHome.objectWithShareUID(bindName)
+ yield shareeView._initSyncToken()
+ yield shareeView._initBindRevision()
+
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
+ bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = groupBindRows[0] #@UnusedVariable
if bindStatus == _BIND_STATUS_ACCEPTED:
- group = yield shareeHome.objectForShareUID(bindName)
+ group = yield shareeHome.objectWithShareUID(bindName)
else:
- group = yield shareeHome.invitedObjectForShareUID(bindName)
+ group = yield shareeHome.invitedObjectWithShareUID(bindName)
bindName = yield self.updateShare(
group, mode=mode, status=status,
message=message
@@ -2416,6 +2429,7 @@
if shareeView._bindStatus == _BIND_STATUS_ACCEPTED:
if 0 == previouslyAcceptedBindCount:
yield shareeView._addressbook._initSyncToken()
+ yield shareeView._addressbook._initBindRevision()
shareeView._home._children[shareeView._addressbook._name] = shareeView._addressbook
shareeView._home._children[shareeView._addressbook._resourceID] = shareeView._addressbook
elif shareeView._bindStatus != _BIND_STATUS_INVITED:
@@ -2446,7 +2460,7 @@
bind = cls._bindSchema
abo = cls._objectSchema
return Select(
- cls._bindColumns(),
+ cls.bindColumns(),
From=bind.join(abo),
Where=(bind.BIND_STATUS == _BIND_STATUS_ACCEPTED)
.And(bind.RESOURCE_ID == abo.RESOURCE_ID)
@@ -2460,7 +2474,7 @@
bind = cls._bindSchema
abo = cls._objectSchema
return Select(
- cls._bindColumns(),
+ cls.bindColumns(),
From=bind.join(abo),
Where=(bind.BIND_STATUS != _BIND_STATUS_ACCEPTED)
.And(bind.RESOURCE_ID == abo.RESOURCE_ID)
@@ -2474,7 +2488,7 @@
bind = cls._bindSchema
abo = cls._objectSchema
return Select(
- cls._bindColumns(),
+ cls.bindColumns(),
From=bind.join(abo),
Where=(bind.RESOURCE_ID == abo.RESOURCE_ID)
.And(bind.HOME_RESOURCE_ID == Parameter("homeID"))
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/file.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/file.py 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/file.py 2013-05-15 22:34:00 UTC (rev 11193)
@@ -286,7 +286,6 @@
self._notificationHomes = {}
self._notifierFactories = notifierFactories
self._notifiedAlready = set()
- self._bumpedAlready = set()
self._migrating = migrating
extraInterfaces = []
@@ -405,25 +404,7 @@
self._notifiedAlready.add(obj)
- def isBumpedAlready(self, obj):
- """
- Indicates whether or not bumpAddedForObject has already been
- called for the given object, in order to facilitate calling
- bumpModified only once per object.
- """
- return obj in self._bumpedAlready
-
- def bumpAddedForObject(self, obj):
- """
- Records the fact that a bumpModified( ) call has already been
- done, in order to facilitate calling bumpModified only once per
- object.
- """
- self._bumpedAlready.add(obj)
-
-
-
class StubResource(object):
"""
Just enough resource to keep the shared sql DB classes going.
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql.py 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql.py 2013-05-15 22:34:00 UTC (rev 11193)
@@ -451,7 +451,7 @@
self._notificationHomes = {}
self._notifierFactories = notifierFactories
self._notifiedAlready = set()
- self._bumpedAlready = set()
+ self._bumpedRevisionAlready = set()
self._label = label
self._migrating = migrating
self._primaryHomeType = None
@@ -885,22 +885,20 @@
self._notifiedAlready.add(obj.id())
- def isBumpedAlready(self, obj):
+ def isRevisionBumpedAlready(self, obj):
"""
- Indicates whether or not bumpAddedForObject has already been
- called for the given object, in order to facilitate calling
- bumpModified only once per object.
+ Indicates whether or not bumpRevisionForObject has already been
+ called for the given object, in order to facilitate changing the
+ revision only once per object.
"""
- return obj.id() in self._bumpedAlready
+ return obj.id() in self._bumpedRevisionAlready
- def bumpAddedForObject(self, obj):
+ def bumpRevisionForObject(self, obj):
"""
- Records the fact that a bumpModified( ) call has already been
- done, in order to facilitate calling bumpModified only once per
- object.
+ Records the fact that a revision token for the object has been bumped.
"""
- self._bumpedAlready.add(obj.id())
+ self._bumpedRevisionAlready.add(obj.id())
_savepointCounter = 0
@@ -1762,8 +1760,8 @@
child = yield self.childWithName(name)
if child is None:
raise NoSuchHomeChildError()
+ resourceID = child._resourceID
- resourceID = child._resourceID
yield child.remove()
self._children.pop(name, None)
self._children.pop(resourceID, None)
@@ -1773,6 +1771,14 @@
def _syncTokenQuery(cls): #@NoSelf
"""
DAL Select statement to find the sync token.
+
+ This is the max(REVISION) from the union of:
+
+ 1) REVISION's for all object resources in all home child collections in the targeted home
+ 2) REVISION's for all child collections in the targeted home
+
+ Note the later is needed to track changes directly to the home child themselves (e.g.
+ property changes, deletion etc).
"""
rev = cls._revisionsSchema
bind = cls._bindSchema
@@ -1802,6 +1808,16 @@
)
+ def revisionFromToken(self, token):
+ if token is None:
+ return 0
+ elif isinstance(token, str):
+ _ignore_uuid, revision = token.split("_", 1)
+ return int(revision)
+ else:
+ return token
+
+
@inlineCallbacks
def syncToken(self):
"""
@@ -1820,39 +1836,69 @@
bind = cls._bindSchema
rev = cls._revisionsSchema
return Select(
- [bind.RESOURCE_NAME,
- rev.COLLECTION_NAME,
- rev.RESOURCE_NAME,
- rev.DELETED],
+ [
+ bind.RESOURCE_NAME,
+ rev.COLLECTION_NAME,
+ rev.RESOURCE_NAME,
+ rev.DELETED,
+ ],
From=rev.join(
bind,
- (
- bind.HOME_RESOURCE_ID == Parameter("resourceID")).And(
- rev.RESOURCE_ID == bind.RESOURCE_ID
- ), 'left outer'
+ (bind.HOME_RESOURCE_ID == Parameter("resourceID")).And
+ (rev.RESOURCE_ID == bind.RESOURCE_ID),
+ 'left outer'
),
- Where=(rev.REVISION > Parameter("token")).And(
- rev.HOME_RESOURCE_ID ==
- Parameter("resourceID")
- )
+ Where=(rev.REVISION > Parameter("revision")).And
+ (rev.HOME_RESOURCE_ID == Parameter("resourceID"))
)
@inlineCallbacks
- def doChangesQuery(self, token):
+ def doChangesQuery(self, revision):
"""
Do the changes query.
Subclasses may override.
"""
result = yield self._changesQuery.on(self._txn,
resourceID=self._resourceID,
- token=token)
+ revision=revision)
returnValue(result)
+ def resourceNamesSinceToken(self, token, depth):
+ """
+ Return the changed and deleted resources since a particular sync-token. This simply extracts
+ the revision from from the token then calls L{resourceNamesSinceRevision}.
+
+ @param revision: the revision to determine changes since
+ @type revision: C{int}
+ """
+
+ return self.resourceNamesSinceRevision(self.revisionFromToken(token), depth)
+
+
@inlineCallbacks
- def resourceNamesSinceToken(self, token, depth): #@UnusedVariable
+ def resourceNamesSinceRevision(self, revision, depth):
+ """
+ Determine the list of child resources that have changed since the specified sync revision.
+ We do the same SQL query for both depth "1" and "infinity", but filter the results for
+ "1" to only account for a collection change.
+ We need to handle shared collection a little differently from owned ones. When a shared collection
+ is bound into a home we record a revision for it using the sharee home id and sharee collection name.
+ That revision is the "starting point" for changes: so if sync occurs with a revision earlier than
+ that, we return the list of all resources in the shared collection since they are all "new" as far
+ as the client is concerned since the shared collection has just appeared. For a later revision, we
+ just report the changes since that one. When a shared collection is removed from a home, we again
+ record a revision for the sharee home and sharee collection name with the "deleted" flag set. That way
+ the shared collection can be reported as removed.
+
+ @param revision: the sync revision to compare to
+ @type revision: C{str}
+ @param depth: depth for determine what changed
+ @type depth: C{str}
+ """
+
results = [
(
path if path else (collection if collection else ""),
@@ -1860,57 +1906,81 @@
wasdeleted
)
for path, collection, name, wasdeleted in
- (yield self.doChangesQuery(token))
+ (yield self.doChangesQuery(revision))
]
- deleted = []
+ changed = set()
+ deleted = set()
deleted_collections = set()
changed_collections = set()
for path, name, wasdeleted in results:
if wasdeleted:
- if token:
- deleted.append("%s/%s" % (path, name,))
- if not name:
- deleted_collections.add(path)
+ if revision:
+ if name:
+ # Resource deleted - for depth "1" report collection as changed,
+ # otherwise report resource as deleted
+ if depth == "1":
+ changed.add("%s/" % (path,))
+ else:
+ deleted.add("%s/%s" % (path, name,))
+ else:
+ # Collection was deleted
+ deleted.add("%s/" % (path,))
+ deleted_collections.add(path)
- changed = []
for path, name, wasdeleted in results:
if path not in deleted_collections:
- changed.append("%s/%s" % (path, name,))
- if not name:
+ # Always report collection as changed
+ changed.add("%s/" % (path,))
+ if name:
+ # Resource changed - for depth "infinity" report resource as changed
+ if depth != "1":
+ changed.add("%s/%s" % (path, name,))
+ else:
+ # Collection was changed
changed_collections.add(path)
# Now deal with shared collections
+ # TODO: think about whether this can be done in one query rather than looping over each share
+ bind = self._bindSchema
rev = self._revisionsSchema
- for share in (yield self.children()):
+ shares = yield self.children()
+ for share in shares:
if not share.owned():
- sharetoken = 0 if share.name() in changed_collections else token
+ sharerevision = 0 if revision < share._bindRevision else revision
+ shareID = (yield Select(
+ [bind.RESOURCE_ID], From=bind,
+ Where=(bind.RESOURCE_NAME == share.name()).And(
+ bind.HOME_RESOURCE_ID == self._resourceID).And(
+ bind.BIND_MODE != _BIND_MODE_OWN)
+ ).on(self._txn))[0][0]
results = [
(
share.name(),
name if name else "",
wasdeleted
)
- for name, wasdeleted in (
- yield Select(
- [rev.RESOURCE_NAME, rev.DELETED],
- From=rev,
- Where=(rev.REVISION > sharetoken).And(
- rev.RESOURCE_ID == share._resourceID)
- ).on(self._txn)
- ) if name
+ for name, wasdeleted in
+ (yield Select([rev.RESOURCE_NAME, rev.DELETED],
+ From=rev,
+ Where=(rev.REVISION > sharerevision).And(
+ rev.RESOURCE_ID == shareID)).on(self._txn))
+ if name
]
for path, name, wasdeleted in results:
if wasdeleted:
- if sharetoken:
- deleted.append("%s/%s" % (path, name,))
+ if sharerevision:
+ if depth == "1":
+ changed.add("%s/" % (path,))
+ else:
+ deleted.add("%s/%s" % (path, name,))
for path, name, wasdeleted in results:
- changed.append("%s/%s" % (path, name,))
+ changed.add("%s/%s" % (path, "" if depth == "1" else name,))
- changed.sort()
- deleted.sort()
+ changed = sorted(changed)
+ deleted = sorted(deleted)
returnValue((changed, deleted))
@@ -2117,18 +2187,22 @@
@inlineCallbacks
def notifyChanged(self):
"""
- Trigger a notification of a change
+ Send notifications, change sync token and bump last modified because the resource has changed. We ensure
+ we only do this once per object per transaction.
"""
+ if self._txn.isNotifiedAlready(self):
+ returnValue(None)
+ self._txn.notificationAddedForObject(self)
+
# Update modified if object still exists
if self._resourceID:
yield self.bumpModified()
- # Only send one set of change notifications per transaction
- if self._notifiers and not self._txn.isNotifiedAlready(self):
+ # Send notifications
+ if self._notifiers:
for notifier in self._notifiers.values():
self._txn.postCommit(notifier.notify)
- self._txn.notificationAddedForObject(self)
@classproperty
@@ -2160,10 +2234,6 @@
delay the transaction whilst waiting for deadlock detection to kick in.
"""
- if self._txn.isBumpedAlready(self):
- returnValue(None)
- self._txn.bumpAddedForObject(self)
-
# NB if modified is bumped we know that sync token will have changed too, so invalidate the cached value
self._syncTokenRevision = None
@@ -2225,8 +2295,13 @@
def revisionFromToken(self, token):
- _ignore_uuid, revision = token.split("_", 1)
- return int(revision)
+ if token is None:
+ return 0
+ elif isinstance(token, str):
+ _ignore_uuid, revision = token.split("_", 1)
+ return int(revision)
+ else:
+ return token
@inlineCallbacks
@@ -2253,19 +2328,32 @@
rev.RESOURCE_ID == Parameter("resourceID")))
- @inlineCallbacks
def resourceNamesSinceToken(self, token):
+ """
+ Return the changed and deleted resources since a particular sync-token. This simply extracts
+ the revision from from the token then calls L{resourceNamesSinceRevision}.
- if token is None:
- token = 0
- elif isinstance(token, str):
- token = self.revisionFromToken(token)
+ @param revision: the revision to determine changes since
+ @type revision: C{int}
+ """
+ return self.resourceNamesSinceRevision(self.revisionFromToken(token))
+
+
+ @inlineCallbacks
+ def resourceNamesSinceRevision(self, revision):
+ """
+ Return the changed and deleted resources since a particular revision.
+
+ @param revision: the revision to determine changes since
+ @type revision: C{int}
+ """
+
results = [
(name if name else "", deleted)
for name, deleted in
(yield self._objectNamesSinceRevisionQuery.on(
- self._txn, revision=token, resourceID=self._resourceID))
+ self._txn, revision=revision, resourceID=self._resourceID))
]
results.sort(key=lambda x: x[1])
@@ -2274,7 +2362,7 @@
for name, wasdeleted in results:
if name:
if wasdeleted:
- if token:
+ if revision:
deleted.append(name)
else:
changed.append(name)
@@ -2312,6 +2400,7 @@
self._addNewRevision.on(self._txn, homeID=self._home._resourceID,
resourceID=self._resourceID,
collectionName=self._name)))[0][0]
+ self._txn.bumpRevisionForObject(self)
@classproperty
@@ -2321,11 +2410,13 @@
resource name).
"""
rev = cls._revisionsSchema
- return Update({
- rev.REVISION: schema.REVISION_SEQ,
- rev.COLLECTION_NAME: Parameter("name")},
- Where=(rev.RESOURCE_ID == Parameter("resourceID")
- ).And(rev.RESOURCE_NAME == None),
+ return Update(
+ {
+ rev.REVISION: schema.REVISION_SEQ,
+ rev.COLLECTION_NAME: Parameter("name")
+ },
+ Where=(rev.RESOURCE_ID == Parameter("resourceID")).And
+ (rev.RESOURCE_NAME == None),
Return=rev.REVISION
)
@@ -2334,18 +2425,44 @@
def _renameSyncToken(self):
self._syncTokenRevision = (yield self._renameSyncTokenQuery.on(
self._txn, name=self._name, resourceID=self._resourceID))[0][0]
+ self._txn.bumpRevisionForObject(self)
@classproperty
+ def _bumpSyncTokenQuery(cls): #@NoSelf
+ """
+ DAL query to change collection sync token.
+ """
+ rev = cls._revisionsSchema
+ return Update(
+ {rev.REVISION: schema.REVISION_SEQ, },
+ Where=(rev.RESOURCE_ID == Parameter("resourceID")).And
+ (rev.RESOURCE_NAME == None),
+ Return=rev.REVISION
+ )
+
+
+ @inlineCallbacks
+ def _bumpSyncToken(self):
+
+ if not self._txn.isRevisionBumpedAlready(self):
+ self._txn.bumpRevisionForObject(self)
+ self._syncTokenRevision = (yield self._bumpSyncTokenQuery.on(
+ self._txn, resourceID=self._resourceID))[0][0]
+
+
+ @classproperty
def _deleteSyncTokenQuery(cls): #@NoSelf
"""
DAL query to update a sync revision to be a tombstone instead.
"""
rev = cls._revisionsSchema
- return Delete(From=rev, Where=(
- rev.HOME_RESOURCE_ID == Parameter("homeID")).And(
- rev.RESOURCE_ID == Parameter("resourceID")).And(
- rev.COLLECTION_NAME == None))
+ return Delete(
+ From=rev,
+ Where=(rev.HOME_RESOURCE_ID == Parameter("homeID")).And
+ (rev.RESOURCE_ID == Parameter("resourceID")).And
+ (rev.COLLECTION_NAME == None)
+ )
@classproperty
@@ -2561,20 +2678,9 @@
@classmethod
- def _bindColumns(cls):
- bind = cls._bindSchema
- return (bind.BIND_MODE,
- bind.HOME_RESOURCE_ID,
- bind.RESOURCE_ID,
- bind.RESOURCE_NAME,
- bind.BIND_STATUS,
- bind.MESSAGE,)
-
-
- @classmethod
def _bindFor(cls, condition): #@NoSelf
bind = cls._bindSchema
- columns = cls._bindColumns() + cls.additionalBindColumns()
+ columns = cls.bindColumns() + cls.additionalBindColumns()
return Select(
columns,
From=bind,
@@ -2667,6 +2773,11 @@
returnValue(newName)
try:
bindName = yield self._txn.subtransaction(doInsert)
+ if status == _BIND_STATUS_ACCEPTED:
+ shareeView = yield shareeHome.objectWithShareUID(bindName)
+ yield shareeView._initSyncToken()
+ yield shareeView._initBindRevision()
+
except AllRetriesFailed:
# FIXME: catch more specific exception
child = yield shareeHome.childWithID(self._resourceID)
@@ -2725,7 +2836,6 @@
if len(columnMap):
- #TODO: with bit of parameter wrangling, call shareWith() here instead.
sharedname = yield self._updateBindColumnsQuery(columnMap).on(
self._txn,
resourceID=self._resourceID, homeID=shareeView._home._resourceID
@@ -2739,6 +2849,7 @@
shareeView._bindStatus = columnMap[bind.BIND_STATUS]
if shareeView._bindStatus == _BIND_STATUS_ACCEPTED:
yield shareeView._initSyncToken()
+ yield shareeView._initBindRevision()
shareeView._home._children[shareeView._name] = shareeView
shareeView._home._children[shareeView._resourceID] = shareeView
elif shareeView._bindStatus == _BIND_STATUS_DECLINED:
@@ -2842,7 +2953,7 @@
result = []
for row in acceptedRows:
- bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = row[:6] #@UnusedVariable
+ bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = row[:self.bindColumnCount] #@UnusedVariable
home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
new = yield home.objectWithShareUID(bindName)
result.append(new)
@@ -2871,7 +2982,7 @@
result = []
for row in rows:
- bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = row[:6] #@UnusedVariable
+ bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = row[:self.bindColumnCount] #@UnusedVariable
home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
new = yield home.invitedObjectWithShareUID(bindName)
result.append(new)
@@ -2879,6 +2990,23 @@
returnValue(result)
+ @inlineCallbacks
+ def _initBindRevision(self):
+ bind = self._bindSchema
+ self._bindRevision = self._syncTokenRevision
+ yield Update(
+ {bind.BIND_REVISION : Parameter("revision"), },
+ Where=(bind.RESOURCE_ID == Parameter("resourceID")).And
+ (bind.HOME_RESOURCE_ID == Parameter("homeID")),
+ ).on(
+ self._txn,
+ revision=self._bindRevision,
+ resourceID=self._resourceID,
+ homeID=self.viewerHome()._resourceID,
+ )
+ yield self.invalidateQueryCache()
+
+
def shareMode(self):
"""
@see: L{ICalendar.shareMode}
@@ -2983,6 +3111,26 @@
@classmethod
+ def bindColumns(cls):
+ """
+ Return a list of column names for retrieval during creation. This allows
+ different child classes to have their own type specific data, but still make use of the
+ common base logic.
+ """
+
+ return (
+ cls._bindSchema.BIND_MODE,
+ cls._bindSchema.HOME_RESOURCE_ID,
+ cls._bindSchema.RESOURCE_ID,
+ cls._bindSchema.RESOURCE_NAME,
+ cls._bindSchema.BIND_STATUS,
+ cls._bindSchema.BIND_REVISION,
+ cls._bindSchema.MESSAGE
+ )
+
+ bindColumnCount = 7
+
+ @classmethod
def additionalBindColumns(cls):
"""
Return a list of column names for retrieval during creation. This allows
@@ -3009,7 +3157,7 @@
child = cls._homeChildSchema
childMetaData = cls._homeChildMetaDataSchema
- columns = cls._bindColumns() + cls.additionalBindColumns() + cls.metadataColumns()
+ columns = cls.bindColumns() + cls.additionalBindColumns() + cls.metadataColumns()
return Select(columns,
From=child.join(
bind, child.RESOURCE_ID == bind.RESOURCE_ID,
@@ -3064,13 +3212,14 @@
_objectSchema = None
- def __init__(self, home, name, resourceID, mode, status, message=None, ownerHome=None, ownerName=None):
+ def __init__(self, home, name, resourceID, mode, status, revision=0, message=None, ownerHome=None, ownerName=None):
self._home = home
self._name = name
self._resourceID = resourceID
self._bindMode = mode
self._bindStatus = status
+ self._bindRevision = revision
self._bindMessage = message
self._ownerHome = home if ownerHome is None else ownerHome
self._ownerName = name if ownerName is None else ownerName
@@ -3156,9 +3305,9 @@
# Create the actual objects merging in properties
for items in dataRows:
- bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = items[:6] #@UnusedVariable
- additionalBind = items[6:6 + len(cls.additionalBindColumns())]
- metadata = items[6 + len(cls.additionalBindColumns()):]
+ bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = items[:cls.bindColumnCount] #@UnusedVariable
+ additionalBind = items[cls.bindColumnCount:cls.bindColumnCount + len(cls.additionalBindColumns())]
+ metadata = items[cls.bindColumnCount + len(cls.additionalBindColumns()):]
if bindMode == _BIND_MODE_OWN:
ownerHome = home
@@ -3171,6 +3320,7 @@
home=home,
name=bindName, resourceID=resourceID,
mode=bindMode, status=bindStatus,
+ revision=bindRevision,
message=bindMessage, ownerHome=ownerHome,
ownerName=ownerName,
)
@@ -3226,10 +3376,10 @@
returnValue(None)
row = rows[0]
- bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = row[:6] #@UnusedVariable
+ bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = row[:cls.bindColumnCount] #@UnusedVariable
if (bindStatus == _BIND_STATUS_ACCEPTED) != bool(accepted):
returnValue(None)
- additionalBind = row[6:6 + len(cls.additionalBindColumns())]
+ additionalBind = row[cls.bindColumnCount:cls.bindColumnCount + len(cls.additionalBindColumns())]
if bindMode == _BIND_MODE_OWN:
ownerHome = home
@@ -3241,6 +3391,7 @@
home=home,
name=name, resourceID=resourceID,
mode=bindMode, status=bindStatus,
+ revision=bindRevision,
message=bindMessage, ownerHome=ownerHome,
ownerName=ownerName
)
@@ -3266,7 +3417,7 @@
returnValue(None)
row = rows[0]
- bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = row[:6] #@UnusedVariable]
+ bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = row[:cls.bindColumnCount] #@UnusedVariable]
if (bindStatus == _BIND_STATUS_ACCEPTED) != bool(accepted):
returnValue(None)
@@ -3834,6 +3985,22 @@
return False
+ def resourceNamesSinceRevision(self, revision):
+ """
+ Return the changed and deleted resources since a particular revision. This implementation takes
+ into account sharing by making use of the bindRevision attribute to determine if the requested
+ revision is earlier than the share acceptance. If so, then we need to return all resources in
+ the results since the collection is in effect "new".
+
+ @param revision: the revision to determine changes since
+ @type revision: C{int}
+ """
+
+ if revision < self._bindRevision:
+ revision = 0
+ return super(CommonHomeChild, self).resourceNamesSinceRevision(revision)
+
+
@inlineCallbacks
def _loadPropertyStore(self, props=None):
if props is None:
@@ -3904,18 +4071,25 @@
@inlineCallbacks
def notifyChanged(self):
"""
- Trigger a notification of a change
+ Send notifications, change sync token and bump last modified because the resource has changed. We ensure
+ we only do this once per object per transaction.
"""
+ if self._txn.isNotifiedAlready(self):
+ returnValue(None)
+ self._txn.notificationAddedForObject(self)
+
# Update modified if object still exists
if self._resourceID:
yield self.bumpModified()
- # Only send one set of change notifications per transaction
- if self._notifiers and not self._txn.isNotifiedAlready(self):
+ # We now also bump the collection level sync token on any change
+ yield self._bumpSyncToken()
+
+ # Send notifications
+ if self._notifiers:
for notifier in self._notifiers.values():
self._txn.postCommit(notifier.notify)
- self._txn.notificationAddedForObject(self)
@classproperty
@@ -3947,10 +4121,6 @@
delay the transaction whilst waiting for deadlock detection to kick in.
"""
- if self._txn.isBumpedAlready(self):
- returnValue(None)
- self._txn.bumpAddedForObject(self)
-
@inlineCallbacks
def _bumpModified(subtxn):
yield self._lockLastModifiedQuery.on(subtxn, resourceID=self._resourceID)
@@ -4729,14 +4899,18 @@
def notifyChanged(self):
"""
- Trigger a notification of a change
+ Send notifications, change sync token and bump last modified because the resource has changed. We ensure
+ we only do this once per object per transaction.
"""
- # Only send one set of change notifications per transaction
- if self._notifiers and not self._txn.isNotifiedAlready(self):
+ if self._txn.isNotifiedAlready(self):
+ returnValue(None)
+ self._txn.notificationAddedForObject(self)
+
+ # Send notifications
+ if self._notifiers:
for notifier in self._notifiers.values():
self._txn.postCommit(notifier.notify)
- self._txn.notificationAddedForObject(self)
@classproperty
Property changes on: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql.py
___________________________________________________________________
Modified: svn:mergeinfo
- /CalendarServer/branches/config-separation/txdav/common/datastore/sql.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/common/datastore/sql.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/common/datastore/sql.py:6167-6191
/CalendarServer/branches/new-store/txdav/common/datastore/sql.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/common/datastore/sql.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/common/datastore/sql.py:5936-5981
/CalendarServer/branches/release/CalendarServer-4.3-dev/txdav/common/datastore/sql.py:10180-10190,10192
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/common/datastore/sql.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/common/datastore/sql.py:5693-5702
/CalendarServer/branches/users/cdaboo/component-set-fixes/txdav/common/datastore/sql.py:8130-8346
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/common/datastore/sql.py:3628-3644
/CalendarServer/branches/users/cdaboo/implicituidrace/txdav/common/datastore/sql.py:8137-8141
/CalendarServer/branches/users/cdaboo/ischedule-dkim/txdav/common/datastore/sql.py:9747-9979
/CalendarServer/branches/users/cdaboo/managed-attachments/txdav/common/datastore/sql.py:9985-10145
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/common/datastore/sql.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/common/datastore/sql.py:4465-4957
/CalendarServer/branches/users/cdaboo/pods/txdav/common/datastore/sql.py:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/common/datastore/sql.py:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/txdav/common/datastore/sql.py:7227-7237
/CalendarServer/branches/users/cdaboo/queued-attendee-refreshes/txdav/common/datastore/sql.py:7740-8287
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/common/datastore/sql.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/common/datastore/sql.py:5188-5440
/CalendarServer/branches/users/cdaboo/timezones/txdav/common/datastore/sql.py:7443-7699
/CalendarServer/branches/users/cdaboo/txn-debugging/txdav/common/datastore/sql.py:8730-8743
/CalendarServer/branches/users/glyph/always-abort-txn-on-error/txdav/common/datastore/sql.py:9958-9969
/CalendarServer/branches/users/glyph/case-insensitive-uid/txdav/common/datastore/sql.py:8772-8805
/CalendarServer/branches/users/glyph/conn-limit/txdav/common/datastore/sql.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/common/datastore/sql.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/common/datastore/sql.py:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect/txdav/common/datastore/sql.py:6824-6876
/CalendarServer/branches/users/glyph/deploybuild/txdav/common/datastore/sql.py:7563-7572
/CalendarServer/branches/users/glyph/digest-auth-redux/txdav/common/datastore/sql.py:10624-10635
/CalendarServer/branches/users/glyph/disable-quota/txdav/common/datastore/sql.py:7718-7727
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/common/datastore/sql.py:6592-6614
/CalendarServer/branches/users/glyph/imip-and-admin-html/txdav/common/datastore/sql.py:7866-7984
/CalendarServer/branches/users/glyph/ipv6-client/txdav/common/datastore/sql.py:9054-9105
/CalendarServer/branches/users/glyph/linux-tests/txdav/common/datastore/sql.py:6893-6900
/CalendarServer/branches/users/glyph/migrate-merge/txdav/common/datastore/sql.py:8690-8713
/CalendarServer/branches/users/glyph/misc-portability-fixes/txdav/common/datastore/sql.py:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/common/datastore/sql.py:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/common/datastore/sql.py:6369-6445
/CalendarServer/branches/users/glyph/multiget-delete/txdav/common/datastore/sql.py:8321-8330
/CalendarServer/branches/users/glyph/new-export/txdav/common/datastore/sql.py:7444-7485
/CalendarServer/branches/users/glyph/one-home-list-api/txdav/common/datastore/sql.py:10048-10073
/CalendarServer/branches/users/glyph/oracle/txdav/common/datastore/sql.py:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls/txdav/common/datastore/sql.py:7340-7351
/CalendarServer/branches/users/glyph/other-html/txdav/common/datastore/sql.py:8062-8091
/CalendarServer/branches/users/glyph/parallel-sim/txdav/common/datastore/sql.py:8240-8251
/CalendarServer/branches/users/glyph/parallel-upgrade/txdav/common/datastore/sql.py:8376-8400
/CalendarServer/branches/users/glyph/parallel-upgrade_to_1/txdav/common/datastore/sql.py:8571-8583
/CalendarServer/branches/users/glyph/q/txdav/common/datastore/sql.py:9560-9688
/CalendarServer/branches/users/glyph/queue-locking-and-timing/txdav/common/datastore/sql.py:10204-10289
/CalendarServer/branches/users/glyph/quota/txdav/common/datastore/sql.py:7604-7637
/CalendarServer/branches/users/glyph/sendfdport/txdav/common/datastore/sql.py:5388-5424
/CalendarServer/branches/users/glyph/shared-pool-fixes/txdav/common/datastore/sql.py:8436-8443
/CalendarServer/branches/users/glyph/shared-pool-take2/txdav/common/datastore/sql.py:8155-8174
/CalendarServer/branches/users/glyph/sharedpool/txdav/common/datastore/sql.py:6490-6550
/CalendarServer/branches/users/glyph/sharing-api/txdav/common/datastore/sql.py:9192-9205
/CalendarServer/branches/users/glyph/skip-lonely-vtimezones/txdav/common/datastore/sql.py:8524-8535
/CalendarServer/branches/users/glyph/sql-store/txdav/common/datastore/sql.py:5929-6073
/CalendarServer/branches/users/glyph/start-service-start-loop/txdav/common/datastore/sql.py:11060-11065
/CalendarServer/branches/users/glyph/subtransactions/txdav/common/datastore/sql.py:7248-7258
/CalendarServer/branches/users/glyph/table-alias/txdav/common/datastore/sql.py:8651-8664
/CalendarServer/branches/users/glyph/uidexport/txdav/common/datastore/sql.py:7673-7676
/CalendarServer/branches/users/glyph/unshare-when-access-revoked/txdav/common/datastore/sql.py:10562-10595
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/common/datastore/sql.py:5084-5149
/CalendarServer/branches/users/glyph/uuid-normalize/txdav/common/datastore/sql.py:9268-9296
/CalendarServer/branches/users/glyph/xattrs-from-files/txdav/common/datastore/sql.py:7757-7769
/CalendarServer/branches/users/sagen/applepush/txdav/common/datastore/sql.py:8126-8184
/CalendarServer/branches/users/sagen/inboxitems/txdav/common/datastore/sql.py:7380-7381
/CalendarServer/branches/users/sagen/locations-resources/txdav/common/datastore/sql.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/common/datastore/sql.py:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events/txdav/common/datastore/sql.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/common/datastore/sql.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/common/datastore/sql.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/common/datastore/sql.py:5084-5093
/CalendarServer/branches/users/sagen/testing/txdav/common/datastore/sql.py:10827-10851,10853-10855
/CalendarServer/branches/users/wsanchez/transations/txdav/common/datastore/sql.py:5515-5593
/CalendarServer/trunk/txdav/common/datastore/sql.py:11090-11095,11097-11111,11139-11174
+ /CalendarServer/branches/config-separation/txdav/common/datastore/sql.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/common/datastore/sql.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/common/datastore/sql.py:6167-6191
/CalendarServer/branches/new-store/txdav/common/datastore/sql.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/common/datastore/sql.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/common/datastore/sql.py:5936-5981
/CalendarServer/branches/release/CalendarServer-4.3-dev/txdav/common/datastore/sql.py:10180-10190,10192
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/common/datastore/sql.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/common/datastore/sql.py:5693-5702
/CalendarServer/branches/users/cdaboo/component-set-fixes/txdav/common/datastore/sql.py:8130-8346
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/common/datastore/sql.py:3628-3644
/CalendarServer/branches/users/cdaboo/implicituidrace/txdav/common/datastore/sql.py:8137-8141
/CalendarServer/branches/users/cdaboo/ischedule-dkim/txdav/common/datastore/sql.py:9747-9979
/CalendarServer/branches/users/cdaboo/managed-attachments/txdav/common/datastore/sql.py:9985-10145
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/common/datastore/sql.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/common/datastore/sql.py:4465-4957
/CalendarServer/branches/users/cdaboo/pods/txdav/common/datastore/sql.py:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/common/datastore/sql.py:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/txdav/common/datastore/sql.py:7227-7237
/CalendarServer/branches/users/cdaboo/queued-attendee-refreshes/txdav/common/datastore/sql.py:7740-8287
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/common/datastore/sql.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/common/datastore/sql.py:5188-5440
/CalendarServer/branches/users/cdaboo/timezones/txdav/common/datastore/sql.py:7443-7699
/CalendarServer/branches/users/cdaboo/txn-debugging/txdav/common/datastore/sql.py:8730-8743
/CalendarServer/branches/users/glyph/always-abort-txn-on-error/txdav/common/datastore/sql.py:9958-9969
/CalendarServer/branches/users/glyph/case-insensitive-uid/txdav/common/datastore/sql.py:8772-8805
/CalendarServer/branches/users/glyph/conn-limit/txdav/common/datastore/sql.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/common/datastore/sql.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/common/datastore/sql.py:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect/txdav/common/datastore/sql.py:6824-6876
/CalendarServer/branches/users/glyph/deploybuild/txdav/common/datastore/sql.py:7563-7572
/CalendarServer/branches/users/glyph/digest-auth-redux/txdav/common/datastore/sql.py:10624-10635
/CalendarServer/branches/users/glyph/disable-quota/txdav/common/datastore/sql.py:7718-7727
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/common/datastore/sql.py:6592-6614
/CalendarServer/branches/users/glyph/imip-and-admin-html/txdav/common/datastore/sql.py:7866-7984
/CalendarServer/branches/users/glyph/ipv6-client/txdav/common/datastore/sql.py:9054-9105
/CalendarServer/branches/users/glyph/linux-tests/txdav/common/datastore/sql.py:6893-6900
/CalendarServer/branches/users/glyph/migrate-merge/txdav/common/datastore/sql.py:8690-8713
/CalendarServer/branches/users/glyph/misc-portability-fixes/txdav/common/datastore/sql.py:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/common/datastore/sql.py:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/common/datastore/sql.py:6369-6445
/CalendarServer/branches/users/glyph/multiget-delete/txdav/common/datastore/sql.py:8321-8330
/CalendarServer/branches/users/glyph/new-export/txdav/common/datastore/sql.py:7444-7485
/CalendarServer/branches/users/glyph/one-home-list-api/txdav/common/datastore/sql.py:10048-10073
/CalendarServer/branches/users/glyph/oracle/txdav/common/datastore/sql.py:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls/txdav/common/datastore/sql.py:7340-7351
/CalendarServer/branches/users/glyph/other-html/txdav/common/datastore/sql.py:8062-8091
/CalendarServer/branches/users/glyph/parallel-sim/txdav/common/datastore/sql.py:8240-8251
/CalendarServer/branches/users/glyph/parallel-upgrade/txdav/common/datastore/sql.py:8376-8400
/CalendarServer/branches/users/glyph/parallel-upgrade_to_1/txdav/common/datastore/sql.py:8571-8583
/CalendarServer/branches/users/glyph/q/txdav/common/datastore/sql.py:9560-9688
/CalendarServer/branches/users/glyph/queue-locking-and-timing/txdav/common/datastore/sql.py:10204-10289
/CalendarServer/branches/users/glyph/quota/txdav/common/datastore/sql.py:7604-7637
/CalendarServer/branches/users/glyph/sendfdport/txdav/common/datastore/sql.py:5388-5424
/CalendarServer/branches/users/glyph/shared-pool-fixes/txdav/common/datastore/sql.py:8436-8443
/CalendarServer/branches/users/glyph/shared-pool-take2/txdav/common/datastore/sql.py:8155-8174
/CalendarServer/branches/users/glyph/sharedpool/txdav/common/datastore/sql.py:6490-6550
/CalendarServer/branches/users/glyph/sharing-api/txdav/common/datastore/sql.py:9192-9205
/CalendarServer/branches/users/glyph/skip-lonely-vtimezones/txdav/common/datastore/sql.py:8524-8535
/CalendarServer/branches/users/glyph/sql-store/txdav/common/datastore/sql.py:5929-6073
/CalendarServer/branches/users/glyph/start-service-start-loop/txdav/common/datastore/sql.py:11060-11065
/CalendarServer/branches/users/glyph/subtransactions/txdav/common/datastore/sql.py:7248-7258
/CalendarServer/branches/users/glyph/table-alias/txdav/common/datastore/sql.py:8651-8664
/CalendarServer/branches/users/glyph/uidexport/txdav/common/datastore/sql.py:7673-7676
/CalendarServer/branches/users/glyph/unshare-when-access-revoked/txdav/common/datastore/sql.py:10562-10595
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/common/datastore/sql.py:5084-5149
/CalendarServer/branches/users/glyph/uuid-normalize/txdav/common/datastore/sql.py:9268-9296
/CalendarServer/branches/users/glyph/xattrs-from-files/txdav/common/datastore/sql.py:7757-7769
/CalendarServer/branches/users/sagen/applepush/txdav/common/datastore/sql.py:8126-8184
/CalendarServer/branches/users/sagen/inboxitems/txdav/common/datastore/sql.py:7380-7381
/CalendarServer/branches/users/sagen/locations-resources/txdav/common/datastore/sql.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/common/datastore/sql.py:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events/txdav/common/datastore/sql.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/common/datastore/sql.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/common/datastore/sql.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/common/datastore/sql.py:5084-5093
/CalendarServer/branches/users/sagen/testing/txdav/common/datastore/sql.py:10827-10851,10853-10855
/CalendarServer/branches/users/wsanchez/transations/txdav/common/datastore/sql.py:5515-5593
/CalendarServer/trunk/txdav/common/datastore/sql.py:11090-11095,11097-11111,11139-11192
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/current-oracle-dialect.sql
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/current-oracle-dialect.sql 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/current-oracle-dialect.sql 2013-05-15 22:34:00 UTC (rev 11193)
@@ -68,6 +68,7 @@
"CALENDAR_RESOURCE_NAME" nvarchar2(255),
"BIND_MODE" integer not null,
"BIND_STATUS" integer not null,
+ "BIND_REVISION" integer default 0 not null,
"MESSAGE" nclob,
"TRANSP" integer default 0 not null,
"ALARM_VEVENT_TIMED" nclob default null,
@@ -219,6 +220,7 @@
"ADDRESSBOOK_RESOURCE_NAME" nvarchar2(255),
"BIND_MODE" integer not null,
"BIND_STATUS" integer not null,
+ "BIND_REVISION" integer default 0 not null,
"MESSAGE" nclob,
primary key("ADDRESSBOOK_HOME_RESOURCE_ID", "OWNER_ADDRESSBOOK_HOME_RESOURCE_ID"),
unique("ADDRESSBOOK_HOME_RESOURCE_ID", "ADDRESSBOOK_RESOURCE_NAME")
@@ -267,6 +269,7 @@
"GROUP_ADDRESSBOOK_RESOURCE_NAME" nvarchar2(255),
"BIND_MODE" integer not null,
"BIND_STATUS" integer not null,
+ "BIND_REVISION" integer default 0 not null,
"MESSAGE" nclob,
primary key("ADDRESSBOOK_HOME_RESOURCE_ID", "GROUP_RESOURCE_ID"),
unique("ADDRESSBOOK_HOME_RESOURCE_ID", "GROUP_ADDRESSBOOK_RESOURCE_NAME")
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/current.sql
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/current.sql 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/current.sql 2013-05-15 22:34:00 UTC (rev 11193)
@@ -133,6 +133,7 @@
CALENDAR_RESOURCE_NAME varchar(255) not null,
BIND_MODE integer not null, -- enum CALENDAR_BIND_MODE
BIND_STATUS integer not null, -- enum CALENDAR_BIND_STATUS
+ BIND_REVISION integer default 0 not null,
MESSAGE text,
TRANSP integer default 0 not null, -- enum CALENDAR_TRANSP
ALARM_VEVENT_TIMED text default null,
@@ -392,6 +393,7 @@
ADDRESSBOOK_RESOURCE_NAME varchar(255) not null,
BIND_MODE integer not null, -- enum CALENDAR_BIND_MODE
BIND_STATUS integer not null, -- enum CALENDAR_BIND_STATUS
+ BIND_REVISION integer default 0 not null,
MESSAGE text, -- FIXME: xml?
primary key (ADDRESSBOOK_HOME_RESOURCE_ID, OWNER_ADDRESSBOOK_HOME_RESOURCE_ID), -- implicit index
@@ -473,6 +475,7 @@
GROUP_ADDRESSBOOK_RESOURCE_NAME varchar(255) not null,
BIND_MODE integer not null, -- enum CALENDAR_BIND_MODE
BIND_STATUS integer not null, -- enum CALENDAR_BIND_STATUS
+ BIND_REVISION integer default 0 not null,
MESSAGE text, -- FIXME: xml?
primary key (ADDRESSBOOK_HOME_RESOURCE_ID, GROUP_RESOURCE_ID), -- implicit index
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/old/oracle-dialect/v19.sql
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/old/oracle-dialect/v19.sql 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/old/oracle-dialect/v19.sql 2013-05-15 22:34:00 UTC (rev 11193)
@@ -68,6 +68,7 @@
"CALENDAR_RESOURCE_NAME" nvarchar2(255),
"BIND_MODE" integer not null,
"BIND_STATUS" integer not null,
+ "BIND_REVISION" integer default 0 not null,
"MESSAGE" nclob,
"TRANSP" integer default 0 not null,
"ALARM_VEVENT_TIMED" nclob default null,
@@ -228,6 +229,7 @@
"ADDRESSBOOK_RESOURCE_NAME" nvarchar2(255),
"BIND_MODE" integer not null,
"BIND_STATUS" integer not null,
+ "BIND_REVISION" integer default 0 not null,
"MESSAGE" nclob,
primary key("ADDRESSBOOK_HOME_RESOURCE_ID", "ADDRESSBOOK_RESOURCE_ID"),
unique("ADDRESSBOOK_HOME_RESOURCE_ID", "ADDRESSBOOK_RESOURCE_NAME")
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/old/postgres-dialect/v19.sql
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/old/postgres-dialect/v19.sql 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/old/postgres-dialect/v19.sql 2013-05-15 22:34:00 UTC (rev 11193)
@@ -130,6 +130,7 @@
CALENDAR_RESOURCE_NAME varchar(255) not null,
BIND_MODE integer not null, -- enum CALENDAR_BIND_MODE
BIND_STATUS integer not null, -- enum CALENDAR_BIND_STATUS
+ BIND_REVISION integer default 0 not null,
MESSAGE text,
TRANSP integer default 0 not null, -- enum CALENDAR_TRANSP
ALARM_VEVENT_TIMED text default null,
@@ -405,6 +406,7 @@
ADDRESSBOOK_RESOURCE_NAME varchar(255) not null,
BIND_MODE integer not null, -- enum CALENDAR_BIND_MODE
BIND_STATUS integer not null, -- enum CALENDAR_BIND_STATUS
+ BIND_REVISION integer default 0 not null,
MESSAGE text, -- FIXME: xml?
primary key (ADDRESSBOOK_HOME_RESOURCE_ID, ADDRESSBOOK_RESOURCE_ID), -- implicit index
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_18_to_19.sql
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_18_to_19.sql 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_18_to_19.sql 2013-05-15 22:34:00 UTC (rev 11193)
@@ -32,7 +32,8 @@
-- Calendar bind related updates
alter table CALENDAR_BIND
- add ("TRANSP" integer default 0 not null,
+ add ("BIND_REVISION" integer default 0 not null,
+ "TRANSP" integer default 0 not null,
"ALARM_VEVENT_TIMED" nclob default null,
"ALARM_VEVENT_ALLDAY" nclob default null,
"ALARM_VTODO_TIMED" nclob default null,
@@ -46,6 +47,13 @@
insert into CALENDAR_TRANSP (DESCRIPTION, ID) values ('opaque', 0);
insert into CALENDAR_TRANSP (DESCRIPTION, ID) values ('transparent', 1);
+
+-- Addressbook bind related updates
+
+alter table ADDRESSBOOK_BIND
+ add ("BIND_REVISION" integer default 0 not null);
+
+
-- Now update the version
-- No data upgrades
update CALENDARSERVER set VALUE = '19' where NAME = 'VERSION';
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/upgrades/postgres-dialect/upgrade_from_18_to_19.sql
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/upgrades/postgres-dialect/upgrade_from_18_to_19.sql 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/sql_schema/upgrades/postgres-dialect/upgrade_from_18_to_19.sql 2013-05-15 22:34:00 UTC (rev 11193)
@@ -33,6 +33,7 @@
-- Calendar bind related updates
alter table CALENDAR_BIND
+ add column BIND_REVISION integer default 0 not null,
add column TRANSP integer default 0 not null,
add column ALARM_VEVENT_TIMED text default null,
add column ALARM_VEVENT_ALLDAY text default null,
@@ -47,6 +48,13 @@
insert into CALENDAR_TRANSP values (0, 'opaque' );
insert into CALENDAR_TRANSP values (1, 'transparent');
+
+-- Addressbook bind related updates
+
+alter table ADDRESSBOOK_BIND
+ add column BIND_REVISION integer default 0 not null;
+
+
-- Now update the version
-- No data upgrades
update CALENDARSERVER set VALUE = '19' where NAME = 'VERSION';
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/upgrade/sql/upgrade.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/upgrade/sql/upgrade.py 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/upgrade/sql/upgrade.py 2013-05-15 22:34:00 UTC (rev 11193)
@@ -25,6 +25,7 @@
from twext.python.log import LoggingMixIn
from twisted.internet.defer import inlineCallbacks, returnValue
+from twisted.python.failure import Failure
from twisted.python.modules import getModule
from twisted.python.reflect import namedObject
@@ -124,10 +125,11 @@
actual_version = int(actual_version)
yield sqlTxn.commit()
except (RuntimeError, ValueError):
+ f = Failure()
self.log_error("Database key %s cannot be determined." % (self.versionKey,))
yield sqlTxn.abort()
if self.defaultKeyValue is None:
- raise
+ f.raiseException()
else:
actual_version = self.defaultKeyValue
@@ -265,8 +267,9 @@
yield sqlTxn.execSQLBlock(sql)
yield sqlTxn.commit()
except RuntimeError:
+ f = Failure()
yield sqlTxn.abort()
- raise
+ f.raiseException()
Modified: CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_3_to_4.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_3_to_4.py 2013-05-15 18:17:40 UTC (rev 11192)
+++ CalendarServer/branches/users/gaya/sharedgroups-3/txdav/common/datastore/upgrade/sql/upgrades/calendar_upgrade_from_3_to_4.py 2013-05-15 22:34:00 UTC (rev 11193)
@@ -109,7 +109,9 @@
calendar = (yield calendarHome.calendarWithName(calendarName))
if calendar is not None:
- yield calendarHome.setDefaultCalendar(calendar, tasks=(propname == sqlStore, customxml.ScheduleDefaultTasksURL))
+ yield calendarHome.setDefaultCalendar(
+ calendar, tasks=(propname ==
+ customxml.ScheduleDefaultTasksURL))
# Always delete the row so that batch processing works correctly
yield Delete(
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130515/ddba8a3c/attachment-0001.html>
More information about the calendarserver-changes
mailing list