[CalendarServer-changes] [11759]
source_changes at macosforge.org
source_changes at macosforge.org
Fri Sep 27 21:04:39 PDT 2013
Revision: 11759
http://trac.calendarserver.org//changeset/11759
Author: gaya at apple.com
Date: 2013-09-27 21:04:39 -0700 (Fri, 27 Sep 2013)
Log Message:
-----------
checkpoint - shared group revisions tests work, but other tests are broken
Modified Paths:
--------------
CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-one/4.xml
CalDAVTester/branches/users/gaya/sharedgroupfixestester/scripts/tests/CardDAV/sharing-sync.xml
CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/carddav/datastore/sql.py
Added Paths:
-----------
CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-one/5.xml
Modified: CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-one/4.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-one/4.xml 2013-09-25 22:35:50 UTC (rev 11758)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-one/4.xml 2013-09-28 04:04:39 UTC (rev 11759)
@@ -1,20 +1,8 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<notification xmlns='http://calendarserver.org/ns/'>
- <dtstamp></dtstamp>
- <invite-notification shared-type='group'>
- <uid></uid>
- <href xmlns='DAV:'>$cuaddrurn2:</href>
- <invite-noresponse/>
- <access>
- <read-write/>
- </access>
- <hosturl>
- <href xmlns='DAV:'>$addressbookpath1:/3.vcf</href>
- </hosturl>
- <organizer>
- <href xmlns='DAV:'>$cuaddrurn1:</href>
- <common-name>User 01</common-name>
- </organizer>
- <summary>My Shared Calendar</summary>
- </invite-notification>
-</notification>
+<?xml version="1.0" encoding="utf-8" ?>
+<CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
+ <CS:set>
+ <D:href>$cuaddrurn2:</D:href>
+ <CS:summary>Shared Group</CS:summary>
+ <CS:read-write/>
+ </CS:set>
+</CS:share>
Added: CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-one/5.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-one/5.xml (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-one/5.xml 2013-09-28 04:04:39 UTC (rev 11759)
@@ -0,0 +1,13 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<invite-reply xmlns='http://calendarserver.org/ns/'>
+ <href xmlns='DAV:'>$cuaddrurn2:</href>
+ <invite-accepted/>
+ <hosturl>
+ <href xmlns='DAV:'>$addressbookpath1:/3.vcf</href>
+ </hosturl>
+ <in-reply-to>$inviteuid:</in-reply-to>
+ <summary>Shared Group</summary>
+ <common-name>$username2:</common-name>
+ <first-name>$firstname2:</first-name>
+ <last-name>$lastname2:</last-name>
+</invite-reply>
Modified: CalDAVTester/branches/users/gaya/sharedgroupfixestester/scripts/tests/CardDAV/sharing-sync.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/scripts/tests/CardDAV/sharing-sync.xml 2013-09-25 22:35:50 UTC (rev 11758)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/scripts/tests/CardDAV/sharing-sync.xml 2013-09-28 04:04:39 UTC (rev 11759)
@@ -38,8 +38,8 @@
</start>
<!-- test suite below is similar to test suite in ../CalDAV/sharing-sync.xml -->
- <test-suite name='Read-write addressbook' ignore='no'>
- <test name='1' ignore='no'>
+ <test-suite name='shared addressbook' ignore='no'>
+ <test name='1a' ignore='no'>
<description>Initial sync tokens</description>
<request print-response='no'>
<method>REPORT</method>
@@ -56,6 +56,8 @@
<variable>$synctoken1:</variable>
</grabelement>
</request>
+ </test>
+ <test name='1b' ignore='no'>
<request print-response='no'>
<method>REPORT</method>
<ruri>$addressbookhome1:/</ruri>
@@ -71,6 +73,8 @@
<variable>$synctoken2:</variable>
</grabelement>
</request>
+ </test>
+ <test name='1c' ignore='no'>
<request print-response='no'>
<method>REPORT</method>
<ruri>$addressbookpath1:/</ruri>
@@ -86,6 +90,8 @@
<variable>$synctoken3:</variable>
</grabelement>
</request>
+ </test>
+ <test name='1d' ignore='no'>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>REPORT</method>
<ruri>$addressbookhome2:/</ruri>
@@ -101,6 +107,8 @@
<variable>$synctoken4:</variable>
</grabelement>
</request>
+ </test>
+ <test name='1e' ignore='no'>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>REPORT</method>
<ruri>$addressbookhome2:/</ruri>
@@ -269,18 +277,19 @@
</grabelement>
</request>
</test>
- <test name='5e' ignore='yes'>
+ <test name='5e' ignore='no'>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>REPORT</method>
<ruri>$addressbookhome2:/</ruri>
<data substitutions='yes'>
<content-type>text/xml; charset=utf-8</content-type>
- <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ <filepath>Resource/Common/REPORT/sync-init-level-infinite.xml</filepath>
</data>
<verify>
<callback>multistatusItems</callback>
<arg>
<name>okhrefs</name>
+ <value>$addressbook:/</value>
<value>$sharedaddressbook:/</value>
</arg>
</verify>
@@ -407,7 +416,7 @@
</grabelement>
</request>
</test>
- <test name='7f' ignore='yes'>
+ <test name='7f' ignore='no'>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>REPORT</method>
<ruri>$addressbookhome2:/</ruri>
@@ -550,7 +559,7 @@
</grabelement>
</request>
</test>
- <test name='9e' ignore='yes'>
+ <test name='9e' ignore='no'>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>REPORT</method>
<ruri>$addressbookhome2:/</ruri>
@@ -692,7 +701,7 @@
</grabelement>
</request>
</test>
- <test name='11e' ignore='yes'>
+ <test name='11e' ignore='no'>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>REPORT</method>
<ruri>$addressbookhome2:/</ruri>
@@ -872,6 +881,850 @@
</request>
</test>
</test-suite>
+
+ <!-- test suite below is similar to test suite in ../CalDAV/sharing-sync.xml -->
+ <test-suite name='one shared group' ignore='no'>
+ <test name='0' ignore='no'>
+ <description>clean up old data</description>
+ <request user="$useradmin:" pswd="$pswdadmin:">
+ <method>DELETEALL</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <ruri>$addressbookhome2:/</ruri>
+ <ruri>$notificationpath1:/</ruri>
+ <ruri>$notificationpath2:/</ruri>
+ </request>
+ <description>create empty group</description>
+ <request>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/3.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-one/3.vcf</filepath>
+ </data>
+ </request>
+ </test>
+ <test name='1a' ignore='no'>
+ <description>Initial sync tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='1b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='1c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='1d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='1e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='2' ignore='no'>
+ <description>user1 POSTs invitation</description>
+ <request print-response="no">
+ <method>POST</method>
+ <ruri>$addressbookpath1:/3.vcf</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-one/4.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='3'>
+ <description>Check user2 notification collection and get invite uid</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$notificationpath2:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$notificationpath2:/</ruri>
+ <grabelement>
+ <name>{http://calendarserver.org/ns/}invite-notification/{http://calendarserver.org/ns/}uid</name>
+ <variable>$inviteuid:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='4'>
+ <description>user2 replies ACCEPTED and deletes notification</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>POST</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions="yes">
+ <content-type>application/xml; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-one/5.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>DELETE</method>
+ <ruri>$notificationpath2:/$inviteuid:</ruri>
+ </request>
+ </test>
+ <test name='5a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='5b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='5c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='5d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='5e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$userguid1:/</value>
+ <value>$userguid1:/3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='5f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='6'>
+ <description>Sharee creates vcard</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>PUT</method>
+ <ruri>$addressbookhome2:/$userguid1:/1.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-one/1.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='7a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='7b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$addressbook:/1.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='7c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>1.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='7e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='7f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ <value>$userguid1:/1.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='7g' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>1.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='8'>
+ <description>Sharer changes vcard</description>
+ <request print-response='no'>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/1.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-one/1.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='9a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='9b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$addressbook:/1.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='9c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>1.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='9d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='9e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ <value>$userguid1:/1.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='9f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>1.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='10'>
+ <description>Sharee deletes vcard</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>DELETE</method>
+ <ruri>$addressbookhome2:/$userguid1:/1.vcf</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='11a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='11b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ <arg>
+ <name>badhrefs</name>
+ <value>$addressbook:/1.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='11c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>badhrefs</name>
+ <value>1.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='11d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='11e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ <arg>
+ <name>badhrefs</name>
+ <value>$userguid1:/1.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='11f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>badhrefs</name>
+ <value>1.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='12'>
+ <description>Sharer unshares</description>
+ <request print-response='no'>
+ <method>POST</method>
+ <ruri>$addressbookpath1:/3.vcf</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/POST/sharingremove2.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='13a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>badhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>badhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13g' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>404</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ </test-suite>
<!-- test suites below are similar to those in ../CalDAV/sync-report.xml but use shared address books of calendars in the home -->
<test-suite name='support-report-set/sync-token property' ignore='no'>
@@ -3810,30 +4663,6 @@
</test>
</test-suite>
- <test-suite name='simple reports - empty inbox' ignore='yes'>
- <test name='1' ignore='no'>
- <description>initial query</description>
- <request print-response='no'>
- <method>REPORT</method>
- <ruri>$inboxpath1:/</ruri>
- <header>
- <name>Depth</name>
- <value>1</value>
- </header>
- <data>
- <content-type>text/xml; charset=utf-8</content-type>
- <filepath>Resource/CardDAV/sharing/sync/addressbook/22.xml</filepath>
- </data>
- <verify>
- <callback>multistatusItems</callback>
- <arg>
- <name>okhrefs</name>
- </arg>
- </verify>
- </request>
- </test>
- </test-suite>
-
<test-suite name='simple reports - valid token' ignore='no'>
<test name='1' ignore='no'>
<description>initial query</description>
@@ -4105,7 +4934,6 @@
</test>
</test-suite>
-
<end>
<request user="$useradmin:" pswd="$pswdadmin:">
<method>DELETEALL</method>
Modified: CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/carddav/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/carddav/datastore/sql.py 2013-09-25 22:35:50 UTC (rev 11758)
+++ CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/carddav/datastore/sql.py 2013-09-28 04:04:39 UTC (rev 11759)
@@ -272,6 +272,8 @@
"""
rev = cls._revisionsSchema
bind = cls._bindSchema
+ abo = cls._objectSchema
+ groupBind = AddressBookObject._bindSchema
return Select(
[Max(rev.REVISION)],
# active shared address books
@@ -284,6 +286,22 @@
[bind.RESOURCE_ID],
From=bind,
Where=bind.HOME_RESOURCE_ID == Parameter("resourceID"),
+ SetExpression=Union(
+ Select(
+ [abo.ADDRESSBOOK_HOME_RESOURCE_ID],
+ From=abo,
+ Where=(
+ abo.RESOURCE_ID.In(
+ Select(
+ [groupBind.GROUP_RESOURCE_ID],
+ From=groupBind,
+ Where=groupBind.ADDRESSBOOK_HOME_RESOURCE_ID == Parameter("resourceID"),
+ )
+ )
+ )
+ ),
+ optype=Union.OPTYPE_ALL,
+ )
)
)
),
@@ -294,7 +312,7 @@
From=rev,
Where=(rev.HOME_RESOURCE_ID == Parameter("resourceID")).And(rev.RESOURCE_ID == None),
SetExpression=Union(
- # owned address book: owned address book cannot be deleted: See AddressBook.remove()
+ # owned address book
Select(
[rev.REVISION],
From=rev,
@@ -313,7 +331,7 @@
def _changesQuery(cls): #@NoSelf
rev = cls._revisionsSchema
return Select(
- [rev.COLLECTION_NAME,
+ [rev.ADDRESSBOOK_NAME,
rev.RESOURCE_NAME,
rev.DELETED],
From=rev,
@@ -325,9 +343,11 @@
@inlineCallbacks
def doChangesQuery(self, revision):
- rows = yield self._changesQuery.on(self._txn,
- resourceID=self._resourceID,
- revision=revision)
+ rows = yield self._changesQuery.on(
+ self._txn,
+ resourceID=self._resourceID,
+ revision=revision
+ )
# If the collection name is None that means we have a change to the owner's default address book,
# so substitute in the name of that. If collection name is not None, then we have a revision
@@ -620,7 +640,7 @@
print("sharedChildResourceNamesSinceRevision:%s results:%s" % (self, results))
# id's are added on deletion
- idToNameMap = dict([(name, id) for name, id, wasdeleted in results if id != 0])
+ idToNameMap = dict([(id, name) for name, id, wasdeleted in results if id != 0])
# now get other names of existing objects
missingNameIds = (allowedObjectIDs | oldAllowedObjectIDs) - set(idToNameMap.keys())
@@ -871,17 +891,6 @@
returnValue(component)
- @inlineCallbacks
- def bumpModified(self):
- # TODO: The next line seems to work too. Why?
- # returnValue((yield self.ownerHome().bumpModified()))
- #
- if self._resourceID == self._home._resourceID:
- returnValue((yield self._home.bumpModified()))
- else:
- returnValue((yield super(AddressBook, self).bumpModified()))
-
-
@classmethod
@inlineCallbacks
def loadAllObjects(cls, home):
@@ -1183,45 +1192,67 @@
returnValue(tuple(names))
- @classproperty
- def _memberIDsWithGroupIDQuery(cls): #@NoSelf
- """
- DAL query to find all member resource ids with the maximum revision for the given group ID
- """
- aboMembers = schema.ABO_MEMBERS
- return Select([aboMembers.MEMBER_ID, aboMembers.REMOVED, Max(aboMembers.REVISION)], From=aboMembers,
- Where=aboMembers.GROUP_ID == Parameter("groupID"),
- GroupBy=(aboMembers.MEMBER_ID, aboMembers.REMOVED)
- )
-
-
@classmethod
def _memberIDsWithGroupIDsQuery(cls, groupIDs):
"""
- DAL query to find all member resource ids with the maximum revision for the given group IDs
+ DAL query to find members and revisions
"""
aboMembers = schema.ABO_MEMBERS
- return Select([aboMembers.MEMBER_ID, aboMembers.REMOVED, Max(aboMembers.REVISION)], From=aboMembers,
+ return Select([aboMembers.MEMBER_ID, aboMembers.REMOVED, aboMembers.REVISION],
+ From=aboMembers,
Where=aboMembers.GROUP_ID.In(Parameter("groupIDs", len(groupIDs))),
- GroupBy=(aboMembers.MEMBER_ID, aboMembers.REMOVED)
)
@classmethod
def _memberIDsWithGroupIDsAndRevisionQuery(cls, groupIDs):
"""
- DAL query to find all member resource ids with the maximum given revision for the given group IDs
+ DAL query to find members and revisions
"""
aboMembers = schema.ABO_MEMBERS
- return Select([aboMembers.MEMBER_ID, aboMembers.REMOVED, Max(aboMembers.REVISION)], From=aboMembers,
+ return Select([aboMembers.MEMBER_ID, aboMembers.REMOVED, aboMembers.REVISION],
+ From=aboMembers,
Where=aboMembers.GROUP_ID.In(Parameter("groupIDs", len(groupIDs)))
.And(aboMembers.REVISION <= Parameter("revision")),
- GroupBy=(aboMembers.MEMBER_ID, aboMembers.REMOVED)
)
@classmethod
+ def _currentMemberIDsFromMemberIDRemovedRevisionRows(cls, memberRows):
+ memberIDs = set()
+ objectIDToVersionToRemovedMap = {}
+ for id, removed, version in memberRows:
+ versionRemovedRow = objectIDToVersionToRemovedMap.get(id, [])
+ versionRemovedRow.append((version, removed,))
+ objectIDToVersionToRemovedMap[id] = versionRemovedRow
+
+ for id, versionRemovedRows in objectIDToVersionToRemovedMap.iteritems():
+ versionToRemovedMap = dict(versionRemovedRows)
+ if not versionToRemovedMap[max(versionToRemovedMap.keys())]:
+ memberIDs.add(id)
+
+ return memberIDs
+
+
+ @classmethod
@inlineCallbacks
+ def memberIDsWithGroupIDs(cls, txn, groupIDs, atRevision=0):
+
+ if atRevision == 0:
+ memberRows = yield cls._memberIDsWithGroupIDsQuery(groupIDs).on(
+ txn, groupIDs=groupIDs
+ )
+ else:
+ memberRows = yield cls._memberIDsWithGroupIDsAndRevisionQuery(groupIDs).on(
+ txn, groupIDs=groupIDs, revision=atRevision
+ )
+
+ memberIDs = cls._currentMemberIDsFromMemberIDRemovedRevisionRows(memberRows)
+ returnValue(memberIDs)
+
+
+ @classmethod
+ @inlineCallbacks
def expandGroupIDs(cls, txn, groupIDs, atRevision=0, includeGroupIDs=True):
"""
Get all AddressBookObject resource IDs contains in the given shared groups with the given groupIDs
@@ -1230,16 +1261,10 @@
examinedIDs = set()
remainingIDs = set(groupIDs)
while remainingIDs:
- if atRevision == 0:
- memberRows = yield cls._memberIDsWithGroupIDsQuery(remainingIDs).on(
- txn, groupIDs=remainingIDs
- )
- else:
- memberRows = yield cls._memberIDsWithGroupIDsAndRevisionQuery(remainingIDs).on(
- txn, groupIDs=remainingIDs, revision=atRevision
- )
- objectIDs |= set(memberRow[0] for memberRow in memberRows if not memberRow[1]) # not removed
+ memberIDs = yield cls.memberIDsWithGroupIDs(txn, remainingIDs, atRevision)
+
+ objectIDs |= memberIDs
examinedIDs |= remainingIDs
remainingIDs = objectIDs - examinedIDs
@@ -1443,6 +1468,7 @@
# Must send notification to ensure cache invalidation occurs
yield self.notifyPropertyChanged()
+ yield shareeView.viewerHome().notifyChanged()
returnValue(shareeView._name)
@@ -1493,6 +1519,7 @@
# Must send notification to ensure cache invalidation occurs
yield self.notifyPropertyChanged()
+ yield shareeHome.notifyChanged()
# delete bind table rows for this share
deletedBindNameRows = yield self._deleteBindForResourceIDAndHomeID.on(self._txn, resourceID=self._resourceID,
@@ -1587,28 +1614,40 @@
# get sync token for delete now
yield self.addressbook()._deleteRevision(self.name(), self._resourceID)
+ # get groups where this object was once a member and version info
aboMembers = schema.ABO_MEMBERS
- groupIDRows = yield Select([aboMembers.GROUP_ID, aboMembers.REMOVED, Max(aboMembers.REVISION)],
+ groupRows = yield Select([aboMembers.GROUP_ID, aboMembers.MEMBER_ID, aboMembers.REMOVED, aboMembers.REVISION],
From=aboMembers,
- Where=aboMembers.MEMBER_ID == self._resourceID,
- GroupBy=(aboMembers.GROUP_ID, aboMembers.REMOVED)
+ Where=(aboMembers.MEMBER_ID == self._resourceID).And(aboMembers.REMOVED == False),
).on(self._txn)
- groupIDs = set([groupIDRow[0] for groupIDRow in groupIDRows if not groupIDRow[1]])
+ # combine by groupID
+ groupIDToMemberRowMap = {}
+ for groupID, id, removed, version in groupRows:
+ memberRow = groupIDToMemberRowMap.get(groupID, [])
+ memberRow.append((id, version, removed,))
+ groupIDToMemberRowMap[groupID] = memberRow
+ # see if this object is in current version
+ groupIDs = set([
+ groupID for groupID, memberRows in groupIDToMemberRowMap.iteritems()
+ if self._resourceID in AddressBook._currentMemberIDsFromMemberIDRemovedRevisionRows(memberRows)
+ ])
+
if not self.owned() and not self.addressbook().fullyShared():
groupIDsToRemoveFrom = readWriteObjectIDs | groupIDs
groupIDs -= readWriteObjectIDs
else:
groupIDsToRemoveFrom = groupIDs
- if groupIDsToRemoveFrom:
- # remove memberships
- yield self._removeMemberIDFromGroupsQuery(groupIDsToRemoveFrom).on(self._txn,
- groupIDs=groupIDsToRemoveFrom,
+ # add to member table rows marked removed
+ for groupIDToRemoveFrom in groupIDsToRemoveFrom:
+ yield self._insertMemberIDQuery.on(self._txn,
+ groupID=groupIDToRemoveFrom,
addressbookID=self._ownerAddressBookResourceID,
memberID=self._resourceID,
revision=self._syncTokenRevision,
+ removed=True,
)
# add to foreign member table row by UID (aboForeignMembers on address books)
@@ -1624,22 +1663,17 @@
if self.kind() == _ABO_KIND_GROUP:
# mark members as deleted
- memberIDRows = yield Select(
- [aboMembers.MEMBER_ID],
- From=aboMembers,
- Where=(aboMembers.GROUP_ID == self._resourceID)
- .And(aboMembers.REMOVED == False),
- ).on(self._txn)
- memberIDsToRemove = [memberIDRow[0] for memberIDRow in memberIDRows]
+ memberIDsToRemove = yield AddressBook.memberIDsWithGroupIDs(self._txn, [self._resourceID])
- if memberIDsToRemove:
- yield self._removeMemberIDsFromGroupQuery(memberIDsToRemove).on(
+ for memberIDToRemove in memberIDsToRemove:
+ yield self._insertMemberIDQuery.on(
self._txn,
groupID=self._resourceID,
addressbookID=self._ownerAddressBookResourceID,
- memberIDs=memberIDsToRemove,
+ memberID=memberIDToRemove,
revision=self._syncTokenRevision,
- )
+ removed=True,
+ )
yield super(AddressBookObject, self).remove()
self._kind = None
@@ -2038,41 +2072,11 @@
aboMembers.ADDRESSBOOK_ID: Parameter("addressbookID"),
aboMembers.MEMBER_ID: Parameter("memberID"),
aboMembers.REVISION: Parameter("revision"),
- #aboMembers.REMOVED: False,
+ aboMembers.REMOVED: Parameter("removed"),
}
)
- @classmethod
- def _removeMemberIDsFromGroupQuery(cls, memberIDs): #@NoSelf
- """
- DAL statement to mark a member table row to as removed
- """
- aboMembers = schema.ABO_MEMBERS
- return Update(
- {aboMembers.REVISION: Parameter("revision"),
- aboMembers.REMOVED: True, },
- Where=(aboMembers.GROUP_ID == Parameter("groupID"))
- .And(aboMembers.ADDRESSBOOK_ID == Parameter("addressbookID"))
- .And(aboMembers.MEMBER_ID.In(Parameter("memberIDs", len(memberIDs)))),
- )
-
-
- @classmethod
- def _removeMemberIDFromGroupsQuery(cls, groupIDs): #@NoSelf
- """
- DAL statement update a group member
- """
- aboMembers = schema.ABO_MEMBERS
- return Update(
- {aboMembers.REVISION: Parameter("revision"),
- aboMembers.REMOVED: True, },
- Where=(aboMembers.GROUP_ID.In(Parameter("groupIDs", len(groupIDs))))
- .And(aboMembers.ADDRESSBOOK_ID == Parameter("addressbookID"))
- .And(aboMembers.MEMBER_ID == Parameter("memberID")),
- )
-
-
@inlineCallbacks
def updateDatabase(self, component, expand_until=None, reCreate=False, #@UnusedVariable
inserting=False):
@@ -2193,6 +2197,7 @@
addressbookID=self._ownerAddressBookResourceID,
memberID=self._resourceID,
revision=self._syncTokenRevision,
+ removed=False,
)
else:
@@ -2210,31 +2215,20 @@
memberIDs.append(self._resourceID)
# get current members
- currentMemberRows = yield AddressBook._memberIDsWithGroupIDsQuery([self._resourceID]).on(
- self._txn, groupIDs=[self._resourceID]
- )
- currentMemberIDs = [currentMemberRow[0] for currentMemberRow in currentMemberRows if not currentMemberRow[1]]
-
+ currentMemberIDs = yield AddressBook.memberIDsWithGroupIDs(self._txn, [self._resourceID])
memberIDsToRemove = set(currentMemberIDs) - set(memberIDs)
memberIDsToAdd = set(memberIDs) - set(currentMemberIDs)
- for memberIDToAdd in memberIDsToAdd:
- yield self._insertMemberIDQuery.on(self._txn,
+ for memberIDToAdd in memberIDsToAdd | memberIDsToRemove:
+ yield self._insertMemberIDQuery.on(
+ self._txn,
groupID=self._resourceID,
addressbookID=self._ownerAddressBookResourceID,
memberID=memberIDToAdd,
revision=self._syncTokenRevision,
+ removed=self._resourceID in memberIDsToRemove,
)
- if memberIDsToRemove:
- yield self._removeMemberIDsFromGroupQuery(memberIDsToRemove).on(
- self._txn,
- groupID=self._resourceID,
- addressbookID=self._ownerAddressBookResourceID,
- memberIDs=memberIDsToRemove,
- revision=self._syncTokenRevision,
- )
-
# get current foreign members
currentForeignMemberRows = yield Select(
[aboForeignMembers.MEMBER_ADDRESS],
@@ -2297,10 +2291,7 @@
# generate "X-ADDRESSBOOKSERVER-MEMBER" properties
# first get member resource ids
- memberRows = yield AddressBook._memberIDsWithGroupIDsQuery([self._resourceID]).on(
- self._txn, groupIDs=[self._resourceID]
- )
- memberIDs = [memberRow[0] for memberRow in memberRows if not memberRow[1]]
+ memberIDs = yield AddressBook.memberIDsWithGroupIDs(self._txn, [self._resourceID])
# then get member UIDs
abo = schema.ADDRESSBOOK_OBJECT
@@ -2402,10 +2393,6 @@
).And(bind.BIND_STATUS == _BIND_STATUS_ACCEPTED))
- def notifyChanged(self):
- return self.addressbook().notifyChanged()
-
-
@classproperty
def _addressbookIDForResourceID(cls): #@NoSelf
obj = cls._objectSchema
@@ -2506,7 +2493,8 @@
shareeHome._children.pop(self.addressbook()._resourceID, None)
# Must send notification to ensure cache invalidation occurs
- yield self.notifyChanged()
+ yield self.addressbook().notifyPropertyChanged()
+ yield shareeHome.notifyChanged()
# delete bind including invites
deletedBindNameRows = yield self._deleteBindForResourceIDAndHomeID.on(
@@ -2583,8 +2571,7 @@
if status == _BIND_STATUS_ACCEPTED:
shareeView = yield shareeHome.objectWithShareUID(bindName)
if not shareeView.addressbook().fullyShared():
- currentAcceptedBindCount = 1 if shareeView.addressbook().fullyShared() else 0
- currentAcceptedBindCount += len((
+ currentAcceptedBindCount = len((
yield AddressBookObject._acceptedBindForHomeIDAndAddressBookID.on(
self._txn, homeID=shareeView.viewerHome()._resourceID, addressbookID=shareeView.addressbook()._resourceID
)
@@ -2592,7 +2579,6 @@
if currentAcceptedBindCount == 1:
yield shareeView.addressbook()._initSyncToken()
- # start share here
yield shareeView._initBindRevision()
queryCacher = self._txn._queryCacher
@@ -2601,7 +2587,9 @@
queryCacher.invalidateAfterCommit(self._txn, cacheKey)
# Must send notification to ensure cache invalidation occurs
- yield self.notifyChanged()
+ yield self.addressbook().notifyPropertyChanged()
+ yield shareeHome.notifyChanged()
+
self.setShared(True)
returnValue(bindName)
@@ -2700,7 +2688,8 @@
shareeView._name = bindNameRows[0][0]
# Must send notification to ensure cache invalidation occurs
- yield self.notifyChanged()
+ yield self.addressbook().notifyPropertyChanged()
+ yield shareeView.viewerHome().notifyChanged()
returnValue(shareeView._name)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130927/eb010856/attachment-0001.html>
More information about the calendarserver-changes
mailing list