caches recursive selects for references
Why didn't we think before ? References are lazy, but when asked for representation why should we fetch the same referenced record over and over ? NB: the code caches only represent() fetching records from tables, that are the only idempotent represent() calls out there. We could cache every representation only asking for every represent() call to be idempotent. As I feel there will be someone returning random values, I left it out. I'll make a PR soon for pyDAL to fix the same behaviour.
This commit is contained in:
@@ -2626,6 +2626,7 @@ class SQLFORM(FORM):
|
||||
htmltable = TABLE(COLGROUP(*cols), THEAD(head))
|
||||
tbody = TBODY()
|
||||
numrec = 0
|
||||
repr_cache = {}
|
||||
for row in rows:
|
||||
trcols = []
|
||||
id = row[field_id]
|
||||
@@ -2641,14 +2642,31 @@ class SQLFORM(FORM):
|
||||
value = row[str(field)]
|
||||
maxlength = maxtextlengths.get(str(field), maxtextlength)
|
||||
if field.represent:
|
||||
try:
|
||||
value = field.represent(value, row)
|
||||
except KeyError:
|
||||
if field.type.startswith('reference'):
|
||||
if field not in repr_cache:
|
||||
repr_cache[field] = {}
|
||||
try:
|
||||
value = field.represent(
|
||||
value, row[field.tablename])
|
||||
nvalue = repr_cache[field][value]
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
nvalue = field.represent(value, row)
|
||||
except KeyError:
|
||||
try:
|
||||
nvalue = field.represent(
|
||||
value, row[field.tablename])
|
||||
except KeyError:
|
||||
nvalue = None
|
||||
repr_cache[field][value] = nvalue
|
||||
else:
|
||||
try:
|
||||
nvalue = field.represent(value, row)
|
||||
except KeyError:
|
||||
try:
|
||||
nvalue = field.represent(
|
||||
value, row[field.tablename])
|
||||
except KeyError:
|
||||
nvalue = None
|
||||
value = nvalue
|
||||
elif field.type == 'boolean':
|
||||
value = INPUT(_type="checkbox", _checked=value,
|
||||
_disabled=True)
|
||||
@@ -3118,6 +3136,7 @@ class SQLTABLE(TABLE):
|
||||
components.append(THEAD(TR(*row)))
|
||||
|
||||
tbody = []
|
||||
repr_cache = {}
|
||||
for (rc, record) in enumerate(sqlrows):
|
||||
row = []
|
||||
if rc % 2 == 1:
|
||||
@@ -3176,7 +3195,11 @@ class SQLTABLE(TABLE):
|
||||
href = '%s/%s?%s' % (linkto, tref, urllib.urlencode({fref: r}))
|
||||
r = A(represent(field, r, record), _href=str(href))
|
||||
elif field.represent:
|
||||
r = represent(field, r, record)
|
||||
if field not in repr_cache:
|
||||
repr_cache[field] = {}
|
||||
if r not in repr_cache[field]:
|
||||
repr_cache[field][r] = represent(field, r, record)
|
||||
r = repr_cache[field][r]
|
||||
elif linkto and hasattr(field._table, '_primarykey')\
|
||||
and fieldname in field._table._primarykey:
|
||||
# have to test this with multi-key tables
|
||||
@@ -3293,6 +3316,7 @@ class ExportClass(object):
|
||||
return value
|
||||
|
||||
represented = []
|
||||
repr_cache = {}
|
||||
for record in self.rows:
|
||||
row = []
|
||||
for col in self.rows.colnames:
|
||||
@@ -3308,7 +3332,14 @@ class ExportClass(object):
|
||||
if field.type == 'blob' and value is not None:
|
||||
value = ''
|
||||
elif field.represent:
|
||||
value = field.represent(value, record)
|
||||
if field.type.startswith('reference'):
|
||||
if field not in repr_cache:
|
||||
repr_cache[field] = {}
|
||||
if value not in repr_cache[field]:
|
||||
repr_cache[field][value] = field.represent(value, record)
|
||||
value = repr_cache[field][value]
|
||||
else:
|
||||
value = field.represent(value, record)
|
||||
row.append(none_exception(value))
|
||||
|
||||
represented.append(row)
|
||||
|
||||
Reference in New Issue
Block a user