[CalendarServer-changes] [11690] CalendarServer/branches/users/gaya/sharedgroupfixes/txdav
source_changes at macosforge.org
source_changes at macosforge.org
Tue Sep 17 13:02:54 PDT 2013
Revision: 11690
http://trac.calendarserver.org//changeset/11690
Author: gaya at apple.com
Date: 2013-09-17 13:02:53 -0700 (Tue, 17 Sep 2013)
Log Message:
-----------
Remove UNSHARED from ADDRESSBOOK_OBJECT_REVISIONS. Various fixes.
Modified Paths:
--------------
CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/carddav/datastore/sql.py
CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/common/datastore/sql.py
CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/common/datastore/sql_schema/current.sql
Modified: CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/carddav/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/carddav/datastore/sql.py 2013-09-14 13:37:14 UTC (rev 11689)
+++ CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/carddav/datastore/sql.py 2013-09-17 20:02:53 UTC (rev 11690)
@@ -457,21 +457,9 @@
def _deleteBumpTokenQuery(cls): #@NoSelf
rev = cls._revisionsSchema
return Update({rev.REVISION: schema.REVISION_SEQ,
+ rev.OBJECT_RESOURCE_ID: Parameter("id"),
rev.DELETED: True},
Where=(rev.RESOURCE_ID == Parameter("resourceID")).And(
- rev.RESOURCE_NAME == Parameter("name")).And(
- rev.OBJECT_RESOURCE_ID == Parameter("id")),
- Return=rev.REVISION)
-
-
- @classproperty
- def _unshareBumpTokenQuery(cls): #@NoSelf
- rev = cls._revisionsSchema
- return Update({rev.REVISION: schema.REVISION_SEQ,
- rev.OBJECT_RESOURCE_ID: Parameter("id"),
- rev.UNSHARED: True,
- },
- Where=(rev.RESOURCE_ID == Parameter("resourceID")).And(
rev.RESOURCE_NAME == Parameter("name")),
Return=rev.REVISION)
@@ -488,12 +476,6 @@
self._txn, resourceID=self._resourceID, name=name, id=id))
if rows:
self._syncTokenRevision = rows[0][0]
- elif action == "unshare":
- rows = (
- yield self._unshareBumpTokenQuery.on(
- self._txn, resourceID=self._resourceID, name=name, id=id))
- if rows:
- self._syncTokenRevision = rows[0][0]
elif action == "update":
rows = (
yield self._updateBumpTokenQuery.on(
@@ -524,16 +506,13 @@
resourceID=self._resourceID, name=name)
)[0][0]
self._maybeNotify()
+ returnValue(self._syncTokenRevision)
- def _deleteRevision(self, name, id):
+ def _deleteRevision(self, name, id=0):
return self._changeRevision("delete", name, id)
- def _unshareRevision(self, name, id):
- return self._changeRevision("unshare", name, id)
-
-
@inlineCallbacks
def resourceNamesSinceRevision(self, revision):
"""
@@ -547,7 +526,7 @@
"""
print("AddressBook: resourceNamesSinceRevision:%s revision:%s" % (self, revision,))
- if self.fullyShared():
+ if self.owned() or self.fullyShared():
returnValue((yield super(AddressBook, self).resourceNamesSinceRevision(revision)))
# call sharedChildResourceNamesSinceRevision() and filter results
@@ -607,27 +586,36 @@
# get revision table changes
rev = self._revisionsSchema
+ results = yield Select([rev.ADDRESSBOOK_HOME_RESOURCE_ID,
+ rev.OWNER_ADDRESSBOOK_HOME_RESOURCE_ID,
+ rev.ADDRESSBOOK_NAME,
+ rev.OBJECT_RESOURCE_ID,
+ rev.RESOURCE_NAME,
+ rev.REVISION,
+ rev.DELETED,
+ ],
+ From=rev,
+ Where=(rev.REVISION > sharerevision).And(
+ rev.RESOURCE_ID == self._resourceID)).on(self._txn)
+ print("sharedChildResourceNamesSinceRevision:%s all results:%s" % (self, results))
+
results = [(
name,
id,
wasdeleted,
- wasunshared,
- ) for name, id, wasdeleted, wasunshared in (
- yield Select([rev.RESOURCE_NAME, rev.OBJECT_RESOURCE_ID, rev.DELETED, rev.UNSHARED],
+ ) for name, id, wasdeleted in (
+ yield Select([rev.RESOURCE_NAME, rev.OBJECT_RESOURCE_ID, rev.DELETED],
From=rev,
Where=(rev.REVISION > sharerevision).And(
rev.RESOURCE_ID == self._resourceID)).on(self._txn)
) if name
]
print("sharedChildResourceNamesSinceRevision:%s results:%s" % (self, results))
+
allowedObjectIDs = set((yield self.expandGroupIDs(self._txn, acceptedGroupIDs)))
print("sharedChildResourceNamesSinceRevision:%s allowedObjectIDs=%s," % (self, allowedObjectIDs,))
- # get unshared groups from revisions
- unsharedGroupIDs = set([id for name, id, wasdeleted, wasunshared in results if wasunshared])
- print("sharedChildResourceNamesSinceRevision:%s allowedObjectIDs=%s," % (self, unsharedGroupIDs,))
-
- oldAllowedObjectIDs = set((yield self.expandGroupIDs(self._txn, acceptedGroupIDs | unsharedGroupIDs, revision)))
+ oldAllowedObjectIDs = set((yield self.expandGroupIDs(self._txn, acceptedGroupIDs, revision)))
print("sharedChildResourceNamesSinceRevision:%s oldAllowedObjectIDs=%s," % (self, oldAllowedObjectIDs,))
addedObjectIds = allowedObjectIDs - oldAllowedObjectIDs
@@ -635,7 +623,7 @@
print("sharedChildResourceNamesSinceRevision:%s addedObjectIds=%s," % (self, addedObjectIds,))
print("sharedChildResourceNamesSinceRevision:%s removedObjectIds=%s," % (self, removedObjectIds,))
- idToNameMap = dict([(name, id) for name, id, wasdeleted, wasunshared in results if id != 0])
+ idToNameMap = dict([(name, id) for name, id, wasdeleted in results if id != 0])
missingNameIds = (allowedObjectIDs | oldAllowedObjectIDs) - set(idToNameMap.keys())
if missingNameIds:
abo = schema.ADDRESSBOOK_OBJECT
@@ -663,7 +651,7 @@
for addedObjectID in addedObjectIds:
changed.add("%s/%s" % (path, idToNameMap[addedObjectID],))
- for name, id, wasdeleted, wasunshared in results:
+ for name, id, wasdeleted in results:
if name in idToNameMap.values():
# Always report collection as changed
changed.add("%s/" % (path,))
@@ -738,10 +726,6 @@
def remove(self):
if self._resourceID == self._home._resourceID:
-
- # Note that revision table is NOT queried for removes
- yield self._updateRevision(self.name())
-
# Allow remove, as a way to reset the address book to an empty state
for abo in (yield self.objectResources()):
yield abo.remove()
@@ -892,7 +876,7 @@
@inlineCallbacks
def bumpModified(self):
- # TODO: The next line seems the next line work too. Why?
+ # TODO: The next line seems to work too. Why?
# returnValue((yield self.ownerHome().bumpModified()))
#
if self._resourceID == self._home._resourceID:
@@ -1202,10 +1186,22 @@
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 load all object resource names for a home child.
+ DAL query to find all member resource ids with the maximum revision for the given group IDs
"""
aboMembers = schema.ABO_MEMBERS
return Select([aboMembers.MEMBER_ID, aboMembers.REMOVED, Max(aboMembers.REVISION)], From=aboMembers,
@@ -1217,7 +1213,7 @@
@classmethod
def _memberIDsWithGroupIDsAndRevisionQuery(cls, groupIDs):
"""
- DAL query to load all object resource names for a home child.
+ DAL query to find all member resource ids with the maximum given revision for the given group IDs
"""
aboMembers = schema.ABO_MEMBERS
return Select([aboMembers.MEMBER_ID, aboMembers.REMOVED, Max(aboMembers.REVISION)], From=aboMembers,
@@ -1245,11 +1241,12 @@
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
examinedIDs |= remainingIDs
remainingIDs = objectIDs - examinedIDs
- returnValue(tuple(objectIDs))
+ returnValue(objectIDs)
@inlineCallbacks
@@ -1582,8 +1579,9 @@
if not self.owned() and not self.addressbook().fullyShared():
readWriteGroupIDs = yield self.addressbook().readWriteGroupIDs()
readWriteObjectIDs = (
- yield self.addressbook().expandGroupIDs(self._txn, readWriteGroupIDs)
- ) if readWriteGroupIDs else []
+ set((yield self.addressbook().expandGroupIDs(self._txn, readWriteGroupIDs)))
+ if readWriteGroupIDs else set()
+ )
# can't delete item in read-only shared group, even if user has addressbook unbind
if self._resourceID not in readWriteObjectIDs:
@@ -1593,19 +1591,22 @@
yield self.addressbook()._deleteRevision(self.name(), self._resourceID)
aboMembers = schema.ABO_MEMBERS
- groupIDRows = yield Select(
- [aboMembers.GROUP_ID],
+ groupIDRows = yield Select([aboMembers.GROUP_ID, aboMembers.REMOVED, Max(aboMembers.REVISION)],
From=aboMembers,
- Where=(aboMembers.MEMBER_ID == self._resourceID)
- .And(aboMembers.REMOVED == False),
+ Where=aboMembers.MEMBER_ID == self._resourceID,
+ GroupBy=(aboMembers.GROUP_ID, aboMembers.REMOVED)
).on(self._txn)
- groupIDs = [groupIDRow[0] for groupIDRow in groupIDRows]
- groupIDsToRemoveFrom = groupIDs if self.owned() or self.addressbook().fullyShared() else readWriteObjectIDs
+ groupIDs = set([groupIDRow[0] for groupIDRow in groupIDRows if not groupIDRow[1]])
+ if not self.owned() and not self.addressbook().fullyShared():
+ groupIDsToRemoveFrom = readWriteObjectIDs | groupIDs
+ groupIDs -= readWriteObjectIDs
+ else:
+ groupIDsToRemoveFrom = groupIDs
+
if groupIDsToRemoveFrom:
# remove memberships
- print("remove:%s _removeMemberIDFromGroupsQuery:revision=%s groupIDs=%s memberID=%s" % (self, self._syncTokenRevision, groupIDsToRemoveFrom, self._resourceID,))
yield self._removeMemberIDFromGroupsQuery(groupIDsToRemoveFrom).on(self._txn,
groupIDs=groupIDsToRemoveFrom,
addressbookID=self._ownerAddressBookResourceID,
@@ -1616,10 +1617,7 @@
# add to foreign member table row by UID (aboForeignMembers on address books)
memberAddress = "urn:uuid:" + self._uid
aboForeignMembers = schema.ABO_FOREIGN_MEMBERS
- if groupIDs:
- print("updateDatabase:%s foreignMemberAddrToAdd=%s" % (self, groupIDs,))
-
- for groupID in groupIDs:#set(groupIDs) - set([self._ownerAddressBookResourceID]):
+ for groupID in groupIDs:
yield Insert(
{aboForeignMembers.GROUP_ID: groupID,
aboForeignMembers.ADDRESSBOOK_ID: self._ownerAddressBookResourceID,
@@ -1638,7 +1636,6 @@
memberIDsToRemove = [memberIDRow[0] for memberIDRow in memberIDRows]
if memberIDsToRemove:
- print("remove:%s _removeMemberIDsFromGroupQuery:revision=%s groupID=%s memberIDsToRemove=%s" % (self, self._ownerAddressBookResourceID, self._resourceID, memberIDsToRemove,))
yield self._removeMemberIDsFromGroupQuery(memberIDsToRemove).on(
self._txn,
groupID=self._resourceID,
@@ -2193,8 +2190,6 @@
groupIDs |= set(readWriteGroupIDs)
# add to member table rows
- if groupIDs:
- print("updateDatabase:%s _insertMemberIDQuery:revision=%s groupIDToRevisionMap=%s memberIDToAdd=%s" % (self, self._syncTokenRevision, groupIDs, self._resourceID,))
for groupID in groupIDs:
yield self._insertMemberIDQuery.on(self._txn,
groupID=groupID,
@@ -2226,8 +2221,6 @@
memberIDsToRemove = set(currentMemberIDs) - set(memberIDs)
memberIDsToAdd = set(memberIDs) - set(currentMemberIDs)
- if memberIDsToAdd:
- print("updateDatabase:%s _insertMemberIDQuery:revision=%s groupID=%s memberIDsToAdd=%s" % (self, self._syncTokenRevision, self._resourceID, memberIDsToAdd,))
for memberIDToAdd in memberIDsToAdd:
yield self._insertMemberIDQuery.on(self._txn,
groupID=self._resourceID,
@@ -2237,7 +2230,6 @@
)
if memberIDsToRemove:
- print("updateDatabase:%s _removeMemberIDsFromGroupQuery:revision=%s groupID=%s memberIDsToRemove=%s" % (self, self._syncTokenRevision, self._resourceID, memberIDsToRemove,))
yield self._removeMemberIDsFromGroupQuery(memberIDsToRemove).on(
self._txn,
groupID=self._resourceID,
@@ -2246,34 +2238,29 @@
revision=self._syncTokenRevision,
)
- # don't bother with aboForeignMembers on address books
- if self._resourceID != self._ownerAddressBookResourceID:
+ # get current foreign members
+ currentForeignMemberRows = yield Select(
+ [aboForeignMembers.MEMBER_ADDRESS],
+ From=aboForeignMembers,
+ Where=aboForeignMembers.GROUP_ID == self._resourceID,).on(self._txn)
+ currentForeignMemberAddrs = [currentForeignMemberRow[0] for currentForeignMemberRow in currentForeignMemberRows]
- # get current foreign members
- currentForeignMemberRows = yield Select(
- [aboForeignMembers.MEMBER_ADDRESS],
- From=aboForeignMembers,
- Where=aboForeignMembers.GROUP_ID == self._resourceID,).on(self._txn)
- currentForeignMemberAddrs = [currentForeignMemberRow[0] for currentForeignMemberRow in currentForeignMemberRows]
+ foreignMemberAddrsToDelete = set(currentForeignMemberAddrs) - set(foreignMemberAddrs)
+ foreignMemberAddrsToAdd = set(foreignMemberAddrs) - set(currentForeignMemberAddrs)
- foreignMemberAddrsToDelete = set(currentForeignMemberAddrs) - set(foreignMemberAddrs)
- foreignMemberAddrsToAdd = set(foreignMemberAddrs) - set(currentForeignMemberAddrs)
+ if foreignMemberAddrsToDelete:
+ yield self._deleteForeignMembersWithGroupIDAndMembeAddrsQuery(self._resourceID, foreignMemberAddrsToDelete).on(
+ self._txn, memberAddrs=foreignMemberAddrsToDelete
+ )
- if foreignMemberAddrsToDelete:
- yield self._deleteForeignMembersWithGroupIDAndMembeAddrsQuery(self._resourceID, foreignMemberAddrsToDelete).on(
- self._txn, memberAddrs=foreignMemberAddrsToDelete
- )
+ for foreignMemberAddrToAdd in foreignMemberAddrsToAdd:
+ yield Insert(
+ {aboForeignMembers.GROUP_ID: self._resourceID,
+ aboForeignMembers.ADDRESSBOOK_ID: self._ownerAddressBookResourceID,
+ aboForeignMembers.MEMBER_ADDRESS: foreignMemberAddrToAdd, }
+ ).on(self._txn)
- if foreignMemberAddrsToAdd:
- print("updateDatabase:%s _insertForeignMemberAddrQuery:revision=%s foreignMemberAddrToAdd=%s" % (self, self._syncTokenRevision, foreignMemberAddrsToAdd,))
- for foreignMemberAddrToAdd in foreignMemberAddrsToAdd:
- yield Insert(
- {aboForeignMembers.GROUP_ID: self._resourceID,
- aboForeignMembers.ADDRESSBOOK_ID: self._ownerAddressBookResourceID,
- aboForeignMembers.MEMBER_ADDRESS: foreignMemberAddrToAdd, }
- ).on(self._txn)
-
@inlineCallbacks
def component(self):
"""
@@ -2507,7 +2494,7 @@
"""
shareeAddressBook = yield shareeHome.addressbookWithName(self.addressbook().shareeName())
- if shareeAddressBook:
+ if shareeAddressBook and shareeAddressBook._bindStatus == _BIND_STATUS_ACCEPTED:
acceptedBindCount = 1 if shareeAddressBook.fullyShared() else 0
acceptedBindCount += len((
@@ -2520,13 +2507,11 @@
yield shareeAddressBook._deletedSyncToken(sharedRemoval=True)
shareeHome._children.pop(self.addressbook().shareeName(), None)
shareeHome._children.pop(self.addressbook()._resourceID, None)
- else:
- yield shareeAddressBook._unshareRevision(self.name(), self._resourceID)
# Must send notification to ensure cache invalidation occurs
yield self.notifyChanged()
- # delete binds including invites
+ # delete bind including invites
deletedBindNameRows = yield self._deleteBindForResourceIDAndHomeID.on(
self._txn, resourceID=self._resourceID,
homeID=shareeHome._resourceID
@@ -2600,7 +2585,17 @@
else:
if status == _BIND_STATUS_ACCEPTED:
shareeView = yield shareeHome.objectWithShareUID(bindName)
- yield shareeView.addressbook()._initSyncToken()
+ if not shareeView.addressbook().fullyShared():
+ currentAcceptedBindCount = 1 if shareeView.addressbook().fullyShared() else 0
+ currentAcceptedBindCount += len((
+ yield AddressBookObject._acceptedBindForHomeIDAndAddressBookID.on(
+ self._txn, homeID=shareeView.viewerHome()._resourceID, addressbookID=shareeView.addressbook()._resourceID
+ )
+ ))
+ if currentAcceptedBindCount == 1:
+ yield shareeView.addressbook()._initSyncToken()
+
+ # start share here
yield shareeView._initBindRevision()
queryCacher = self._txn._queryCacher
@@ -2619,10 +2614,8 @@
return self.addressbook()._syncTokenRevision
- @inlineCallbacks
- def _initBindRevision(self):
- yield self.addressbook().syncToken() # init self.addressbook()._syncTokenRevision
- yield super(AddressBookObject, self)._initBindRevision()
+ def syncToken(self):
+ return self.addressbook().syncToken() # init self.addressbook()._syncTokenRevision
@inlineCallbacks
Modified: CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/common/datastore/sql.py 2013-09-14 13:37:14 UTC (rev 11689)
+++ CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/common/datastore/sql.py 2013-09-17 20:02:53 UTC (rev 11690)
@@ -2588,6 +2588,7 @@
resourceID=self._resourceID, name=name)
)[0][0]
self._maybeNotify()
+ returnValue(self._syncTokenRevision)
def _maybeNotify(self):
@@ -3101,6 +3102,7 @@
@inlineCallbacks
def _initBindRevision(self):
+ yield self.syncToken() # init self._syncTokenRevision if None
self._bindRevision = self._syncTokenRevision
bind = self._bindSchema
Modified: CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/common/datastore/sql_schema/current.sql
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/common/datastore/sql_schema/current.sql 2013-09-14 13:37:14 UTC (rev 11689)
+++ CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/common/datastore/sql_schema/current.sql 2013-09-17 20:02:53 UTC (rev 11690)
@@ -552,8 +552,7 @@
OBJECT_RESOURCE_ID integer default 0,
RESOURCE_NAME varchar(255),
REVISION integer default nextval('REVISION_SEQ') not null,
- DELETED boolean not null,
- UNSHARED boolean not null default false
+ DELETED boolean not null
);
create index ADDRESSBOOK_OBJECT_REVISIONS_HOME_RESOURCE_ID_OWNER_ADDRESSBOOK_HOME_RESOURCE_ID
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130917/57c0675a/attachment-0001.html>
More information about the calendarserver-changes
mailing list