@@ -667,57 +667,68 @@ def fetch_mappings(self, refetch=False):
667667 self ._mappings = self .get_mappings ()
668668 self ._fetched = True
669669
670- def get_concepts (self , system_version = None ): # pylint: disable=too-many-branches
670+ def get_concepts (self , system_version = None ):
671671 system_version = system_version or self .resolve_system_version
672- queryset = self .get_resource_queryset_from_system_and_valueset ('concepts' , system_version )
672+ concept_queryset = self .get_resource_queryset_from_system_and_valueset ('concepts' , system_version )
673673 valueset_versions = self .resolve_valueset_versions
674674 mapping_queryset = Mapping .objects .none ()
675- if queryset is None :
675+
676+ if concept_queryset is None :
676677 return Concept .objects .none (), mapping_queryset
677678
678679 if self .code :
679- queryset = queryset .filter (mnemonic = decode_string (self .code ))
680+ concept_queryset = concept_queryset .filter (mnemonic = decode_string (self .code ))
680681 if self .resource_version :
681- queryset = queryset .filter (version = self .resource_version )
682- elif queryset .count () > 1 :
683- queryset = Concept .objects .filter (id = queryset .order_by ('-id' ).first ().id )
682+ concept_queryset = concept_queryset .filter (version = self .resource_version )
683+ elif concept_queryset .count () > 1 :
684+ concept_queryset = Concept .objects .filter (id = concept_queryset .order_by ('-id' ).first ().id )
684685
685686 if self .should_apply_filter ():
686- queryset = self .apply_filters (queryset , Concept )
687-
687+ concept_queryset = self ._apply_filters (concept_queryset , Concept )
688688 if self .cascade :
689- cascade_params = self .get_concept_cascade_params (system_version or valueset_versions [0 ])
690- concept_ids = set ()
691- mapping_ids = set ()
692- traversed = []
693- for concept in queryset :
694- concept_uri = drop_version (concept .uri )
695- if concept_uri in traversed :
696- continue
697- traversed .append (concept_uri )
698- result = concept .cascade (** cascade_params )
699- concept_ids .update (set (result ['concepts' ].values_list ('id' , flat = True )))
700- mapping_ids .update (set (result ['mappings' ].values_list ('id' , flat = True )))
701- concept_ids .update (set (queryset .values_list ('id' , flat = True )))
702- mapping_ids .update (set (mapping_queryset .values_list ('id' , flat = True )))
703- queryset = Concept .objects .filter (id__in = concept_ids )
704- mapping_queryset = Mapping .objects .filter (id__in = mapping_ids )
689+ concept_queryset , mapping_queryset = self ._apply_cascade (
690+ concept_queryset , mapping_queryset , system_version , valueset_versions )
691+ if self .transform :
692+ concept_queryset , mapping_queryset = self ._apply_transform (
693+ concept_queryset , mapping_queryset , system_version )
694+
695+ if concept_queryset is None :
696+ concept_queryset = Concept .objects .none ()
705697
698+ return concept_queryset , mapping_queryset
699+
700+ def _apply_transform (self , concept_queryset , mapping_queryset , system_version ):
706701 if self .should_transform_to_latest_version ():
707- queryset = self .transform_to_latest_version (queryset , Concept )
708- if self .code :
709- concept = queryset .first ()
710- if concept :
711- self .resource_version = concept .version
712- self .expression = concept .uri
702+ concept_queryset = self ._update_by_transform_to_latest_version (concept_queryset , Concept )
713703 mapping_queryset = self .transform_to_latest_version (mapping_queryset , Mapping )
714704 if self .should_transform_to_versioned () and not system_version .is_head : # For HEAD it will be versioned
715- queryset = Concept .objects .filter (id__in = queryset .values_list ('versioned_object_id' , flat = True ))
705+ self .version = HEAD
706+ concept_queryset = Concept .objects .filter (
707+ id__in = concept_queryset .values_list ('versioned_object_id' , flat = True ))
716708 mapping_queryset = Mapping .objects .filter (
717709 id__in = mapping_queryset .values_list ('versioned_object_id' , flat = True ))
718- if queryset is None :
719- queryset = Concept .objects .none ()
720- return queryset , mapping_queryset
710+
711+ return concept_queryset , mapping_queryset
712+
713+ def _apply_cascade (self , concept_queryset , mapping_queryset , system_version , valueset_versions ):
714+ cascade_params = self .get_concept_cascade_params (system_version or valueset_versions [0 ])
715+ concept_ids = set ()
716+ mapping_ids = set ()
717+ traversed = []
718+
719+ for concept in concept_queryset :
720+ concept_uri = drop_version (concept .uri )
721+ if concept_uri in traversed :
722+ continue
723+ traversed .append (concept_uri )
724+ result = concept .cascade (** cascade_params )
725+ concept_ids .update (set (result ['concepts' ].values_list ('id' , flat = True )))
726+ mapping_ids .update (set (result ['mappings' ].values_list ('id' , flat = True )))
727+
728+ concept_ids .update (set (concept_queryset .values_list ('id' , flat = True )))
729+ mapping_ids .update (set (mapping_queryset .values_list ('id' , flat = True )))
730+
731+ return Concept .objects .filter (id__in = concept_ids ), Mapping .objects .filter (id__in = mapping_ids )
721732
722733 def get_mappings (self , system_version = None ):
723734 queryset = self .get_resource_queryset_from_system_and_valueset ('mappings' , system_version )
@@ -730,48 +741,74 @@ def get_mappings(self, system_version=None):
730741 queryset = queryset .filter (version = self .resource_version )
731742
732743 if self .should_apply_filter ():
733- queryset = self .apply_filters (queryset , Mapping )
744+ queryset = self ._apply_filters (queryset , Mapping )
734745
735746 if self .should_transform_to_latest_version ():
736- queryset = self .transform_to_latest_version (queryset , Mapping )
737- if self .code :
738- mapping = queryset .first ()
739- self .resource_version = mapping .version
740- self .expression = mapping .uri
747+ queryset = self ._update_by_transform_to_latest_version (queryset , Mapping )
741748 if queryset is None :
742749 queryset = Mapping .objects .none ()
743750 return queryset
744751
752+ def _update_by_transform_to_latest_version (self , queryset , klass ):
753+ queryset = self .transform_to_latest_version (queryset , klass )
754+ if self .code :
755+ resource = queryset .first ()
756+ if resource :
757+ self .version = get (resource .latest_source_version , 'version' )
758+ self .resource_version = None
759+ if not self .version :
760+ self .version = HEAD
761+ self .resource_version = resource .version
762+ # self.resource_version = resource.version # old
763+ self .expression = resource .uri
764+ return queryset
765+
745766 @staticmethod
746767 def dedupe_by_expression (references ):
747768 return list ({reference .expression : reference for reference in references }.values ())
748769
770+ def __get_repo_and_resource_version (self , resource , is_intensional , is_extensional ):
771+ repo_version = self .version
772+ resource_version = None
773+ if not self .version and self .transform :
774+ repo_version = get (resource .latest_source_version , 'version' ) or HEAD
775+ is_head = repo_version == HEAD
776+ if is_intensional and is_head :
777+ resource_version = resource .version
778+ elif is_extensional :
779+ resource_version = None
780+ if is_intensional and repo_version == HEAD and not resource_version :
781+ resource_version = resource .version
782+ return repo_version , resource_version
783+
784+ def __generate_references_for_type (self , queryset , resource_type ):
785+ references = []
786+ is_extensional = self .is_extensional_transform
787+ is_intensional = self .is_static_transform
788+
789+ for resource in queryset :
790+ repo_version , resource_version = self .__get_repo_and_resource_version (
791+ resource , is_intensional , is_extensional )
792+
793+ references .append (CollectionReference (
794+ expression = resource .uri ,
795+ reference_type = resource_type ,
796+ code = encode_string (resource .mnemonic ) if resource_type == 'concepts' else resource .mnemonic ,
797+ collection_id = self .collection_id ,
798+ created_by = self .created_by ,
799+ resource_version = resource_version ,
800+ system = self .system ,
801+ version = repo_version
802+ ))
803+ return references
804+
749805 def generate_references (self ):
750806 references = []
807+
751808 if self .should_generate_multiple_references ():
752809 concepts , mappings = self .get_concepts ()
753- for concept in concepts :
754- references .append (CollectionReference (
755- expression = concept .uri ,
756- reference_type = 'concepts' ,
757- code = encode_string (concept .mnemonic ),
758- collection_id = self .collection_id ,
759- created_by = self .created_by ,
760- resource_version = concept .version if self .transform == TRANSFORM_TO_RESOURCE_VERSIONS else None ,
761- system = self .system ,
762- version = self .version
763- ))
764- for mapping in mappings :
765- references .append (CollectionReference (
766- expression = mapping .uri ,
767- reference_type = 'mappings' ,
768- code = mapping .mnemonic ,
769- collection_id = self .collection_id ,
770- created_by = self .created_by ,
771- resource_version = mapping .version if self .transform == TRANSFORM_TO_RESOURCE_VERSIONS else None ,
772- system = self .system ,
773- version = self .version
774- ))
810+ references += self .__generate_references_for_type (concepts , 'concepts' )
811+ references += self .__generate_references_for_type (mappings , 'mappings' )
775812 else :
776813 references .append (self )
777814 return references
@@ -854,7 +891,7 @@ def clean_fields(_fields):
854891 )
855892 return search
856893
857- def apply_filters (self , queryset , resource_klass ):
894+ def _apply_filters (self , queryset , resource_klass ):
858895 if self .filter :
859896 pks = []
860897 document = resource_klass .get_search_document ()
0 commit comments