[Zope-Checkins] CVS: Zope2 - UnIndex.py:1.23.2.7.2.1

chrism@serenade.digicool.com chrism@serenade.digicool.com
Thu, 12 Apr 2001 18:44:41 -0400


Update of /cvs-repository/Zope2/lib/python/SearchIndex
In directory serenade.digicool.com:/home/chrism/sandboxes/CatalogForNow/lib/python/SearchIndex

Modified Files:
      Tag: chrism-CatalogForNow-branch
	UnIndex.py 
Log Message:
*Slightly*, and ever-so-carefully changed behavior of FieldIndexes' _apply_index method.  The old behavior was not sane.

Now the behavior is:

  - if the value in the request is a bare blank string, return None

  - if the value in the request is a nonblank string, turn it into a
    single-valued sequence and perform a search.

  - if the value in the request is a sequence, perform a union search.

To search for empty strings as values, use {'indexname':('',)} in the query.


--- Updated File UnIndex.py in package Zope2 --
--- UnIndex.py	2001/03/30 20:12:51	1.23.2.7
+++ UnIndex.py	2001/04/12 22:44:41	1.23.2.7.2.1
@@ -329,28 +329,45 @@
                 ' with id %s' % documentId)
 
     def _apply_index(self, request, cid='', type=type, None=None): 
-        """Apply the index to query parameters given in the argument,
-        request
+        """Apply the index to query parameters given in the request arg.
 
-        The argument should be a mapping object.
+        The request argument should be a mapping object.
 
-        If the request does not contain the needed parameters, then
-        None is returned.
+        If the request does not have a key which matches the "id" of
+        the index instance, then None is returned.
 
+        If the request *does* have a key which matches the "id" of
+        the index instance, one of a few things can happen:
+
+          - if the value is a blank string, None is returned (in
+            order to support requests from web forms where
+            you can't tell a blank string from empty).
+
+          - if the value is a nonblank string, turn the value into
+            a single-element sequence, and proceed.
+
+          - if the value is a sequence, return a union search.
+
         If the request contains a parameter with the name of the
         column + '_usage', it is sniffed for information on how to
         handle applying the index.
 
-        Otherwise two objects are returned.  The first object is a
+        If None is not returned as a result of the abovementioned
+        constraints, two objects are returned.  The first object is a
         ResultSet containing the record numbers of the matching
         records.  The second object is a tuple containing the names of
         all data fields used.
 
+        FAQ answer:  to search a Field Index for documents that
+        have a blank string as their value, wrap the request value
+        up in a tuple ala: request = {'id':('',)}
+
         """
         id = self.id              #name of the column
 
         cidid = "%s/%s" % (cid,id)
 
+        # i have no f'ing clue what this cdid stuff is for - chrism
         if request.has_key(cidid):
             keys = request[cidid]
         elif request.has_key(id):
@@ -359,60 +376,43 @@
             return None
 
         if type(keys) not in (ListType, TupleType):
-            keys = [keys]
+            if keys == '':
+                return None
+            else:
+                keys = [keys]
 
         index = self._index
         r = None
-        anyTrue = 0
         opr = None
-        IntType=type(1)
 
         if request.has_key(id+'_usage'):
             # see if any usage params are sent to field
             opr=string.split(string.lower(request[id+"_usage"]),':')
             opr, opr_args=opr[0], opr[1:]
 
-        if opr=="range":
+        if opr=="range":   # range search
             if 'min' in opr_args: lo = min(keys)
             else: lo = None
             if 'max' in opr_args: hi = max(keys)
             else: hi = None
-
-            anyTrue=1
-            try:
-                if hi:
-                    setlist = index.items(lo,hi)
-                else:
-                    setlist = index.items(lo)
-
-                for k, set in setlist:
-                    r = union(r, set)
-
-            except KeyError:
-                pass
+            if hi:
+                setlist = index.items(lo,hi)
+            else:
+                setlist = index.items(lo)
 
-        else:           #not a range
-            get = index.get
+            for k, set in setlist:
+                r = union(r, set)
+        else: # not a range search
             for key in keys:
-                if nonEmpty(key):
-                    anyTrue = 1
-                set=get(key, None)
+                set=index.get(key, None)
                 if set is not None:
                     r = union(r, set)
-
-        if type(r) is IntType: r=IISet((r,))
-        if r:
-            return r, (id,)
 
-                
+        if type(r) is type(1):  r=IISet((r,))
         if r is None:
-            if anyTrue:
-                r=IISet()
-            else:
-                return None
-
-        return r, (id,)
-
+            return IISet(), (id,)
+        else:
+            return r, (id,)
 
     def hasUniqueValuesFor(self, name):
         ' has unique values for column NAME '
@@ -434,14 +434,18 @@
         elif name != self.id:
             return []
 
-        if not withLengths: return tuple(
-            filter(nonEmpty, self._index.keys())
-            )
+        if not withLengths:
+            return tuple(self._index.keys())
         else: 
             rl=[]
             for i in self._index.keys():
-                if not nonEmpty(i): continue
-                else: rl.append((i, len(self._index[i])))
+                set = self._index[i]
+                if type(set) is type(1):
+                    # bleah
+                    l = 1
+                else:
+                    l = len(set)
+                rl.append((i, l))
             return tuple(rl)
 
     def keyForDocument(self, id):