[CalendarServer-changes] [9922] CalendarServer/branches/users/gaya/sharedgroups

source_changes at macosforge.org source_changes at macosforge.org
Wed Oct 10 19:33:59 PDT 2012


Revision: 9922
          http://trac.calendarserver.org//changeset/9922
Author:   gaya at apple.com
Date:     2012-10-10 19:33:59 -0700 (Wed, 10 Oct 2012)
Log Message:
-----------
add test_addressbookObjectMembers and make it work (almost)

Modified Paths:
--------------
    CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/vcard.py
    CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py
    CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/test/test_sql.py
    CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current.sql

Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/vcard.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/vcard.py	2012-10-11 02:33:10 UTC (rev 9921)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/vcard.py	2012-10-11 02:33:59 UTC (rev 9922)
@@ -427,12 +427,12 @@
 
     def resourceMembers(self):
         """
-        @return: an iterable of L{Property} objects, one for each member of this
+        @return: an iterable of X-ADDRESSBOOKSERVER-MEMBER property values
         """
         assert self.name() == "VCARD", "Not a vcard: %r" % (self,)
 
         if not hasattr(self, "_resource_members"):
-            self._resource_members = self.properties("X-ADDRESSBOOKSERVER-MEMBERS")
+            self._resource_members = [prop.value() for prop in list(self.properties("X-ADDRESSBOOKSERVER-MEMBER"))]
 
         return self._resource_members
 

Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py	2012-10-11 02:33:10 UTC (rev 9921)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py	2012-10-11 02:33:59 UTC (rev 9922)
@@ -237,40 +237,38 @@
     @inlineCallbacks
     def remove(self):
 
-        uid = self._uid
-        resourceID = self._resourceID
-        yield super(AddressBookObject, self).remove()
+        aboForeignMembers = schema.ABO_FOREIGN_MEMBERS
+        aboMembers = schema.ABO_MEMBERS
 
-        fmTable = schema.FOREIGN_MEMBERS
-        mTable = schema.MEMBERS
-
-        # delete members
-        yield Delete(
-            mTable,
-            Where=mTable.GROUP_ID == resourceID,
-        ).on(self._txn)
-
-        # delete foreign members
-        yield Delete(
-            fmTable,
-            Where=fmTable.GROUP_ID == resourceID,
-        ).on(self._txn)
-
         # delete members table row for this object
         groupIDs = yield Delete(
-            mTable,
-            Where=mTable.MEMBER_ID == resourceID,
-            Return=mTable.GROUP_ID
+            aboMembers,
+            Where=aboMembers.MEMBER_ID == self._resourceID,
+            Return=aboMembers.GROUP_ID
         ).on(self._txn)
 
         # add to foreign member table row by UID
         for groupID in groupIDs:
             yield Insert(
-                {fmTable.GROUP_ID: groupID,
-                  fmTable.MEMBER_ADDRESS: "urn:uuid" + uid, }
+                {aboForeignMembers.GROUP_ID: groupID,
+                  aboForeignMembers.MEMBER_ADDRESS: "urn:uuid:" + self._uid, }
             ).on(self._txn)
 
-        # Set to non-existent state
+        if self._kind == _ABO_KIND_GROUP:
+
+            # delete this group's members
+            yield Delete(
+                aboMembers,
+                Where=aboMembers.GROUP_ID == self._resourceID,
+            ).on(self._txn)
+
+            # delete this group's foreign members
+            yield Delete(
+                aboForeignMembers,
+                Where=aboForeignMembers.GROUP_ID == self._resourceID,
+            ).on(self._txn)
+
+        yield super(AddressBookObject, self).remove()
         self._kind = None
 
     @classproperty
@@ -331,6 +329,8 @@
         """
 
         abo = schema.ADDRESSBOOK_OBJECT
+        aboForeignMembers = schema.ABO_FOREIGN_MEMBERS
+        aboMembers = schema.ABO_MEMBERS
 
         componentText = str(component)
         self._objectText = componentText
@@ -357,9 +357,6 @@
         assert inserting or self._kind == kind  # can't change kind. Should be checked in upper layers
         self._kind = kind
 
-        fmTable = schema.FOREIGN_MEMBERS
-        mTable = schema.MEMBERS
-
         if inserting:
             self._resourceID, self._created, self._modified = (
                 yield Insert(
@@ -375,19 +372,18 @@
                 ).on(self._txn))[0]
 
             # update existing group member tables for this new object
-
             # delete foreign members table row for this object
             groupIDs = yield Delete(
-                fmTable,
-                Where=fmTable.MEMBER_ADDRESS == "urn:uuid" + self._uid,
-                Return=fmTable.GROUP_ID
+                aboForeignMembers,
+                Where=aboForeignMembers.MEMBER_ADDRESS == "urn:uuid:" + self._uid,
+                Return=aboForeignMembers.GROUP_ID
             ).on(self._txn)
 
             # add to member table row by resourceID
             for groupID in groupIDs:
                 yield Insert(
-                    {mTable.GROUP_ID: groupID,
-                     mTable.MEMBER_ID: self._resourceID, }
+                    {aboMembers.GROUP_ID: groupID,
+                     aboMembers.MEMBER_ID: self._resourceID, }
                 ).on(self._txn)
 
         else:
@@ -398,65 +394,65 @@
                 Where=abo.RESOURCE_ID == self._resourceID,
                 Return=abo.MODIFIED).on(self._txn))[0][0]
 
-        # if group, update members
+        if self._kind == _ABO_KIND_GROUP:
 
-        if self.kind == _ABO_KIND_GROUP:
-
             # get member resource ID for each member string, or keep as string
             memberIDs = []
             foreignMemberAddrs = []
-            for memberAddr in set(component.resourceMembers()):
+            for memberAddr in component.resourceMembers():
+                memberRow = []
                 if len(memberAddr) > len("urn:uuid:") and memberAddr.startswith("urn:uuid:"):
                     memberUID = memberAddr[len("urn:uuid:"):]
-                    memberID = (yield Select([abo.RESOURCE_ID],
+                    memberRow = yield Select([abo.RESOURCE_ID],
                                      From=abo,
                                      Where=((abo.ADDRESSBOOK_RESOURCE_ID == self._addressbook._resourceID)
-                                            ).And(abo.VCARD_UID == memberUID)).on(self._txn))[0][0]
-                if memberID:
-                    memberIDs.append(memberID)
+                                            ).And(abo.VCARD_UID == memberUID)).on(self._txn)
+                if memberRow:
+                    memberIDs.append(memberRow[0][0])
                 else:
                     foreignMemberAddrs.append(memberAddr)
 
             #get current members
-            [currentMemberIDs] = yield Select([mTable.MEMBER_ID],
-                                 From=mTable,
-                                 Where=(mTable.GROUP_ID == self._resourceID)).on(self._txn)
+            currentMemberIDs = yield Select([aboMembers.MEMBER_ID],
+                                 From=aboMembers,
+                                 Where=(aboMembers.GROUP_ID == self._resourceID)).on(self._txn)
 
             memberIDsToDelete = set(currentMemberIDs) - set(memberIDs)
+            memberIDsToAdd = set(memberIDs) - set(currentMemberIDs)
+
             for memberIDToDelete in memberIDsToDelete:
                 yield Delete(
-                    fmTable,
-                    Where=((mTable.GROUP_ID == self._resourceID).And(mTable.MEMBER_ID == memberIDToDelete))
+                    aboMembers,
+                    Where=((aboMembers.GROUP_ID == self._resourceID).And(aboMembers.MEMBER_ID == memberIDToDelete))
                 ).on(self._txn)
 
-            memberIDsToAdd = set(memberIDs) - set(currentMemberIDs)
             for memberIDToAdd in memberIDsToAdd:
                 yield Insert(
-                    {mTable.GROUP_ID: self._resourceID,
-                     mTable.MEMBER_ID: memberIDToAdd, }
+                    {aboMembers.GROUP_ID: self._resourceID,
+                     aboMembers.MEMBER_ID: memberIDToAdd, }
                 ).on(self._txn)
 
             #get current foreign members 
-            [currentForeignMemberAddrs] = yield Select([fmTable.MEMBER_ADDRESS],
-                                                 From=fmTable,
-                                                 Where=(fmTable.GROUP_ID == self._resourceID)).on(self._txn)
+            currentForeignMemberAddrs = yield Select([aboForeignMembers.MEMBER_ADDRESS],
+                                                 From=aboForeignMembers,
+                                                 Where=(aboForeignMembers.GROUP_ID == self._resourceID)).on(self._txn)
 
             foreignMemberAddrsToDelete = set(currentForeignMemberAddrs) - set(foreignMemberAddrs)
+            foreignMemberAddrsToAdd = set(foreignMemberAddrs) - set(currentForeignMemberAddrs)
+
             for foreignMemberAddrToDelete in foreignMemberAddrsToDelete:
                 yield Delete(
-                    fmTable,
-                    Where=((mTable.GROUP_ID == self._resourceID).And(mTable.MEMBER_ADDRESS == foreignMemberAddrToDelete))
+                    aboForeignMembers,
+                    Where=((aboMembers.GROUP_ID == self._resourceID).And(aboForeignMembers.MEMBER_ADDRESS == foreignMemberAddrToDelete))
                 ).on(self._txn)
 
-            foreignMemberAddrsToAdd = set(foreignMemberAddrs) - set(currentForeignMemberAddrs)
             for foreignMemberAddrToAdd in foreignMemberAddrsToAdd:
                 yield Insert(
-                    {mTable.GROUP_ID: self._resourceID,
-                     mTable.MEMBER_ADDRESS: foreignMemberAddrToAdd, }
+                    {aboForeignMembers.GROUP_ID: self._resourceID,
+                     aboForeignMembers.MEMBER_ADDRESS: foreignMemberAddrToAdd, }
                 ).on(self._txn)
 
 
-
     @inlineCallbacks
     def component(self):
         """

Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/test/test_sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/test/test_sql.py	2012-10-11 02:33:10 UTC (rev 9921)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/test/test_sql.py	2012-10-11 02:33:59 UTC (rev 9922)
@@ -263,7 +263,7 @@
 
         @inlineCallbacks
         def _defer1():
-            yield adbk1.createObjectResourceWithName("1.vcf", VCard.fromString(
+            yield adbk1.createAddressBookObjectWithName("1.vcf", VCard.fromString(
                 """BEGIN:VCARD
 VERSION:3.0
 N:Thompson;Default1;;;
@@ -282,7 +282,7 @@
 
         @inlineCallbacks
         def _defer2():
-            yield adbk2.createObjectResourceWithName("2.vcf", VCard.fromString(
+            yield adbk2.createAddressBookObjectWithName("2.vcf", VCard.fromString(
                 """BEGIN:VCARD
 VERSION:3.0
 N:Thompson;Default2;;;
@@ -331,7 +331,7 @@
 """.replace("\n", "\r\n")
             )
         self.assertEqual(person.resourceUID(), "uid1")
-        abObject = yield adbk.createObjectResourceWithName("1.vcf", person)
+        abObject = yield adbk.createAddressBookObjectWithName("1.vcf", person)
         self.assertEqual(abObject.uid(), "uid1")
         yield txn.commit()
 
@@ -375,7 +375,7 @@
 """.replace("\n", "\r\n")
             )
         self.assertEqual(person.resourceKind(), None)
-        abObject = yield adbk.createObjectResourceWithName("p.vcf", person)
+        abObject = yield adbk.createAddressBookObjectWithName("p.vcf", person)
         self.assertEqual(abObject.kind(), _ABO_KIND_PERSON)
 
         group = VCard.fromString(
@@ -392,7 +392,7 @@
 """.replace("\n", "\r\n")
             )
         abObject = self.assertEqual(group.resourceKind(), "group")
-        abObject = yield adbk.createObjectResourceWithName("g.vcf", group)
+        abObject = yield adbk.createAddressBookObjectWithName("g.vcf", group)
         self.assertEqual(abObject.kind(), _ABO_KIND_GROUP)
 
         badgroup = VCard.fromString(
@@ -409,7 +409,7 @@
 """.replace("\n", "\r\n")
             )
         abObject = self.assertEqual(badgroup.resourceKind(), "badgroup")
-        abObject = yield adbk.createObjectResourceWithName("bg.vcf", badgroup)
+        abObject = yield adbk.createAddressBookObjectWithName("bg.vcf", badgroup)
         self.assertEqual(abObject.kind(), _ABO_KIND_PERSON)
 
         yield txn.commit()
@@ -436,7 +436,93 @@
         yield txn.commit()
 
 
+    @inlineCallbacks
+    def test_addressbookObjectMembers(self):
+        """
+        Test that kind property vCard is stored correctly in database
+        """
+        addressbookStore = yield buildStore(self, self.notifierFactory)
 
+        # Provision the home and addressbook, one user and one group
+        txn = addressbookStore.newTransaction()
+        home = yield txn.homeWithUID(EADDRESSBOOKTYPE, "uid1", create=True)
+        self.assertNotEqual(home, None)
+        adbk = yield home.addressbookWithName("addressbook")
+        self.assertNotEqual(adbk, None)
+
+        person = VCard.fromString(
+            """BEGIN:VCARD
+VERSION:3.0
+N:Thompson;Default;;;
+FN:Default Thompson
+EMAIL;type=INTERNET;type=WORK;type=pref:lthompson at example.com
+TEL;type=WORK;type=pref:1-555-555-5555
+TEL;type=CELL:1-444-444-4444
+item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;USA
+item1.X-ABADR:us
+UID:uid1
+END:VCARD
+""".replace("\n", "\r\n")
+            )
+        self.assertEqual(person.resourceKind(), None)
+        personObject = yield adbk.createAddressBookObjectWithName("p.vcf", person)
+
+        group = VCard.fromString(
+            """BEGIN:VCARD
+VERSION:3.0
+PRODID:-//Apple Inc.//AddressBook 6.1//EN
+UID:uid2
+FN:Top Group
+N:Top Group;;;;
+REV:20120503T194243Z
+X-ADDRESSBOOKSERVER-KIND:group
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:uid3
+END:VCARD
+""".replace("\n", "\r\n")
+            )
+        groupObject = yield adbk.createAddressBookObjectWithName("g.vcf", group)
+
+        aboForeignMembers = schema.ABO_FOREIGN_MEMBERS
+        aboMembers = schema.ABO_MEMBERS
+        memberRows = yield Select([aboMembers.GROUP_ID, aboMembers.MEMBER_ID], From=aboMembers,).on(txn)
+        self.assertEqual(memberRows, [])
+
+        foreignMemberRows = yield Select([aboForeignMembers.GROUP_ID, aboForeignMembers.MEMBER_ADDRESS], From=aboForeignMembers).on(txn)
+        self.assertEqual(foreignMemberRows, [[groupObject._resourceID, "urn:uuid:uid3"]])
+
+        subgroup = VCard.fromString(
+            """BEGIN:VCARD
+VERSION:3.0
+PRODID:-//Apple Inc.//AddressBook 6.1//EN
+UID:uid3
+FN:Sub Group
+N:Sub Group;;;;
+REV:20120503T194243Z
+X-ADDRESSBOOKSERVER-KIND:group
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:uid1
+END:VCARD
+""".replace("\n", "\r\n")
+            )
+        subgroupObject = yield adbk.createAddressBookObjectWithName("sg.vcf", subgroup)
+
+        memberRows = yield Select([aboMembers.GROUP_ID, aboMembers.MEMBER_ID], From=aboMembers,).on(txn)
+        self.assertEqual(memberRows.sort(), [[groupObject._resourceID, subgroupObject._resourceID], [subgroupObject._resourceID, personObject._resourceID]].sort())
+
+        foreignMemberRows = yield Select([aboForeignMembers.GROUP_ID, aboForeignMembers.MEMBER_ADDRESS], From=aboForeignMembers).on(txn)
+        self.assertEqual(foreignMemberRows, [])
+
+
+        yield adbk.removeAddressBookObjectWithName("sg.vcf")
+        memberRows = yield Select([aboMembers.GROUP_ID, aboMembers.MEMBER_ID], From=aboMembers,).on(txn)
+        self.assertEqual(memberRows, [])
+
+        foreignMemberRows = yield Select([aboForeignMembers.GROUP_ID, aboForeignMembers.MEMBER_ADDRESS], From=aboForeignMembers).on(txn)
+        self.assertEqual(foreignMemberRows, [[groupObject._resourceID, "urn:uuid:uid3"]])
+
+        yield txn.commit()
+
+
+
     @inlineCallbacks
     def test_removeAddressBookPropertiesOnDelete(self):
         """

Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current.sql
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current.sql	2012-10-11 02:33:10 UTC (rev 9921)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current.sql	2012-10-11 02:33:59 UTC (rev 9922)
@@ -389,21 +389,21 @@
 insert into ADDRESS_BOOK_OBJECT_KIND values (2, 'resource');
 insert into ADDRESS_BOOK_OBJECT_KIND values (3, 'location');
 
--------------
--- Members --
--------------
+---------------------------------
+-- Address Book Object Members --
+---------------------------------
 
-create table MEMBERS (
+create table ABO_MEMBERS (
     GROUP_ID              integer      references ADDRESSBOOK_OBJECT,			-- AddressBook Object's (kind=='group') RESOURCE_ID
     MEMBER_ID             integer      not null references ADDRESSBOOK_OBJECT,	-- member AddressBook Object's RESOURCE_ID
     primary key(GROUP_ID, MEMBER_ID) -- implicit index
 );
 
-----------------------
--- Foreign Members  --
-----------------------
+------------------------------------------
+-- Address Book Object Foreign Members  --
+------------------------------------------
 
-create table FOREIGN_MEMBERS (
+create table ABO_FOREIGN_MEMBERS (
     GROUP_ID              integer      references ADDRESSBOOK_OBJECT,	-- AddressBook Object's (kind=='group') RESOURCE_ID
     MEMBER_ADDRESS  	  varchar(255) not null, 						-- member AddressBook Object's address
     primary key(GROUP_ID, MEMBER_ADDRESS) -- implicit index
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20121010/5d1fb33d/attachment-0001.html>


More information about the calendarserver-changes mailing list