Commit d91b6c02 authored by Vincent Pelletier's avatar Vincent Pelletier

Only compute indexation ZSQLMethod parameter values when accessed.

Several ZSQLMethods do tests on parameter values, causing other parameter
values to be discarded (ie not indexed). A pseudo-code example is
  if isMovement[x]:
    append(getPrice[x])
parent ae2f9a0b
...@@ -22,6 +22,7 @@ from App.special_dtml import DTMLFile ...@@ -22,6 +22,7 @@ from App.special_dtml import DTMLFile
from thread import allocate_lock, get_ident from thread import allocate_lock, get_ident
from OFS.Folder import Folder from OFS.Folder import Folder
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from AccessControl.SimpleObjectPolicies import ContainerAssertions
from BTrees.OIBTree import OIBTree from BTrees.OIBTree import OIBTree
from App.config import getConfiguration from App.config import getConfiguration
from BTrees.Length import Length from BTrees.Length import Length
...@@ -244,6 +245,50 @@ class DummyDict(dict): ...@@ -244,6 +245,50 @@ class DummyDict(dict):
def __setitem__(self, key, value): def __setitem__(self, key, value):
pass pass
class LazyIndexationParameterList(tuple):
def __new__(cls, document_list, attribute, global_cache):
self = super(LazyIndexationParameterList, cls).__new__(cls)
self._document_list = document_list
self._attribute = attribute
self._global_cache = global_cache
return self
def __getitem__(self, index):
document = self._document_list[index]
attribute = self._attribute
global_cache_key = (document.uid, attribute)
global_cache = self._global_cache
if global_cache_key in global_cache:
value = global_cache[global_cache_key]
else:
value = getattr(document, attribute, None)
if callable(value):
try:
value = value()
except ConflictError:
raise
except Exception:
LOG('SQLCatalog', WARNING,
'Failed to call method %s on %r' % (attribute, document),
error=True,
)
value = None
global_cache[global_cache_key] = value
return value
def __iter__(self):
for index in xrange(len(self)):
yield self[index]
def __len__(self):
return len(self._document_list)
def __repr__(self):
return '<%s(%i documents, %r) at %x>' % (self.__class__.__name__,
len(self), self._attribute, id(self))
ContainerAssertions[LazyIndexationParameterList] = 1
related_key_definition_cache = {} related_key_definition_cache = {}
related_key_warned_column_set = set() related_key_warned_column_set = set()
...@@ -1634,28 +1679,12 @@ class Catalog(Folder, ...@@ -1634,28 +1679,12 @@ class Catalog(Folder,
method.func_code.co_varnames[:method.func_code.co_argcount] method.func_code.co_varnames[:method.func_code.co_argcount]
else: else:
arguments = [] arguments = []
kw = {} kw = dict(
for arg in arguments: (x, LazyIndexationParameterList(
value_list = [] catalogged_object_list,
append = value_list.append x,
for object in catalogged_object_list: argument_cache,
argument_cache_key = (object.uid, arg) )) for x in arguments)
try:
value = argument_cache[argument_cache_key]
except KeyError:
try:
value = getattr(object, arg, None)
if callable(value):
value = value()
except ConflictError:
raise
except:
LOG('SQLCatalog', WARNING, 'Failed to call method %s on %r' %
(arg, object), error=sys.exc_info())
value = None
argument_cache[argument_cache_key] = value
append(value)
kw[arg] = value_list
# Alter/Create row # Alter/Create row
try: try:
......
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