merge 3.19.9 into 3.20 branch
authorJulien Cristau <julien.cristau@logilab.fr>
Thu, 05 Feb 2015 15:49:02 +0100
changeset 10187 0df931eb08de
parent 10177 7b95eae7669d (current diff)
parent 10186 bc1f5faad60b (diff)
child 10188 811327820691
merge 3.19.9 into 3.20 branch
.hgtags
__pkginfo__.py
cubicweb.spec
debian/changelog
hooks/email.py
hooks/test/unittest_hooks.py
rset.py
server/sources/native.py
test/unittest_rset.py
web/views/primary.py
--- 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