[CalendarServer-changes] [13236] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Wed Apr 9 18:55:12 PDT 2014
Revision: 13236
http://trac.calendarserver.org//changeset/13236
Author: sagen at apple.com
Date: 2014-04-09 18:55:12 -0700 (Wed, 09 Apr 2014)
Log Message:
-----------
Adds inTransaction( ) method to the store, and now delegates.py uses that.
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/directory/principal.py
CalendarServer/trunk/txdav/common/datastore/file.py
CalendarServer/trunk/txdav/common/datastore/sql.py
CalendarServer/trunk/txdav/common/datastore/test/test_sql.py
CalendarServer/trunk/txdav/who/delegates.py
CalendarServer/trunk/txdav/who/util.py
Modified: CalendarServer/trunk/twistedcaldav/directory/principal.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/principal.py 2014-04-10 01:43:23 UTC (rev 13235)
+++ CalendarServer/trunk/twistedcaldav/directory/principal.py 2014-04-10 01:55:12 UTC (rev 13236)
@@ -484,7 +484,7 @@
for record in (
yield self.directory.recordsWithRecordType(self.recordType)
):
- for shortName in record.shortNames:
+ for shortName in getattr(record, "shortNames", []):
children.append(shortName)
except AttributeError:
log.warn("Cannot list children of record type {rt}",
@@ -638,19 +638,17 @@
emailAddresses = record.emailAddresses
except AttributeError:
emailAddresses = []
+ try:
+ shortNames = record.shortNames
+ except AttributeError:
+ shortNames = []
return tag.fillSlots(
directoryGUID=str(record.service.guid),
realm=record.service.realmName.encode("utf-8"),
principalGUID=guid,
recordType=record.service.recordTypeToOldName(record.recordType),
- shortNames=",".join([n.encode("utf-8") for n in record.shortNames]),
- # MOVE2WHO: need this?
- # securityIDs=",".join(record.authIDs),
+ shortNames=",".join([n.encode("utf-8") for n in shortNames]),
fullName=record.displayName.encode("utf-8"),
- # MOVE2WHO: need this?
- # firstName=str(record.firstName),
- # MOVE2WHO: need this?
- # lastName=str(record.lastName),
emailAddresses=formatList(emailAddresses),
principalUID=str(self.resource.principalUID()),
principalURL=formatLink(self.resource.principalURL()),
@@ -815,12 +813,12 @@
record.service.recordTypeToOldName(record.recordType),
quote(shortName.encode("utf-8"))
) + slash
- for shortName in record.shortNames
+ for shortName in getattr(record, "shortNames", [])
])
def __str__(self):
- return "(%s)%s" % (self.record.recordType, self.record.shortNames[0])
+ return "(%s)%s" % (self.record.recordType, self.record.uid)
def __eq__(self, other):
Modified: CalendarServer/trunk/txdav/common/datastore/file.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/file.py 2014-04-10 01:43:23 UTC (rev 13235)
+++ CalendarServer/trunk/txdav/common/datastore/file.py 2014-04-10 01:55:12 UTC (rev 13236)
@@ -31,6 +31,7 @@
from twisted.internet.defer import succeed, inlineCallbacks, returnValue
from twisted.python.util import FancyEqMixin
from twisted.python import hashlib
+from twisted.python.failure import Failure
from twistedcaldav import customxml
from twistedcaldav.customxml import NotificationType
@@ -182,6 +183,41 @@
@inlineCallbacks
+ def inTransaction(self, label, operation, transactionCreator=None):
+ """
+ Perform the given operation in a transaction, committing or aborting as
+ required.
+
+ @param label: the label to pass to the transaction creator
+
+ @param operation: a 1-arg callable that takes an L{IAsyncTransaction} and
+ returns a value.
+
+ @param transactionCreator: a 1-arg callable that takes a "label" arg and
+ returns a transaction
+
+ @return: a L{Deferred} that fires with C{operation}'s result or fails with
+ its error, unless there is an error creating, aborting or committing
+ the transaction.
+ """
+
+ if transactionCreator is None:
+ txn = self.newTransaction()
+ else:
+ txn = transactionCreator(label=label)
+
+ try:
+ result = yield operation(txn)
+ except:
+ f = Failure()
+ yield txn.abort()
+ returnValue(f)
+ else:
+ yield txn.commit()
+ returnValue(result)
+
+
+ @inlineCallbacks
def _withEachHomeDo(self, enumerator, action, batchSize):
"""
Implementation of L{ICalendarStore.withEachCalendarHomeDo} and
Modified: CalendarServer/trunk/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql.py 2014-04-10 01:43:23 UTC (rev 13235)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py 2014-04-10 01:55:12 UTC (rev 13236)
@@ -293,6 +293,41 @@
return txn
+ @inlineCallbacks
+ def inTransaction(self, label, operation, transactionCreator=None):
+ """
+ Perform the given operation in a transaction, committing or aborting as
+ required.
+
+ @param label: the label to pass to the transaction creator
+
+ @param operation: a 1-arg callable that takes an L{IAsyncTransaction} and
+ returns a value.
+
+ @param transactionCreator: a 1-arg callable that takes a "label" arg and
+ returns a transaction
+
+ @return: a L{Deferred} that fires with C{operation}'s result or fails with
+ its error, unless there is an error creating, aborting or committing
+ the transaction.
+ """
+
+ if transactionCreator is None:
+ txn = self.newTransaction()
+ else:
+ txn = transactionCreator(label=label)
+
+ try:
+ result = yield operation(txn)
+ except:
+ f = Failure()
+ yield txn.abort()
+ returnValue(f)
+ else:
+ yield txn.commit()
+ returnValue(result)
+
+
def setMigrating(self, state):
"""
Set the "migrating" state
Modified: CalendarServer/trunk/txdav/common/datastore/test/test_sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/test/test_sql.py 2014-04-10 01:43:23 UTC (rev 13235)
+++ CalendarServer/trunk/txdav/common/datastore/test/test_sql.py 2014-04-10 01:55:12 UTC (rev 13236)
@@ -21,7 +21,7 @@
from twext.enterprise.dal.syntax import Select
from twext.enterprise.dal.syntax import Insert
-from twisted.internet.defer import inlineCallbacks, returnValue
+from twisted.internet.defer import inlineCallbacks, returnValue, succeed
from twisted.internet.task import Clock
from twisted.trial.unittest import TestCase
from twisted.internet.defer import Deferred
@@ -433,3 +433,50 @@
yield fixUUIDNormalization(self.storeUnderTest())
self.assertEqual((yield self.allHomeUIDs(schema.ADDRESSBOOK_HOME)),
[[normalizedUID]])
+
+
+ @inlineCallbacks
+ def test_inTransaction(self):
+ """
+ Make sure a successful operation commits the transaction while an
+ unsuccessful operation (raised an exception) aborts the transaction.
+ """
+
+ store = self.storeUnderTest()
+
+ def txnCreator(label):
+ self.txn = StubTransaction(label)
+ return self.txn
+
+ def goodOperation(txn):
+ return succeed(None)
+
+ def badOperation(txn):
+ 1 / 0
+ return succeed(None)
+
+ yield store.inTransaction("good", goodOperation, txnCreator)
+ self.assertEquals(self.txn.action, "committed")
+
+ try:
+ yield store.inTransaction("bad", badOperation, txnCreator)
+ except:
+ pass
+ self.assertEquals(self.txn.action, "aborted")
+
+
+
+class StubTransaction(object):
+
+ def __init__(self, label):
+ self.label = label
+ self.action = None
+
+ def commit(self):
+ self.action = "committed"
+ return succeed(None)
+
+ def abort(self):
+ self.action = "aborted"
+ return succeed(None)
+
Modified: CalendarServer/trunk/txdav/who/delegates.py
===================================================================
--- CalendarServer/trunk/txdav/who/delegates.py 2014-04-10 01:43:23 UTC (rev 13235)
+++ CalendarServer/trunk/txdav/who/delegates.py 2014-04-10 01:55:12 UTC (rev 13236)
@@ -68,21 +68,26 @@
"""
parentUID, _ignore_proxyType = self.uid.split(u"#")
- txn = self.service._store.newTransaction(label="DirectoryRecord.members")
+ @inlineCallbacks
+ def _members(txn):
+ if self.recordType in (
+ RecordType.readDelegateGroup, RecordType.writeDelegateGroup
+ ): # Members are delegates of this record
+ readWrite = (self.recordType is RecordType.writeDelegateGroup)
+ delegateUIDs = (
+ yield txn.delegates(parentUID, readWrite, expanded=expanded)
+ )
- if self.recordType in (
- RecordType.readDelegateGroup, RecordType.writeDelegateGroup
- ): # Members are delegates of this record
- readWrite = (self.recordType is RecordType.writeDelegateGroup)
- delegateUIDs = (
- yield txn.delegates(parentUID, readWrite, expanded=expanded)
- )
+ else: # Members have delegated to this record
+ readWrite = (self.recordType is RecordType.writeDelegatorGroup)
+ delegateUIDs = (
+ yield txn.delegators(parentUID, readWrite)
+ )
+ returnValue(delegateUIDs)
- else: # Members have delegated to this record
- readWrite = (self.recordType is RecordType.writeDelegatorGroup)
- delegateUIDs = (
- yield txn.delegators(parentUID, readWrite)
- )
+ delegateUIDs = yield self.service._store.inTransaction(
+ "DirectoryRecord.members", _members
+ )
records = []
for uid in delegateUIDs:
@@ -90,7 +95,6 @@
record = yield self.service._masterDirectory.recordWithUID(uid)
if record is not None:
records.append(record)
- yield txn.commit()
returnValue(records)
@@ -117,22 +121,24 @@
m=[r.uid for r in memberRecords]
)
- txn = self.service._store.newTransaction(label="DirectoryRecord.setMembers")
+ @inlineCallbacks
+ def _setMembers(txn):
+ yield txn.removeDelegates(parentUID, readWrite)
+ yield txn.removeDelegateGroups(parentUID, readWrite)
- yield txn.removeDelegates(parentUID, readWrite)
- yield txn.removeDelegateGroups(parentUID, readWrite)
+ delegator = (
+ yield self.service._masterDirectory.recordWithUID(parentUID)
+ )
- delegator = (
- yield self.service._masterDirectory.recordWithUID(parentUID)
+ for delegate in memberRecords:
+ yield addDelegate(txn, delegator, delegate, readWrite)
+
+ yield self.service._store.inTransaction(
+ "DirectoryRecord.setMembers", _setMembers
)
- for delegate in memberRecords:
- yield addDelegate(txn, delegator, delegate, readWrite)
- yield txn.commit()
-
-
def recordTypeToProxyType(recordType):
return {
RecordType.readDelegateGroup: "calendar-proxy-read",
Modified: CalendarServer/trunk/txdav/who/util.py
===================================================================
--- CalendarServer/trunk/txdav/who/util.py 2014-04-10 01:43:23 UTC (rev 13235)
+++ CalendarServer/trunk/txdav/who/util.py 2014-04-10 01:55:12 UTC (rev 13236)
@@ -106,7 +106,6 @@
params.rdnSchema.base,
credentials=creds,
fieldNameToAttributesMap=MappingProxyType({
- # FieldName.dn: (LDAPAttribute.dn.value,),
BaseFieldName.uid: ("apple-generateduid",),
BaseFieldName.guid: ("apple-generateduid",),
BaseFieldName.shortNames: (LDAPAttribute.uid.value,),
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140409/c8ffe52e/attachment-0001.html>
More information about the calendarserver-changes
mailing list