[CalendarServer-changes] [11970] CalendarServer/trunk/twext/who

source_changes at macosforge.org source_changes at macosforge.org
Wed Mar 12 11:24:34 PDT 2014


Revision: 11970
          http://trac.calendarserver.org//changeset/11970
Author:   wsanchez at apple.com
Date:     2013-11-19 08:45:53 -0800 (Tue, 19 Nov 2013)
Log Message:
-----------
Add an indexRecords() method and remove ability to set the index.

Modified Paths:
--------------
    CalendarServer/trunk/twext/who/index.py
    CalendarServer/trunk/twext/who/test/test_index.py
    CalendarServer/trunk/twext/who/xml.py

Modified: CalendarServer/trunk/twext/who/index.py
===================================================================
--- CalendarServer/trunk/twext/who/index.py	2013-11-19 05:59:39 UTC (rev 11969)
+++ CalendarServer/trunk/twext/who/index.py	2013-11-19 16:45:53 UTC (rev 11970)
@@ -172,34 +172,62 @@
         return self._index
 
 
-    @index.setter
-    def index(self, value):
+    def loadRecords(self):
         """
-        Sets the index.
+        Load records.  This method is called by the L{index} property and
+        provides a hook into which the index can be updated.
 
-        @param index: An index.
-        @type index: L{dict}
+        This method must be implemented by subclasses.
+
+        An example implementation::
+
+            def loadRecords(self):
+                self.flush()
+                while True:
+                    records = readSomeRecordsFromMyBackEnd()
+                    if not records:
+                        break
+                    self.indexRecords(records)
         """
-        self._index = value
+        raise NotImplementedError("Subclasses must implement loadRecords().")
 
 
-    def loadRecords(self):
+    def indexRecords(self, records):
         """
-        Load records.  This must be implemented by subclasses.
+        Add some records to the index.
 
-        The implementation should set the index property with current index
-        data.
+        @param records: The records to index.
+        @type records: iterable of L{DirectoryRecord}
         """
-        raise NotImplementedError("Subclasses must implement loadRecords().")
+        index = self._index
 
+        for fieldName in self.indexedFields:
+            index.setdefault(fieldName, {})
 
+        for record in records:
+            for fieldName in self.indexedFields:
+                values = record.fields.get(fieldName, None)
+
+                if values is not None:
+                    if not BaseFieldName.isMultiValue(fieldName):
+                        values = (values,)
+
+                    for value in values:
+                        index[fieldName].setdefault(value, set()).add(record)
+
+
     def flush(self):
         """
         Flush the index.
         """
-        self._index = None
+        index = {}
 
+        for fieldName in self.indexedFields:
+            index.setdefault(fieldName, {})
 
+        self._index = index
+
+
     def indexedRecordsFromMatchExpression(self, expression, records=None):
         """
         Finds records in the internal indexes matching a single expression.

Modified: CalendarServer/trunk/twext/who/test/test_index.py
===================================================================
--- CalendarServer/trunk/twext/who/test/test_index.py	2013-11-19 05:59:39 UTC (rev 11969)
+++ CalendarServer/trunk/twext/who/test/test_index.py	2013-11-19 16:45:53 UTC (rev 11970)
@@ -51,36 +51,24 @@
         Index starts as C{None}.
         """
         service = self.service()
-        self.assertIdentical(service._index, None)
+        self.assertTrue(emptyIndex(service._index))
 
 
     def test_index_get(self):
         """
-        Getting the C{index} property calls C{loadRecords} and returns the
-        index set by C{loadRecords}.
+        Getting the C{index} property calls C{loadRecords}.
         """
         class TestService(DirectoryService):
+            loaded = False
+
             def loadRecords(self):
-                self.index = self.indexToLoad
+                self.loaded = True
 
         service = TestService(u"")
+        service.index
+        self.assertTrue(service.loaded)
 
-        for index in ({}, {}, {}):
-            service.indexToLoad = index
-            self.assertIdentical(service.index, index)
 
-
-    def test_index_set(self):
-        """
-        Setting the index and getting it gives us back the same value.
-        """
-        service = NoLoadDirectoryService(u"")
-
-        for index in ({}, {}, {}):
-            service.index = index
-            self.assertIdentical(service.index, index)
-
-
     def test_loadRecords(self):
         """
         L{DirectoryService.loadRecords} raises C{NotImplementedError}.
@@ -96,7 +84,7 @@
         service = NoLoadDirectoryService(u"")
         service._index = {}
         service.flush()
-        self.assertIdentical(service._index, None)
+        self.assertTrue(emptyIndex(service._index))
 
 
     def _noop(self):
@@ -157,3 +145,24 @@
 
     test_members_group = _noop
     test_memberships = _noop
+
+
+
+def emptyIndex(index):
+    """
+    Determine whether an index is empty.
+
+    @param index: An index.
+    @type index: L{dict}
+
+    @return: true if C{index} is empty, otherwise false.
+    """
+    if not index:
+        return True
+
+    for fieldName, fieldIndex in index.iteritems():
+        for fieldValue, records in fieldIndex:
+            if records:
+                return False
+
+    return True

Modified: CalendarServer/trunk/twext/who/xml.py
===================================================================
--- CalendarServer/trunk/twext/who/xml.py	2013-11-19 05:59:39 UTC (rev 11969)
+++ CalendarServer/trunk/twext/who/xml.py	2013-11-19 16:45:53 UTC (rev 11970)
@@ -242,7 +242,7 @@
         if not realmName:
             raise ParseError("No realm name.")
 
-        unknownRecordTypes   = set()
+        unknownRecordTypes = set()
         unknownFieldElements = set()
 
         records = set()
@@ -259,32 +259,17 @@
         # Store results
         #
 
-        index = {}
+        self.flush()
+        self.indexRecords(records)
 
-        for fieldName in self.indexedFields:
-            index[fieldName] = {}
-
-        for record in records:
-            for fieldName in self.indexedFields:
-                values = record.fields.get(fieldName, None)
-
-                if values is not None:
-                    if not BaseFieldName.isMultiValue(fieldName):
-                        values = (values,)
-
-                    for value in values:
-                        index[fieldName].setdefault(value, set()).add(record)
-
         self._realmName = realmName
 
-        self._unknownRecordTypes   = unknownRecordTypes
+        self._unknownRecordTypes = unknownRecordTypes
         self._unknownFieldElements = unknownFieldElements
 
         self._cacheTag = cacheTag
         self._lastRefresh = now
 
-        self.index = index
-
         return etree
 
 
@@ -348,11 +333,11 @@
     def flush(self):
         BaseDirectoryService.flush(self)
 
-        self._realmName            = None
-        self._unknownRecordTypes   = None
+        self._realmName = None
+        self._unknownRecordTypes = None
         self._unknownFieldElements = None
-        self._cacheTag             = None
-        self._lastRefresh          = 0
+        self._cacheTag = None
+        self._lastRefresh = 0
 
 
     def updateRecords(self, records, create=False):
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140312/de109d87/attachment.html>


More information about the calendarserver-changes mailing list