Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions builder/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,26 +130,32 @@ def create_search(*, draft, term=None, code=None, codes):

@transaction.atomic
def delete_search(*, search):
# Grab the PK before we delete the instance
# Grab the PK and related version before we delete the instance
search_pk = search.pk
version = search.version

# Delete any codes that:
# - only belong to this search
# - are not included
# - are not descendants of an included code

# Find all code objs that belong to this search and no others
search_only_code_objs = search.version.code_objs.annotate(
search_only_code_objs = version.code_objs.annotate(
num_results=Count("results")
).filter(results__search=search, num_results=1)
codes_to_keep = get_codes_to_keep(search.version, search_only_code_objs)
codes_to_keep = get_codes_to_keep(version, search_only_code_objs)

# Delete any code objs that belong to this search only, and are not in the codes_to_keep set
search_only_code_objs.exclude(code__in=codes_to_keep).delete()

# Delete the search
search.delete()

# Update the cached hierarchy
from codelists.actions import cache_hierarchy # avoid circular imports

cache_hierarchy(version=version)

logger.info("Deleted Search", search_pk=search_pk)


Expand Down
2 changes: 1 addition & 1 deletion codelists/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ def _create_version_with_codes(
for code, status in codeset.code_to_status.items()
)

cache_hierarchy(version=clv, hierarchy=hierarchy)
cache_hierarchy(version=clv)

return clv

Expand Down
16 changes: 9 additions & 7 deletions codelists/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,24 +476,26 @@ def full_slug(self):
def has_hierarchy(self):
return self.coding_system.is_builder_compatible()

def calculate_hierarchy(self):
def calculate_hierarchy(self, coding_system=None):
"""Return Hierarchy of codes related to this CodelistVersion."""
if self.csv_data:
return self._calculate_old_style_hierarchy()
return self._calculate_old_style_hierarchy(coding_system=None)
else:
return self._calculate_new_style_hierarchy()
return self._calculate_new_style_hierarchy(coding_system=None)

def _calculate_old_style_hierarchy(self):
def _calculate_old_style_hierarchy(self, coding_system):
if not self.has_hierarchy:
# If coding system does not define relationships, then we cannot build a
# hierarchy, and so it's not clear what a hierarchy is for.
return

return Hierarchy.from_codes(self.coding_system, self.codes)
return Hierarchy.from_codes(coding_system or self.coding_system, self.codes)

def _calculate_new_style_hierarchy(self):
def _calculate_new_style_hierarchy(self, coding_system):
code_to_status = dict(self.code_objs.values_list("code", "status"))
return Hierarchy.from_codes(self.coding_system, list(code_to_status))
return Hierarchy.from_codes(
coding_system or self.coding_system, list(code_to_status)
)

@cached_property
def hierarchy(self):
Expand Down
3 changes: 1 addition & 2 deletions coding_systems/base/import_data_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from tqdm import tqdm

from codelists.coding_systems import CODING_SYSTEMS
from codelists.hierarchy import Hierarchy
from codelists.models import CodelistVersion, Status
from codelists.search import do_search
from coding_systems.versioning.models import (
Expand Down Expand Up @@ -347,7 +346,7 @@ def _check_version_by_hierarchy(coding_system, version):
# will have a cached hierarchy, built with the original coding system release.
# We compare this to a hierarchy built from the same codes, but with the new release.

return version.hierarchy == Hierarchy.from_codes(coding_system, version.codes)
return version.hierarchy == version.calculate_hierarchy(coding_system=coding_system)


def _check_version_by_search(coding_system, version):
Expand Down
22 changes: 21 additions & 1 deletion coding_systems/base/tests/test_import_data_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
from codelists.coding_systems import CODING_SYSTEMS
from codelists.hierarchy import Hierarchy
from codelists.models import Status
from coding_systems.base.import_data_utils import update_codelist_version_compatibility
from coding_systems.base.import_data_utils import (
_check_version_by_hierarchy,
update_codelist_version_compatibility,
)
from coding_systems.base.tests.dynamic_db_classes import DynamicDatabaseTestCase
from coding_systems.bnf.models import Concept
from coding_systems.conftest import mock_migrate_coding_system
Expand Down Expand Up @@ -367,3 +370,20 @@ def test_update_codelist_version_compatibility_is_order_insensitive(

update_codelist_version_compatibility("bnf", self.bnf_release.database_alias)
assert self.bnf_review_version_with_search.compatible_releases.exists()


class TestCodelistVersionCompatibilityRoundTrips(
BaseCodingSystemDynamicDatabaseTestCase
):
db_aliases = [
"bnf_import-data_20221101",
]

@pytest.mark.usefixtures("_get_bnf_release", "_get_bnf_review_version_with_search")
def test_codelist_version_compatibility_round_trips(
self,
):
assert _check_version_by_hierarchy(
self.bnf_review_version_with_search.coding_system,
self.bnf_review_version_with_search,
)
Loading