Skip to content

Commit

Permalink
Allow metadata schema deletion with child schemas; fixes #22
Browse files Browse the repository at this point in the history
  • Loading branch information
mark-saeon committed Jun 11, 2018
1 parent f1baa75 commit 5331e65
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 20 deletions.
26 changes: 14 additions & 12 deletions ckanext/metadata/logic/action/delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,32 +35,34 @@ def metadata_schema_delete(context, data_dict):
id_ = obj.id
tk.check_access('metadata_schema_delete', context, data_dict)

errors = []
if session.query(ckanext_model.MetadataSchema) \
.filter(ckanext_model.MetadataSchema.base_schema_id == id_) \
.filter(ckanext_model.MetadataSchema.state != 'deleted') \
.count() > 0:
errors += [_('Metadata schema has dependent metadata schemas.')]

if session.query(model.Package) \
.join(model.PackageExtra, model.Package.id == model.PackageExtra.package_id) \
.filter(model.PackageExtra.key == 'metadata_schema_id') \
.filter(model.PackageExtra.value == id_) \
.filter(model.Package.type == 'metadata_record') \
.filter(model.Package.state != 'deleted') \
.count() > 0:
errors += [_('Metadata schema has dependent metadata records.')]
raise tk.ValidationError(_('Metadata schema has dependent metadata records'))

if errors:
raise tk.ValidationError(' '.join(errors))

# cascade delete to dependent metadata models
cascade_context = {
'model': model,
'user': user,
'session': session,
'defer_commit': True,
}

# clear the base_schema_id on any referencing metadata schemas - implying that
# such schemas are now 'root' schemas, no longer derived from this one
metadata_schemas = session.query(ckanext_model.MetadataSchema) \
.filter(ckanext_model.MetadataSchema.base_schema_id == id_) \
.filter(ckanext_model.MetadataSchema.state != 'deleted') \
.all()
for metadata_schema in metadata_schemas:
metadata_schema_dict = model_dictize.metadata_schema_dictize(metadata_schema, cascade_context)
metadata_schema_dict['base_schema_id'] = ''
tk.get_action('metadata_schema_update')(cascade_context, metadata_schema_dict)

# cascade delete to dependent metadata models
metadata_model_ids = session.query(ckanext_model.MetadataModel.id) \
.filter(ckanext_model.MetadataModel.metadata_schema_id == id_) \
.filter(ckanext_model.MetadataModel.state != 'deleted') \
Expand Down
24 changes: 16 additions & 8 deletions ckanext/metadata/tests/test_metadata_schema_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,24 +332,32 @@ def test_delete_valid(self):
model_class=ckanext_model.MetadataSchema,
id=metadata_schema['id'])

def test_delete_with_dependencies(self):
def test_delete_with_child_schemas(self):
metadata_schema1 = ckanext_factories.MetadataSchema()
metadata_schema2 = ckanext_factories.MetadataSchema(base_schema_id=metadata_schema1['id'])
metadata_model = ckanext_factories.MetadataModel(metadata_schema_id=metadata_schema1['id'])
metadata_record = ckanext_factories.MetadataRecord(metadata_schema_id=metadata_schema1['id'])
assert metadata_schema2['base_schema_id'] == metadata_schema1['id']

self._test_action('delete', 'metadata_schema',
model_class=ckanext_model.MetadataSchema,
id=metadata_schema1['id'])
metadata_schema2['base_schema_id'] = None
del metadata_schema2['revision_id']
assert_object_matches_dict(ckanext_model.MetadataSchema.get(metadata_schema2['id']), metadata_schema2)

def test_delete_with_dependencies(self):
metadata_schema = ckanext_factories.MetadataSchema()
metadata_model = ckanext_factories.MetadataModel(metadata_schema_id=metadata_schema['id'])
metadata_record = ckanext_factories.MetadataRecord(metadata_schema_id=metadata_schema['id'])

result, obj = self._test_action('delete', 'metadata_schema',
exception_class=tk.ValidationError,
id=metadata_schema1['id'])
id=metadata_schema['id'])

assert_error(result, 'message', 'Metadata schema has dependent metadata schemas')
assert_error(result, 'message', 'Metadata schema has dependent metadata records')
assert ckanext_model.MetadataModel.get(metadata_model['id']).state == 'active'

call_action('metadata_schema_delete', id=metadata_schema2['id'])
call_action('metadata_record_delete', id=metadata_record['id'])

self._test_action('delete', 'metadata_schema',
model_class=ckanext_model.MetadataSchema,
id=metadata_schema1['id'])
id=metadata_schema['id'])
assert ckanext_model.MetadataModel.get(metadata_model['id']).state == 'deleted'

0 comments on commit 5331e65

Please sign in to comment.