--- 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
--- 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 <julien.cristau@logilab.fr> Tue, 06 Jan 2015 18:11:03 +0100
+cubicweb (3.19.9-1) unstable; urgency=low
+
+ * new upstream release
+
+ -- Julien Cristau <julien.cristau@logilab.fr> Thu, 05 Feb 2015 15:35:19 +0100
+
cubicweb (3.19.8-1) unstable; urgency=medium
* new upstream release
--- 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
--- 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,
--- 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})
--- 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]
--- 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
--- 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}
--- 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()
--- 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