[entity/optimization] Cache rset when entity.related is called with entities=False
If fail to see why we couldn't cache in this case, while this is important for
optimization reason: when doing a single HTTP request, some queries are done two
or three times because of predicates / uicfg or alike.
Also always store tuple and not list in the cache, because:
* else we get some regression
* and inconsistent result type (tuple or list)
* and it simply feels better to cache an unmutable object.
--- a/cubicweb/entity.py Wed Nov 09 16:14:17 2016 +0100
+++ b/cubicweb/entity.py Fri Nov 18 17:50:56 2016 +0100
@@ -985,11 +985,10 @@
if not safe:
raise
rset = self._cw.empty_rset()
+ if cacheable:
+ self.cw_set_relation_cache(rtype, role, rset)
if entities:
- if cacheable:
- self.cw_set_relation_cache(rtype, role, rset)
- return self.related(rtype, role, entities=entities)
- return list(rset.entities())
+ return tuple(rset.entities())
else:
return rset
@@ -1251,7 +1250,7 @@
def cw_set_relation_cache(self, rtype, role, rset):
"""set cached values for the given relation"""
if rset:
- related = list(rset.entities(0))
+ related = tuple(rset.entities(0))
rschema = self._cw.vreg.schema.rschema(rtype)
if role == 'subject':
rcard = rschema.rdef(self.e_schema, related[0].e_schema).cardinality[1]
--- a/cubicweb/test/unittest_entity.py Wed Nov 09 16:14:17 2016 +0100
+++ b/cubicweb/test/unittest_entity.py Fri Nov 18 17:50:56 2016 +0100
@@ -182,10 +182,15 @@
req.create_entity('Tag', name=tag)
req.execute('SET X tags Y WHERE X is Tag, Y is Personne')
self.assertEqual(len(p.related('tags', 'object', limit=2)), 2)
+ self.assertFalse(p.cw_relation_cached('tags', 'object'))
self.assertEqual(len(p.related('tags', 'object')), 4)
+ self.assertTrue(p.cw_relation_cached('tags', 'object'))
p.cw_clear_all_caches()
+ self.assertFalse(p.cw_relation_cached('tags', 'object'))
self.assertEqual(len(p.related('tags', 'object', entities=True, limit=2)), 2)
+ self.assertFalse(p.cw_relation_cached('tags', 'object'))
self.assertEqual(len(p.related('tags', 'object', entities=True)), 4)
+ self.assertTrue(p.cw_relation_cached('tags', 'object'))
def test_related_targettypes(self):
with self.admin_access.web_request() as req:
--- a/cubicweb/web/test/unittest_application.py Wed Nov 09 16:14:17 2016 +0100
+++ b/cubicweb/web/test/unittest_application.py Fri Nov 18 17:50:56 2016 +0100
@@ -503,7 +503,7 @@
self.assertTrue(cnx.find('Directory', eid=subd.eid))
self.assertTrue(cnx.find('Filesystem', eid=fs.eid))
self.assertEqual(cnx.find('Directory', eid=subd.eid).one().parent,
- [topd,])
+ (topd,))
def test_subject_mixed_composite_subentity_removal_2(self):
"""Editcontroller: detaching several subentities respects each rdef's
@@ -542,7 +542,7 @@
self.assertTrue(cnx.find('Directory', eid=subd.eid))
self.assertTrue(cnx.find('Filesystem', eid=fs.eid))
self.assertEqual(cnx.find('Directory', eid=subd.eid).one().parent,
- [topd,])
+ (topd,))
def test_object_mixed_composite_subentity_removal_2(self):
"""Editcontroller: detaching several subentities respects each rdef's