-
-
Notifications
You must be signed in to change notification settings - Fork 152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Multiple Catalogs for Dexterity Contents #1489
Changes from all commits
3f81fe9
a3411cd
b7a3b9b
0eee80c
108646e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from Acquisition import aq_base | ||
from bika.lims import api | ||
from bika.lims import logger | ||
from bika.lims.config import USE_COLLECTIVE_INDEXING | ||
from bika.lims.interfaces import IMultiCatalogBehavior | ||
from zope.interface import implements | ||
|
||
if USE_COLLECTIVE_INDEXING: | ||
from collective.indexing.interfaces import IIndexQueueProcessor | ||
|
||
REQUIRED_CATALOGS = [ | ||
"auditlog_catalog", | ||
] | ||
|
||
|
||
class CatalogMultiplexProcessor(object): | ||
"""A catalog multiplex processor | ||
""" | ||
if USE_COLLECTIVE_INDEXING: | ||
implements(IIndexQueueProcessor) | ||
|
||
def get_catalogs_for(self, obj): | ||
catalogs = getattr(obj, "_catalogs", []) | ||
for rc in REQUIRED_CATALOGS: | ||
if rc in catalogs: | ||
continue | ||
catalogs.append(rc) | ||
return map(api.get_tool, catalogs) | ||
|
||
def supports_multi_catalogs(self, obj): | ||
"""Check if the Multi Catalog Behavior is enabled | ||
""" | ||
if IMultiCatalogBehavior(obj, None) is None: | ||
return False | ||
return True | ||
|
||
def index(self, obj, attributes=None): | ||
if attributes is None: | ||
attributes = [] | ||
|
||
if not self.supports_multi_catalogs(obj): | ||
return | ||
|
||
catalogs = self.get_catalogs_for(obj) | ||
url = api.get_path(obj) | ||
|
||
for catalog in catalogs: | ||
logger.info( | ||
"CatalogMultiplexProcessor::indexObject:catalog={} url={}" | ||
.format(catalog.id, url)) | ||
# We want the intersection of the catalogs idxs | ||
# and the incoming list. | ||
indexes = set(catalog.indexes()).intersection(attributes) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If attributes have been manually specified, but no matches with current catalog are found, the object will be reindexed for all indexes. I would rather skip this case for better performance: indexes = set(catalog.indexes()).intersection(attributes)
if attributes and not indexes:
continue
logger.info(
"CatalogMultiplexProcessor::indexObject:catalog={} url={}"
.format(catalog.id, url))
catalog.catalog_object(obj, url, idxs=list(indexes)) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agree, will change that |
||
# Skip reindexing if no indexes match | ||
if attributes and not indexes: | ||
continue | ||
# recatalog the object | ||
catalog.catalog_object(obj, url, idxs=list(indexes)) | ||
|
||
def reindex(self, obj, attributes=None): | ||
self.index(obj, attributes) | ||
|
||
def unindex(self, obj): | ||
wrapped_obj = obj | ||
if aq_base(obj).__class__.__name__ == "PathWrapper": | ||
# Could be a PathWrapper object from collective.indexing. | ||
obj = obj.context | ||
|
||
if not self.supports_multi_catalogs(obj): | ||
return | ||
|
||
catalogs = self.get_catalogs_for(obj) | ||
# get the old path from the wrapped object | ||
url = api.get_path(wrapped_obj) | ||
|
||
for catalog in catalogs: | ||
if catalog._catalog.uids.get(url, None) is not None: | ||
logger.info( | ||
"CatalogMultiplexProcessor::unindex:catalog={} url={}" | ||
.format(catalog.id, url)) | ||
catalog.uncatalog_object(url) | ||
|
||
def begin(self): | ||
pass | ||
|
||
def commit(self): | ||
pass | ||
|
||
def abort(self): | ||
pass |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<configure xmlns="http://namespaces.zope.org/zope" | ||
xmlns:zcml="http://namespaces.zope.org/zcml" | ||
i18n_domain="senaite.core"> | ||
|
||
<!-- Catalog Indexes --> | ||
<include package=".indexers" /> | ||
|
||
<!-- N.B. `IPortalCatalogQueueProcessor` will be included in | ||
`Products.CMFCore` in Plone 5 and can be removed then --> | ||
<include | ||
zcml:condition="installed collective.indexing" | ||
package="collective.indexing" /> | ||
|
||
<utility | ||
zcml:condition="installed collective.indexing" | ||
factory=".catalog_multiplex_processor.CatalogMultiplexProcessor" | ||
provides="collective.indexing.indexer.IPortalCatalogQueueProcessor" | ||
name="catalogmultiplex" | ||
/> | ||
|
||
</configure> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't the following be easier?:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the current approach is more readable and performant, because in your approach the list hast to be iterated multiple times to generate first a
set
and convert it then to alist
.But indeed, it would be interesting what approach is faster...
... 5 minutes later ...
Here comes the proof:
Output:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pheew!