[CalendarServer-changes] [6201] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Sun Aug 29 19:28:25 PDT 2010
Revision: 6201
http://trac.macosforge.org/projects/calendarserver/changeset/6201
Author: glyph at apple.com
Date: 2010-08-29 19:28:22 -0700 (Sun, 29 Aug 2010)
Log Message:
-----------
store-to-store migration API and tests
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/test/test_calendarquery.py
CalendarServer/trunk/twistedcaldav/test/test_sharing.py
CalendarServer/trunk/twistedcaldav/test/test_wrapping.py
CalendarServer/trunk/txdav/base/propertystore/test/test_sql.py
CalendarServer/trunk/txdav/caldav/datastore/scheduling.py
CalendarServer/trunk/txdav/caldav/datastore/test/common.py
CalendarServer/trunk/txdav/caldav/datastore/test/test_file.py
CalendarServer/trunk/txdav/caldav/datastore/test/test_scheduling.py
CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py
CalendarServer/trunk/txdav/caldav/datastore/util.py
CalendarServer/trunk/txdav/caldav/icalendarstore.py
CalendarServer/trunk/txdav/carddav/datastore/test/test_sql.py
CalendarServer/trunk/txdav/common/datastore/file.py
CalendarServer/trunk/txdav/common/datastore/sql.py
CalendarServer/trunk/txdav/common/datastore/test/util.py
Modified: CalendarServer/trunk/twistedcaldav/test/test_calendarquery.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_calendarquery.py 2010-08-28 02:53:27 UTC (rev 6200)
+++ CalendarServer/trunk/twistedcaldav/test/test_calendarquery.py 2010-08-30 02:28:22 UTC (rev 6201)
@@ -34,7 +34,7 @@
from twistedcaldav.config import config
from twistedcaldav.test.util import HomeTestCase
from twisted.internet.defer import inlineCallbacks, returnValue
-from txdav.caldav.datastore.test.test_sql import buildStore
+from txdav.common.datastore.test.util import buildStore
from txdav.caldav.datastore.test.common import StubNotifierFactory
Modified: CalendarServer/trunk/twistedcaldav/test/test_sharing.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_sharing.py 2010-08-28 02:53:27 UTC (rev 6200)
+++ CalendarServer/trunk/twistedcaldav/test/test_sharing.py 2010-08-30 02:28:22 UTC (rev 6201)
@@ -25,9 +25,11 @@
from twistedcaldav.config import config
from twistedcaldav.test.util import HomeTestCase, norequest
from twistedcaldav.resource import CalDAVResource
-from txdav.caldav.datastore.test.test_sql import buildStore
+from txdav.common.datastore.test.util import buildStore
from txdav.caldav.datastore.test.common import StubNotifierFactory
+sharedOwnerType = davxml.ResourceType.sharedownercalendar #@UndefinedVariable
+regularCalendarType = davxml.ResourceType.calendar #@UndefinedVariable
class SharingTests(HomeTestCase):
@@ -119,14 +121,14 @@
request = SimpleRequest(self.site, "MKCOL", "/calendar/")
rtype = self.resource.resourceType()
- self.assertEquals(rtype, davxml.ResourceType.calendar)
+ self.assertEquals(rtype, regularCalendarType)
propInvite = (yield self.resource.readProperty(customxml.Invite, request))
self.assertEquals(propInvite, None)
self.resource.upgradeToShare()
rtype = self.resource.resourceType()
- self.assertEquals(rtype, davxml.ResourceType.sharedownercalendar)
+ self.assertEquals(rtype, sharedOwnerType)
propInvite = (yield self.resource.readProperty(customxml.Invite, request))
self.assertEquals(propInvite, customxml.Invite())
@@ -140,14 +142,14 @@
request = SimpleRequest(self.site, "PROPPATCH", "/calendar/")
rtype = self.resource.resourceType()
- self.assertEquals(rtype, davxml.ResourceType.calendar)
+ self.assertEquals(rtype, regularCalendarType)
propInvite = (yield self.resource.readProperty(customxml.Invite, request))
self.assertEquals(propInvite, None)
self.resource.upgradeToShare()
rtype = self.resource.resourceType()
- self.assertEquals(rtype, davxml.ResourceType.sharedownercalendar)
+ self.assertEquals(rtype, sharedOwnerType)
propInvite = (yield self.resource.readProperty(customxml.Invite, request))
self.assertEquals(propInvite, customxml.Invite())
@@ -158,19 +160,17 @@
@inlineCallbacks
def test_downgradeFromShare(self):
- request = SimpleRequest(self.site, "PROPPATCH", "/calendar/")
-
- self.resource.writeDeadProperty(davxml.ResourceType.sharedownercalendar)
+ self.resource.writeDeadProperty(sharedOwnerType)
self.resource.writeDeadProperty(customxml.Invite())
rtype = self.resource.resourceType()
- self.assertEquals(rtype, davxml.ResourceType.sharedownercalendar)
+ self.assertEquals(rtype, sharedOwnerType)
propInvite = (yield self.resource.readProperty(customxml.Invite, None))
self.assertEquals(propInvite, customxml.Invite())
yield self.resource.downgradeFromShare(None)
rtype = self.resource.resourceType()
- self.assertEquals(rtype, davxml.ResourceType.calendar)
+ self.assertEquals(rtype, regularCalendarType)
propInvite = (yield self.resource.readProperty(customxml.Invite, None))
self.assertEquals(propInvite, None)
Modified: CalendarServer/trunk/twistedcaldav/test/test_wrapping.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_wrapping.py 2010-08-28 02:53:27 UTC (rev 6200)
+++ CalendarServer/trunk/twistedcaldav/test/test_wrapping.py 2010-08-30 02:28:22 UTC (rev 6201)
@@ -41,7 +41,7 @@
from txdav.carddav.datastore.test.test_file import vcard4_text
-from txdav.caldav.datastore.test.test_sql import buildStore
+from txdav.common.datastore.test.util import buildStore
from txdav.caldav.datastore.test.common import StubNotifierFactory, \
assertProvides
from txdav.caldav.icalendarstore import ICalendarHome
@@ -258,8 +258,9 @@
)
self.commit()
self.assertIsInstance(dropBoxResource, DropboxCollection)
+ dropboxHomeType = davxml.ResourceType.dropboxhome #@UndefinedVariable
self.assertEquals(dropBoxResource.resourceType(),
- davxml.ResourceType.dropboxhome)
+ dropboxHomeType)
@inlineCallbacks
@@ -271,8 +272,9 @@
C{CalendarHome.calendarWithName}.
"""
calDavFile = yield self.getResource("calendars/users/wsanchez/calendar")
+ regularCalendarType = davxml.ResourceType.calendar #@UndefinedVariable
self.assertEquals(calDavFile.resourceType(),
- davxml.ResourceType.calendar)
+ regularCalendarType)
self.commit()
Modified: CalendarServer/trunk/txdav/base/propertystore/test/test_sql.py
===================================================================
--- CalendarServer/trunk/txdav/base/propertystore/test/test_sql.py 2010-08-28 02:53:27 UTC (rev 6200)
+++ CalendarServer/trunk/txdav/base/propertystore/test/test_sql.py 2010-08-30 02:28:22 UTC (rev 6201)
@@ -23,7 +23,7 @@
from txdav.caldav.datastore.test.common import StubNotifierFactory
-from txdav.common.datastore.test.util import SQLStoreBuilder
+from txdav.common.datastore.test.util import buildStore
from txdav.base.propertystore.base import PropertyName
from txdav.base.propertystore.test import base
@@ -36,10 +36,6 @@
-theStoreBuilder = SQLStoreBuilder()
-buildStore = theStoreBuilder.buildStore
-
-
class PropertyStoreTest(base.PropertyStoreTest):
def _preTest(self):
Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling.py 2010-08-28 02:53:27 UTC (rev 6200)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling.py 2010-08-30 02:28:22 UTC (rev 6201)
@@ -16,8 +16,8 @@
##
from zope.interface.declarations import implements
from txdav.caldav.icalendarstore import ICalendarHome, ICalendar, ICalendarObject,\
- ICalendarTransaction
-from txdav.idav import IDataStore
+ ICalendarTransaction, ICalendarStore
+
from twisted.python.util import FancyEqMixin
from twisted.python.components import proxyForInterface
@@ -137,14 +137,12 @@
# return self._subCalendar.calendarObjectWithName(name)
-class ImplicitStore(object):
+class ImplicitStore(proxyForInterface(ICalendarStore, "_calendarStore")):
"""
This is a wrapper around an L{ICalendarStore} that implements implicit
scheduling.
"""
- implements(IDataStore)
-
def __init__(self, calendarStore):
"""
Create an L{ImplicitStore} wrapped around another
Modified: CalendarServer/trunk/txdav/caldav/datastore/test/common.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/test/common.py 2010-08-28 02:53:27 UTC (rev 6200)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/common.py 2010-08-30 02:28:22 UTC (rev 6201)
@@ -1184,7 +1184,33 @@
calendar2.calendarObjectWithUID(obj.uid()), None)
+ def test_eachCalendarHome(self):
+ """
+ L{ICalendarTransaction.eachCalendarHome} returns an iterator that
+ yields 2-tuples of (transaction, home).
+ """
+ # create some additional calendar homes
+ additionalUIDs = set('alpha-uid home2 home3 beta-uid'.split())
+ txn = self.transactionUnderTest()
+ for name in additionalUIDs:
+ txn.calendarHomeWithUID(name, create=True)
+ self.commit()
+ foundUIDs = set([])
+ lastTxn = None
+ for txn, home in self.storeUnderTest().eachCalendarHome():
+ self.addCleanup(txn.commit)
+ foundUIDs.add(home.uid())
+ self.assertNotIdentical(lastTxn, txn)
+ lastTxn = txn
+ requiredUIDs = set([
+ uid for uid in self.requirements
+ if self.requirements[uid] is not None
+ ])
+ expectedUIDs = additionalUIDs.union(requiredUIDs)
+ self.assertEquals(foundUIDs, expectedUIDs)
+
+
class StubNotifierFactory(object):
""" For testing push notifications without an XMPP server """
Modified: CalendarServer/trunk/txdav/caldav/datastore/test/test_file.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/test/test_file.py 2010-08-28 02:53:27 UTC (rev 6200)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/test_file.py 2010-08-30 02:28:22 UTC (rev 6201)
@@ -444,11 +444,14 @@
File storage tests.
"""
+ calendarStore = None
+
def storeUnderTest(self):
"""
Create and return a L{CalendarStore} for testing.
"""
- setUpCalendarStore(self)
+ if self.calendarStore is None:
+ setUpCalendarStore(self)
return self.calendarStore
Modified: CalendarServer/trunk/txdav/caldav/datastore/test/test_scheduling.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/test/test_scheduling.py 2010-08-28 02:53:27 UTC (rev 6200)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/test_scheduling.py 2010-08-30 02:28:22 UTC (rev 6201)
@@ -16,6 +16,14 @@
"""
Tests for L{txdav.caldav.datastore.scheduling}.
+
+The aforementioned module is intended to eventually support implicit
+scheduling; however, it does not currently. The interim purpose of this module
+and accompanying tests is to effectively test the interface specifications to
+make sure that the common tests don't require anything I{not} specified in the
+interface, so that dynamic proxies specified with a tool like
+C{proxyForInterface} can be used to implement features such as implicit
+scheduling or data caching as middleware in the data-store layer.
"""
from twisted.trial.unittest import TestCase
@@ -42,7 +50,10 @@
Tests for L{ImplicitSchedulingStore}.
"""
+ implicitStore = None
+
def storeUnderTest(self):
- setUpCalendarStore(self)
- self.implicitStore = ImplicitStore(self.calendarStore)
+ if self.implicitStore is None:
+ setUpCalendarStore(self)
+ self.implicitStore = ImplicitStore(self.calendarStore)
return self.implicitStore
Modified: CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py 2010-08-28 02:53:27 UTC (rev 6200)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py 2010-08-30 02:28:22 UTC (rev 6201)
@@ -24,18 +24,21 @@
from txdav.caldav.datastore.test.common import CommonTests as CalendarCommonTests
from txdav.common.datastore.sql import ECALENDARTYPE
-from txdav.common.datastore.test.util import SQLStoreBuilder
+from txdav.common.datastore.test.util import buildStore
from txdav.common.icommondatastore import NoSuchHomeChildError
from twisted.trial import unittest
from twisted.internet.defer import inlineCallbacks
from twisted.internet.threads import deferToThread
from twext.python.vcomponent import VComponent
+from twext.web2.dav.element.rfc2518 import GETContentLanguage, ResourceType
+from txdav.caldav.datastore.test.test_file import setUpCalendarStore
+from txdav.caldav.datastore.util import _migrateCalendar, migrateHome
+from txdav.base.propertystore.base import PropertyName
-theStoreBuilder = SQLStoreBuilder()
-buildStore = theStoreBuilder.buildStore
+
class CalendarSQLStorageTests(CalendarCommonTests, unittest.TestCase):
"""
Calendar SQL storage tests.
@@ -44,12 +47,12 @@
@inlineCallbacks
def setUp(self):
super(CalendarSQLStorageTests, self).setUp()
- self.calendarStore = yield buildStore(self, self.notifierFactory)
+ self._sqlCalendarStore = yield buildStore(self, self.notifierFactory)
self.populate()
def populate(self):
- populateTxn = self.calendarStore.newTransaction()
+ populateTxn = self.storeUnderTest().newTransaction()
for homeUID in self.requirements:
calendars = self.requirements[homeUID]
if calendars is not None:
@@ -79,8 +82,112 @@
"""
Create and return a L{CalendarStore} for testing.
"""
- return self.calendarStore
+ return self._sqlCalendarStore
+
+ def assertCalendarsSimilar(self, a, b, bCalendarFilter=None):
+ """
+ Assert that two calendars have a similar structure (contain the same
+ events).
+ """
+ def namesAndComponents(x, filter=lambda x:x.component()):
+ return dict([(fromObj.name(), filter)
+ for fromObj in x.calendarObjects()])
+ if bCalendarFilter is not None:
+ extra = [bCalendarFilter]
+ else:
+ extra = []
+ self.assertEquals(namesAndComponents(a), namesAndComponents(b, *extra))
+
+
+ def assertPropertiesSimilar(self, a, b, disregard=[]):
+ """
+ Assert that two objects with C{properties} methods have similar
+ properties.
+
+ @param disregard: a list of L{PropertyName} keys to discard from both
+ input and output.
+ """
+ def sanitize(x):
+ result = dict(x.properties().items())
+ for key in disregard:
+ result.pop(key, None)
+ return result
+ self.assertEquals(sanitize(a), sanitize(b))
+
+
+ def fileTransaction(self):
+ """
+ Create a file-backed calendar transaction, for migration testing.
+ """
+ setUpCalendarStore(self)
+ fileStore = self.calendarStore
+ txn = fileStore.newTransaction()
+ self.addCleanup(txn.commit)
+ return txn
+
+
+ def test_migrateCalendarFromFile(self):
+ """
+ C{_migrateCalendar()} can migrate a file-backed calendar to a database-
+ backed calendar.
+ """
+ fromCalendar = self.fileTransaction().calendarHomeWithUID(
+ "home1").calendarWithName("calendar_1")
+ toHome = self.transactionUnderTest().calendarHomeWithUID(
+ "new-home", create=True)
+ toCalendar = toHome.calendarWithName("calendar")
+ _migrateCalendar(fromCalendar, toCalendar, lambda x: x.component())
+ self.assertCalendarsSimilar(fromCalendar, toCalendar)
+
+
+ def test_migrateHomeFromFile(self):
+ """
+ L{migrateHome} will migrate an L{ICalendarHome} provider from one
+ backend to another; in this specific case, from the file-based backend
+ to the SQL-based backend.
+ """
+ fromHome = self.fileTransaction().calendarHomeWithUID("home1")
+
+ builtinProperties = [PropertyName.fromElement(ResourceType)]
+
+ # Populate an arbitrary / unused dead properties so there's something
+ # to verify against.
+
+ key = PropertyName.fromElement(GETContentLanguage)
+ fromHome.properties()[key] = GETContentLanguage("C")
+ fromHome.calendarWithName("calendar_1").properties()[key] = (
+ GETContentLanguage("pig-latin")
+ )
+ toHome = self.transactionUnderTest().calendarHomeWithUID(
+ "new-home", create=True
+ )
+ migrateHome(fromHome, toHome, lambda x: x.component())
+ self.assertEquals(set([c.name() for c in toHome.calendars()]),
+ set([k for k in self.requirements['home1'].keys()
+ if self.requirements['home1'][k] is not None]))
+ for c in fromHome.calendars():
+ self.assertPropertiesSimilar(
+ c, toHome.calendarWithName(c.name()),
+ builtinProperties
+ )
+ self.assertPropertiesSimilar(fromHome, toHome, builtinProperties)
+
+
+ def test_eachCalendarHome(self):
+ """
+ L{ICalendarStore.eachCalendarHome} is currently stubbed out by
+ L{txdav.common.datastore.sql.CommonDataStore}.
+ """
+ return super(CalendarSQLStorageTests, self).test_eachCalendarHome()
+
+
+ test_eachCalendarHome.todo = (
+ "stubbed out, as migration only needs to go from file->sql currently")
+
+
+
+
@inlineCallbacks
def test_homeProvisioningConcurrency(self):
Modified: CalendarServer/trunk/txdav/caldav/datastore/util.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/util.py 2010-08-28 02:53:27 UTC (rev 6200)
+++ CalendarServer/trunk/txdav/caldav/datastore/util.py 2010-08-30 02:28:22 UTC (rev 6201)
@@ -20,7 +20,7 @@
from twext.python.vcomponent import InvalidICalendarDataError
from twext.python.vcomponent import VComponent
-from txdav.common.icommondatastore import InvalidObjectResourceError,\
+from txdav.common.icommondatastore import InvalidObjectResourceError, \
NoSuchObjectResourceError
@@ -28,7 +28,8 @@
"""
Validate a calendar component for a particular calendar.
- @param calendarObject: The calendar object whose component will be replaced.
+ @param calendarObject: The calendar object whose component will be
+ replaced.
@type calendarObject: L{ICalendarObject}
@param calendar: The calendar which the L{ICalendarObject} is present in.
@@ -74,15 +75,61 @@
if dropboxProperty is not None:
componentDropboxID = dropboxProperty.value().split("/")[-1]
return componentDropboxID
- attachProperty = calendarObject.component().getFirstPropertyInAnyComponent("ATTACH")
+ attachProperty = calendarObject.component().getFirstPropertyInAnyComponent(
+ "ATTACH"
+ )
if attachProperty is not None:
# Make sure the value type is URI
valueType = attachProperty.params().get("VALUE", ("TEXT",))
- if valueType[0] == "URI":
+ if valueType[0] == "URI":
# FIXME: more aggressive checking to see if this URI is really the
# 'right' URI. Maybe needs to happen in the front end.
attachPath = attachProperty.value().split("/")[-2]
return attachPath
-
+
return calendarObject.uid() + ".dropbox"
-
\ No newline at end of file
+
+
+def _migrateCalendar(inCalendar, outCalendar, getComponent):
+ """
+ Copy all calendar objects and properties in the given input calendar to the
+ given output calendar.
+
+ @param inCalendar: the L{ICalendar} to retrieve calendar objects from.
+ @param outCalendar: the L{ICalendar} to store calendar objects to.
+ @param getComponent: a 1-argument callable; see L{migrateHome}.
+ """
+ outCalendar.properties().update(inCalendar.properties())
+ for calendarObject in inCalendar.calendarObjects():
+ outCalendar.createCalendarObjectWithName(
+ calendarObject.name(),
+ calendarObject.component()) # XXX WRONG SHOULD CALL getComponent
+ outCalendar.calendarObjectWithName(
+ calendarObject.name()).properties().update(
+ calendarObject.properties())
+ # XXX attachments
+
+
+def migrateHome(inHome, outHome, getComponent):
+ """
+ Copy all calendars and properties in the given input calendar to the given
+ output calendar.
+
+ @param inHome: the L{ICalendarHome} to retrieve calendars and properties
+ from.
+
+ @param outHome: the L{ICalendarHome} to store calendars and properties
+ into.
+
+ @param getComponent: a 1-argument callable that takes an L{ICalendarObject}
+ (from a calendar in C{inHome}) and returns a L{VComponent} (to store in
+ a calendar in outHome).
+ """
+ outHome.removeCalendarWithName("calendar")
+ outHome.removeCalendarWithName("inbox")
+ outHome.properties().update(inHome.properties())
+ for calendar in inHome.calendars():
+ name = calendar.name()
+ outHome.createCalendarWithName(name)
+ outCalendar = outHome.calendarWithName(name)
+ _migrateCalendar(calendar, outCalendar, getComponent)
Modified: CalendarServer/trunk/txdav/caldav/icalendarstore.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/icalendarstore.py 2010-08-28 02:53:27 UTC (rev 6200)
+++ CalendarServer/trunk/txdav/caldav/icalendarstore.py 2010-08-30 02:28:22 UTC (rev 6201)
@@ -19,9 +19,9 @@
Calendar store interfaces
"""
-from txdav.common.icommondatastore import ICommonTransaction,\
+from txdav.common.icommondatastore import ICommonTransaction, \
IShareableCollection
-from txdav.idav import IDataStoreResource
+from txdav.idav import IDataStoreResource, IDataStore
from txdav.idav import INotifier
@@ -62,6 +62,23 @@
"""
+
+class ICalendarStore(IDataStore):
+ """
+ API root for calendar data storage.
+ """
+
+ def eachCalendarHome(self):
+ """
+ Enumerate all calendar homes in this store, with each one in an
+ accompanying transaction.
+
+ @return: an iterator of 2-tuples of C{(transaction, calendar home)}
+ where C{transaction} is an L{ITransaction} provider and C{calendar
+ home} is an L{ICalendarHome} provider.
+ """
+
+
#
# Interfaces
#
Modified: CalendarServer/trunk/txdav/carddav/datastore/test/test_sql.py
===================================================================
--- CalendarServer/trunk/txdav/carddav/datastore/test/test_sql.py 2010-08-28 02:53:27 UTC (rev 6200)
+++ CalendarServer/trunk/txdav/carddav/datastore/test/test_sql.py 2010-08-30 02:28:22 UTC (rev 6201)
@@ -24,15 +24,13 @@
from txdav.carddav.datastore.test.common import CommonTests as AddressBookCommonTests
from txdav.common.datastore.sql import EADDRESSBOOKTYPE
-from txdav.common.datastore.test.util import SQLStoreBuilder
+from txdav.common.datastore.test.util import buildStore
from twisted.trial import unittest
from twisted.internet.defer import inlineCallbacks
from twisted.internet.threads import deferToThread
from twistedcaldav.vcard import Component as VCard
-theStoreBuilder = SQLStoreBuilder()
-buildStore = theStoreBuilder.buildStore
class AddressBookSQLStorageTests(AddressBookCommonTests, unittest.TestCase):
"""
Modified: CalendarServer/trunk/txdav/common/datastore/file.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/file.py 2010-08-28 02:53:27 UTC (rev 6200)
+++ CalendarServer/trunk/txdav/common/datastore/file.py 2010-08-30 02:28:22 UTC (rev 6201)
@@ -31,6 +31,7 @@
from twistedcaldav.notifications import NotificationRecord
from twistedcaldav.notifications import NotificationsDatabase as OldNotificationIndex
from twistedcaldav.sharing import SharedCollectionsDatabase
+from txdav.caldav.icalendarstore import ICalendarStore
from txdav.common.icommondatastore import HomeChildNameNotAllowedError, \
HomeChildNameAlreadyExistsError, NoSuchHomeChildError, \
@@ -41,7 +42,7 @@
from txdav.base.datastore.file import DataStoreTransaction, DataStore, writeOperation, \
hidden, isValidName, FileMetaDataMixin
from txdav.base.datastore.util import cached
-from txdav.idav import IDataStore
+
from txdav.base.propertystore.base import PropertyName
from txdav.base.propertystore.xattr import PropertyStore
@@ -65,7 +66,7 @@
@ivar _path: A L{CachingFilePath} referencing a directory on disk that
stores all calendar and addressbook data for a group of UIDs.
"""
- implements(IDataStore)
+ implements(ICalendarStore)
def __init__(self, path, notifierFactory, enableCalendars=True,
enableAddressBooks=True):
@@ -82,14 +83,48 @@
self._notifierFactory = notifierFactory
self._transactionClass = CommonStoreTransaction
+
def newTransaction(self, name='no name'):
"""
Create a new transaction.
@see Transaction
"""
- return self._transactionClass(self, name, self.enableCalendars, self.enableAddressBooks, self._notifierFactory)
+ return self._transactionClass(
+ self, name, self.enableCalendars,
+ self.enableAddressBooks, self._notifierFactory
+ )
+
+ def _homesOfType(self, storeType):
+ """
+ Common implementation of L{ICalendarStore.eachCalendarHome} and
+ L{IAddressBookStore.eachAddressbookHome}; see those for a description
+ of the return type.
+
+ @param storeType: one of L{EADDRESSBOOKTYPE} or L{ECALENDARTYPE}.
+ """
+ top = self._path.child(TOPPATHS[storeType]).child(UIDPATH)
+ for firstPrefix in top.children():
+ if not isValidName(firstPrefix.basename()):
+ continue
+ for secondPrefix in firstPrefix.children():
+ if not isValidName(secondPrefix.basename()):
+ continue
+ for actualHome in secondPrefix.children():
+ uid = actualHome.basename()
+ if not isValidName(uid):
+ continue
+ txn = self.newTransaction("enumerate home %r" % (uid,))
+ home = txn.homeWithUID(storeType, uid, False)
+ yield (txn, home)
+
+
+ def eachCalendarHome(self):
+ return self._homesOfType(ECALENDARTYPE)
+
+
+
class CommonStoreTransaction(DataStoreTransaction):
"""
In-memory implementation of
@@ -672,7 +707,7 @@
def syncToken(self):
-
+
try:
urnuuid = str(self.properties()[PropertyName.fromElement(ResourceID)].children[0])
except KeyError:
Modified: CalendarServer/trunk/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql.py 2010-08-28 02:53:27 UTC (rev 6200)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py 2010-08-30 02:28:22 UTC (rev 6201)
@@ -1,3 +1,4 @@
+# -*- test-case-name: txdav.caldav.datastore.test.test_sql,txdav.carddav.datastore.test.test_sql -*-
##
# Copyright (c) 2010 Apple Inc. All rights reserved.
#
@@ -36,7 +37,7 @@
from twistedcaldav.customxml import NotificationType
from txdav.common.datastore.sql_legacy import PostgresLegacyNotificationsEmulator
-from txdav.caldav.icalendarstore import ICalendarTransaction
+from txdav.caldav.icalendarstore import ICalendarTransaction, ICalendarStore
from txdav.carddav.iaddressbookstore import IAddressBookTransaction
@@ -51,7 +52,7 @@
INotificationObject
from txdav.base.datastore.sql import memoized
from txdav.base.datastore.util import cached
-from txdav.idav import IDataStore, AlreadyFinishedError
+from txdav.idav import AlreadyFinishedError
from txdav.base.propertystore.base import PropertyName
from txdav.base.propertystore.sql import PropertyStore
@@ -67,7 +68,7 @@
class CommonDataStore(Service, object):
- implements(IDataStore)
+ implements(ICalendarStore)
def __init__(self, connectionFactory, notifierFactory, attachmentsPath,
enableCalendars=True, enableAddressBooks=True):
@@ -78,6 +79,13 @@
self.attachmentsPath = attachmentsPath
self.enableCalendars = enableCalendars
self.enableAddressBooks = enableAddressBooks
+
+
+ def eachCalendarHome(self):
+ """
+ @see L{ICalendarStore.eachCalendarHome}
+ """
+ return []
def newTransaction(self, label="unlabeled"):
Modified: CalendarServer/trunk/txdav/common/datastore/test/util.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/test/util.py 2010-08-28 02:53:27 UTC (rev 6200)
+++ CalendarServer/trunk/txdav/common/datastore/test/util.py 2010-08-30 02:28:22 UTC (rev 6201)
@@ -137,3 +137,6 @@
log.err()
cleanupConn.commit()
cleanupConn.close()
+
+theStoreBuilder = SQLStoreBuilder()
+buildStore = theStoreBuilder.buildStore
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100829/e26f3099/attachment-0001.html>
More information about the calendarserver-changes
mailing list