[CalendarServer-changes] [11127] CalendarServer/branches/users/cdaboo/store-scheduling

source_changes at macosforge.org source_changes at macosforge.org
Fri May 3 11:58:13 PDT 2013


Revision: 11127
          http://trac.calendarserver.org//changeset/11127
Author:   cdaboo at apple.com
Date:     2013-05-03 11:58:13 -0700 (Fri, 03 May 2013)
Log Message:
-----------
Remove ResourceType from dead prop store.

Modified Paths:
--------------
    CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/cache.py
    CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/customxml.py
    CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/directory/aggregate.py
    CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/sharing.py
    CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/storebridge.py
    CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_addressbookmultiget.py
    CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_addressbookquery.py
    CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_mkcalendar.py
    CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_props.py
    CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_resource.py
    CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_sharing.py
    CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/file.py
    CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/sql.py
    CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/test/common.py
    CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/test/test_sql.py
    CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/file.py
    CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/sql.py
    CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/test/common.py
    CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/test/test_sql.py
    CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/file.py
    CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/sql.py
    CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/upgrade/sql/upgrades/test/test_upgrade_from_3_to_4.py
    CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/upgrade/sql/upgrades/upgrade_from_3_to_4.py

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/cache.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/cache.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/cache.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -20,8 +20,7 @@
 
 from zope.interface import implements
 
-from twisted.internet.defer import succeed, maybeDeferred, inlineCallbacks, \
-    returnValue
+from twisted.internet.defer import succeed, inlineCallbacks, returnValue
 from twext.web2.dav.util import allDataFromStream
 from twext.web2.http import Response
 from twext.web2.iweb import IResource
@@ -440,21 +439,19 @@
     A mixin that causes a resource's PROPFIND response to be cached. It also adds an api to change the
     resource's uriToken - this must be used whenever something changes to cause the cache to be invalidated.
     """
+
+    @inlineCallbacks
     def renderHTTP(self, request):
-        def _cacheResponse(responseCache, response):
-            return responseCache.cacheResponseForRequest(request, response)
+        response = (yield super(PropfindCacheMixin, self).renderHTTP(request))
 
-        def _getResponseCache(response):
-            d1 = request.locateResource("/")
-            d1.addCallback(lambda resource: resource.responseCache)
-            d1.addCallback(_cacheResponse, response)
-            return d1
+        if request.method == 'PROPFIND':
+            resource = (yield request.locateResource("/"))
 
-        d = maybeDeferred(super(PropfindCacheMixin, self).renderHTTP, request)
+            # responseCache might not be present during unit tests
+            if hasattr(resource, "responseCache"):
+                yield resource.responseCache.cacheResponseForRequest(request, response)
 
-        if request.method == 'PROPFIND':
-            d.addCallback(_getResponseCache)
-        return d
+        returnValue(response)
 
 
     def changeCache(self):

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/customxml.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/customxml.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/customxml.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -468,8 +468,6 @@
 
 
 
-
-
 PrincipalPropertySearch.allowed_children[(calendarserver_namespace, "limit")] = (0, 1)
 PrincipalPropertySearch.allowed_attributes["type"] = False
 Match.allowed_attributes = {
@@ -1460,6 +1458,7 @@
 
 ResourceType.sharedownercalendar = ResourceType(Collection(), caldavxml.Calendar(), SharedOwner())
 ResourceType.sharedcalendar = ResourceType(Collection(), caldavxml.Calendar(), Shared())
+ResourceType.sharedowneraddressbook = ResourceType(Collection(), carddavxml.AddressBook(), SharedOwner())
 ResourceType.sharedaddressbook = ResourceType(Collection(), carddavxml.AddressBook(), Shared())
 
 ResourceType.link = ResourceType(Link())

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/directory/aggregate.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/directory/aggregate.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/directory/aggregate.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -119,6 +119,37 @@
 
     addressBookHomesCollection = property(_getAddressBookHomesCollection, _setAddressBookHomesCollection)
 
+
+    def addService(self, service):
+        """
+        Add another service to this aggregate.
+
+        @param service: the service to add
+        @type service: L{IDirectoryService}
+        """
+        service = IDirectoryService(service)
+
+        if service.realmName != self.realmName:
+            assert self.realmName is None, (
+                "Aggregated directory services must have the same realm name: %r != %r\nServices: %r"
+                % (service.realmName, self.realmName, service)
+            )
+
+        if not hasattr(service, "recordTypePrefix"):
+            service.recordTypePrefix = ""
+        prefix = service.recordTypePrefix
+
+        for recordType in (prefix + r for r in service.recordTypes()):
+            if recordType in self._recordTypes:
+                raise DuplicateRecordTypeError(
+                    "%r is in multiple services: %s, %s"
+                    % (recordType, self.recordTypes[recordType], service)
+                )
+            self._recordTypes[recordType] = service
+
+        service.aggregateService = self
+
+
     def recordTypes(self):
         return set(self._recordTypes)
 

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/sharing.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/sharing.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/sharing.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -88,8 +88,7 @@
                 )
 
             # See if this property is on the shared calendar
-            isShared = yield self.isShared(request)
-            if isShared:
+            if self.isShared():
                 yield self.validateInvites(request)
                 invitations = yield self._allInvitations()
                 returnValue(customxml.Invite(
@@ -117,25 +116,21 @@
         returnValue(None)
 
 
+    @inlineCallbacks
     def upgradeToShare(self):
         """
         Set the resource-type property on this resource to indicate that this
         is the owner's version of a resource which has been shared.
         """
-        # Change resourcetype
-        rtype = self.resourceType()
-        rtype = element.ResourceType(*(rtype.children + (customxml.SharedOwner(),)))
-        self.writeDeadProperty(rtype)
+        # Change status on store object
+        yield self._newStoreObject.setShared(True)
 
 
     @inlineCallbacks
     def downgradeFromShare(self, request):
 
-        # Change resource type (note this might be called after deleting a resource
-        # so we have to cope with that)
-        rtype = self.resourceType()
-        rtype = element.ResourceType(*([child for child in rtype.children if child != customxml.SharedOwner()]))
-        self.writeDeadProperty(rtype)
+        # Change status on store object
+        yield self._newStoreObject.setShared(False)
 
         # Remove all invitees
         for invitation in (yield self._allInvitations()):
@@ -146,8 +141,7 @@
 
     @inlineCallbacks
     def changeUserInviteState(self, request, inviteUID, shareeUID, state, summary=None):
-        shared = (yield self.isShared(request))
-        if not shared:
+        if not self.isShared():
             raise HTTPError(ErrorResponse(
                 responsecode.FORBIDDEN,
                 (customxml.calendarserver_namespace, "valid-request"),
@@ -241,12 +235,11 @@
         returnValue(response)
 
 
-    @inlineCallbacks
-    def isShared(self, request):
+    def isShared(self):
         """
         Return True if this is an owner shared calendar collection.
         """
-        returnValue((yield self.isSpecialCollection(customxml.SharedOwner)))
+        return self._newStoreObject.isShared() if self._newStoreObject else False
 
 
     def setShare(self, share):
@@ -278,26 +271,6 @@
         returnValue((yield shareeHome.removeShare(request, self._share)))
 
 
-    def resourceType(self):
-        superObject = super(SharedCollectionMixin, self)
-        try:
-            superMethod = superObject.resourceType
-        except AttributeError:
-            rtype = element.ResourceType()
-        else:
-            rtype = superMethod()
-
-        isShareeCollection = self.isShareeCollection()
-        if isShareeCollection:
-            rtype = element.ResourceType(
-                *(
-                    tuple([child for child in rtype.children if child.qname() != customxml.SharedOwner.qname()]) +
-                    (customxml.Shared(),)
-                )
-            )
-        return rtype
-
-
     def sharedResourceType(self):
         """
         Return the DAV:resourcetype stripped of any shared elements.
@@ -896,11 +869,11 @@
         numRecords = (yield self.validateInvites(request))
 
         # Set the sharing state on the collection
-        shared = (yield self.isShared(request))
+        shared = self.isShared()
         if shared and numRecords == 0:
             yield self.downgradeFromShare(request)
         elif not shared and numRecords != 0:
-            self.upgradeToShare()
+            yield self.upgradeToShare()
 
         # Create the multistatus response - only needed if some are bad
         if badusers:

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/storebridge.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/storebridge.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/storebridge.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -70,7 +70,7 @@
     UIDExistsElsewhereError, InvalidUIDError, InvalidResourceMove, \
     InvalidComponentForStoreError
 from txdav.idav import PropertyChangeNotAllowedError
-from txdav.xml import element as davxml
+from txdav.xml import element as davxml, element
 from txdav.xml.base import dav_namespace, WebDAVUnknownElement, encodeXMLName
 
 from urlparse import urlsplit
@@ -494,7 +494,7 @@
         # Now do normal delete
 
         # Handle sharing
-        wasShared = (yield self.isShared(request))
+        wasShared = self.isShared()
         if wasShared:
             yield self.downgradeFromShare(request)
 
@@ -1085,6 +1085,15 @@
         return True
 
 
+    def resourceType(self):
+        if self.isShared():
+            return customxml.ResourceType.sharedownercalendar
+        elif self.isShareeCollection():
+            return customxml.ResourceType.sharedcalendar
+        else:
+            return caldavxml.ResourceType.calendar
+
+
     @inlineCallbacks
     def iCalendarRolledup(self, request):
         # FIXME: uncached: implement cache in the storage layer
@@ -2905,6 +2914,15 @@
         """
         return True
 
+
+    def resourceType(self):
+        if self.isShared():
+            return customxml.ResourceType.sharedowneraddressbook
+        elif self.isShareeCollection():
+            return customxml.ResourceType.sharedaddressbook
+        else:
+            return carddavxml.ResourceType.addressbook
+
     createAddressBookCollection = _CommonHomeChildCollectionMixin.createCollection
 
 

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_addressbookmultiget.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_addressbookmultiget.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_addressbookmultiget.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -15,27 +15,22 @@
 ##
 
 import os
-import shutil
 
 from twext.web2 import responsecode
 from twext.web2.iweb import IResponse
 from twext.web2.stream import MemoryStream
 from txdav.xml import element as davxml
-from twext.web2.dav.fileop import rmdir
-from twext.web2.dav.util import davXMLFromStream
-from twext.web2.test.test_server import SimpleRequest
+from twext.web2.dav.util import davXMLFromStream, joinURL
 
 from twistedcaldav import carddavxml
 from twistedcaldav import vcard
 
-# FIXME: remove this, we should not be importing this module, we should be
-# testing the public API.  See comments below about cheating.
-from txdav.carddav.datastore.index_file import db_basename
-
 from twistedcaldav.config import config
-from twistedcaldav.test.util import AddressBookHomeTestCase
+from twistedcaldav.test.util import StoreTestCase, SimpleStoreRequest
+from twisted.python.filepath import FilePath
+from twisted.internet.defer import inlineCallbacks, returnValue
 
-class AddressBookMultiget (AddressBookHomeTestCase):
+class AddressBookMultiget (StoreTestCase):
     """
     addressbook-multiget REPORT
     """
@@ -53,6 +48,7 @@
 
         return self.simple_vcard_multiget("/addressbook_multiget_vcards/", okuids, baduids)
 
+
     def test_multiget_all_vcards(self):
         """
         All vcards.
@@ -63,6 +59,7 @@
 
         return self.simple_vcard_multiget("/addressbook_multiget_vcards/", okuids, baduids)
 
+
     def test_multiget_limited_with_data(self):
         """
         All vcards.
@@ -85,6 +82,7 @@
         d.addCallbacks(_restoreValueOK, _restoreValueError)
         return d
 
+
     def test_multiget_limited_no_data(self):
         """
         All vcards.
@@ -105,7 +103,11 @@
 
         return self.simple_vcard_multiget("/addressbook_multiget_vcards/", okuids, baduids, withData=False)
 
+
     def simple_vcard_multiget(self, vcard_uri, okuids, baduids, data=None, no_init=False, withData=True):
+
+        vcard_uri = joinURL("/addressbooks/users/wsanchez", vcard_uri)
+
         props = (
             davxml.GETETag(),
         )
@@ -115,14 +117,14 @@
             )
         children = []
         children.append(davxml.PropertyContainer(*props))
-        
+
         okhrefs = [vcard_uri + x + ".vcf" for x in okuids]
         badhrefs = [vcard_uri + x + ".vcf" for x in baduids]
         for href in okhrefs + badhrefs:
             children.append(davxml.HRef.fromString(href))
-        
+
         query = carddavxml.AddressBookMultiGet(*children)
-        
+
         def got_xml(doc):
             if not isinstance(doc.root_element, davxml.MultiStatus):
                 self.fail("REPORT response XML root element is not multistatus: %r" % (doc.root_element,))
@@ -140,7 +142,8 @@
 
                     for property in properties:
                         qname = property.qname()
-                        if qname == (davxml.dav_namespace, "getetag"): continue
+                        if qname == (davxml.dav_namespace, "getetag"):
+                            continue
                         if qname != (carddavxml.carddav_namespace, "address-data"):
                             self.fail("Response included unexpected property %r" % (property,))
 
@@ -163,7 +166,7 @@
                             original_address = vcard.Component.fromStream(original_filename)
 
                         self.assertEqual(result_address, original_address)
-            
+
             for response in doc.root_element.childrenOfType(davxml.StatusResponse):
                 href = str(response.childOfType(davxml.HRef))
                 propstatus = response.childOfType(davxml.PropertyStatus)
@@ -181,58 +184,17 @@
                             continue
                         else:
                             self.fail("Got unexpected href %r" % (href,))
-        
+
             if withData and (len(okuids) + len(badhrefs)):
                 self.fail("Some components were not returned: %r, %r" % (okuids, badhrefs))
 
         return self.addressbook_query(vcard_uri, query, got_xml, data, no_init)
 
+
+    @inlineCallbacks
     def addressbook_query(self, addressbook_uri, query, got_xml, data, no_init):
-        addressbook_path = os.path.join(self.docroot, addressbook_uri[1:])
 
-        if not no_init and os.path.exists(addressbook_path): rmdir(addressbook_path)
-
-        def do_report(response):
-            if not no_init:
-                response = IResponse(response)
-    
-                if response.code != responsecode.CREATED:
-                    self.fail("MKCOL failed: %s" % (response.code,))
-    
-                if data:
-                    for filename, icaldata in data.iteritems():
-                        path = os.path.join(addressbook_path, filename + ".vcf")
-                        f = open(path, "w")
-                        f.write(icaldata)
-                        f.close()
-                else:
-                    # Add vcards to addressbook
-                    # We're cheating by simply copying the files in
-                    for filename in os.listdir(self.vcards_dir):
-                        if os.path.splitext(filename)[1] != ".vcf": continue
-                        path = os.path.join(self.vcards_dir, filename)
-                        shutil.copy(path, addressbook_path)
-    
-                # Delete the index because we cheated
-                index_path = os.path.join(addressbook_path, db_basename)
-                if os.path.isfile(index_path): os.remove(index_path)
-
-            request = SimpleRequest(self.site, "REPORT", addressbook_uri)
-            request.stream = MemoryStream(query.toxml())
-
-            def do_test(response):
-                response = IResponse(response)
-
-                if response.code != responsecode.MULTI_STATUS:
-                    self.fail("REPORT failed: %s" % (response.code,))
-
-                return davXMLFromStream(response.stream).addCallback(got_xml)
-
-            return self.send(request, do_test)
-
-        if no_init:
-            return do_report(None)
-        else:
+        if not no_init:
             mkcol = """<?xml version="1.0" encoding="utf-8" ?>
 <D:mkcol xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:carddav">
 <D:set>
@@ -242,6 +204,36 @@
 </D:set>
 </D:mkcol>
 """
-            request = SimpleRequest(self.site, "MKCOL", addressbook_uri, content=mkcol)
-    
-            return self.send(request, do_report)
+            response = yield self.send(SimpleStoreRequest(self, "MKCOL", addressbook_uri, content=mkcol, authid="wsanchez"))
+
+            response = IResponse(response)
+
+            if response.code != responsecode.CREATED:
+                self.fail("MKCOL failed: %s" % (response.code,))
+
+            if data:
+                for filename, icaldata in data.iteritems():
+                    request = SimpleStoreRequest(self, "PUT", joinURL(addressbook_uri, filename + ".vcf"), authid="wsanchez")
+                    request.stream = MemoryStream(icaldata)
+                    yield self.send(request)
+            else:
+                # Add vcards to addressbook
+                for child in FilePath(self.vcards_dir).children():
+                    if os.path.splitext(child.basename())[1] != ".vcf":
+                        continue
+                    request = SimpleStoreRequest(self, "PUT", joinURL(addressbook_uri, child.basename()), authid="wsanchez")
+                    request.stream = MemoryStream(child.getContent())
+                    yield self.send(request)
+
+        request = SimpleStoreRequest(self, "REPORT", addressbook_uri, authid="wsanchez")
+        request.stream = MemoryStream(query.toxml())
+        response = yield self.send(request)
+
+        response = IResponse(response)
+
+        if response.code != responsecode.MULTI_STATUS:
+            self.fail("REPORT failed: %s" % (response.code,))
+
+        returnValue(
+            (yield davXMLFromStream(response.stream).addCallback(got_xml))
+        )

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_addressbookquery.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_addressbookquery.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_addressbookquery.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -15,25 +15,20 @@
 ##
 
 import os
-import shutil
 
 from twext.web2 import responsecode
 from twext.web2.iweb import IResponse
 from twext.web2.stream import MemoryStream
 from txdav.xml import element as davxml
-from twext.web2.dav.fileop import rmdir
-from twext.web2.dav.util import davXMLFromStream
-from twext.web2.test.test_server import SimpleRequest
+from twext.web2.dav.util import davXMLFromStream, joinURL
 
-# FIXME: remove this, we should not be importing this module, we should be
-# testing the public API.  See comments below about cheating.
-from txdav.carddav.datastore.index_file import db_basename
-
 from twistedcaldav import carddavxml, vcard
 from twistedcaldav.config import config
-from twistedcaldav.test.util import AddressBookHomeTestCase
+from twistedcaldav.test.util import StoreTestCase, SimpleStoreRequest
+from twisted.internet.defer import inlineCallbacks, returnValue
+from twisted.python.filepath import FilePath
 
-class AddressBookQuery (AddressBookHomeTestCase):
+class AddressBookQuery(StoreTestCase):
     """
     addressbook-query REPORT
     """
@@ -55,6 +50,7 @@
             [uid]
         )
 
+
     def test_addressbook_query_all_vcards(self):
         """
         All vCards.
@@ -63,11 +59,12 @@
 
         return self.simple_vcard_query("/addressbook_query_vcards/", None, uids)
 
+
     def test_addressbook_query_limited_with_data(self):
         """
         All vCards.
         """
-        
+
         oldValue = config.MaxQueryWithDataResults
         config.MaxQueryWithDataResults = 1
         def _restoreValueOK(f):
@@ -84,11 +81,12 @@
         d.addCallbacks(_restoreValueOK, _restoreValueError)
         return d
 
+
     def test_addressbook_query_limited_without_data(self):
         """
         All vCards.
         """
-        
+
         oldValue = config.MaxQueryWithDataResults
         config.MaxQueryWithDataResults = 1
         def _restoreValueOK(f):
@@ -105,7 +103,11 @@
         d.addCallbacks(_restoreValueOK, _restoreValueError)
         return d
 
-    def simple_vcard_query(self, cal_uri, vcard_filter, uids, withData=True, limit=None):
+
+    def simple_vcard_query(self, vcard_uri, vcard_filter, uids, withData=True, limit=None):
+
+        vcard_uri = joinURL("/addressbooks/users/wsanchez", vcard_uri)
+
         props = (
             davxml.GETETag(),
         )
@@ -142,7 +144,8 @@
 
                     for property in properties:
                         qname = property.qname()
-                        if qname == (davxml.dav_namespace, "getetag"): continue
+                        if qname == (davxml.dav_namespace, "getetag"):
+                            continue
                         if qname != (carddavxml.carddav_namespace, "address-data"):
                             self.fail("Response included unexpected property %r" % (property,))
 
@@ -165,44 +168,13 @@
 
                 if limit is not None and count != limit:
                     self.fail("Wrong number of limited results: %d" % (count,))
-                    
-        return self.addressbook_query(cal_uri, query, got_xml)
 
-    def addressbook_query(self, addressbook_uri, query, got_xml):
-        addressbook_path = os.path.join(self.docroot, addressbook_uri[1:])
+        return self.addressbook_query(vcard_uri, query, got_xml)
 
-        if os.path.exists(addressbook_path): rmdir(addressbook_path)
 
-        def do_report(response):
-            response = IResponse(response)
+    @inlineCallbacks
+    def addressbook_query(self, addressbook_uri, query, got_xml):
 
-            if response.code != responsecode.CREATED:
-                self.fail("MKCOL failed: %s" % (response.code,))
-
-            # Add vCards to addressbook
-            # We're cheating by simply copying the files in
-            for filename in os.listdir(self.vcards_dir):
-                if os.path.splitext(filename)[1] != ".vcf": continue
-                path = os.path.join(self.vcards_dir, filename)
-                shutil.copy(path, addressbook_path)
-
-            # Delete the index because we cheated
-            index_path = os.path.join(addressbook_path, db_basename)
-            if os.path.isfile(index_path): os.remove(index_path)
-
-            request = SimpleRequest(self.site, "REPORT", addressbook_uri)
-            request.stream = MemoryStream(query.toxml())
-
-            def do_test(response):
-                response = IResponse(response)
-
-                if response.code != responsecode.MULTI_STATUS:
-                    self.fail("REPORT failed: %s" % (response.code,))
-
-                return davXMLFromStream(response.stream).addCallback(got_xml)
-
-            return self.send(request, do_test)
-
         mkcol = """<?xml version="1.0" encoding="utf-8" ?>
 <D:mkcol xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:carddav">
 <D:set>
@@ -212,6 +184,30 @@
 </D:set>
 </D:mkcol>
 """
-        request = SimpleRequest(self.site, "MKCOL", addressbook_uri, content=mkcol)
+        response = yield self.send(SimpleStoreRequest(self, "MKCOL", addressbook_uri, content=mkcol, authid="wsanchez"))
 
-        return self.send(request, do_report)
+        response = IResponse(response)
+
+        if response.code != responsecode.CREATED:
+            self.fail("MKCOL failed: %s" % (response.code,))
+
+        # Add vCards to addressbook
+        for child in FilePath(self.vcards_dir).children():
+            if os.path.splitext(child.basename())[1] != ".vcf":
+                continue
+            request = SimpleStoreRequest(self, "PUT", joinURL(addressbook_uri, child.basename()), authid="wsanchez")
+            request.stream = MemoryStream(child.getContent())
+            yield self.send(request)
+
+        request = SimpleStoreRequest(self, "REPORT", addressbook_uri, authid="wsanchez")
+        request.stream = MemoryStream(query.toxml())
+        response = yield self.send(request)
+
+        response = IResponse(response)
+
+        if response.code != responsecode.MULTI_STATUS:
+            self.fail("REPORT failed: %s" % (response.code,))
+
+        returnValue(
+            (yield davXMLFromStream(response.stream).addCallback(got_xml))
+        )

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_mkcalendar.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_mkcalendar.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_mkcalendar.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -23,12 +23,11 @@
 from twext.web2.stream import MemoryStream
 from txdav.xml import element as davxml
 from twext.web2.dav.fileop import rmdir
-from twext.web2.test.test_server import SimpleRequest
 
 from twistedcaldav import caldavxml
-from twistedcaldav.test.util import HomeTestCase
+from twistedcaldav.test.util import StoreTestCase, SimpleStoreRequest
 
-class MKCALENDAR (HomeTestCase):
+class MKCALENDAR (StoreTestCase):
     """
     MKCALENDAR request
     """
@@ -40,13 +39,13 @@
         """
         Make calendar
         """
-        uri  = "/calendar_make/"
+        uri = "/calendars/users/user01/calendar_make/"
         path = os.path.join(self.docroot, uri[1:])
 
         if os.path.exists(path):
             rmdir(path)
 
-        request = SimpleRequest(self.site, "MKCALENDAR", uri)
+        request = SimpleStoreRequest(self, "MKCALENDAR", uri, authid="user01")
 
         @inlineCallbacks
         def do_test(response):
@@ -65,11 +64,12 @@
 
         return self.send(request, do_test)
 
+
     def test_make_calendar_with_props(self):
         """
         Make calendar with properties (CalDAV-access-09, section 5.3.1.2)
         """
-        uri  = "/calendar_prop/"
+        uri = "/calendars/users/user01/calendar_prop/"
         path = os.path.join(self.docroot, uri[1:])
 
         if os.path.exists(path):
@@ -110,7 +110,7 @@
             tz = tz.calendar()
             self.failUnless(tz.resourceType() == "VTIMEZONE")
             self.failUnless(tuple(tz.subcomponents())[0].propertyValue("TZID") == "US-Eastern")
-        
+
         mk = caldavxml.MakeCalendar(
             davxml.Set(
                 davxml.PropertyContainer(
@@ -146,7 +146,7 @@
             )
         )
 
-        request = SimpleRequest(self.site, "MKCALENDAR", uri)
+        request = SimpleStoreRequest(self, "MKCALENDAR", uri, authid="user01")
         request.stream = MemoryStream(mk.toxml())
         return self.send(request, do_test)
 
@@ -155,12 +155,8 @@
         """
         Make calendar on existing collection
         """
-        uri  = "/calendar_on_resource/"
-        path = os.path.join(self.docroot, uri[1:])
+        uri = "/calendars/users/user01/calendar/"
 
-        if not os.path.exists(path):
-            os.mkdir(path)
-
         def do_test(response):
             response = IResponse(response)
 
@@ -169,18 +165,17 @@
 
             # FIXME: Check for DAV:resource-must-be-null element
 
-        request = SimpleRequest(self.site, "MKCALENDAR", uri)
+        request = SimpleStoreRequest(self, "MKCALENDAR", uri, authid="user01")
         return self.send(request, do_test)
 
+
     def test_make_calendar_in_calendar(self):
         """
         Make calendar in calendar
         """
-        first_uri  = "/calendar_in_calendar/"
-        first_path = os.path.join(self.docroot, first_uri[1:])
+        first_uri = "/calendars/users/user01/calendar_in_calendar/"
 
-        if os.path.exists(first_path): rmdir(first_path)
-
+        @inlineCallbacks
         def next(response):
             response = IResponse(response)
 
@@ -193,10 +188,10 @@
                 if response.code != responsecode.FORBIDDEN:
                     self.fail("Incorrect response to nested MKCALENDAR: %s" % (response.code,))
 
-            nested_uri  = os.path.join(first_uri, "nested")
+            nested_uri = os.path.join(first_uri, "nested")
 
-            request = SimpleRequest(self.site, "MKCALENDAR", nested_uri)
-            self.send(request, do_test)
+            request = SimpleStoreRequest(self, "MKCALENDAR", nested_uri, authid="user01")
+            yield self.send(request, do_test)
 
-        request = SimpleRequest(self.site, "MKCALENDAR", first_uri)
+        request = SimpleStoreRequest(self, "MKCALENDAR", first_uri, authid="user01")
         return self.send(request, next)

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_props.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_props.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_props.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -14,20 +14,17 @@
 # limitations under the License.
 ##
 
+from twext.web2 import responsecode, http_headers
+from twext.web2.dav.util import davXMLFromStream
+from twext.web2.iweb import IResponse
 from twext.web2.stream import MemoryStream
 
-import os
+from twistedcaldav import caldavxml
+from twistedcaldav.test.util import StoreTestCase, SimpleStoreRequest
 
-from twext.web2 import responsecode, http_headers
-from twext.web2.iweb import IResponse
 from txdav.xml import element as davxml
-from twext.web2.dav.util import davXMLFromStream
-from twext.web2.test.test_server import SimpleRequest
-from twistedcaldav import caldavxml
 
-from twistedcaldav.test.util import HomeTestCase
-
-class Properties(HomeTestCase):
+class Properties(StoreTestCase):
     """
     CalDAV properties
     """
@@ -35,8 +32,7 @@
         """
         Live CalDAV properties
         """
-        calendar_path, calendar_uri = self.mkdtemp("live_props")
-        os.rmdir(calendar_path)
+        calendar_uri = "/calendars/users/user01/test/"
 
         def mkcalendar_cb(response):
             response = IResponse(response)
@@ -116,7 +112,7 @@
                             cal_multiget = True
                         if report.childOfType(caldavxml.FreeBusyQuery) is not None:
                             cal_freebusy = True
-                        
+
                     if not cal_query:
                         self.fail("Expected CalDAV:CalendarQuery element; but got none.")
                     if not cal_multiget:
@@ -134,24 +130,25 @@
                         ),
                     )
 
-            request = SimpleRequest(
-                self.site,
+            request = SimpleStoreRequest(
+                self,
                 "PROPFIND",
                 calendar_uri,
-                headers=http_headers.Headers({"Depth":"0"}),
+                headers=http_headers.Headers({"Depth": "0"}),
+                authid="user01",
             )
             request.stream = MemoryStream(query.toxml())
             return self.send(request, propfind_cb)
 
-        request = SimpleRequest(self.site, "MKCALENDAR", calendar_uri)
+        request = SimpleStoreRequest(self, "MKCALENDAR", calendar_uri, authid="user01")
         return self.send(request, mkcalendar_cb)
 
+
     def test_all_props(self):
         """
         Live CalDAV properties
         """
-        calendar_path, calendar_uri = self.mkdtemp("all_props")
-        os.rmdir(calendar_path)
+        calendar_uri = "/calendars/users/user01/test/"
 
         def mkcalendar_cb(response):
             response = IResponse(response)
@@ -205,15 +202,15 @@
                 davxml.AllProperties(),
             )
 
-            request = SimpleRequest(
-                self.site,
+            request = SimpleStoreRequest(
+                self,
                 "PROPFIND",
                 calendar_uri,
-                headers=http_headers.Headers({"Depth":"0"}),
+                headers=http_headers.Headers({"Depth": "0"}),
+                authid="user01",
             )
             request.stream = MemoryStream(query.toxml())
             return self.send(request, propfind_cb)
 
-        request = SimpleRequest(self.site, "MKCALENDAR", calendar_uri)
+        request = SimpleStoreRequest(self, "MKCALENDAR", calendar_uri, authid="user01")
         return self.send(request, mkcalendar_cb)
-        

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_resource.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_resource.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_resource.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -24,7 +24,8 @@
 from twistedcaldav.config import config
 from twistedcaldav.resource import CalDAVResource, CommonHomeResource, \
  CalendarHomeResource, AddressBookHomeResource
-from twistedcaldav.test.util import InMemoryPropertyStore
+from twistedcaldav.test.util import InMemoryPropertyStore, StoreTestCase, \
+    SimpleStoreRequest
 from twistedcaldav.test.util import TestCase
 from twistedcaldav.notifications import NotificationCollectionResource
 
@@ -182,21 +183,15 @@
 
 
 
-class DefaultAddressBook (TestCase):
+class DefaultAddressBook (StoreTestCase):
 
-    def setUp(self):
-        super(DefaultAddressBook, self).setUp()
-        self.createStockDirectoryService()
-        self.setupCalendars()
-
-
     @inlineCallbacks
     def test_pick_default_addressbook(self):
         """
         Make calendar
         """
 
-        request = SimpleRequest(self.site, "GET", "/addressbooks/users/wsanchez/")
+        request = SimpleStoreRequest(self, "GET", "/addressbooks/users/wsanchez/", authid="wsanchez")
         home = yield request.locateResource("/addressbooks/users/wsanchez")
 
         # default property initially not present
@@ -216,16 +211,14 @@
         else:
             self.assertEqual(str(default.children[0]), "/addressbooks/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/addressbook/")
 
-        request._newStoreTransaction.abort()
 
-
     @inlineCallbacks
     def test_pick_default_other(self):
         """
         Make adbk
         """
 
-        request = SimpleRequest(self.site, "GET", "/addressbooks/users/wsanchez/")
+        request = SimpleStoreRequest(self, "GET", "/addressbooks/users/wsanchez/", authid="wsanchez")
         home = yield request.locateResource("/addressbooks/users/wsanchez")
 
         # default property not present
@@ -242,10 +235,9 @@
         home.writeDeadProperty(carddavxml.DefaultAddressBookURL(
             HRef("/addressbooks/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/newadbk/")
         ))
-        request._newStoreTransaction.commit()
 
         # Delete the normal adbk
-        request = SimpleRequest(self.site, "GET", "/addressbooks/users/wsanchez/")
+        request = SimpleStoreRequest(self, "GET", "/addressbooks/users/wsanchez/", authid="wsanchez")
         home = yield request.locateResource("/addressbooks/users/wsanchez")
         adbk = yield request.locateResource("/addressbooks/users/wsanchez/addressbook")
         yield adbk.storeRemove(request)
@@ -259,9 +251,10 @@
             pass
         else:
             self.fail("carddavxml.DefaultAddressBookURL is not empty")
-        request._newStoreTransaction.commit()
 
-        request = SimpleRequest(self.site, "GET", "/addressbooks/users/wsanchez/")
+        yield self.commit()
+
+        request = SimpleStoreRequest(self, "GET", "/addressbooks/users/wsanchez/", authid="wsanchez")
         home = yield request.locateResource("/addressbooks/users/wsanchez")
         yield home.pickNewDefaultAddressBook(request)
 
@@ -272,16 +265,14 @@
         else:
             self.assertEqual(str(default.children[0]), "/addressbooks/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/newadbk/")
 
-        request._newStoreTransaction.abort()
 
-
     @inlineCallbacks
     def test_fix_shared_default(self):
         """
         Make calendar
         """
 
-        request = SimpleRequest(self.site, "GET", "/addressbooks/users/wsanchez/")
+        request = SimpleStoreRequest(self, "GET", "/addressbooks/users/wsanchez/", authid="wsanchez")
         home = yield request.locateResource("/addressbooks/users/wsanchez")
 
         # Create a new default adbk
@@ -306,5 +297,3 @@
             self.fail("carddavxml.DefaultAddressBookURL is not present")
         else:
             self.assertEqual(str(default.children[0]), "/addressbooks/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/addressbook/")
-
-        request._newStoreTransaction.abort()

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_sharing.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_sharing.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/twistedcaldav/test/test_sharing.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -14,28 +14,28 @@
 # limitations under the License.
 ##
 
-from xml.etree.cElementTree import XML
-
-from txdav.xml import element as davxml
-from txdav.xml.parser import WebDAVDocument
-
 from twext.web2 import responsecode
-from twext.web2.test.test_server import SimpleRequest
+from twext.web2.dav.util import allDataFromStream
+from twext.web2.http_headers import MimeType
+from twext.web2.iweb import IResponse
 
 from twisted.internet.defer import inlineCallbacks, returnValue, succeed
+
 from twistedcaldav import customxml
+from twistedcaldav import sharing
 from twistedcaldav.config import config
-from twistedcaldav.test.util import HomeTestCase, norequest
-from twistedcaldav import sharing
+from twistedcaldav.resource import CalDAVResource
 from twistedcaldav.sharing import WikiDirectoryService
+from twistedcaldav.test.test_cache import StubResponseCacheResource
+from twistedcaldav.test.util import norequest, StoreTestCase, SimpleStoreRequest
 
-from twistedcaldav.resource import CalDAVResource
-
-from txdav.common.datastore.test.util import buildStore, StubNotifierFactory
 from txdav.caldav.icalendarstore import BIND_DIRECT
-from twistedcaldav.test.test_cache import StubResponseCacheResource
+from txdav.xml import element as davxml
+from txdav.xml.parser import WebDAVDocument
 
+from xml.etree.cElementTree import XML
 
+
 sharedOwnerType = davxml.ResourceType.sharedownercalendar #@UndefinedVariable
 regularCalendarType = davxml.ResourceType.calendar #@UndefinedVariable
 
@@ -91,9 +91,8 @@
 
     @inlineCallbacks
     def calendarHome(self, request):
-        a, seg = yield self._test.homeProvisioner.locateChild(request,
-                                                              ["__uids__"])
-        b, seg = yield a.locateChild(request, [self._name])
+        a, _ignore_seg = yield self._test.calendarCollection.locateChild(request, ["__uids__"])
+        b, _ignore_seg = yield a.locateChild(request, [self._name])
         if b is None:
             # XXX all tests except test_noWikiAccess currently rely on the
             # fake thing here.
@@ -114,7 +113,7 @@
 
 
 
-class SharingTests(HomeTestCase):
+class SharingTests(StoreTestCase):
 
     def configure(self):
         """
@@ -127,8 +126,6 @@
 
     @inlineCallbacks
     def setUp(self):
-        self.calendarStore = yield buildStore(self, StubNotifierFactory())
-
         yield super(SharingTests, self).setUp()
 
         def patched(c):
@@ -177,11 +174,9 @@
         def principalForUID(resourceSelf, principalUID):
             return FakePrincipal("urn:uuid:" + principalUID, self)
 
+        self.resource = yield self._getResource()
 
-    def createDataStore(self):
-        return self.calendarStore
 
-
     @inlineCallbacks
     def _refreshRoot(self, request=None):
         if request is None:
@@ -195,11 +190,31 @@
         returnValue(result)
 
 
+    @inlineCallbacks
     def _doPOST(self, body, resultcode=responsecode.OK):
-        return self.simpleSend("POST", "/calendar/", body,
-                               resultcode=resultcode)
+        request = SimpleStoreRequest(self, "POST", "/calendars/__uids__/user01/calendar/", content=body, authid="user01")
+        request.headers.setHeader("content-type", MimeType("text", "xml"))
+        response = yield self.send(request)
+        response = IResponse(response)
+        self.assertEqual(response.code, resultcode)
 
+        # Reload resource
+        self.resource = yield self._getResource()
 
+        if response.stream:
+            data = yield allDataFromStream(response.stream)
+            returnValue(data)
+        else:
+            returnValue(None)
+
+
+    @inlineCallbacks
+    def _getResource(self):
+        request = SimpleStoreRequest(self, "GET", "/calendars/__uids__/user01/calendar/")
+        resource = yield request.locateResource("/calendars/__uids__/user01/calendar/")
+        returnValue(resource)
+
+
     def _clearUIDElementValue(self, xml):
 
         for user in xml.children:
@@ -214,16 +229,16 @@
 
         rtype = self.resource.resourceType()
         self.assertEquals(rtype, regularCalendarType)
-        isShared = (yield self.resource.isShared(None))
+        isShared = self.resource.isShared()
         self.assertFalse(isShared)
         isShareeCollection = self.resource.isShareeCollection()
         self.assertFalse(isShareeCollection)
 
-        self.resource.upgradeToShare()
+        yield self.resource.upgradeToShare()
 
         rtype = self.resource.resourceType()
         self.assertEquals(rtype, sharedOwnerType)
-        isShared = (yield self.resource.isShared(None))
+        isShared = self.resource.isShared()
         self.assertTrue(isShared)
         isShareeCollection = self.resource.isShareeCollection()
         self.assertFalse(isShareeCollection)
@@ -232,11 +247,11 @@
     @inlineCallbacks
     def test_downgradeFromShare(self):
 
-        self.resource.upgradeToShare()
+        yield self.resource.upgradeToShare()
 
         rtype = self.resource.resourceType()
         self.assertEquals(rtype, sharedOwnerType)
-        isShared = (yield self.resource.isShared(None))
+        isShared = self.resource.isShared()
         self.assertTrue(isShared)
         isShareeCollection = self.resource.isShareeCollection()
         self.assertFalse(isShareeCollection)
@@ -245,7 +260,7 @@
 
         rtype = self.resource.resourceType()
         self.assertEquals(rtype, regularCalendarType)
-        isShared = (yield self.resource.isShared(None))
+        isShared = self.resource.isShared()
         self.assertFalse(isShared)
         isShareeCollection = self.resource.isShareeCollection()
         self.assertFalse(isShareeCollection)
@@ -254,7 +269,7 @@
     @inlineCallbacks
     def test_POSTaddInviteeAlreadyShared(self):
 
-        self.resource.upgradeToShare()
+        yield self.resource.upgradeToShare()
 
         yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
             <CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
@@ -277,7 +292,7 @@
             )
         ))
 
-        isShared = (yield self.resource.isShared(None))
+        isShared = self.resource.isShared()
         self.assertTrue(isShared)
         isShareeCollection = self.resource.isShareeCollection()
         self.assertFalse(isShareeCollection)
@@ -307,7 +322,7 @@
             )
         ))
 
-        isShared = (yield self.resource.isShared(None))
+        isShared = self.resource.isShared()
         self.assertTrue(isShared)
         isShareeCollection = (yield self.resource.isShareeCollection())
         self.assertFalse(isShareeCollection)
@@ -316,7 +331,7 @@
     @inlineCallbacks
     def test_POSTupdateInvitee(self):
 
-        isShared = (yield self.resource.isShared(None))
+        isShared = self.resource.isShared()
         self.assertFalse(isShared)
 
         yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
@@ -329,7 +344,7 @@
             </CS:share>
             """)
 
-        isShared = (yield self.resource.isShared(None))
+        isShared = self.resource.isShared()
         self.assertTrue(isShared)
 
         yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
@@ -342,7 +357,7 @@
             </CS:share>
             """)
 
-        isShared = (yield self.resource.isShared(None))
+        isShared = self.resource.isShared()
         self.assertTrue(isShared)
 
         propInvite = (yield self.resource.readProperty(customxml.Invite, None))
@@ -360,7 +375,7 @@
     @inlineCallbacks
     def test_POSTremoveInvitee(self):
 
-        isShared = (yield self.resource.isShared(None))
+        isShared = self.resource.isShared()
         self.assertFalse(isShared)
 
         yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
@@ -373,7 +388,7 @@
             </CS:share>
             """)
 
-        isShared = (yield self.resource.isShared(None))
+        isShared = self.resource.isShared()
         self.assertTrue(isShared)
 
         yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
@@ -384,7 +399,7 @@
             </CS:share>
             """)
 
-        isShared = (yield self.resource.isShared(None))
+        isShared = self.resource.isShared()
         self.assertFalse(isShared)
 
         propInvite = (yield self.resource.readProperty(customxml.Invite, None))
@@ -394,7 +409,7 @@
     @inlineCallbacks
     def test_POSTaddMoreInvitees(self):
 
-        self.resource.upgradeToShare()
+        yield self.resource.upgradeToShare()
 
         yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
             <CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
@@ -449,7 +464,7 @@
     @inlineCallbacks
     def test_POSTaddRemoveInvitees(self):
 
-        self.resource.upgradeToShare()
+        yield self.resource.upgradeToShare()
 
         yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
             <CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
@@ -496,10 +511,11 @@
             ),
         ))
 
+
     @inlineCallbacks
     def test_POSTaddRemoveSameInvitee(self):
 
-        self.resource.upgradeToShare()
+        yield self.resource.upgradeToShare()
 
         yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
             <CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
@@ -555,7 +571,7 @@
         removed the sharee.
         """
 
-        self.resource.upgradeToShare()
+        yield self.resource.upgradeToShare()
 
         yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
             <CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
@@ -595,7 +611,7 @@
 
     @inlineCallbacks
     def test_POSTaddInvalidInvitee(self):
-        self.resource.upgradeToShare()
+        yield self.resource.upgradeToShare()
 
         data = (yield self._doPOST(
             """<?xml version="1.0" encoding="utf-8" ?>
@@ -633,12 +649,12 @@
     @inlineCallbacks
     def test_POSTremoveInvalidInvitee(self):
 
-        self.resource.upgradeToShare()
+        yield self.resource.upgradeToShare()
 
         yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
             <CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
                 <CS:set>
-                    <D:href>mailto:user01 at example.com</D:href>
+                    <D:href>mailto:user02 at example.com</D:href>
                     <CS:summary>My Shared Calendar</CS:summary>
                     <CS:read-write/>
                 </CS:set>
@@ -649,8 +665,8 @@
         self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
             customxml.InviteUser(
                 customxml.UID.fromString(""),
-                davxml.HRef.fromString("urn:uuid:user01"),
-                customxml.CommonName.fromString("USER01"),
+                davxml.HRef.fromString("urn:uuid:user02"),
+                customxml.CommonName.fromString("USER02"),
                 customxml.InviteAccess(customxml.ReadWriteAccess()),
                 customxml.InviteStatusNoResponse(),
             )
@@ -664,8 +680,8 @@
         self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
             customxml.InviteUser(
                 customxml.UID.fromString(""),
-                davxml.HRef.fromString("urn:uuid:user01"),
-                customxml.CommonName.fromString("user01"),
+                davxml.HRef.fromString("urn:uuid:user02"),
+                customxml.CommonName.fromString("user02"),
                 customxml.InviteAccess(customxml.ReadWriteAccess()),
                 customxml.InviteStatusInvalid(),
             )
@@ -674,7 +690,7 @@
         yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
             <CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
                 <CS:remove>
-                    <D:href>mailto:user01 at example.com</D:href>
+                    <D:href>mailto:user02 at example.com</D:href>
                 </CS:remove>
             </CS:share>
             """)
@@ -690,17 +706,19 @@
         home is at /.  Return the name of the newly shared calendar in the
         sharee's home.
         """
-        wcreate = self.calendarStore.newTransaction("create wiki")
+        wcreate = self._sqlCalendarStore.newTransaction("create wiki")
         yield wcreate.calendarHomeWithUID("wiki-testing", create=True)
         yield wcreate.commit()
-        self.directoryFixture.addDirectoryService(WikiDirectoryService())
 
-        txn = self.site.resource._associatedTransaction
-        sharee = self.site.resource._newStoreHome
+        newService = WikiDirectoryService()
+        newService.realmName = self.directory.realmName
+        self.directory.addService(newService)
+
+        txn = self.transactionUnderTest()
+        sharee = yield self.homeUnderTest(name="user01")
         sharer = yield txn.calendarHomeWithUID("wiki-testing")
         cal = yield sharer.calendarWithName("calendar")
         sharedName = yield cal.shareWith(sharee, BIND_DIRECT)
-        yield self._refreshRoot()
         returnValue(sharedName)
 
 
@@ -718,8 +736,8 @@
         self.patch(sharing, "getWikiAccess", stubWikiAccessMethod)
 
         sharedName = yield self.wikiSetup()
-        request = SimpleRequest(self.site, "GET", "/404")
-        collection = yield request.locateResource("/" + sharedName)
+        request = SimpleStoreRequest(self, "GET", "/calendars/__uids__/user01/")
+        collection = yield request.locateResource("/calendars/__uids__/user01/" + sharedName)
 
         # Simulate the wiki server granting Read access
         acl = (yield collection.shareeAccessControlList(request))
@@ -745,10 +763,12 @@
         self.patch(sharing, "getWikiAccess", stubWikiAccessMethod)
         @inlineCallbacks
         def listChildrenViaPropfind():
-            data = yield self.simpleSend(
-                "PROPFIND", "/", resultcode=responsecode.MULTI_STATUS,
-                headers=[('Depth', '1')]
-            )
+            request = SimpleStoreRequest(self, "PROPFIND", "/calendars/__uids__/user01/", authid="user01")
+            request.headers.setHeader("depth", "1")
+            response = yield self.send(request)
+            response = IResponse(response)
+            data = yield allDataFromStream(response.stream)
+
             tree = XML(data)
             seq = [e.text for e in tree.findall("{DAV:}response/{DAV:}href")]
             shortest = min(seq, key=len)
@@ -760,7 +780,3 @@
         access = "no-access"
         childNames = yield listChildrenViaPropfind()
         self.assertNotIn(sharedName, childNames)
-
-
-
-

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/file.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/file.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/file.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -37,7 +37,7 @@
 
 from twext.python.vcomponent import VComponent
 from txdav.xml import element as davxml
-from txdav.xml.rfc2518 import ResourceType, GETContentType
+from txdav.xml.rfc2518 import GETContentType
 from twext.web2.dav.resource import TwistedGETContentMD5
 from twext.web2.http_headers import generateContentType, MimeType
 
@@ -261,10 +261,6 @@
     def _calendarHome(self):
         return self._home
 
-
-    def resourceType(self):
-        return ResourceType.calendar #@UndefinedVariable
-
     ownerCalendarHome = CommonHomeChild.ownerHome
     viewerCalendarHome = CommonHomeChild.viewerHome
     calendarObjects = CommonHomeChild.objectResources

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/sql.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/sql.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -92,7 +92,6 @@
     ObjectResourceNameNotAllowedError, TooManyObjectResourcesError, \
     InvalidUIDError, UIDExistsError, UIDExistsElsewhereError, \
     InvalidResourceMove, InvalidComponentForStoreError
-from txdav.xml.rfc2518 import ResourceType
 
 from pycalendar.datetime import PyCalendarDateTime
 from pycalendar.duration import PyCalendarDuration
@@ -914,11 +913,6 @@
     def _calendarHome(self):
         return self._home
 
-
-    # FIXME: resource type is DAV.  This doesn't belong in the data store.  -wsv
-    def resourceType(self):
-        return ResourceType.calendar # @UndefinedVariable
-
     ownerCalendarHome = CommonHomeChild.ownerHome
     viewerCalendarHome = CommonHomeChild.viewerHome
     calendarObjects = CommonHomeChild.objectResources
@@ -1068,6 +1062,7 @@
             Where=(cal.CALENDAR_HOME_RESOURCE_ID == self.viewerHome()._resourceID).And(cal.CALENDAR_RESOURCE_ID == self._resourceID)
         ).on(self._txn)
         yield self.invalidateQueryCache()
+        yield self.notifyChanged()
 
 
     def isUsedForFreeBusy(self):

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/test/common.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/test/common.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/test/common.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -31,7 +31,7 @@
 from twext.python.filepath import CachingFilePath as FilePath
 from twext.enterprise.ienterprise import AlreadyFinishedError
 
-from txdav.xml.element import WebDAVUnknownElement, ResourceType
+from txdav.xml.element import WebDAVUnknownElement
 from txdav.idav import IPropertyStore, IDataStore
 from txdav.base.propertystore.base import PropertyName
 from txdav.common.icommondatastore import HomeChildNameAlreadyExistsError, \
@@ -701,18 +701,8 @@
         self.assertIdentical((yield home.calendarWithName(name)), None)
         yield home.createCalendarWithName(name)
         self.assertNotIdentical((yield home.calendarWithName(name)), None)
-        @inlineCallbacks
-        def checkProperties():
-            calendarProperties = (
-                yield home.calendarWithName(name)).properties()
-            self.assertEquals(
-                calendarProperties[
-                    PropertyName.fromString(ResourceType.sname())
-                ],
-                ResourceType.calendar #@UndefinedVariable
-            )
-        yield checkProperties()
-
+        calendarProperties = (yield home.calendarWithName(name)).properties()
+        self.assertEqual(len(calendarProperties), 0)
         yield self.commit()
 
         # Make sure notification fired after commit
@@ -722,14 +712,7 @@
         home = yield self.homeUnderTest()
         self.assertNotIdentical((yield home.calendarWithName(name)), None)
 
-        # Sanity check: are the properties actually persisted?  Check in
-        # subsequent transaction.
-        yield checkProperties()
 
-        # FIXME: no independent testing of the property store's persistence
-        # right now
-
-
     @inlineCallbacks
     def test_createCalendarWithName_exists(self):
         """

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/test/test_sql.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/test/test_sql.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/txdav/caldav/datastore/test/test_sql.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -782,10 +782,10 @@
                         From=prop,
                         Where=prop.RESOURCE_ID == Parameter("resourceID"))
 
-        # Check that two properties are present
+        # Check that one property is present
         home = yield self.homeUnderTest()
         rows = yield _allWithID.on(self.transactionUnderTest(), resourceID=resourceID)
-        self.assertEqual(len(tuple(rows)), 2)
+        self.assertEqual(len(tuple(rows)), 1)
         yield self.commit()
 
         # Remove calendar and check for no properties

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/file.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/file.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/file.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -29,7 +29,7 @@
 
 from errno import ENOENT
 
-from txdav.xml.rfc2518 import ResourceType, GETContentType
+from txdav.xml.rfc2518 import GETContentType
 from twext.web2.dav.resource import TwistedGETContentMD5
 from twext.web2.http_headers import MimeType
 
@@ -121,10 +121,6 @@
     def _addressbookHome(self):
         return self._home
 
-
-    def resourceType(self):
-        return ResourceType.addressbook #@UndefinedVariable
-
     ownerAddressBookHome = CommonHomeChild.ownerHome
     addressbookObjects = CommonHomeChild.objectResources
     listAddressbookObjects = CommonHomeChild.listObjectResources

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/sql.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/sql.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -55,7 +55,6 @@
 from txdav.common.icommondatastore import InternalDataStoreError, \
     InvalidUIDError, UIDExistsError, ObjectResourceTooBigError, \
     InvalidObjectResourceError, InvalidComponentForStoreError
-from txdav.xml.rfc2518 import ResourceType
 
 from zope.interface.declarations import implements
 
@@ -168,10 +167,6 @@
     def _addressbookHome(self):
         return self._home
 
-
-    def resourceType(self):
-        return ResourceType.addressbook #@UndefinedVariable
-
     ownerAddressBookHome = CommonHomeChild.ownerHome
     addressbookObjects = CommonHomeChild.objectResources
     listAddressbookObjects = CommonHomeChild.listObjectResources

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/test/common.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/test/common.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/test/common.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -40,7 +40,7 @@
 from twistedcaldav.vcard import Component as VComponent
 
 from twext.python.filepath import CachingFilePath as FilePath
-from txdav.xml.element import WebDAVUnknownElement, ResourceType
+from txdav.xml.element import WebDAVUnknownElement
 
 
 storePath = FilePath(__file__).parent().child("addressbook_store")
@@ -315,17 +315,8 @@
         self.assertIdentical((yield home.addressbookWithName(name)), None)
         yield home.createAddressBookWithName(name)
         self.assertNotIdentical((yield home.addressbookWithName(name)), None)
-        @inlineCallbacks
-        def checkProperties():
-            addressbookProperties = (yield home.addressbookWithName(name)).properties()
-            addressbookType = ResourceType.addressbook #@UndefinedVariable
-            self.assertEquals(
-                addressbookProperties[
-                    PropertyName.fromString(ResourceType.sname())
-                ],
-                addressbookType
-            )
-        yield checkProperties()
+        addressbookProperties = (yield home.addressbookWithName(name)).properties()
+        self.assertEqual(len(addressbookProperties), 0)
         yield self.commit()
 
         # Make sure notification fired after commit
@@ -335,15 +326,7 @@
         home = yield self.homeUnderTest()
         self.assertNotIdentical((yield home.addressbookWithName(name)), None)
 
-        # FIXME: These two lines aren't in the calendar common tests:
-        # home = self.addressbookStore.newTransaction().addressbookHomeWithUID(
-        #     "home1")
 
-        # Sanity check: are the properties actually persisted?
-        # FIXME: no independent testing of this right now
-        yield checkProperties()
-
-
     @inlineCallbacks
     def test_createAddressBookWithName_exists(self):
         """

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/test/test_sql.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/test/test_sql.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/txdav/carddav/datastore/test/test_sql.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -315,7 +315,7 @@
         # Check that two properties are present
         home = yield self.homeUnderTest()
         rows = yield _allWithID.on(self.transactionUnderTest(), resourceID=resourceID)
-        self.assertEqual(len(tuple(rows)), 2)
+        self.assertEqual(len(tuple(rows)), 1)
         yield self.commit()
 
         # Remove address book and check for no properties

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/file.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/file.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/file.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -22,7 +22,7 @@
 import sys
 from twext.internet.decorate import memoizedKey
 from twext.python.log import LoggingMixIn
-from txdav.xml.rfc2518 import ResourceType, GETContentType, HRef
+from txdav.xml.rfc2518 import GETContentType, HRef
 from txdav.xml.rfc5842 import ResourceID
 from twext.web2.http_headers import generateContentType, MimeType
 from twext.web2.dav.resource import TwistedGETContentMD5, \
@@ -826,8 +826,6 @@
             return lambda: self._path.child(childPath.basename()).remove()
 
         self._transaction.addOperation(do, "create child %r" % (name,))
-        props = c.properties()
-        props[PropertyName(*ResourceType.qname())] = c.resourceType()
 
         self.notifyChanged()
         return c
@@ -1033,10 +1031,6 @@
         return self._transaction.store().directoryService()
 
 
-    def resourceType(self):
-        return NotImplementedError
-
-
     def retrieveOldIndex(self):
         """
         Retrieve the old Index object.
@@ -1522,14 +1516,8 @@
 
         txn.addOperation(do, "create notification child %r" %
                           (collectionName,))
-        props = c.properties()
-        props[PropertyName(*ResourceType.qname())] = c.resourceType()
         return c
 
-
-    def resourceType(self):
-        return ResourceType.notification #@UndefinedVariable
-
     notificationObjects = CommonHomeChild.objectResources
     listNotificationObjects = CommonHomeChild.listObjectResources
     notificationObjectWithName = CommonHomeChild.objectResourceWithName

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/sql.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/sql.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -34,7 +34,6 @@
 from twext.python.log import Logger, LoggingMixIn
 from twisted.python.log import msg as log_msg, err as log_err
 
-from txdav.xml.element import ResourceType
 from txdav.xml.parser import WebDAVDocument
 from twext.web2.http_headers import MimeType
 
@@ -79,7 +78,6 @@
 
 from twistedcaldav.config import config
 
-from txdav.base.propertystore.base import PropertyName
 from txdav.base.propertystore.none import PropertyStore as NonePropertyStore
 from txdav.base.propertystore.sql import PropertyStore
 
@@ -2899,6 +2897,42 @@
         return self._bindMode == _BIND_MODE_OWN
 
 
+    def isShared(self):
+        """
+        For an owned collection indicate whether it is shared.
+
+        @return: C{True} if shared, C{False} otherwise
+        @rtype: C{bool}
+        """
+        return self._bindMode == _BIND_MODE_OWN and self._bindMessage == "shared"
+
+
+    @inlineCallbacks
+    def setShared(self, shared):
+        """
+        Set an owned collection to shared or unshared state. Technically this is not useful as "shared"
+        really means it has invitees, but the current sharing spec supports a notion of a shared collection
+        that has not yet had invitees added. For the time being we will support that option by using a new
+        BINS_STATUS value to indicate an owned collection that is "shared".
+
+        @param shared: whether or not the owned collection is "shared"
+        @type shared: C{bool}
+        """
+        assert self.owned()
+
+        self._bindMessage = "shared" if shared else None
+
+        bind = self._bindSchema
+        yield Update(
+            {bind.MESSAGE: self._bindMessage},
+            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()
+
+
     def shareStatus(self):
         """
         @see: L{ICalendar.shareStatus}
@@ -3370,9 +3404,6 @@
         child._modified = _modified
         yield child._loadPropertyStore()
 
-        child.properties()[
-            PropertyName.fromElement(ResourceType)
-        ] = child.resourceType()
         yield child._initSyncToken()
 
         # Change notification for a create is on the home collection
@@ -3442,10 +3473,6 @@
         return self._txn.store().directoryService()
 
 
-    def resourceType(self):
-        return NotImplementedError
-
-
     def retrieveOldIndex(self):
         return self._index
 
@@ -4639,10 +4666,6 @@
         )
 
 
-    def resourceType(self):
-        return ResourceType.notification #@UndefinedVariable
-
-
     def __repr__(self):
         return "<%s: %s>" % (self.__class__.__name__, self._resourceID)
 

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/upgrade/sql/upgrades/test/test_upgrade_from_3_to_4.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/upgrade/sql/upgrades/test/test_upgrade_from_3_to_4.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/upgrade/sql/upgrades/test/test_upgrade_from_3_to_4.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -20,7 +20,8 @@
 from txdav.xml.element import HRef
 from twext.enterprise.dal.syntax import Update
 from txdav.common.datastore.upgrade.sql.upgrades.upgrade_from_3_to_4 import moveDefaultCalendarProperties, \
-    moveCalendarTranspProperties
+    moveCalendarTranspProperties, removeResourceType
+from txdav.xml import element
 
 """
 Tests for L{txdav.common.datastore.upgrade.sql.upgrade}.
@@ -106,3 +107,23 @@
         self.assertTrue(calendar.isUsedForFreeBusy())
         inbox = (yield self.calendarUnderTest(name="inbox", home="user01"))
         self.assertTrue(PropertyName.fromElement(CalendarFreeBusySet) not in inbox.properties())
+
+
+    @inlineCallbacks
+    def test_resourceTypeUpgrade(self):
+
+        # Set dead property on calendar
+        calendar = (yield self.calendarUnderTest(name="calendar_1", home="user01"))
+        calendar.properties()[PropertyName.fromElement(element.ResourceType)] = element.ResourceType(element.Collection())
+        yield self.commit()
+
+        calendar = (yield self.calendarUnderTest(name="calendar_1", home="user01"))
+        self.assertTrue(PropertyName.fromElement(element.ResourceType) in calendar.properties())
+        yield self.commit()
+
+        # Trigger upgrade
+        yield removeResourceType(self._sqlCalendarStore)
+
+        # Test results
+        calendar = (yield self.calendarUnderTest(name="calendar_1", home="user01"))
+        self.assertTrue(PropertyName.fromElement(element.ResourceType) not in calendar.properties())

Modified: CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/upgrade/sql/upgrades/upgrade_from_3_to_4.py
===================================================================
--- CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/upgrade/sql/upgrades/upgrade_from_3_to_4.py	2013-05-03 00:45:15 UTC (rev 11126)
+++ CalendarServer/branches/users/cdaboo/store-scheduling/txdav/common/datastore/upgrade/sql/upgrades/upgrade_from_3_to_4.py	2013-05-03 18:58:13 UTC (rev 11127)
@@ -26,6 +26,7 @@
 from txdav.common.datastore.upgrade.sql.upgrades.util import rowsForProperty, updateDataVersion, \
     updateAllCalendarHomeDataVersions, removeProperty, cleanPropertyStore
 from txdav.xml.parser import WebDAVDocument
+from txdav.xml import element
 
 """
 Data upgrade from database version 3 to 4
@@ -41,6 +42,7 @@
     """
     yield moveDefaultCalendarProperties(sqlStore)
     yield moveCalendarTranspProperties(sqlStore)
+    yield removeResourceType(sqlStore)
 
     # Always bump the DB value
     yield updateDataVersion(sqlStore, "CALENDAR-DATAVERSION", UPGRADE_TO_VERSION)
@@ -186,3 +188,12 @@
     except RuntimeError:
         yield sqlTxn.abort()
         raise
+
+
+
+ at inlineCallbacks
+def removeResourceType(sqlStore):
+    sqlTxn = sqlStore.newTransaction()
+    yield removeProperty(sqlTxn, PropertyName.fromElement(element.ResourceType))
+    yield sqlTxn.commit()
+    yield cleanPropertyStore()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130503/d3e41a46/attachment-0001.html>


More information about the calendarserver-changes mailing list