# HG changeset patch # User Julien Cristau # Date 1423147742 -3600 # Node ID 0df931eb08deef89315c5c2384fd18e4fa4036f7 # Parent 7b95eae7669d29da5c944639c1f8c940f8222781# Parent bc1f5faad60b83e12d33ab3448d11778baccfea3 merge 3.19.9 into 3.20 branch diff -r 7b95eae7669d -r 0df931eb08de .hgtags --- a/.hgtags Mon Feb 02 12:32:07 2015 +0100 +++ b/.hgtags Thu Feb 05 15:49:02 2015 +0100 @@ -395,6 +395,9 @@ efc8645ece4300958e3628db81464fef12d5f6e8 cubicweb-version-3.19.8 efc8645ece4300958e3628db81464fef12d5f6e8 cubicweb-debian-version-3.19.8-1 efc8645ece4300958e3628db81464fef12d5f6e8 cubicweb-centos-version-3.19.8-1 +b7c373d74754f5ba9344575cb179b47282c413b6 cubicweb-version-3.19.9 +b7c373d74754f5ba9344575cb179b47282c413b6 cubicweb-debian-version-3.19.9-1 +b7c373d74754f5ba9344575cb179b47282c413b6 cubicweb-centos-version-3.19.9-1 7e6b7739afe6128589ad51b0318decb767cbae36 cubicweb-version-3.20.0 7e6b7739afe6128589ad51b0318decb767cbae36 cubicweb-debian-version-3.20.0-1 7e6b7739afe6128589ad51b0318decb767cbae36 cubicweb-centos-version-3.20.0-1 diff -r 7b95eae7669d -r 0df931eb08de __pkginfo__.py diff -r 7b95eae7669d -r 0df931eb08de cubicweb.spec diff -r 7b95eae7669d -r 0df931eb08de debian/changelog --- a/debian/changelog Mon Feb 02 12:32:07 2015 +0100 +++ b/debian/changelog Thu Feb 05 15:49:02 2015 +0100 @@ -22,6 +22,12 @@ -- Julien Cristau Tue, 06 Jan 2015 18:11:03 +0100 +cubicweb (3.19.9-1) unstable; urgency=low + + * new upstream release + + -- Julien Cristau Thu, 05 Feb 2015 15:35:19 +0100 + cubicweb (3.19.8-1) unstable; urgency=medium * new upstream release diff -r 7b95eae7669d -r 0df931eb08de etwist/service.py --- a/etwist/service.py Mon Feb 02 12:32:07 2015 +0100 +++ b/etwist/service.py Thu Feb 05 15:49:02 2015 +0100 @@ -80,7 +80,7 @@ config.info('clear ui caches') for cachedir in ('uicache', 'uicachehttps'): rm(join(config.appdatahome, cachedir, '*')) - root_resource = CubicWebRootResource(config) + root_resource = CubicWebRootResource(config, config.repository()) website = server.Site(root_resource) # serve it via standard HTTP on port set in the configuration port = config['port'] or 8080 diff -r 7b95eae7669d -r 0df931eb08de hooks/email.py --- a/hooks/email.py Mon Feb 02 12:32:07 2015 +0100 +++ b/hooks/email.py Thu Feb 05 15:49:02 2015 +0100 @@ -35,6 +35,10 @@ if self.email.eid == e.eid) def precommit_event(self): + if self.cnx.deleted_in_transaction(self.entity.eid): + return + if self.cnx.deleted_in_transaction(self.email.eid): + return if self.condition(): self.cnx.execute( 'SET X %s Y WHERE X eid %%(x)s, Y eid %%(y)s' % self.rtype, diff -r 7b95eae7669d -r 0df931eb08de hooks/metadata.py --- a/hooks/metadata.py Mon Feb 02 12:32:07 2015 +0100 +++ b/hooks/metadata.py Thu Feb 05 15:49:02 2015 +0100 @@ -93,6 +93,10 @@ class SyncOwnersOp(hook.DataOperationMixIn, hook.Operation): def precommit_event(self): for compositeeid, composedeid in self.get_data(): + if self.cnx.deleted_in_transaction(compositeeid): + continue + if self.cnx.deleted_in_transaction(composedeid): + continue self.cnx.execute('SET X owned_by U WHERE C owned_by U, C eid %(c)s,' 'NOT EXISTS(X owned_by U, X eid %(x)s)', {'c': compositeeid, 'x': composedeid}) diff -r 7b95eae7669d -r 0df931eb08de hooks/test/unittest_hooks.py --- a/hooks/test/unittest_hooks.py Mon Feb 02 12:32:07 2015 +0100 +++ b/hooks/test/unittest_hooks.py Thu Feb 05 15:49:02 2015 +0100 @@ -184,6 +184,17 @@ 'U login "toto", X address A')[0][0], 'toto@logilab.fr') + def test_user_composite_no_owner_on_deleted_entity(self): + with self.admin_access.repo_cnx() as cnx: + u = self.create_user(cnx, 'toto').eid + cnx.commit() + e = cnx.create_entity('EmailAddress', address=u'toto@logilab.fr', reverse_use_email=u) + e.cw_delete() + cnx.commit() + self.assertFalse(cnx.system_sql( + 'SELECT * FROM owned_by_relation ' + 'WHERE eid_from NOT IN (SELECT eid FROM entities)').fetchall()) + def test_no_created_by_on_deleted_entity(self): with self.admin_access.repo_cnx() as cnx: eid = cnx.execute('INSERT EmailAddress X: X address "toto@logilab.fr"')[0][0] diff -r 7b95eae7669d -r 0df931eb08de rset.py --- a/rset.py Mon Feb 02 12:32:07 2015 +0100 +++ b/rset.py Thu Feb 05 15:49:02 2015 +0100 @@ -521,6 +521,7 @@ def _rset_structure(self, eschema, entity_col): eid_col = col = entity_col rqlst = self.syntax_tree() + get_rschema = eschema.schema.rschema attr_cols = {} rel_cols = {} if rqlst.TYPE == 'select': @@ -532,10 +533,7 @@ # take care, due to outer join support, we may find None # values for non final relation for i, attr, role in attr_desc_iterator(select, col, entity_col): - if role == 'subject': - rschema = eschema.subjrels[attr] - else: - rschema = eschema.objrels[attr] + rschema = get_rschema(attr) if rschema.final: if attr == 'eid': eid_col = i diff -r 7b95eae7669d -r 0df931eb08de server/sources/native.py --- a/server/sources/native.py Mon Feb 02 12:32:07 2015 +0100 +++ b/server/sources/native.py Thu Feb 05 15:49:02 2015 +0100 @@ -719,13 +719,13 @@ if self.repo.config.mode != 'test': # during test we get those message when trying to alter sqlite # db schema - self.critical("sql: %r\n args: %s\ndbms message: %r", + self.info("sql: %r\n args: %s\ndbms message: %r", query, args, ex.args[0]) if rollback: try: cnx.cnxset.rollback() if self.repo.config.mode != 'test': - self.critical('transaction has been rolled back') + self.debug('transaction has been rolled back') except Exception as ex: pass if ex.__class__.__name__ == 'IntegrityError': @@ -1242,7 +1242,7 @@ # unvisible as transaction action self.doexec(cnx, 'DELETE FROM is_relation WHERE eid_from=%s' % eid) self.doexec(cnx, 'DELETE FROM is_instance_of_relation WHERE eid_from=%s' % eid) - self.doexec(cnx, 'DELETE FROM cw_source_relation WHERE eid_from=%s' % self.eid) + self.doexec(cnx, 'DELETE FROM cw_source_relation WHERE eid_from=%s' % eid) # XXX check removal of inlined relation? # delete the entity attrs = {'cw_eid': eid} diff -r 7b95eae7669d -r 0df931eb08de test/unittest_rset.py --- a/test/unittest_rset.py Mon Feb 02 12:32:07 2015 +0100 +++ b/test/unittest_rset.py Thu Feb 05 15:49:02 2015 +0100 @@ -563,6 +563,14 @@ self.assertIsInstance(str(rset), basestring) self.assertEqual(len(str(rset).splitlines()), 1) + def test_nonregr_symmetric_relation(self): + # see https://www.cubicweb.org/ticket/4739253 + with self.admin_access.client_cnx() as cnx: + p1 = cnx.create_entity('Personne', nom=u'sylvain') + cnx.create_entity('Personne', nom=u'denis', connait=p1) + cnx.commit() + rset = cnx.execute('Any X,Y WHERE X connait Y') + rset.get_entity(0, 1) # used to raise KeyError if __name__ == '__main__': unittest_main() diff -r 7b95eae7669d -r 0df931eb08de web/views/primary.py --- a/web/views/primary.py Mon Feb 02 12:32:07 2015 +0100 +++ b/web/views/primary.py Thu Feb 05 15:49:02 2015 +0100 @@ -224,7 +224,9 @@ rtype=rschema.type, role=role) else: vid = dispctrl.get('vid', 'autolimited') - limit = defaultlimit if vid == 'autolimited' else None + limit = dispctrl.get('limit', defaultlimit) if vid == 'autolimited' else None + if limit is not None: + limit += 1 # need one more so the view can check if there is more than the limit rset = self._relation_rset(entity, rschema, role, dispctrl, limit=limit) if not rset: continue