From baa850a38eaf26c4edb2da0cdecbf9bf71a2ad4f Mon Sep 17 00:00:00 2001 From: David Read Date: Fri, 12 Jul 2019 21:21:11 +0100 Subject: [PATCH] Deleting a dataset sends out IResourceController.before_delete events Although it doesn't actually delete the resources, because when a sysadmin views the deleted dataset it should show with those resource, and they wouldn't show up if we set their state=deleted. This fixes #4705 by sending the IResourceController.before_delete events necessary for Datastore and FileStore to get rid of the associated data. --- ckan/logic/action/delete.py | 19 +++++++------------ ckan/tests/logic/action/test_delete.py | 10 ++++++---- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/ckan/logic/action/delete.py b/ckan/logic/action/delete.py index 7a73b2ddc9d..85dec4aa1ac 100644 --- a/ckan/logic/action/delete.py +++ b/ckan/logic/action/delete.py @@ -92,7 +92,11 @@ def package_delete(context, data_dict): rev.author = user rev.message = _(u'REST API: Delete Package: %s') % entity.name - # delete the dataset's resources + # notify IResourceControllers that the dataset's resources are essentially + # deleted, by virtue of the dataset being deleted + # BUT don't actually delete the resource (state=deleted) because would mean + # that when a sysadmin views the deleted dataset it would show with no + # resources pkg_dict = _get_action('package_show')(context, {'id': id}) for res in pkg_dict['resources']: for plugin in plugins.PluginImplementations( @@ -100,19 +104,10 @@ def package_delete(context, data_dict): plugin.before_delete(context, res, pkg_dict.get('resources', [])) - def pop_resource(pkg_dict, res_id): - for res in pkg_dict.get('resources', []): - if res['id'] == res_id: - pkg_dict['resources'].remove(res) - return - - pkg_dict = _get_action('package_show')(context, {'id': id}) - for res in entity.resources: - pop_resource(pkg_dict, res.id) - res.delete() + for res in pkg_dict['resources']: for plugin in plugins.PluginImplementations( plugins.IResourceController): - plugin.after_delete(context, pkg_dict.get('resources', [])) + plugin.after_delete(context, []) # delete the dataset for item in plugins.PluginImplementations(plugins.IPackageController): diff --git a/ckan/tests/logic/action/test_delete.py b/ckan/tests/logic/action/test_delete.py index 6ec2ebd0841..742347ac99c 100644 --- a/ckan/tests/logic/action/test_delete.py +++ b/ckan/tests/logic/action/test_delete.py @@ -49,11 +49,13 @@ def test_with_resource(self): dataset = helpers.call_action( 'package_show', {'user': sysadmin['name']}, id=dataset['id']) assert_equals(dataset['state'], 'deleted') - # The resource is not shown though - assert_equals(dataset['resources'], []) - # The resource is still there but with state=deleted + # It's complete with resources + assert_equals([res['id'] for res in dataset['resources']], + [resource['id']]) + # The resource is still there, not deleted, otherwise it wouldn't have + # shown up as part of the deleted dataset res_obj = model.Resource.get(resource['id']) - assert_equals(res_obj.state, 'deleted') + assert_equals(res_obj.state, 'active') class TestResourceDelete: