[Checkins] SVN: zc.catalog/trunk/src/zc/catalog/ Added CallableWrapper, which allows using a function to extract the indexable

Albertas Agejevas alga at pov.lt
Fri Apr 20 17:18:57 EDT 2007


Log message for revision 74273:
  Added CallableWrapper, which allows using a function to extract the indexable
  value from the document, instead of a special adapter with AttributeIndex.
  

Changed:
  A   zc.catalog/trunk/src/zc/catalog/callablewrapper.txt
  U   zc.catalog/trunk/src/zc/catalog/catalogindex.py
  U   zc.catalog/trunk/src/zc/catalog/index.py
  U   zc.catalog/trunk/src/zc/catalog/interfaces.py
  U   zc.catalog/trunk/src/zc/catalog/tests.py

-=-
Added: zc.catalog/trunk/src/zc/catalog/callablewrapper.txt
===================================================================
--- zc.catalog/trunk/src/zc/catalog/callablewrapper.txt	2007-04-20 18:04:26 UTC (rev 74272)
+++ zc.catalog/trunk/src/zc/catalog/callablewrapper.txt	2007-04-20 21:18:57 UTC (rev 74273)
@@ -0,0 +1,46 @@
+CallableWrapper
+===============
+
+If we want to index some value that is easily derivable from a
+document, we have to define an interface with this value as an
+attribute, and create an adapter that calculates this value and
+implements this interface.  All this is too much hassle if the want to
+store a single easily derivable value.   CallableWrapper solves this
+problem, by converting the document to the indexed value with a
+callable converter.
+
+Here's a contrived example.  Suppose we have cars that know their
+mileage expressed in miles per gallon, but we want to index their
+economy in litres per 100 km.
+
+    >>> class Car(object):
+    ...     def __init__(self, mpg):
+    ...         self.mpg = mpg
+
+    >>> def mpg2lp100(car):
+    ...     return 100.0/(1.609344/3.7854118 * car.mpg)
+
+Let's create an index that would index cars' l/100 km rating.
+
+    >>> from zc.catalog import index, catalogindex
+    >>> idx = catalogindex.CallableWrapper(index.ValueIndex(), mpg2lp100)
+
+Let's add a couple of cars to the index!
+
+    >>> hummer = Car(10.0)
+    >>> beamer = Car(22.0)
+    >>> civic = Car(45.0)
+
+    >>> idx.index_doc(1, hummer)
+    >>> idx.index_doc(2, beamer)
+    >>> idx.index_doc(3, civic)
+
+The indexed values should be the converted l/100 km ratings:
+
+    >>> list(idx.values())
+    [5.2269907628339389, 10.691572014887601, 23.521458432752723]
+
+We can query for cars that consume fuel in some range:
+
+    >>> list(idx.apply({'between': (5.0, 7.0)}))
+    [3]


Property changes on: zc.catalog/trunk/src/zc/catalog/callablewrapper.txt
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Modified: zc.catalog/trunk/src/zc/catalog/catalogindex.py
===================================================================
--- zc.catalog/trunk/src/zc/catalog/catalogindex.py	2007-04-20 18:04:26 UTC (rev 74272)
+++ zc.catalog/trunk/src/zc/catalog/catalogindex.py	2007-04-20 21:18:57 UTC (rev 74273)
@@ -42,6 +42,12 @@
 
     pass
 
+
+class CallableWrapper(zc.catalog.index.CallableWrapper,
+                      zope.app.container.contained.Contained):
+    pass
+
+
 @zope.interface.implementer(
     zope.interface.implementedBy(NormalizationWrapper),
     zc.catalog.interfaces.IValueIndex)

Modified: zc.catalog/trunk/src/zc/catalog/index.py
===================================================================
--- zc.catalog/trunk/src/zc/catalog/index.py	2007-04-20 18:04:26 UTC (rev 74272)
+++ zc.catalog/trunk/src/zc/catalog/index.py	2007-04-20 21:18:57 UTC (rev 74273)
@@ -28,7 +28,6 @@
 import zope.index.interfaces
 import zope.security.management
 from zope.publisher.interfaces import IRequest
-
 import zc.catalog.interfaces
 from zc.catalog.i18n import _
 
@@ -371,6 +370,26 @@
     def ids(self):
         return self.index.ids()
 
+
+class CallableWrapper(persistent.Persistent):
+
+    interface.implements(zc.catalog.interfaces.ICallableWrapper)
+
+    converter = None
+    index = None
+
+    def __init__(self, index, converter):
+        self.index = index
+        self.converter = converter
+
+    def index_doc(self, docid, value):
+        "See zope.index.interfaces.IInjection"
+        self.index.index_doc(docid, self.converter(value))
+
+    def __getattr__(self, name):
+        return getattr(self.index, name)
+
+
 def set_resolution(value, resolution):
     resolution += 2
     if resolution < 6:
@@ -414,6 +433,7 @@
     return datetime.datetime.combine(
         value, datetime.time(tzinfo=get_tz()))
 
+
 class DateTimeNormalizer(persistent.Persistent):
 
     interface.implements(zc.catalog.interfaces.IDateTimeNormalizer)

Modified: zc.catalog/trunk/src/zc/catalog/interfaces.py
===================================================================
--- zc.catalog/trunk/src/zc/catalog/interfaces.py	2007-04-20 18:04:26 UTC (rev 74272)
+++ zc.catalog/trunk/src/zc/catalog/interfaces.py	2007-04-20 21:18:57 UTC (rev 74273)
@@ -307,3 +307,16 @@
         title=_('Resolution'),
         default=2,
         required=True)
+
+
+class ICallableWrapper(zope.index.interfaces.IInjection,
+                       zope.index.interfaces.IIndexSearch,
+                       zope.index.interfaces.IStatistics,
+                       IIndexValues):
+    """A wrapper for an index that uses a callable to convert injection."""
+
+    index = interface.Attribute(
+        """An index implementing IInjection, IIndexSearch, IStatistics, and
+        IIndexValues""")
+
+    converter = interface.Attribute("A callable converter")

Modified: zc.catalog/trunk/src/zc/catalog/tests.py
===================================================================
--- zc.catalog/trunk/src/zc/catalog/tests.py	2007-04-20 18:04:26 UTC (rev 74272)
+++ zc.catalog/trunk/src/zc/catalog/tests.py	2007-04-20 21:18:57 UTC (rev 74273)
@@ -73,6 +73,7 @@
         doctest.DocFileSuite('valueindex.txt'),
         doctest.DocFileSuite('normalizedindex.txt'),
         doctest.DocFileSuite('globber.txt'),
+        doctest.DocFileSuite('callablewrapper.txt'),
 
         # 64 bits
         doctest.DocFileSuite(
@@ -86,6 +87,8 @@
                              tearDown=tearDown64bit),
         doctest.DocFileSuite('globber.txt', setUp=setUp64bit,
                              tearDown=tearDown64bit),
+        doctest.DocFileSuite('callablewrapper.txt', setUp=setUp64bit,
+                             tearDown=tearDown64bit),
         ))
     import zc.catalog.stemmer
     if not zc.catalog.stemmer.broken:



More information about the Checkins mailing list