# HG changeset patch # User Philippe Pepiot # Date 1570614262 -7200 # Node ID 8e5f2c449e60a6932b7d6a821c089ec004f5da79 # Parent 6c48a49cd3c2ddb82897c4e805d29a77baa243a4# Parent 6bcd8899f71b974c6b284b9fbaa94f218087a09a Merge 3.26 diff -r 6c48a49cd3c2 -r 8e5f2c449e60 cubicweb/devtools/test/unittest_dbfill.py --- a/cubicweb/devtools/test/unittest_dbfill.py Wed May 22 01:16:55 2019 +0200 +++ b/cubicweb/devtools/test/unittest_dbfill.py Wed Oct 09 11:44:22 2019 +0200 @@ -108,12 +108,5 @@ self.assertEqual(self.person_valgen.generate_attribute_value({}, 'description', 12), u'yo') - -class ConstraintInsertionTC(TestCase): - - def test_writeme(self): - self.skipTest('Test automatic insertion / Schema Constraints') - - if __name__ == '__main__': unittest_main() diff -r 6c48a49cd3c2 -r 8e5f2c449e60 cubicweb/server/sources/native.py --- a/cubicweb/server/sources/native.py Wed May 22 01:16:55 2019 +0200 +++ b/cubicweb/server/sources/native.py Wed Oct 09 11:44:22 2019 +0200 @@ -648,6 +648,18 @@ def delete_relation(self, cnx, subject, rtype, object): """delete a relation from the source""" rschema = self.schema.rschema(rtype) + # we should not issue UPDATE on inlined relations when subject is going + # to be deleted. + # Unless object is also going to be deleted and is not equal to the + # subject, in this case DELETE should occur in a order which cubicweb + # doesn't handle (yet). For example + # cubicweb/server/test/unittest_migractions.py::MigrationCommandsTC::test_add_drop_entity_type + # trigger such case. + if ( + rschema.inlined and cnx.deleted_in_transaction(subject) + and (subject == object or not cnx.deleted_in_transaction(object)) + ): + return self._delete_relation(cnx, subject, rtype, object, rschema.inlined) if cnx.ertype_supports_undo(rtype): self._record_tx_action(cnx, 'tx_relation_actions', u'R', diff -r 6c48a49cd3c2 -r 8e5f2c449e60 cubicweb/server/test/unittest_repository.py --- a/cubicweb/server/test/unittest_repository.py Wed May 22 01:16:55 2019 +0200 +++ b/cubicweb/server/test/unittest_repository.py Wed Oct 09 11:44:22 2019 +0200 @@ -320,6 +320,58 @@ cnx.commit() self.assertEqual(bk.title, 'root') + def test_delete_entity_with_inlined_relation(self): + """Test deletion of entity with inlined relations. + + In this case, inlined relation column should not be deleted (= e.g. not + updated to NULL), but hooks before_delete_relation and + afer_delete_relation must be called. + """ + class OnDeleteInlined(Hook): + __regid__ = 'on_delete_inlined' + __select__ = Hook.__select__ & hook.match_rtype('personne_inlined') + events = ('before_delete_relation', 'after_delete_relation') + CALLED = [] + + def __call__(self): + OnDeleteInlined.CALLED.append(self.event) + + with self.admin_access.cnx() as cnx: + # allow only one null on cw_personne_inlined column + cnx.system_sql( + 'CREATE UNIQUE INDEX test_composite_idx ON cw_personne(true) ' + 'WHERE cw_personne_inlined is NULL') + cnx.commit() + + # deletion of p1 should not set personne_inlined to NULL (otherwise + # the unique index will raise) + p0 = cnx.create_entity('Personne', nom=u'p0') + p1 = cnx.create_entity('Personne', nom=u'p1', personne_inlined=p0) + cnx.commit() + with self.temporary_appobjects(OnDeleteInlined): + cnx.entity_from_eid(p1.eid).cw_delete() + assert OnDeleteInlined.CALLED == [ + 'before_delete_relation', 'after_delete_relation'] + cnx.commit() + + # XXX: This case is not handled because entities need to be deleted + # in a specific order + # p1 = cnx.create_entity('Personne', nom=u'p1', personne_inlined=p0) + # cnx.commit() + # cnx.execute('DELETE Personne X WHERE X eid IN ({}, {})'.format(p1.eid, p0.eid)) + # cnx.commit() + cnx.entity_from_eid(p0.eid).cw_delete() + cnx.commit() + + # deletion of p1 should not set personne_inlined to NULL + p1 = cnx.create_entity('Personne', nom=u'p1') + p1.cw_set(personne_inlined=p1) + p0 = cnx.create_entity('Personne', nom=u'p0') + cnx.commit() + cnx.entity_from_eid(p1.eid).cw_delete() + cnx.commit() + + class SchemaDeserialTC(CubicWebTC): appid = 'data-schemaserial' diff -r 6c48a49cd3c2 -r 8e5f2c449e60 cubicweb/web/views/undohistory.py --- a/cubicweb/web/views/undohistory.py Wed May 22 01:16:55 2019 +0200 +++ b/cubicweb/web/views/undohistory.py Wed Oct 09 11:44:22 2019 +0200 @@ -45,8 +45,7 @@ self.action_type = action_type def __str__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join( - "%s=%v" % (str(k), str(v)) for k, v in kwargs.items() )) + return '%s()' % (self.__class__.__name__) def __call__(self, cls, req, tx_action=None, **kwargs): # tx_action is expected to be a transaction.AbstractAction diff -r 6c48a49cd3c2 -r 8e5f2c449e60 doc/changes/3.21.rst --- a/doc/changes/3.21.rst Wed May 22 01:16:55 2019 +0200 +++ b/doc/changes/3.21.rst Wed Oct 09 11:44:22 2019 +0200 @@ -24,7 +24,7 @@ User-visible changes -------------------- -* the use of fckeditor for text form fields is disabled by default +* the use of fckeditor for text form fields is disabled by default, to re-enable it simply install the `cubicweb-ckeditor` cube (then `add_cude('ckeditor')` in a migration or in the shell) * the 'https-deny-anonymous' configuration setting no longer exists