Commit d9085bc3 authored by Andreas Jung's avatar Andreas Jung

Merging ajung-oneindex-multipleattributes-branch

This implements: http://lists.zope.org/pipermail/zope-coders/20002-November/002680.html
parent d9bd146e
......@@ -29,6 +29,9 @@ Zope Changes
enforce this behaviour inside the ZPublisher. See also
doc/ENVIRONMENT.txt to check with the DATETIME_FORMAT
- KeywordIndex and FieldIndex are now capable to index more
than one attribute of an object. This removes the ties between the
indexes ID and the attribute name to be indexed.
Bugs Fixed
......
......@@ -11,8 +11,7 @@
#
##############################################################################
"""$Id: DateIndex.py,v 1.9 2002/12/05 21:35:52 caseman Exp $
"""
"""$Id: DateIndex.py,v 1.10 2003/01/23 17:46:19 andreasjung Exp $ """
from DateTime.DateTime import DateTime
from Products.PluginIndexes import PluggableIndex
......
......@@ -12,8 +12,7 @@
##############################################################################
"""Simple column indices
$Id: FieldIndex.py,v 1.11 2002/12/05 21:35:52 caseman Exp $
$Id: FieldIndex.py,v 1.12 2003/01/23 17:46:21 andreasjung Exp $
"""
from Products.PluginIndexes import PluggableIndex
......@@ -44,7 +43,8 @@ class FieldIndex(UnIndex):
manage_addFieldIndexForm = DTMLFile('dtml/addFieldIndex', globals())
def manage_addFieldIndex(self, id, REQUEST=None, RESPONSE=None, URL3=None):
def manage_addFieldIndex(self, id, extra=None,
REQUEST=None, RESPONSE=None, URL3=None):
"""Add a field index"""
return self.manage_addIndex(id, 'FieldIndex', extra=None, \
return self.manage_addIndex(id, 'FieldIndex', extra=extra, \
REQUEST=REQUEST, RESPONSE=RESPONSE, URL1=URL3)
......@@ -25,6 +25,19 @@ of object values, such as 'meta_type'.
<input type="text" name="id" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Indexed attributes
</div>
</td>
<td align="left" valign="top">
<input type="text" name="extra.indexed_attrs:record:string" size="40" />
<em>attribute1,attribute2,...</em> or leave empty
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-optional">
......
......@@ -42,7 +42,7 @@ class KeywordIndex(UnIndex):
This should have an _apply_index that returns a relevance score
"""
def index_object(self, documentId, obj, threshold=None):
def _index_object(self, documentId, obj, threshold=None, attr=''):
""" index an object 'obj' with integer id 'i'
Ideally, we've been passed a sequence of some sort that we
......@@ -55,7 +55,7 @@ class KeywordIndex(UnIndex):
# attribute we're interested in. If the attribute is callable,
# we'll do so.
newKeywords = self._get_object_keywords(obj)
newKeywords = self._get_object_keywords(obj, attr)
oldKeywords = self._unindex.get(documentId, None)
......@@ -85,8 +85,8 @@ class KeywordIndex(UnIndex):
self.insertForwardIndexEntry(kw, documentId)
return 1
def _get_object_keywords(self,obj):
newKeywords = getattr(obj, self.id, ())
def _get_object_keywords(self, obj, attr):
newKeywords = getattr(obj, attr, ())
if callable(newKeywords):
newKeywords = newKeywords()
if hasattr(newKeywords,'capitalize'): # is it string-like ?
......@@ -119,7 +119,8 @@ class KeywordIndex(UnIndex):
manage_addKeywordIndexForm = DTMLFile('dtml/addKeywordIndex', globals())
def manage_addKeywordIndex(self, id, REQUEST=None, RESPONSE=None, URL3=None):
def manage_addKeywordIndex(self, id, extra=None,
REQUEST=None, RESPONSE=None, URL3=None):
"""Add a keyword index"""
return self.manage_addIndex(id, 'KeywordIndex', extra=None, \
return self.manage_addIndex(id, 'KeywordIndex', extra=extra, \
REQUEST=REQUEST, RESPONSE=RESPONSE, URL1=URL3)
......@@ -24,6 +24,19 @@ that have one or more keywords specified in a search query.
<input type="text" name="id" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Indexed attributes
</div>
</td>
<td align="left" valign="top">
<input type="text" name="extra.indexed_attrs:record:string" size="40" />
<em>attribute1,attribute2,...</em> or leave empty
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-optional">
......
......@@ -11,7 +11,7 @@
#
##############################################################################
__version__ = '$Id: PathIndex.py,v 1.30 2002/12/05 21:35:53 caseman Exp $'
__version__ = '$Id: PathIndex.py,v 1.31 2003/01/23 17:46:27 andreasjung Exp $'
from Products.PluginIndexes import PluggableIndex
from Products.PluginIndexes.common.util import parseIndexRequest
......@@ -341,6 +341,11 @@ class PathIndex(Persistent, Implicit, SimpleItem):
return self._index.keys()
def getIndexSourceNames(self):
""" return names of indexed attributes """
return ('getPhysicalPath', )
def getEntryForObject(self,documentId,default=_marker):
""" Takes a document ID and returns all the information we have
on that specific object. """
......
......@@ -14,7 +14,7 @@
"""Text Index
"""
__version__ = '$Revision: 1.34 $'[11:-2]
__version__ = '$Revision: 1.35 $'[11:-2]
import re
......@@ -644,6 +644,10 @@ class TextIndex(Persistent, Implicit, SimpleItem):
return query[0]
def getIndexSourceNames(self):
""" return name of indexed attributes """
return (self.id, )
def numObjects(self):
""" return number of index objects """
......
......@@ -11,7 +11,7 @@
#
##############################################################################
__version__ = '$Id: TopicIndex.py,v 1.11 2002/12/05 21:35:53 caseman Exp $'
__version__ = '$Id: TopicIndex.py,v 1.12 2003/01/23 17:46:31 andreasjung Exp $'
from Products.PluginIndexes import PluggableIndex
from Products.PluginIndexes.common.util import parseIndexRequest
......@@ -214,6 +214,10 @@ class TopicIndex(Persistent, Implicit, SimpleItem):
RESPONSE.redirect(URL1+'/manage_workspace?'
'manage_tabs_message=FilteredSet(s)%20updated')
def getIndexSourceNames(self):
""" return names of indexed attributes """
return ('n/a',)
def manage_clearFilteredSet(self, filterIds=[], URL1=None, \
REQUEST=None,RESPONSE=None):
......
......@@ -12,7 +12,7 @@
##############################################################################
"""Pluggable Index Interface"""
__version__='$Revision: 1.8 $'[11:-2]
__version__='$Revision: 1.9 $'[11:-2]
import Interface
......@@ -24,6 +24,11 @@ class PluggableIndexInterface(Interface.Base):
def getEntryForObject(documentId, default=None):
"""Get all information contained for 'documentId'."""
def getIndexSourceNames():
""" return a sequence of attribute names that are indexed
by the index.
"""
def index_object(documentId, obj, threshold=None):
"""Index an object.
......
......@@ -13,7 +13,7 @@
"""Simple column indices"""
__version__='$Revision: 1.16 $'[11:-2]
__version__='$Revision: 1.17 $'[11:-2]
from Globals import Persistent
from Acquisition import Implicit
......@@ -38,7 +38,7 @@ class UnIndex(Persistent, Implicit, SimpleItem):
"""UnIndex object interface"""
def __init__(self, id, ignore_ex=None, call_methods=None):
def __init__(self, id, ignore_ex=None, call_methods=None, extra=None, caller=None):
"""Create an unindex
UnIndexes are indexes that contain two index components, the
......@@ -69,16 +69,27 @@ class UnIndex(Persistent, Implicit, SimpleItem):
You will also need to pass in an object in the index and
uninded methods for this to work.
'extra' -- a record-style object that keeps additional
index-related parameters
'caller' -- reference to the calling object (usually
a (Z)Catalog instance
"""
self.id = id
self.ignore_ex=ignore_ex # currently unimplimented
self.call_methods=call_methods
# experimental code for specifing the operator
self.operators = ['or','and']
self.operators = ('or', 'and')
self.useOperator = 'or'
# allow index to index multiple attributes
try:
self.indexed_attrs = extra.indexed_attrs.split(',')
self.indexed_attrs = [ attr.strip() for attr in self.indexed_attrs if attr ]
except: self.indexed_attrs = [ self.id ]
self.__len__=BTrees.Length.Length() # see __len__ method docstring
self.clear()
......@@ -214,13 +225,28 @@ class UnIndex(Persistent, Implicit, SimpleItem):
indexRow=IITreeSet((indexRow, documentId))
self._index[entry] = indexRow
def index_object(self, documentId, obj, threshold=None):
""" wrapper to handle indexing of multiple attributes """
# needed for backward compatibility
try: fields = self.indexed_attrs
except: fields = [ self.id ]
res = 0
for attr in fields:
res += self._index_object(documentId, obj, threshold, attr)
return res > 0
def _index_object(self, documentId, obj, threshold=None, attr=''):
""" index and object 'obj' with integer id 'documentId'"""
global _marker
returnStatus = 0
# First we need to see if there's anything interesting to look at
datum = self._get_object_datum(obj)
datum = self._get_object_datum(obj, attr)
# We don't want to do anything that we don't have to here, so we'll
# check to see if the new and existing information is the same.
......@@ -244,12 +270,12 @@ class UnIndex(Persistent, Implicit, SimpleItem):
return returnStatus
def _get_object_datum(self,obj):
def _get_object_datum(self,obj, attr):
# self.id is the name of the index, which is also the name of the
# attribute we're interested in. If the attribute is callable,
# we'll do so.
try:
datum = getattr(obj, self.id)
datum = getattr(obj, attr)
if callable(datum):
datum = datum()
except AttributeError:
......@@ -389,6 +415,17 @@ class UnIndex(Persistent, Implicit, SimpleItem):
else:
return 0
def getIndexSourceNames(self):
""" return name of indexed attributes """
return (self.id, )
def getIndexSourceNames(self):
""" return sequence of indexed attributes """
try:
return self.indexed_attrs
except:
return [ self.id ]
def uniqueValues(self, name=None, withLengths=0):
"""\
......
......@@ -131,7 +131,12 @@ function toggleSelect() {
<td align="left" valign="top">
<div class="list-item">
<a href="Indexes/&dtml.url_quote-sequence-key;/manage_workspace">
&dtml-sequence-key; <dtml-if title>(&dtml-title;)</dtml-if>
&dtml-sequence-key;
<dtml-try>
(indexed attrs: <dtml-var "', '.join(_['sequence-item'].getIndexSourceNames())">)
<dtml-except>
<dtml-if title> (&dtml-title;) </dtml-if>
</dtml-try>
</a>
</div>
......@@ -141,7 +146,7 @@ function toggleSelect() {
<td>
<div class="list-item">
<dtml-if "_.string.find(_.str(_.getattr(this(),'__implements__','old')),'PluggableIndexInterface')>-1">
<dtml-if "_.string.find(_.str(_.getattr(this(),'__implements__','old')),'PluggableIndex')>-1">
&dtml-meta_type;
<dtml-else>
<dtml-call "REQUEST.set('oldidx',1)">
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment