diff --git a/ckanext/datastore/plugin.py b/ckanext/datastore/plugin.py index 073ffcee214..e3dae30bb97 100644 --- a/ckanext/datastore/plugin.py +++ b/ckanext/datastore/plugin.py @@ -9,6 +9,7 @@ import ckan.plugins as p import ckan.logic as logic import ckan.model as model +from ckan.model.core import State from ckan.common import config import ckanext.datastore.logic.action as action import ckanext.datastore.logic.auth as auth @@ -251,6 +252,8 @@ def before_map(self, m): action='dump') return m + # IResourceController + def before_show(self, resource_dict): # Modify the resource url of datastore resources so that # they link to the datastore dumps. @@ -265,6 +268,27 @@ def before_show(self, resource_dict): return resource_dict + def after_delete(self, context, resources): + model = context['model'] + pkg = context['package'] + res_query = model.Session.query(model.Resource) + query = res_query.filter( + model.Resource.package_id == pkg.id, + model.Resource.state == State.DELETED + ) + deleted = [ + res for res in query.all() + if res.extras.get('datastore_active') is True] + + for res in deleted: + db.delete(context, { + 'resource_id': res.id, + 'connection_url': self.write_url + }) + res.extras['datastore_active'] = False + res_query.update( + {'extras': res.extras}, synchronize_session=False) + def datastore_validate(self, context, data_dict, fields_types): column_names = fields_types.keys() fields = data_dict.get('fields') diff --git a/ckanext/datastore/tests/test_delete.py b/ckanext/datastore/tests/test_delete.py index 53f9d487f06..f5c14fd4944 100644 --- a/ckanext/datastore/tests/test_delete.py +++ b/ckanext/datastore/tests/test_delete.py @@ -11,10 +11,15 @@ import ckan.model as model import ckan.tests.legacy as tests from ckan.common import config +import ckan.tests.factories as factories +import ckan.tests.helpers as helpers +from ckan.logic import NotFound import ckanext.datastore.db as db from ckanext.datastore.tests.helpers import rebuild_all_dbs, set_url_type +assert_raises = nose.tools.assert_raises + class TestDatastoreDelete(tests.WsgiAppCase): sysadmin_user = None @@ -99,6 +104,23 @@ def test_delete_basic(self): self.Session.remove() + def test_datastore_deleted_during_resource_deletion(self): + package = factories.Dataset() + data = { + 'resource': { + 'boo%k': 'crime', + 'author': ['tolstoy', 'dostoevsky'], + 'package_id': package['id'] + }, + } + result = helpers.call_action('datastore_create', **data) + resource_id = result['resource_id'] + helpers.call_action('resource_delete', id=resource_id) + + assert_raises( + NotFound, helpers.call_action, 'datastore_search', + resource_id=resource_id) + def test_delete_invalid_resource_id(self): postparams = '%s=1' % json.dumps({'resource_id': 'bad'}) auth = {'Authorization': str(self.sysadmin_user.apikey)}