[CalendarServer-changes] [6854] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Wed Feb 2 17:15:04 PST 2011
Revision: 6854
http://trac.macosforge.org/projects/calendarserver/changeset/6854
Author: cdaboo at apple.com
Date: 2011-02-02 17:15:04 -0800 (Wed, 02 Feb 2011)
Log Message:
-----------
No more properties on object resources in sqlstore.
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/method/put_addressbook_common.py
CalendarServer/trunk/twistedcaldav/storebridge.py
CalendarServer/trunk/txdav/base/propertystore/sql.py
CalendarServer/trunk/txdav/caldav/datastore/sql.py
CalendarServer/trunk/txdav/caldav/datastore/test/common.py
CalendarServer/trunk/txdav/caldav/datastore/util.py
CalendarServer/trunk/txdav/carddav/datastore/test/common.py
CalendarServer/trunk/txdav/common/datastore/file.py
CalendarServer/trunk/txdav/common/datastore/sql.py
CalendarServer/trunk/txdav/common/datastore/sql_schema_v1.sql
CalendarServer/trunk/txdav/common/datastore/test/test_util.py
Modified: CalendarServer/trunk/twistedcaldav/method/put_addressbook_common.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/put_addressbook_common.py 2011-02-03 01:14:28 UTC (rev 6853)
+++ CalendarServer/trunk/twistedcaldav/method/put_addressbook_common.py 2011-02-03 01:15:04 UTC (rev 6854)
@@ -440,17 +440,6 @@
# Do the actual put or copy
response = (yield self.doStore())
- # Remember the resource's content-type.
- if self.destinationadbk:
- content_type = self.request.headers.getHeader("content-type")
- if content_type is None:
- content_type = MimeType("text", "vcard",
- params={"charset":"utf-8"})
- self.destination.writeDeadProperty(
- davxml.GETContentType.fromString(generateContentType(content_type))
- )
-
- # Do quota check on destination
if reservation:
yield reservation.unreserve()
Modified: CalendarServer/trunk/twistedcaldav/storebridge.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/storebridge.py 2011-02-03 01:14:28 UTC (rev 6853)
+++ CalendarServer/trunk/twistedcaldav/storebridge.py 2011-02-03 01:15:04 UTC (rev 6854)
@@ -63,6 +63,7 @@
from txdav.base.propertystore.base import PropertyName
from txdav.common.icommondatastore import NoSuchObjectResourceError
+from txdav.idav import PropertyChangeNotAllowedError
log = Logger()
@@ -91,42 +92,40 @@
# FIXME 'uid' here should be verifying something.
def get(self, qname, uid=None):
- """
-
- """
try:
return self._newPropertyStore[self._convertKey(qname)]
except KeyError:
raise HTTPError(StatusResponse(
- NOT_FOUND,
- "No such property: {%s}%s" % qname))
+ NOT_FOUND,
+ "No such property: {%s}%s" % qname
+ ))
def set(self, property, uid=None):
- """
-
- """
- self._newPropertyStore[self._convertKey(property.qname())] = property
+ try:
+ self._newPropertyStore[self._convertKey(property.qname())] = property
+ except PropertyChangeNotAllowedError:
+ raise HTTPError(StatusResponse(
+ FORBIDDEN,
+ "Property cannot be changed: {%s}%s" % property.qname(),
+ ))
+
def delete(self, qname, uid=None):
- """
-
- """
- del self._newPropertyStore[self._convertKey(qname)]
+ try:
+ del self._newPropertyStore[self._convertKey(qname)]
+ except KeyError:
+ # RFC 2518 Section 12.13.1 says that removal of
+ # non-existing property is not an error.
+ pass
def contains(self, qname, uid=None, cache=True):
- """
-
- """
return (self._convertKey(qname) in self._newPropertyStore)
def list(self, uid=None, filterByUID=True, cache=True):
- """
-
- """
return [(pname.namespace, pname.name) for pname in
self._newPropertyStore.keys()]
@@ -1037,6 +1036,7 @@
super(CalendarAttachment, self).__init__(**kw)
self._newStoreCalendarObject = calendarObject
self._newStoreAttachment = self._newStoreObject = attachment
+ self._dead_properties = NonePropertyStore(self)
self.attachmentName = attachmentName
@@ -1104,19 +1104,20 @@
http_MKCOL = None
http_MKCALENDAR = None
+ def http_PROPPATCH(self, request):
+ """
+ No dead properties allowed on attachments.
+ """
+ return FORBIDDEN
+
def isCollection(self):
return False
-
-
-
-
class NoParent(CalDAVResource):
def http_MKCALENDAR(self, request):
return CONFLICT
-
def http_PUT(self, request):
return CONFLICT
@@ -1145,7 +1146,7 @@
self._newStoreObject = storeObject
self._dead_properties = _NewStorePropertiesWrapper(
self._newStoreObject.properties()
- ) if self._newStoreObject else NonePropertyStore(self)
+ ) if self._newStoreObject and self._newStoreParent.objectResourcesHaveProperties() else NonePropertyStore(self)
def isCollection(self):
@@ -1186,6 +1187,14 @@
return self.storeRemove(request, True, request.uri)
+ def http_PROPPATCH(self, request):
+ """
+ No dead properties allowed on object resources.
+ """
+ if self._newStoreParent.objectResourcesHaveProperties():
+ return super(_CommonObjectResource, self).http_PROPPATCH(request)
+ else:
+ return FORBIDDEN
@inlineCallbacks
def storeStream(self, stream):
@@ -1636,11 +1645,27 @@
def _initializeWithObject(self, notificationObject):
self._newStoreObject = notificationObject
- self._dead_properties = _NewStorePropertiesWrapper(
- self._newStoreObject.properties()
- ) if self._newStoreObject else NonePropertyStore(self)
+ self._dead_properties = NonePropertyStore(self)
+ def liveProperties(self):
+
+ props = super(StoreNotificationObjectFile, self).liveProperties()
+ props += (customxml.NotificationType.qname(),)
+ return props
+
+ @inlineCallbacks
+ def readProperty(self, property, request):
+ if type(property) is tuple:
+ qname = property
+ else:
+ qname = property.qname()
+
+ if qname == customxml.NotificationType.qname():
+ returnValue(self._newStoreObject.xmlType())
+
+ returnValue((yield super(StoreNotificationObjectFile, self).readProperty(property, request)))
+
def isCollection(self):
return False
@@ -1678,6 +1703,11 @@
return self.storeRemove(request, request.uri)
+ def http_PROPPATCH(self, request):
+ """
+ No dead properties allowed on notification objects.
+ """
+ return FORBIDDEN
@inlineCallbacks
def storeRemove(self, request, where):
Modified: CalendarServer/trunk/txdav/base/propertystore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/base/propertystore/sql.py 2011-02-03 01:14:28 UTC (rev 6853)
+++ CalendarServer/trunk/txdav/base/propertystore/sql.py 2011-02-03 01:15:04 UTC (rev 6854)
@@ -67,28 +67,37 @@
rows = yield txn.execSQL(
"""
select
+ %s,
RESOURCE_PROPERTY.RESOURCE_ID,
RESOURCE_PROPERTY.NAME,
RESOURCE_PROPERTY.VIEWER_UID,
RESOURCE_PROPERTY.VALUE
from RESOURCE_PROPERTY
- left join %s on (RESOURCE_PROPERTY.RESOURCE_ID = %s)
+ right join %s on (RESOURCE_PROPERTY.RESOURCE_ID = %s)
where %s = %%s
- """ % (joinTable, joinColumn, parentIDColumn),
+ """ % (joinColumn, joinTable, joinColumn, parentIDColumn),
[parentID]
)
createdStores = {}
- for resource_id, name, view_uid, value in rows:
- if resource_id not in createdStores:
+ for object_resource_id, resource_id, name, view_uid, value in rows:
+ if resource_id:
+ if resource_id not in createdStores:
+ store = cls.__new__(cls)
+ super(PropertyStore, store).__init__(defaultuser)
+ store._txn = txn
+ store._resourceID = resource_id
+ store._cached = {}
+ createdStores[resource_id] = store
+ createdStores[resource_id]._cached[(name, view_uid)] = value
+ else:
store = cls.__new__(cls)
super(PropertyStore, store).__init__(defaultuser)
store._txn = txn
- store._resourceID = resource_id
+ store._resourceID = object_resource_id
store._cached = {}
- createdStores[resource_id] = store
- createdStores[resource_id]._cached[(name, view_uid)] = value
-
+ createdStores[object_resource_id] = store
+
returnValue(createdStores)
Modified: CalendarServer/trunk/txdav/caldav/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/sql.py 2011-02-03 01:14:28 UTC (rev 6853)
+++ CalendarServer/trunk/txdav/caldav/datastore/sql.py 2011-02-03 01:15:04 UTC (rev 6854)
@@ -227,6 +227,13 @@
raise NotImplementedError()
+ def objectResourcesHaveProperties(self):
+ """
+ inbox resources need to store Originator, Recipient etc properties.
+ Other calendars do not have object resources with properties.
+ """
+ return self._name == "inbox"
+
def initPropertyStore(self, props):
# Setup peruser special properties
props.setSpecialProperties(
Modified: CalendarServer/trunk/txdav/caldav/datastore/test/common.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/test/common.py 2011-02-03 01:14:28 UTC (rev 6853)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/common.py 2011-02-03 01:15:04 UTC (rev 6854)
@@ -1144,34 +1144,36 @@
propertyContent.name = propertyName.name
propertyContent.namespace = propertyName.namespace
- (yield self.calendarObjectUnderTest()).properties()[
- propertyName] = propertyContent
- yield self.commit()
- # Sanity check; are properties even readable in a separate transaction?
- # Should probably be a separate test.
- self.assertEquals(
- (yield self.calendarObjectUnderTest()).properties()[propertyName],
- propertyContent)
- obj = yield self.calendarObjectUnderTest()
- event1_text = yield obj.iCalendarText()
- event1_text_withDifferentSubject = event1_text.replace(
- "SUMMARY:CalDAV protocol updates",
- "SUMMARY:Changed"
- )
- # Sanity check; make sure the test has the right idea of the subject.
- self.assertNotEquals(event1_text, event1_text_withDifferentSubject)
- newComponent = VComponent.fromString(event1_text_withDifferentSubject)
- yield obj.setComponent(newComponent)
+ calobject = (yield self.calendarObjectUnderTest())
+ if calobject._parentCollection.objectResourcesHaveProperties():
+ (yield self.calendarObjectUnderTest()).properties()[
+ propertyName] = propertyContent
+ yield self.commit()
+ # Sanity check; are properties even readable in a separate transaction?
+ # Should probably be a separate test.
+ self.assertEquals(
+ (yield self.calendarObjectUnderTest()).properties()[propertyName],
+ propertyContent)
+ obj = yield self.calendarObjectUnderTest()
+ event1_text = yield obj.iCalendarText()
+ event1_text_withDifferentSubject = event1_text.replace(
+ "SUMMARY:CalDAV protocol updates",
+ "SUMMARY:Changed"
+ )
+ # Sanity check; make sure the test has the right idea of the subject.
+ self.assertNotEquals(event1_text, event1_text_withDifferentSubject)
+ newComponent = VComponent.fromString(event1_text_withDifferentSubject)
+ yield obj.setComponent(newComponent)
+
+ # Putting everything into a separate transaction to account for any
+ # caching that may take place.
+ yield self.commit()
+ self.assertEquals(
+ (yield self.calendarObjectUnderTest()).properties()[propertyName],
+ propertyContent
+ )
- # Putting everything into a separate transaction to account for any
- # caching that may take place.
- yield self.commit()
- self.assertEquals(
- (yield self.calendarObjectUnderTest()).properties()[propertyName],
- propertyContent
- )
-
eventWithDropbox = "\r\n".join("""
BEGIN:VCALENDAR
CALSCALE:GREGORIAN
Modified: CalendarServer/trunk/txdav/caldav/datastore/util.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/util.py 2011-02-03 01:14:28 UTC (rev 6853)
+++ CalendarServer/trunk/txdav/caldav/datastore/util.py 2011-02-03 01:15:04 UTC (rev 6854)
@@ -133,7 +133,8 @@
# calendar server didn't have per-user properties.
outObject = yield outCalendar.calendarObjectWithName(
calendarObject.name())
- outObject.properties().update(calendarObject.properties())
+ if outCalendar.objectResourcesHaveProperties():
+ outObject.properties().update(calendarObject.properties())
# Migrate attachments.
for attachment in (yield calendarObject.attachments()):
Modified: CalendarServer/trunk/txdav/carddav/datastore/test/common.py
===================================================================
--- CalendarServer/trunk/txdav/carddav/datastore/test/common.py 2011-02-03 01:14:28 UTC (rev 6853)
+++ CalendarServer/trunk/txdav/carddav/datastore/test/common.py 2011-02-03 01:15:04 UTC (rev 6854)
@@ -874,36 +874,38 @@
propertyContent.name = propertyName.name
propertyContent.namespace = propertyName.namespace
- (yield self.addressbookObjectUnderTest()).properties()[
- propertyName] = propertyContent
- yield self.commit()
- # Sanity check; are properties even readable in a separate transaction?
- # Should probably be a separate test.
- self.assertEquals(
+ abobject = (yield self.addressbookObjectUnderTest())
+ if abobject._parentCollection.objectResourcesHaveProperties():
(yield self.addressbookObjectUnderTest()).properties()[
- propertyName
- ],
- propertyContent)
- obj = yield self.addressbookObjectUnderTest()
- vcard1_text = yield obj.vCardText()
- vcard1_text_withDifferentNote = vcard1_text.replace(
- "NOTE:CardDAV protocol updates",
- "NOTE:Changed"
- )
- # Sanity check; make sure the test has the right idea of the subject.
- self.assertNotEquals(vcard1_text, vcard1_text_withDifferentNote)
- newComponent = VComponent.fromString(vcard1_text_withDifferentNote)
- yield obj.setComponent(newComponent)
+ propertyName] = propertyContent
+ yield self.commit()
+ # Sanity check; are properties even readable in a separate transaction?
+ # Should probably be a separate test.
+ self.assertEquals(
+ (yield self.addressbookObjectUnderTest()).properties()[
+ propertyName
+ ],
+ propertyContent)
+ obj = yield self.addressbookObjectUnderTest()
+ vcard1_text = yield obj.vCardText()
+ vcard1_text_withDifferentNote = vcard1_text.replace(
+ "NOTE:CardDAV protocol updates",
+ "NOTE:Changed"
+ )
+ # Sanity check; make sure the test has the right idea of the subject.
+ self.assertNotEquals(vcard1_text, vcard1_text_withDifferentNote)
+ newComponent = VComponent.fromString(vcard1_text_withDifferentNote)
+ yield obj.setComponent(newComponent)
+
+ # Putting everything into a separate transaction to account for any
+ # caching that may take place.
+ yield self.commit()
+ self.assertEquals(
+ (yield self.addressbookObjectUnderTest()).properties()[propertyName],
+ propertyContent
+ )
- # Putting everything into a separate transaction to account for any
- # caching that may take place.
- yield self.commit()
- self.assertEquals(
- (yield self.addressbookObjectUnderTest()).properties()[propertyName],
- propertyContent
- )
-
@inlineCallbacks
def test_dontLeakAddressbooks(self):
"""
Modified: CalendarServer/trunk/txdav/common/datastore/file.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/file.py 2011-02-03 01:14:28 UTC (rev 6853)
+++ CalendarServer/trunk/txdav/common/datastore/file.py 2011-02-03 01:15:04 UTC (rev 6854)
@@ -49,6 +49,7 @@
from txdav.base.datastore.util import cached
from txdav.base.propertystore.base import PropertyName
+from txdav.base.propertystore.none import PropertyStore as NonePropertyStore
from txdav.base.propertystore.xattr import PropertyStore
from errno import EEXIST, ENOENT
@@ -812,6 +813,12 @@
return succeed(self.retrieveOldIndex().whatchanged(token))
+ def objectResourcesHaveProperties(self):
+ """
+ So filestore objects do need to support properties.
+ """
+ return True
+
# FIXME: property writes should be a write operation
@cached
def properties(self):
@@ -911,7 +918,7 @@
@cached
def properties(self):
uid = self._parentCollection._home.uid()
- props = PropertyStore(uid, lambda : self._path)
+ props = PropertyStore(uid, lambda : self._path) if self._parentCollection.objectResourcesHaveProperties() else NonePropertyStore(uid)
self.initPropertyStore(props)
self._transaction.addOperation(props.flush, "object properties flush")
return props
@@ -1169,6 +1176,10 @@
def uid(self):
return self._uid
+ def xmlType(self):
+ # NB This is the NotificationType property element
+ return self.properties()[PropertyName.fromElement(NotificationType)]
+
def initPropertyStore(self, props):
# Setup peruser special properties
props.setSpecialProperties(
Modified: CalendarServer/trunk/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql.py 2011-02-03 01:14:28 UTC (rev 6853)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py 2011-02-03 01:15:04 UTC (rev 6854)
@@ -31,6 +31,7 @@
from twext.python.log import Logger, LoggingMixIn
from twext.web2.dav.element.rfc2518 import ResourceType
+from twext.web2.dav.element.parser import WebDAVDocument
from twext.web2.http_headers import MimeType
from twisted.python import hashlib
@@ -61,8 +62,9 @@
from twext.python.clsprop import classproperty
from twext.enterprise.dal.syntax import Select
+from txdav.base.propertystore.base import PropertyName
+from txdav.base.propertystore.none import PropertyStore as NonePropertyStore
from txdav.base.propertystore.sql import PropertyStore
-from txdav.base.propertystore.base import PropertyName
from twistedcaldav.customxml import NotificationType
from twistedcaldav.dateops import datetimeMktime
@@ -1609,6 +1611,9 @@
[self._home._resourceID, self._resourceID, name]
))[0][0]
+ def objectResourcesHaveProperties(self):
+ return False
+
@inlineCallbacks
def _loadPropertyStore(self, props=None):
if props is None:
@@ -1734,14 +1739,17 @@
if dataRows:
# Get property stores for all these child resources (if any found)
- propertyStores =(yield PropertyStore.loadAll(
- parent._home.uid(),
- parent._txn,
- cls._objectTable["name"],
- "%s.%s" % (cls._objectTable["name"], cls._objectTable["column_RESOURCE_ID"],),
- "%s.%s" % (cls._objectTable["name"], cls._objectTable["column_PARENT_RESOURCE_ID"]),
- parent._resourceID,
- ))
+ if parent.objectResourcesHaveProperties():
+ propertyStores =(yield PropertyStore.loadAll(
+ parent._home.uid(),
+ parent._txn,
+ cls._objectTable["name"],
+ "%s.%s" % (cls._objectTable["name"], cls._objectTable["column_RESOURCE_ID"],),
+ "%s.%s" % (cls._objectTable["name"], cls._objectTable["column_PARENT_RESOURCE_ID"]),
+ parent._resourceID,
+ ))
+ else:
+ propertyStores = {}
# Create the actual objects merging in properties
for row in dataRows:
@@ -1853,12 +1861,15 @@
@inlineCallbacks
def _loadPropertyStore(self, props=None, created=False):
if props is None:
- props = yield PropertyStore.load(
- self._parentCollection.ownerHome().uid(),
- self._txn,
- self._resourceID,
- created=created
- )
+ if self._parentCollection.objectResourcesHaveProperties():
+ props = yield PropertyStore.load(
+ self._parentCollection.ownerHome().uid(),
+ self._txn,
+ self._resourceID,
+ created=created
+ )
+ else:
+ props = NonePropertyStore(self._parentCollection.ownerHome().uid())
self.initPropertyStore(props)
self._propertyStore = props
@@ -2278,6 +2289,7 @@
self._size = None
self._created = None
self._modified = None
+ self._xmlType = None
self._objectText = None
def __repr__(self):
@@ -2301,6 +2313,7 @@
NOTIFICATION_UID,
MD5,
character_length(XML_DATA),
+ XML_TYPE,
CREATED,
MODIFIED
from NOTIFICATION
@@ -2327,9 +2340,10 @@
child._uid,
child._md5,
child._size,
+ child._xmlType,
child._created,
child._modified,) = tuple(row)
- yield child._loadPropertyStore(props=propertyStores.get(child._resourceID, None))
+ child._loadPropertyStore(props=propertyStores.get(child._resourceID, None))
results.append(child)
returnValue(results)
@@ -2347,6 +2361,7 @@
RESOURCE_ID,
MD5,
character_length(XML_DATA),
+ XML_TYPE,
CREATED,
MODIFIED
from NOTIFICATION
@@ -2357,23 +2372,17 @@
(self._resourceID,
self._md5,
self._size,
+ self._xmlType,
self._created,
self._modified,) = tuple(rows[0])
- yield self._loadPropertyStore()
+ self._loadPropertyStore()
returnValue(self)
else:
returnValue(None)
- @inlineCallbacks
def _loadPropertyStore(self, props=None, created=False):
if props is None:
- props = yield PropertyStore.load(
- self._home.uid(),
- self._txn,
- self._resourceID,
- created=created
- )
- self.initPropertyStore(props)
+ props = NonePropertyStore(self._home.uid())
self._propertyStore = props
@@ -2381,17 +2390,6 @@
return self._propertyStore
- def initPropertyStore(self, props):
- # Setup peruser special properties
- props.setSpecialProperties(
- (
- ),
- (
- PropertyName.fromElement(NotificationType),
- ),
- )
-
-
@property
def _txn(self):
return self._home._txn
@@ -2415,7 +2413,7 @@
Set the object resource data and update and cached metadata.
"""
- xmltypeString = xmltype.toxml()
+ self._xmlType = NotificationType(xmltype)
self._md5 = hashlib.md5(xmldata).hexdigest()
self._size = len(xmldata)
if inserting:
@@ -2429,10 +2427,10 @@
CREATED,
MODIFIED
""",
- [self._home._resourceID, uid, xmltypeString, xmldata, self._md5]
+ [self._home._resourceID, uid, self._xmlType.toxml(), xmldata, self._md5]
)
self._resourceID, self._created, self._modified = rows[0]
- yield self._loadPropertyStore()
+ self._loadPropertyStore()
else:
rows = yield self._txn.execSQL("""
update NOTIFICATION
@@ -2440,10 +2438,8 @@
where NOTIFICATION_HOME_RESOURCE_ID = %s and NOTIFICATION_UID = %s
returning MODIFIED
""",
- [xmltypeString, xmldata, self._md5, self._home._resourceID, uid])
+ [self._xmlType.toxml(), xmldata, self._md5, self._home._resourceID, uid])
self._modified = rows[0][0]
-
- self.properties()[PropertyName.fromElement(NotificationType)] = NotificationType(xmltype)
self._objectText = xmldata
@@ -2480,7 +2476,14 @@
def size(self):
return self._size
+ def xmlType(self):
+ # NB This is the NotificationType property element
+ if isinstance(self._xmlType, str):
+ # Convert into NotificationType property element
+ self._xmlType = WebDAVDocument.fromString(self._xmlType).root_element
+ return self._xmlType
+
def created(self):
utc = datetime.datetime.strptime(self._created, "%Y-%m-%d %H:%M:%S.%f")
return datetimeMktime(utc)
Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema_v1.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema_v1.sql 2011-02-03 01:14:28 UTC (rev 6853)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema_v1.sql 2011-02-03 01:15:04 UTC (rev 6854)
@@ -89,8 +89,8 @@
RESOURCE_ID integer primary key default nextval('RESOURCE_ID_SEQ'),
NOTIFICATION_HOME_RESOURCE_ID integer not null references NOTIFICATION_HOME,
NOTIFICATION_UID varchar(255) not null,
- XML_TYPE varchar not null,
- XML_DATA varchar not null,
+ XML_TYPE varchar(255) not null,
+ XML_DATA text not null,
MD5 char(32) not null,
CREATED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
MODIFIED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
Modified: CalendarServer/trunk/txdav/common/datastore/test/test_util.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/test/test_util.py 2011-02-03 01:14:28 UTC (rev 6853)
+++ CalendarServer/trunk/txdav/common/datastore/test/test_util.py 2011-02-03 01:15:04 UTC (rev 6854)
@@ -144,7 +144,7 @@
transport = attachment.store(someAttachmentType)
someAttachmentData = "Here is some data for your attachment, enjoy."
transport.write(someAttachmentData)
- transport.loseConnection()
+ yield transport.loseConnection()
yield maybeCommit()
self.topService.startService()
yield self.subStarted
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110202/f03ec7a9/attachment-0001.html>
More information about the calendarserver-changes
mailing list