[CalendarServer-changes] [13264] twext/trunk/twext/who/opendirectory

source_changes at macosforge.org source_changes at macosforge.org
Fri Apr 11 19:44:55 PDT 2014


Revision: 13264
          http://trac.calendarserver.org//changeset/13264
Author:   gaya at apple.com
Date:     2014-04-11 19:44:55 -0700 (Fri, 11 Apr 2014)
Log Message:
-----------
_queryStringAndRecordTypesFromExpression always returns recordTypes (instead of None for default types)

Modified Paths:
--------------
    twext/trunk/twext/who/opendirectory/_service.py
    twext/trunk/twext/who/opendirectory/test/test_service.py

Modified: twext/trunk/twext/who/opendirectory/_service.py
===================================================================
--- twext/trunk/twext/who/opendirectory/_service.py	2014-04-11 18:33:28 UTC (rev 13263)
+++ twext/trunk/twext/who/opendirectory/_service.py	2014-04-12 02:44:55 UTC (rev 13264)
@@ -86,6 +86,7 @@
     """
 
 
+
 class OpenDirectoryDataError(OpenDirectoryError):
     """
     OpenDirectory data error.
@@ -210,15 +211,19 @@
             self._node = node
 
 
-    def _queryStringAndRecordTypesFromMatchExpression(self, expression):
+    def _queryStringAndRecordTypeFromMatchExpression(self, expression, recordTypes):
         """
         Generates an LDAP query string from a match expression.
 
         @param expression: A match expression.
         @type expression: L{MatchExpression}
 
-        @return: tuple(LDAP query string, recordTypes)
-        @rtype: (C{unicode}, set())
+        @param recordTypes: allowed Open Directory record type strings
+            or None for default record type strings
+        @type recordTypes: set(str)
+
+        @return: tuple(LDAP query string, Open Directory record type string)
+        @rtype: tuple(C{unicode}, C{unicode})
         """
         matchType = ODMatchType.fromMatchType(expression.matchType)
         if matchType is None:
@@ -237,7 +242,7 @@
         #     raise NotImplementedError("Need to handle case sensitive")
 
         if expression.fieldName is self.fieldName.recordType:
-            return (notOp, set([ODRecordType.fromRecordType(expression.fieldValue).value]),)
+            return (notOp, ODRecordType.fromRecordType(expression.fieldValue).value)
 
         if expression.fieldName is self.fieldName.uid:
             odAttr = ODAttribute.guid
@@ -259,35 +264,48 @@
             matchType.queryString.format(
                 notOp=notOp, attribute=odAttr.value, value=value
             ),
-            None,
+            None if recordTypes else set([t.value for t in ODRecordType.iterconstants()]),
         )
 
 
-    def _queryStringAndRecordTypesFromCompoundExpression(self, expression):
+    def _queryStringAndRecordTypesFromCompoundExpression(self, expression, recordTypes):
         """
         Generates an LDAP query string from a compound expression.
 
         @param expression: A compound expression.
         @type expression: L{MatchExpression}
 
-        @return: tuple(LDAP query string, recordTypes)
-        @rtype: (C{unicode}, set())
+        @param recordTypes: allowed Open Directory record type strings
+            or None for default record type strings
+        @type recordTypes: set(str)
+
+        @return: tuple(LDAP query string, set(Open Directory record type strings))
+        @rtype: (C{unicode}, set(C{unicode}))
         """
+        if recordTypes is None:
+            recordTypes = set([t.value for t in ODRecordType.iterconstants()])
+
         queryTokens = []
-        recordTypes = set()
-
         for subExpression in expression.expressions:
-            queryToken, subExpRecordTypes = self._queryStringAndRecordTypesFromExpression(subExpression)
+            queryToken, subExpRecordTypes = self._queryStringAndRecordTypesFromExpression(
+                subExpression, recordTypes
+            )
             if subExpRecordTypes:
-                if expression.operand is Operand.AND:
-                    recordTypes |= subExpRecordTypes
-                elif queryToken == u"!": #NOR
-                    recordTypes |= set([t.value for t in ODRecordType.iterconstants()]) - subExpRecordTypes
+                if not isinstance(subExpRecordTypes, set):
+                    if bool(expression.operand is Operand.AND) != bool(queryToken): # AND or NOR
+                        if expression.operand is Operand.AND:
+                            recordTypes = recordTypes & set([subExpRecordTypes])
+                        else:
+                            recordTypes = recordTypes - set([subExpRecordTypes])
+                        queryToken = None
+                    else:
+                        raise QueryNotSupportedError(
+                            "Record type matches must AND or NOR"
+                        )
                 else:
-                    raise QueryNotSupportedError(
-                        "Record type matches must AND or NOR"
-                    )
-            else:
+                    recordTypes = subExpRecordTypes
+
+            if queryToken:
                 queryTokens.append(queryToken)
 
         if queryTokens:
@@ -301,10 +319,10 @@
                 queryTokens[:0] = (u"(")
                 queryTokens.append(u")")
 
-        return (u"".join(queryTokens), recordTypes if recordTypes else None,)
+        return (u"".join(queryTokens), recordTypes)
 
 
-    def _queryStringAndRecordTypesFromExpression(self, expression):
+    def _queryStringAndRecordTypesFromExpression(self, expression, recordTypes=None):
         """
         Converts either a MatchExpression or a CompoundExpression into an LDAP
         query string.
@@ -312,15 +330,23 @@
         @param expression: An expression.
         @type expression: L{MatchExpression} or L{CompoundExpression}
 
-        @return: tuple(LDAP query string, recordTypes)
-        @rtype: (C{unicode}, set())
+        @param recordTypes: allowed Open Directory record type strings
+            or None for default record type strings
+        @type recordTypes: set(str)
+
+        @return: tuple(LDAP query string, set(Open Directory record type strings))
+        @rtype: (C{unicode}, set(C{unicode}))
         """
 
         if isinstance(expression, MatchExpression):
-            return self._queryStringAndRecordTypesFromMatchExpression(expression)
+            return self._queryStringAndRecordTypeFromMatchExpression(
+                expression, recordTypes
+            )
 
         if isinstance(expression, CompoundExpression):
-            return self._queryStringAndRecordTypesFromCompoundExpression(expression)
+            return self._queryStringAndRecordTypesFromCompoundExpression(
+                expression, recordTypes
+            )
 
         raise QueryNotSupportedError(
             "Unknown expression type: {0!r}".format(expression)
@@ -334,20 +360,16 @@
         @param expression: A compound expression.
         @type expression: L{CompoundExpression}
 
-        @return: A native OpenDirectory query.
+        @return: A native OpenDirectory query or None if query will return no records
         @rtype: L{ODQuery}
         """
 
-        queryString, recordTypes = self._queryStringAndRecordTypesFromExpression(expression)
-        supportedRecordTypes = set([t.value for t in ODRecordType.iterconstants()])
-        if recordTypes:
-            recordTypes = supportedRecordTypes & recordTypes
-            if not recordTypes:
-                raise QueryNotSupportedError(
-                    "Query for unsupported record types: {0!r}".format(recordTypes - supportedRecordTypes)
-                )
-        else:
-            recordTypes = supportedRecordTypes
+        queryString, recordTypes = self._queryStringAndRecordTypesFromExpression(
+            expression,
+            set([t.value for t in ODRecordType.iterconstants()])
+        )
+        if not recordTypes:
+            return None
 
         attributes = [a.value for a in ODAttribute.iterconstants()]
         maxResults = 0
@@ -357,7 +379,7 @@
             recordTypes,
             None,
             ODMatchType.compound.value if queryString else ODMatchType.any.value,
-            queryString if queryString else None,
+            queryString,
             attributes,
             maxResults,
             None
@@ -489,6 +511,9 @@
         # We can call scheduleInRunLoop:forMode:, which will call back to
         # its delegate...
 
+        if query is None:
+            return succeed(tuple())
+
         odRecords, error = query.resultsAllowingPartial_error_(False, None)
 
         if error:
@@ -762,7 +787,6 @@
         return succeed(result)
 
 
-
     @inlineCallbacks
     def members(self):
         members = set()

Modified: twext/trunk/twext/who/opendirectory/test/test_service.py
===================================================================
--- twext/trunk/twext/who/opendirectory/test/test_service.py	2014-04-11 18:33:28 UTC (rev 13263)
+++ twext/trunk/twext/who/opendirectory/test/test_service.py	2014-04-12 02:44:55 UTC (rev 13264)
@@ -76,8 +76,11 @@
                 matchType=matchType
             )
             queryString, recordTypes = service._queryStringAndRecordTypesFromExpression(expression)
-            self.assertEquals(recordTypes, None)
             self.assertEquals(
+                recordTypes,
+                set([u"dsRecTypeStandard:Groups", u"dsRecTypeStandard:Users"])
+            )
+            self.assertEquals(
                 queryString,
                 u"({attribute}{expected})".format(
                     attribute=ODAttribute.shortName.value, expected=expected
@@ -96,8 +99,11 @@
             flags=MatchFlags.NOT
         )
         queryString, recordTypes = service._queryStringAndRecordTypesFromExpression(expression)
-        self.assertEquals(recordTypes, None)
         self.assertEquals(
+            recordTypes,
+            set([u"dsRecTypeStandard:Groups", u"dsRecTypeStandard:Users"])
+        )
+        self.assertEquals(
             queryString,
             u"(!{attribute}=xyzzy)".format(
                 attribute=ODAttribute.shortName.value,
@@ -117,8 +123,11 @@
             flags=MatchFlags.caseInsensitive
         )
         queryString, recordTypes = service._queryStringAndRecordTypesFromExpression(expression)
-        self.assertEquals(recordTypes, None)
         self.assertEquals(
+            recordTypes,
+            set([u"dsRecTypeStandard:Groups", u"dsRecTypeStandard:Users"])
+        )
+        self.assertEquals(
             queryString,
             u"???????({attribute}=xyzzy)".format(
                 attribute=ODAttribute.shortName.value,
@@ -141,8 +150,11 @@
             u"\\xyzzy: a/b/(c)* ~~ >=< ~~ &| \0!!"
         )
         queryString, recordTypes = service._queryStringAndRecordTypesFromExpression(expression)
-        self.assertEquals(recordTypes, None)
         self.assertEquals(
+            recordTypes,
+            set([u"dsRecTypeStandard:Groups", u"dsRecTypeStandard:Users"])
+        )
+        self.assertEquals(
             queryString,
             u"({attribute}={expected})".format(
                 attribute=ODAttribute.fullName.value,
@@ -185,8 +197,11 @@
             Operand.AND
         )
         queryString, recordTypes = service._queryStringAndRecordTypesFromExpression(expression)
-        self.assertEquals(recordTypes, None)
         self.assertEquals(
+            recordTypes,
+            set([u"dsRecTypeStandard:Groups", u"dsRecTypeStandard:Users"])
+        )
+        self.assertEquals(
             queryString,
             (
                 u"(&(dsAttrTypeStandard:GeneratedUID=*a*)"
@@ -216,8 +231,11 @@
             Operand.OR
         )
         queryString, recordTypes = service._queryStringAndRecordTypesFromExpression(expression)
-        self.assertEquals(recordTypes, None)
         self.assertEquals(
+            recordTypes,
+            set([u"dsRecTypeStandard:Groups", u"dsRecTypeStandard:Users"])
+        )
+        self.assertEquals(
             queryString,
             (
                 u"(|(dsAttrTypeStandard:RecordName=*a*)"
@@ -255,7 +273,7 @@
             Operand.AND
         )
         queryString, recordTypes = service._queryStringAndRecordTypesFromExpression(expression)
-        self.assertEquals(set(recordTypes), set([u"dsRecTypeStandard:Groups", u"dsRecTypeStandard:Users"]))
+        self.assertEquals(recordTypes, set())
         self.assertEquals(
             queryString,
             u"(dsAttrTypeStandard:RecordName=xyzzy)"
@@ -266,7 +284,7 @@
             [
                 MatchExpression(
                     service.fieldName.shortNames,
-                    u"xyzzy",
+                    u"xxxxx",
                     matchType=MatchType.equals
                 ),
                 CompoundExpression(
@@ -278,23 +296,25 @@
                             matchType=MatchType.equals
                         ),
                         MatchExpression(
-                            service.fieldName.recordType,
-                            service.recordType.user,
+                            service.fieldName.shortNames,
+                            u"yyyyy",
                             matchType=MatchType.equals
                         ),
                     ],
                     Operand.AND
                 ),
             ],
-            Operand.AND
+            Operand.OR
         )
         queryString, recordTypes = service._queryStringAndRecordTypesFromExpression(expression)
-        self.assertEquals(set(recordTypes), set([u"dsRecTypeStandard:Groups", u"dsRecTypeStandard:Users"]))
+        self.assertEquals(set(recordTypes), set([u"dsRecTypeStandard:Groups", ]))
         self.assertEquals(
             queryString,
-            u"(dsAttrTypeStandard:RecordName=xyzzy)"
+            u"("
+                u"|(dsAttrTypeStandard:RecordName=xxxxx)"
+                u"(dsAttrTypeStandard:RecordName=yyyyy)"
+            u")"
         )
-
         # NOR expression
         expression = CompoundExpression(
             [
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140411/901c9c53/attachment-0001.html>


More information about the calendarserver-changes mailing list