[CalendarServer-changes] [5831] CalendarServer/branches/new-store

source_changes at macosforge.org source_changes at macosforge.org
Thu Jul 1 13:34:17 PDT 2010


Revision: 5831
          http://trac.macosforge.org/projects/calendarserver/changeset/5831
Author:   glyph at apple.com
Date:     2010-07-01 13:34:16 -0700 (Thu, 01 Jul 2010)
Log Message:
-----------
Restore separate addressbook and calendar transaction interfaces, so that you can implement one store without necessarily implementing the other, since they have different methods; dynamically have the 'common' transaction declare its provision of the appropriate one.

Modified Paths:
--------------
    CalendarServer/branches/new-store/txcaldav/calendarstore/scheduling.py
    CalendarServer/branches/new-store/txcaldav/calendarstore/test/common.py
    CalendarServer/branches/new-store/txcaldav/icalendarstore.py
    CalendarServer/branches/new-store/txcarddav/addressbookstore/test/common.py
    CalendarServer/branches/new-store/txcarddav/iaddressbookstore.py
    CalendarServer/branches/new-store/txdav/common/datastore/file.py
    CalendarServer/branches/new-store/txdav/common/icommondatastore.py
    CalendarServer/branches/new-store/txdav/idav.py

Modified: CalendarServer/branches/new-store/txcaldav/calendarstore/scheduling.py
===================================================================
--- CalendarServer/branches/new-store/txcaldav/calendarstore/scheduling.py	2010-07-01 20:33:12 UTC (rev 5830)
+++ CalendarServer/branches/new-store/txcaldav/calendarstore/scheduling.py	2010-07-01 20:34:16 UTC (rev 5831)
@@ -15,16 +15,16 @@
 # limitations under the License.
 ##
 from zope.interface.declarations import implements
-from txcaldav.icalendarstore import ICalendarHome, ICalendar, ICalendarObject
-from txdav.common.icommondatastore import ICommonStoreTransaction,\
-    ICommonDataStore
+from txcaldav.icalendarstore import ICalendarHome, ICalendar, ICalendarObject,\
+    ICalendarTransaction
+from txdav.idav import IDataStore
 from twisted.python.util import FancyEqMixin
 from twisted.python.components import proxyForInterface
 
 
 
 class ImplicitTransaction(
-        proxyForInterface(ICommonStoreTransaction,
+        proxyForInterface(ICalendarTransaction,
                           originalAttribute="_transaction")):
     """
     Wrapper around an L{ICalendarStoreTransaction}.
@@ -143,7 +143,7 @@
     scheduling.
     """
 
-    implements(ICommonDataStore)
+    implements(IDataStore)
 
     def __init__(self, calendarStore):
         """

Modified: CalendarServer/branches/new-store/txcaldav/calendarstore/test/common.py
===================================================================
--- CalendarServer/branches/new-store/txcaldav/calendarstore/test/common.py	2010-07-01 20:33:12 UTC (rev 5830)
+++ CalendarServer/branches/new-store/txcaldav/calendarstore/test/common.py	2010-07-01 20:34:16 UTC (rev 5831)
@@ -24,11 +24,11 @@
 from zope.interface.exceptions import (
     BrokenMethodImplementation, DoesNotImplement)
 
-from txdav.idav import IPropertyStore
+from txdav.idav import IPropertyStore, IDataStore
 from txdav.propertystore.base import PropertyName
 
 from txdav.common.icommondatastore import HomeChildNameAlreadyExistsError,\
-    ICommonDataStore, ICommonStoreTransaction
+    ICommonTransaction
 from txdav.common.icommondatastore import InvalidObjectResourceError
 from txdav.common.icommondatastore import NoSuchHomeChildError
 from txdav.common.icommondatastore import NoSuchObjectResourceError
@@ -36,7 +36,7 @@
 
 from txcaldav.icalendarstore import (
     ICalendarObject, ICalendarHome,
-    ICalendar, IAttachment)
+    ICalendar, IAttachment, ICalendarTransaction)
 
 from twext.python.filepath import CachingFilePath as FilePath
 from twext.web2.dav import davxml
@@ -252,20 +252,21 @@
 
     def test_calendarStoreProvides(self):
         """
-        The calendar store provides L{ICommonDataStore} and its required
-        attributes.
+        The calendar store provides L{IDataStore} and its required attributes.
         """
         calendarStore = self.storeUnderTest()
-        self.assertProvides(ICommonDataStore, calendarStore)
+        self.assertProvides(IDataStore, calendarStore)
 
 
     def test_transactionProvides(self):
         """
         The transactions generated by the calendar store provide
-        L{ICommonStoreTransaction} and its required attributes.
+        L{ICommonStoreTransaction}, L{ICalendarTransaction}, and their
+        respectively required attributes.
         """
-        self.assertProvides(ICommonStoreTransaction,
-                            self.storeUnderTest().newTransaction())
+        txn = self.storeUnderTest().newTransaction()
+        self.assertProvides(ICommonTransaction, txn)
+        self.assertProvides(ICalendarTransaction, txn)
 
 
     def test_homeProvides(self):

Modified: CalendarServer/branches/new-store/txcaldav/icalendarstore.py
===================================================================
--- CalendarServer/branches/new-store/txcaldav/icalendarstore.py	2010-07-01 20:33:12 UTC (rev 5830)
+++ CalendarServer/branches/new-store/txcaldav/icalendarstore.py	2010-07-01 20:34:16 UTC (rev 5831)
@@ -14,6 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 ##
+from txdav.common.icommondatastore import ICommonTransaction
 
 """
 Calendar store interfaces
@@ -24,6 +25,7 @@
 
 __all__ = [
     # Classes
+    "ICalendarTransaction",
     "ICalendarHome",
     "ICalendar",
     "ICalendarObject",
@@ -40,6 +42,23 @@
 # from txdav.idav import IPropertyStore
 # from txdav.idav import ITransaction
 
+class ICalendarTransaction(ICommonTransaction):
+    """
+    Transaction functionality required to be implemented by calendar stores.
+    """
+
+    def calendarHomeWithUID(uid, create=False):
+        """
+        Retrieve the calendar home for the principal with the given C{uid}.
+
+        If C{create} is C{True}, create the calendar home if it doesn't
+        already exist.
+
+        @return: an L{ICalendarHome} or C{None} if no such calendar
+            home exists.
+        """
+
+
 #
 # Interfaces
 #
@@ -59,11 +78,6 @@
         @return: a string.
         """
 
-    def created():
-        """
-        Calendar home was created. Do initialization
-        """
-
     def calendars():
         """
         Retrieve calendars contained in this calendar home.

Modified: CalendarServer/branches/new-store/txcarddav/addressbookstore/test/common.py
===================================================================
--- CalendarServer/branches/new-store/txcarddav/addressbookstore/test/common.py	2010-07-01 20:33:12 UTC (rev 5830)
+++ CalendarServer/branches/new-store/txcarddav/addressbookstore/test/common.py	2010-07-01 20:34:16 UTC (rev 5831)
@@ -20,13 +20,15 @@
 
 from zope.interface.verify import verifyObject
 from zope.interface.exceptions import (
-    BrokenMethodImplementation, DoesNotImplement)
+    BrokenMethodImplementation, DoesNotImplement
+)
 
-from txdav.idav import IPropertyStore
+from txdav.idav import IPropertyStore, IDataStore
 from txdav.propertystore.base import PropertyName
 
-from txdav.common.icommondatastore import HomeChildNameAlreadyExistsError,\
-    ICommonDataStore, ICommonStoreTransaction
+from txdav.common.icommondatastore import (
+    HomeChildNameAlreadyExistsError, ICommonTransaction
+)
 from txdav.common.icommondatastore import InvalidObjectResourceError
 from txdav.common.icommondatastore import NoSuchHomeChildError
 from txdav.common.icommondatastore import NoSuchObjectResourceError
@@ -34,7 +36,7 @@
 
 from txcarddav.iaddressbookstore import (
     IAddressBookObject, IAddressBookHome,
-    IAddressBook,
+    IAddressBook, IAddressBookTransaction
 )
 from twistedcaldav.vcard import Component as VComponent
 
@@ -211,7 +213,7 @@
         attributes.
         """
         addressbookStore = self.storeUnderTest()
-        self.assertProvides(ICommonDataStore, addressbookStore)
+        self.assertProvides(IDataStore, addressbookStore)
 
 
     def test_transactionProvides(self):
@@ -219,8 +221,9 @@
         The transactions generated by the addressbook store provide
         L{IAddressBookStoreTransaction} and its required attributes.
         """
-        self.assertProvides(ICommonStoreTransaction,
-                            self.storeUnderTest().newTransaction())
+        txn = self.storeUnderTest().newTransaction()
+        self.assertProvides(ICommonTransaction, txn)
+        self.assertProvides(IAddressBookTransaction, txn)
 
 
     def test_homeProvides(self):

Modified: CalendarServer/branches/new-store/txcarddav/iaddressbookstore.py
===================================================================
--- CalendarServer/branches/new-store/txcarddav/iaddressbookstore.py	2010-07-01 20:33:12 UTC (rev 5830)
+++ CalendarServer/branches/new-store/txcarddav/iaddressbookstore.py	2010-07-01 20:34:16 UTC (rev 5831)
@@ -18,18 +18,35 @@
 Address book store interfaces
 """
 
-__all__ = [
-]
-
 from zope.interface import Interface
+from txdav.common.icommondatastore import ICommonTransaction
 
 __all__ = [
     # Classes
+    "IAddressBookTransaction",
     "IAddressBookHome",
     "IAddressBook",
     "IAddressBookObject",
 ]
 
+class IAddressBookTransaction(ICommonTransaction):
+    """
+    Transaction interface that addressbook stores must provide.
+    """
+
+    def addressbookHomeWithUID(uid, create=False):
+        """
+        Retrieve the addressbook home for the principal with the given C{uid}.
+
+        If C{create} is C{True}, create the addressbook home if it doesn't
+        already exist.
+
+        @return: an L{IAddressBookHome} or C{None} if no such addressbook
+            home exists.
+        """
+
+
+
 #
 # Interfaces
 #
@@ -43,6 +60,7 @@
     includes both addressbooks owned by the principal as well as
     addressbooks that have been shared with and accepts by the principal.
     """
+
     def uid():
         """
         Retrieve the unique identifier for this addressbook home.
@@ -50,11 +68,7 @@
         @return: a string.
         """
 
-    def created():
-        """
-        Addressbook home was created. Do initialization
-        """
-        
+
     def addressbooks():
         """
         Retrieve addressbooks contained in this addressbook home.

Modified: CalendarServer/branches/new-store/txdav/common/datastore/file.py
===================================================================
--- CalendarServer/branches/new-store/txdav/common/datastore/file.py	2010-07-01 20:33:12 UTC (rev 5830)
+++ CalendarServer/branches/new-store/txdav/common/datastore/file.py	2010-07-01 20:34:16 UTC (rev 5831)
@@ -1,4 +1,4 @@
-# -*- test-case-name: txdav.datastore.test.test_file -*-
+# -*- test-case-name: txcaldav.calendarstore.test.test_file -*-
 ##
 # Copyright (c) 2010 Apple Inc. All rights reserved.
 #
@@ -15,37 +15,39 @@
 # limitations under the License.
 ##
 
+"""
+Common utility functions for a file based datastore.
+"""
+
 from errno import EEXIST, ENOENT
 
 from twext.python.log import LoggingMixIn
 from twext.web2.dav.element.rfc2518 import ResourceType, GETContentType
 
-from txdav.datastore.file import DataStoreTransaction, DataStore, writeOperation,\
+from txdav.datastore.file import DataStoreTransaction, DataStore, writeOperation, \
     hidden, isValidName, cached
 from txdav.propertystore.base import PropertyName
 from txdav.propertystore.xattr import PropertyStore
-from txdav.common.icommondatastore import HomeChildNameNotAllowedError,\
-    HomeChildNameAlreadyExistsError, NoSuchHomeChildError,\
-    InternalDataStoreError, ObjectResourceNameNotAllowedError,\
-    ObjectResourceNameAlreadyExistsError, NoSuchObjectResourceError,\
-    ICommonDataStore, ICommonStoreTransaction
+from txdav.common.icommondatastore import HomeChildNameNotAllowedError, \
+    HomeChildNameAlreadyExistsError, NoSuchHomeChildError, \
+    InternalDataStoreError, ObjectResourceNameNotAllowedError, \
+    ObjectResourceNameAlreadyExistsError, NoSuchObjectResourceError
+
 from twisted.python.util import FancyEqMixin
 from twistedcaldav.customxml import GETCTag, NotificationType
 from uuid import uuid4
-from zope.interface.declarations import implements
-from txdav.common.inotifications import INotificationCollection,\
+from zope.interface import implements, directlyProvides
+from txdav.common.inotifications import INotificationCollection, \
     INotificationObject
 from twistedcaldav.notifications import NotificationRecord
 from twistedcaldav.notifications import NotificationsDatabase as OldNotificationIndex
 from twext.web2.http_headers import generateContentType, MimeType
 from twistedcaldav.sharing import SharedCollectionsDatabase
+from txdav.idav import IDataStore
 
-"""
-Common utility functions for a file based datastore.
-"""
 
-ECALENDARTYPE     = 0
-EADDRESSBOOKTYPE  = 1
+ECALENDARTYPE = 0
+EADDRESSBOOKTYPE = 1
 TOPPATHS = (
     "calendars",
     "addressbooks"
@@ -57,9 +59,9 @@
     An implementation of data store.
 
     @ivar _path: A L{CachingFilePath} referencing a directory on disk that
-        stores all addressbook data for a group of uids.
+        stores all calendar and addressbook data for a group of UIDs.
     """
-    implements(ICommonDataStore)
+    implements(IDataStore)
 
     def __init__(self, path, enableCalendars=True, enableAddressBooks=True):
         """
@@ -90,8 +92,6 @@
     operations.
     """
 
-    implements(ICommonStoreTransaction)
-
     _homeClass = {}
 
     def __init__(self, dataStore, enableCalendars, enableAddressBooks):
@@ -101,27 +101,33 @@
 
         @param dataStore: The store that created this transaction.
 
-        @type dataStore: L{DataStore}
+        @type dataStore: L{CommonDataStore}
         """
-        
-        assert enableCalendars or enableAddressBooks
+        from txcaldav.icalendarstore import ICalendarTransaction
+        from txcarddav.iaddressbookstore import IAddressBookTransaction
+        from txcaldav.calendarstore.file import CalendarHome
+        from txcarddav.addressbookstore.file import AddressBookHome
 
         super(CommonStoreTransaction, self).__init__(dataStore)
         self._homes = {}
         self._homes[ECALENDARTYPE] = {}
         self._homes[EADDRESSBOOKTYPE] = {}
         self._notifications = {}
-        
+
+        extraInterfaces = []
         if enableCalendars:
+            extraInterfaces.append(ICalendarTransaction)
             self._notificationHomeType = ECALENDARTYPE
         else:
             self._notificationHomeType = EADDRESSBOOKTYPE
+        if enableAddressBooks:
+            extraInterfaces.append(IAddressBookTransaction)
+        directlyProvides(self, *extraInterfaces)
 
-        from txcaldav.calendarstore.file import CalendarHome
-        from txcarddav.addressbookstore.file import AddressBookHome
         CommonStoreTransaction._homeClass[ECALENDARTYPE] = CalendarHome
         CommonStoreTransaction._homeClass[EADDRESSBOOKTYPE] = AddressBookHome
 
+
     def calendarHomeWithUID(self, uid, create=False):
         return self.homeWithUID(ECALENDARTYPE, uid, create)
 
@@ -159,7 +165,7 @@
             for child in childPathSegments:
                 if not child.isdir():
                     createDirectory(child)
-                
+
             if childPath.isdir():
                 homePath = childPath
             else:
@@ -186,7 +192,7 @@
         self._homes[storeType][(uid, self)] = home
         if creating:
             home.created()
-            
+
             # Create notification collection
             if storeType == ECALENDARTYPE:
                 self.notificationsWithUID(uid)
@@ -196,12 +202,12 @@
 
         if (uid, self) in self._notifications:
             return self._notifications[(uid, self)]
-        
+
         home = self.homeWithUID(self._notificationHomeType, uid, create=True)
         notificationPath = home._path.child("notification")
         if not notificationPath.isdir():
             notificationPath = self.createNotifcationCollection(home, notificationPath)
-        
+
         notifications = NotificationCollection(notificationPath.basename(), home)
         self._notifications[(uid, self)] = notifications
         return notifications
@@ -612,8 +618,8 @@
         props = PropertyStore(self._path)
         self._transaction.addOperation(props.flush, "flush object resource properties")
         return props
-    
-    
+
+
     def _doValidate(self, component):
         raise NotImplementedError
 
@@ -702,7 +708,7 @@
         @param parent: the home containing this notification collection.
         @type parent: L{CommonHome}
         """
-        
+
         super(NotificationCollection, self).__init__(name, parent, realName)
 
         self._index = NotificationIndex(self)
@@ -718,7 +724,7 @@
     notificationObjectsSinceToken = CommonHomeChild.objectResourcesSinceToken
 
     def notificationObjectWithUID(self, uid):
-        
+
         record = self.retrieveOldIndex().recordForUID(uid)
         return self.notificationObjectWithName(record.name) if record else None
 

Modified: CalendarServer/branches/new-store/txdav/common/icommondatastore.py
===================================================================
--- CalendarServer/branches/new-store/txdav/common/icommondatastore.py	2010-07-01 20:33:12 UTC (rev 5830)
+++ CalendarServer/branches/new-store/txdav/common/icommondatastore.py	2010-07-01 20:34:16 UTC (rev 5831)
@@ -15,10 +15,11 @@
 ##
 
 """
-Common store interfaces
+Storage interfaces that are not implied by DAV, but are shared between the
+requirements for both CalDAV and CardDAV extensions.
 """
 
-from zope.interface.interface import Interface
+from txdav.idav import ITransaction
 
 __all__ = [
     # Exceptions
@@ -110,48 +111,12 @@
 # Interfaces
 #
 
-class ICommonDataStore(Interface):
+class ICommonTransaction(ITransaction):
     """
-    Data store
+    Transaction functionality shared in common by calendar and addressbook
+    stores.
     """
 
-    def newTransaction():
-        """
-        Create a new transaction.
-        
-        @rtype: L{ICommonStoreTransaction}
-        """
-
-
-class ICommonStoreTransaction(Interface):
-    """
-    AddressBook store transaction
-    """
-
-    def calendarHomeWithUID(uid, create=False):
-        """
-        Retrieve the calendar home for the principal with the given C{uid}.
-
-        If C{create} is C{True}, create the calendar home if it doesn't
-        already exist.
-
-        @return: an L{ICalendarHome} or C{None} if no such calendar
-            home exists.
-        """
-
-
-    def addressbookHomeWithUID(uid, create=False):
-        """
-        Retrieve the addressbook home for the principal with the given C{uid}.
-
-        If C{create} is C{True}, create the addressbook home if it doesn't
-        already exist.
-
-        @return: an L{IAddressBookHome} or C{None} if no such addressbook
-            home exists.
-        """
-
-
     def notificationsWithUID(uid):
         """
         Retrieve the notification collection for the principal with the given
@@ -162,13 +127,4 @@
         """
 
 
-    def commit():
-        """
-        Persist all of the effects which have occurred in this transaction.
-        """
 
-
-    def abort():
-        """
-        Reverse all of the effects which have occurred in this transaction.
-        """

Modified: CalendarServer/branches/new-store/txdav/idav.py
===================================================================
--- CalendarServer/branches/new-store/txdav/idav.py	2010-07-01 20:33:12 UTC (rev 5830)
+++ CalendarServer/branches/new-store/txdav/idav.py	2010-07-01 20:34:16 UTC (rev 5831)
@@ -21,15 +21,16 @@
 __all__ = [
     "PropertyStoreError",
     "PropertyChangeNotAllowedError",
+    "AbortedTransactionError",
     "IPropertyName",
     "IPropertyStore",
+    "IDataStore",
 ]
 
 from zope.interface import Attribute, Interface
 
 from zope.interface.common.mapping import IMapping
 
-
 #
 # Exceptions
 #
@@ -39,6 +40,7 @@
     Property store error.
     """
 
+
 class PropertyChangeNotAllowedError(PropertyStoreError):
     """
     Property cannot be edited.
@@ -48,6 +50,12 @@
         self.keys = keys
 
 
+class AbortedTransactionError(RuntimeError):
+    """
+    This transaction has aborted.
+    """
+
+
 #
 # Interfaces
 #
@@ -92,23 +100,37 @@
         """
 
 
+
+class IDataStore(Interface):
+    """
+    An L{IDataStore} is a storage of some objects.
+    """
+
+    def newTransaction():
+        """
+        Create a new transaction.
+
+        @return: a new transaction which provides L{ITransaction}, as well as
+            sub-interfaces to request appropriate data objects.
+
+        @rtype: L{ITransaction}
+        """
+
+
+
 class ITransaction(Interface):
     """
     Transaction that can be aborted and either succeeds or fails in
     its entirety.
     """
+
     def abort():
         """
         Abort this transaction.
         """
 
+
     def commit():
         """
         Perform this transaction.
         """
-
-
-class AbortedTransactionError(RuntimeError):
-    """
-    This transaction has aborted.  Go away.
-    """
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100701/acfc67a6/attachment-0001.html>


More information about the calendarserver-changes mailing list