[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