diff --git a/ckanext/datastore/db.py b/ckanext/datastore/db.py index 81f3649916f..04c606cda32 100644 --- a/ckanext/datastore/db.py +++ b/ckanext/datastore/db.py @@ -1446,12 +1446,16 @@ def create_trigger_function(name, definition, or_replace): def drop_function(name, if_exists): sql = u''' - DROP FUNCTION {if_exists} {name}; + DROP FUNCTION {if_exists} {name}(); '''.format( if_exists=u'IF EXISTS' if if_exists else u'', name=datastore_helpers.identifier(name)) - _write_engine_execute(sql) + try: + _write_engine_execute(sql) + except ProgrammingError as pe: + message = pe.args[0].split('\n')[0].decode('utf8') + raise ValidationError({u'name': [message.split(u') ', 1)[-1]]}) def _write_engine_execute(sql): diff --git a/ckanext/datastore/logic/action.py b/ckanext/datastore/logic/action.py index c88b6e8dfcd..1120f2d627c 100644 --- a/ckanext/datastore/logic/action.py +++ b/ckanext/datastore/logic/action.py @@ -605,4 +605,4 @@ def datastore_function_delete(context, data_dict): ''' p.toolkit.check_access('datastore_function_delete', context, data_dict) - db.drop_function(data_dict['name']) + db.drop_function(data_dict['name'], data_dict['if_exists']) diff --git a/ckanext/datastore/logic/schema.py b/ckanext/datastore/logic/schema.py index 1616f52d461..4931c7ae41c 100644 --- a/ckanext/datastore/logic/schema.py +++ b/ckanext/datastore/logic/schema.py @@ -179,4 +179,5 @@ def datastore_function_create_schema(): def datastore_function_delete_schema(): return { 'name': [unicode_only, not_empty], + 'if_exists': [default(False), boolean_validator], } diff --git a/ckanext/datastore/tests/test_delete.py b/ckanext/datastore/tests/test_delete.py index 745a5c68d84..67b46130406 100644 --- a/ckanext/datastore/tests/test_delete.py +++ b/ckanext/datastore/tests/test_delete.py @@ -1,5 +1,6 @@ import json import nose +from nose.tools import assert_equal import pylons import sqlalchemy @@ -9,9 +10,11 @@ import ckan.lib.create_test_data as ctd import ckan.model as model import ckan.tests.legacy as tests +from ckan.plugins.toolkit import ValidationError import ckanext.datastore.db as db -from ckanext.datastore.tests.helpers import rebuild_all_dbs, set_url_type +from ckanext.datastore.tests.helpers import ( + rebuild_all_dbs, set_url_type, DatastoreFunctionalTestBase) class TestDatastoreDelete(tests.WsgiAppCase): @@ -234,3 +237,33 @@ def test_delete_with_blank_filters(self): assert(len(results['result']['records']) == 0) self._delete() + + +class TestDatastoreFunctionDelete(DatastoreFunctionalTestBase): + def test_create_delete(self): + helpers.call_action( + u'datastore_function_create', + name=u'test_nop', + rettype=u'trigger', + definition=u'BEGIN RETURN NEW; END;') + helpers.call_action( + u'datastore_function_delete', + name=u'test_nop') + + def test_delete_nonexistant(self): + try: + helpers.call_action( + u'datastore_function_delete', + name=u'test_not_there') + except ValidationError as ve: + assert_equal( + ve.error_dict, + {u'name': [u'function test_not_there() does not exist']}) + else: + assert 0, u'no validation error' + + def test_delete_if_exitst(self): + helpers.call_action( + u'datastore_function_delete', + name=u'test_not_there_either', + if_exists=True)