[Zope-Checkins] SVN: Zope/branches/andig-compositeindex/src/Products/ transpose query integration into the catalog
Andreas Gabriel
gabriel at hrz.uni-marburg.de
Wed Sep 29 17:23:02 EDT 2010
Log message for revision 117072:
transpose query integration into the catalog
Changed:
U Zope/branches/andig-compositeindex/src/Products/PluginIndexes/CompositeIndex/CompositeIndex.py
U Zope/branches/andig-compositeindex/src/Products/PluginIndexes/interfaces.py
U Zope/branches/andig-compositeindex/src/Products/ZCatalog/Catalog.py
-=-
Modified: Zope/branches/andig-compositeindex/src/Products/PluginIndexes/CompositeIndex/CompositeIndex.py
===================================================================
--- Zope/branches/andig-compositeindex/src/Products/PluginIndexes/CompositeIndex/CompositeIndex.py 2010-09-29 18:56:43 UTC (rev 117071)
+++ Zope/branches/andig-compositeindex/src/Products/PluginIndexes/CompositeIndex/CompositeIndex.py 2010-09-29 21:23:01 UTC (rev 117072)
@@ -25,27 +25,31 @@
from BTrees.IOBTree import IOBTree
import BTrees.Length
+from zope.interface import implements
+
from ZODB.POSException import ConflictError
+from Products.PluginIndexes.interfaces import ITransposeQuery
from Products.PluginIndexes.interfaces import IUniqueValueIndex
from Products.PluginIndexes.KeywordIndex.KeywordIndex import KeywordIndex
from Products.PluginIndexes.common.util import parseIndexRequest
from util import PermuteKeywordList
-from config import PROJECTNAME
+
_marker = []
-logger = logging.getLogger(PROJECTNAME)
+logger = logging.getLogger('CompositeIndex')
class CompositeIndex(KeywordIndex):
"""Index for composition of simple fields.
or sequences of items
"""
+
+ implements(ITransposeQuery)
-
meta_type="CompositeIndex"
manage_options= (
@@ -455,98 +459,80 @@
kw = self._tindex.get(k,k)
items.append((kw, v))
return items
-
- manage = manage_main = DTMLFile('dtml/manageCompositeIndex', globals())
- manage_main._setName('manage_main')
- manage_browse = DTMLFile('dtml/browseIndex', globals())
+ def make_query(self, query):
+ """ optimize the query """
+
+ cquery = query.copy()
-manage_addCompositeIndexForm = DTMLFile('dtml/addCompositeIndex', globals())
+ catalog = aq_parent(self)
-def manage_addCompositeIndex(self, id, extra=None,
- REQUEST=None, RESPONSE=None, URL3=None):
- """Add a composite index"""
- return self.manage_addIndex(id, 'CompositeIndex', extra=extra, \
- REQUEST=REQUEST, RESPONSE=RESPONSE, URL1=URL3)
-
-
-
-class compositeSearchArgumentsMap:
- """ parse a request from the ZPublisher to optimize the query by means
- of CompositeIndexes
- """
-
- keywords = {}
-
- def __init__(self, catalog, request):
- """ indexes -- dict of index objects
- request -- the request dictionary send from the ZPublisher
- """
-
indexes = catalog.indexes
parent = aq_parent(catalog)
- if parent.hasProperty('unimr.compositeindex') and not parent.getProperty('unimr.compositeindex',True):
- logger.warn('skip compositeSearchArgumentsMap')
+ if parent.hasProperty('compositeindex') and not parent.getProperty('compositeindex',True):
+ logger.warn('skip make_query')
return
- cRank=[]
- for index in indexes.values():
- if isinstance(index,CompositeIndex):
-
- cId = index.id
- logger.debug('CompositeIndex "%s" found' % cId)
- # get indexes managed by CompositeIndex
- cIdxs = index.getComponentIndexNames()
- cRank.append((cId,cIdxs))
-
- # sort from specific to unspecific CompositeIndex
- cRank.sort(lambda x,y: cmp((len(y[1]),y[1]),(len(x[1]),x[1])))
+ cIdxs = self.getComponentIndexNames()
- for cId, cIdxs in cRank:
- records=[]
- for i in cIdxs:
- index = indexes.get(i,None)
- abort = False
+ records=[]
+ for i in cIdxs:
+ index = indexes.get(i,None)
+ abort = False
- if index:
- rec = parseIndexRequest(request, index.id, index.query_options)
+ if index:
+ rec = parseIndexRequest(query, index.id, index.query_options)
- if not IUniqueValueIndex.providedBy(index):
- logger.warn('index %s: not an instance of IUniqueValueIndex' % index.id)
- abort = True
+ if not IUniqueValueIndex.providedBy(index):
+ logger.warn('index %s: not an instance of IUniqueValueIndex' % index.id)
+ abort = True
- if abort or rec.keys is None:
- continue
+ if abort or rec.keys is None:
+ continue
- records.append((i, rec))
+ records.append((i, rec))
- # transform request only if more than one component of the composite key is applied
- if len(records) > 1:
+ # transform request only if more than one component
+ # of the composite key is applied
+ if len(records) > 1:
- query = { cId: { 'query': records } }
+ cquery.update( { cId: { 'query': records }} )
- logger.debug('composite query build "%s"' % query)
+
+ # delete obsolete query attributes from request
+ for i in cIdxs[:len(records)+1]:
+ if cquery.has_key(i):
+ del cquery[i]
+ logger.debug('composite query build "%s"' % cquery)
+ return cquery
+
+ else:
+ logger.debug('only one component was affected, skip composite query build')
+
- # delete obsolete query attributes from request
- for i in cIdxs[:len(records)+1]:
-
- if isinstance(request, dict):
- if request.has_key(i):
- del request[i]
- else:
- if request.keywords.has_key(i):
- del request.keywords[i]
- if isinstance(request.request, dict) and \
- request.request.has_key(i):
-
- del request.request[i]
+ return query
+
- request.keywords.update(query)
-
+ manage = manage_main = DTMLFile('dtml/manageCompositeIndex', globals())
+ manage_main._setName('manage_main')
+ manage_browse = DTMLFile('dtml/browseIndex', globals())
+manage_addCompositeIndexForm = DTMLFile('dtml/addCompositeIndex', globals())
+
+def manage_addCompositeIndex(self, id, extra=None,
+ REQUEST=None, RESPONSE=None, URL3=None):
+ """Add a composite index"""
+ return self.manage_addIndex(id, 'CompositeIndex', extra=extra, \
+ REQUEST=REQUEST, RESPONSE=RESPONSE, URL1=URL3)
+
+
+
+
+
+
Modified: Zope/branches/andig-compositeindex/src/Products/PluginIndexes/interfaces.py
===================================================================
--- Zope/branches/andig-compositeindex/src/Products/PluginIndexes/interfaces.py 2010-09-29 18:56:43 UTC (rev 117071)
+++ Zope/branches/andig-compositeindex/src/Products/PluginIndexes/interfaces.py 2010-09-29 21:23:01 UTC (rev 117072)
@@ -236,3 +236,13 @@
E.g. {'indexed_attrs' : ('SearchableText', )}.
The interface does not define any specifc mapping keys.
"""
+
+
+#
+#
+#
+
+class ITransposeQuery(Interface):
+
+ def make_query(query):
+ """ returns optimized query for given index """
Modified: Zope/branches/andig-compositeindex/src/Products/ZCatalog/Catalog.py
===================================================================
--- Zope/branches/andig-compositeindex/src/Products/ZCatalog/Catalog.py 2010-09-29 18:56:43 UTC (rev 117071)
+++ Zope/branches/andig-compositeindex/src/Products/ZCatalog/Catalog.py 2010-09-29 21:23:01 UTC (rev 117072)
@@ -24,6 +24,7 @@
from Missing import MV
from Persistence import Persistent
from Products.PluginIndexes.interfaces import ILimitedResultIndex
+from Products.PluginIndexes.interfaces import ITransposeQuery
import BTrees.Length
from BTrees.IIBTree import intersection, weightedIntersection, IISet
@@ -438,6 +439,7 @@
def make_query(self, request):
# This is a bit of a mess, but the ZCatalog API has traditionally
# supported passing in query restrictions in almost arbitary ways
+
real_req = None
if isinstance(request, dict):
query = request.copy()
@@ -471,6 +473,13 @@
value = real_req.get(iid)
if value:
query[iid] = value
+
+ indexes = self.indexes.keys()
+ for i in indexes:
+ index = self.getIndex(i)
+ if ITransposeQuery.providedBy(index):
+ query = index.make_query(query)
+
return query
def _sorted_search_indexes(self, query):
More information about the Zope-Checkins
mailing list