Skip to content

Commit

Permalink
Merge pull request #522 from pretaweb/pretaweb-display-field-index
Browse files Browse the repository at this point in the history
Index computed display fields
  • Loading branch information
ebrehault committed Jan 29, 2014
2 parents 460929b + 35e8c03 commit 366ce3e
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 10 deletions.
3 changes: 2 additions & 1 deletion Products/CMFPlomino/PlominoDesignManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ def refreshDB(self):
index.createFieldIndex(
f.id,
f.getFieldType(),
indextype=f.getIndexType())
indextype=f.getIndexType(),
fieldmode=f.getFieldMode())
logger.info('Field indexing initialized')

#declare all the view formulas and columns index entries
Expand Down
56 changes: 52 additions & 4 deletions Products/CMFPlomino/PlominoDocument.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
except ImportError:
from zope.app.container.contained import Contained
from zope.component.factory import Factory
from zope.component import queryUtility
from zope.component import queryUtility, adapts
from zope.interface import implements
from ZPublisher.HTTPRequest import FileUpload
import transaction
Expand Down Expand Up @@ -65,7 +65,12 @@
from PlominoUtils import sendMail
from Products.CMFPlomino.browser import PlominoMessageFactory as _
from Products.CMFPlomino.config import *
from index.PlominoIndex import DISPLAY_INDEXED_ATTR_PREFIX
from Products.ZCatalog.interfaces import IZCatalog
from plone.indexer.wrapper import IndexableObjectWrapper
from plone.indexer.interfaces import IIndexer
import interfaces
from zope.component import adapts, queryMultiAdapter

import logging
_logger = logging.getLogger('Plomino')
Expand All @@ -77,6 +82,7 @@
URL_NORMALIZER = True
except ImportError:
URL_NORMALIZER = False
from plone.indexer.interfaces import IIndexableObjectWrapper, IIndexableObject


class PlominoDocument(CatalogAware, CMFBTreeFolder, Contained):
Expand Down Expand Up @@ -626,19 +632,27 @@ def getForm(self):
- and finally fall back to document `Form` item.
"""
formname = None
# if called from __getattr__ we're not wrapped and we have don't have real
# request
if hasattr(self, 'REQUEST'):
formname = self.REQUEST.get("openwithform", None)
request = self.REQUEST
if type(request == type("")):
request = None
else:
request = None
if request is not None:
formname = request.get("openwithform", None)
if not formname:
if hasattr(self, 'evaluateViewForm'):
formname = self.evaluateViewForm(self)
if not formname:
formname = self.getItem('Form')
form = self.getParentDatabase().getForm(formname)
if not form:
if hasattr(self, "REQUEST") and formname:
if request is not None and formname:
self.writeMessageOnPage(
"Form %s does not exist." % formname,
self.REQUEST,
request,
True)
return form

Expand Down Expand Up @@ -1071,3 +1085,37 @@ def id(self):
"""
"""
return self.real_id


class PlominoIndexableObjectWrapper(IndexableObjectWrapper):
"""Our special adapter so we can index displayfields specially
"""

implements(IIndexableObject, IIndexableObjectWrapper)
adapts(interfaces.IPlominoDocument, IZCatalog)

def __init__(self, object, catalog):
self.__object = object
self.__catalog = catalog
self.__vars = {}

def __getattr__(self, name):
# First, try to look up an indexer adapter
indexer = queryMultiAdapter((self.__object, self.__catalog,), IIndexer, name=name)
if indexer is not None:
return indexer()

# Then, try displayfields
# we can't calc a displayfield in a ZODB __getattr__ since self is not
# aquisition wrapped in __getattr__.
if name.startswith(DISPLAY_INDEXED_ATTR_PREFIX):
field_name = name[len(DISPLAY_INDEXED_ATTR_PREFIX):]
value = self.__object.computeItem(field_name, store=False)
return value

# Finally see if the object provides the attribute directly. This
# is allowed to raise AttributeError.
return getattr(self.__object, name)


4 changes: 2 additions & 2 deletions Products/CMFPlomino/PlominoField.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ def at_post_edit_script(self):
self.cleanFormulaScripts(self.id)
db = self.getParentDatabase()
if self.getToBeIndexed() and not db.DoNotReindex:
db.getIndex().createFieldIndex(self.id, self.getFieldType(), indextype=self.getIndexType())
db.getIndex().createFieldIndex(self.id, self.getFieldType(), indextype=self.getIndexType(), fieldmode=self.getFieldMode())

security.declarePublic('at_post_create_script')
def at_post_create_script(self):
Expand All @@ -327,7 +327,7 @@ def at_post_create_script(self):
self._setupConfigAnnotation()
db = self.getParentDatabase()
if self.getToBeIndexed() and not db.DoNotReindex:
db.getIndex().createFieldIndex(self.id, self.getFieldType(), indextype=self.getIndexType())
db.getIndex().createFieldIndex(self.id, self.getFieldType(), indextype=self.getIndexType(), fieldmode=self.getFieldMode())

security.declarePublic('getSettings')
def getSettings(self, key=None):
Expand Down
3 changes: 2 additions & 1 deletion Products/CMFPlomino/PlominoView.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,8 @@ def declareColumn(self, column_name, column_obj, index=None):
field.id,
field.getFieldType(),
refresh=refresh,
indextype=field.getIndexType())
indextype=field.getIndexType(),
fieldmode=field.getFieldMode())
else:
column_obj.setFormula("'Non-existing field'")
index.createIndex(
Expand Down
5 changes: 5 additions & 0 deletions Products/CMFPlomino/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,10 @@
handler="Products.CMFPlomino.events.PlominoDocumentRemoveEventHandler"
/>

<adapter
factory=".PlominoDocument.PlominoIndexableObjectWrapper"
provides="plone.indexer.interfaces.IIndexableObject"
/>


</configure>
10 changes: 8 additions & 2 deletions Products/CMFPlomino/index/PlominoIndex.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
from Products.CMFPlomino.index.PlominoViewIndex import PlominoViewIndex
from Products.CMFPlomino.PlominoField import get_field_types

DISPLAY_INDEXED_ATTR_PREFIX = 'PlominoDisplay_'

class PlominoIndex(UniqueObject, CatalogTool):
""" Plomino index
Expand Down Expand Up @@ -89,7 +90,7 @@ def createIndex(self, fieldname, refresh=True):

security.declareProtected(DESIGN_PERMISSION, 'createFieldIndex')
def createFieldIndex(self, fieldname, fieldtype, refresh=True,
indextype='DEFAULT'):
indextype='DEFAULT', fieldmode=None):
"""
"""
if indextype == 'DEFAULT':
Expand All @@ -112,7 +113,12 @@ def createFieldIndex(self, fieldname, fieldtype, refresh=True,
)
else:
if not fieldname in self.indexes():
self.addIndex(fieldname, indextype)
if fieldmode == 'DISPLAY':
display_extra = SimpleRecord(
indexed_attrs='%s%s' % (DISPLAY_INDEXED_ATTR_PREFIX, fieldname))
self.addIndex(fieldname, indextype, extra=display_extra)
else:
self.addIndex(fieldname, indextype)

if not self._catalog.schema.has_key(fieldname):
self.addColumn(fieldname)
Expand Down
38 changes: 38 additions & 0 deletions Products/CMFPlomino/tests/test_displayfieldindex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import unittest
from AccessControl.unauthorized import Unauthorized
from DateTime import DateTime
import Missing
from decimal import Decimal
from Products.CMFPlomino.testing import PLOMINO_FUNCTIONAL_TESTING
from Products.CMFPlomino.config import TIMEZONE
import Products.CMFPlomino.PlominoUtils as utils


class DisplayFieldIndexTest(unittest.TestCase):

layer = PLOMINO_FUNCTIONAL_TESTING

def setUp(self):
self.portal = self.layer['portal']
self.db = self.portal.mydb
self.db.invokeFactory('PlominoForm', id='frm1', title='Form 1')
self.frm1 = self.db.frm1
self.frm1.invokeFactory('PlominoField', id='a_field',
Title='Display Field',
FieldType="TEXT",
FieldMode="DISPLAY",
ToBeIndexed="True",
Formula="return 'spam'")
self.field_obj = self.frm1.a_field
self.field_obj.at_post_create_script()

def test_indexed_attrs(self):
doc1 = self.db.createDocument()
doc1.setItem('Form', 'frm1')
doc1.save()
doc_id = doc1.id
res = self.db.getIndex().dbsearch({'a_field': 'notspam'})
self.assertEquals(len(res), 0)
res = self.db.getIndex().dbsearch({'a_field': 'spam'})
self.assertEquals(len(res), 1)
#import pdb; pdb.set_trace()
5 changes: 5 additions & 0 deletions docs/HISTORY.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Changelog
=========

1.18.6 (unreleased)
-------------------
* Allow indexing of computed display fields
[djay, ivant]

1.18.5 (2013-12-04)
-------------------
* Working on BaseField.getFieldValue, handling of field defaults
Expand Down

0 comments on commit 366ce3e

Please sign in to comment.