diff --git a/datagateway_api/src/search_api/filters.py b/datagateway_api/src/search_api/filters.py index a10a2105..c83538c1 100644 --- a/datagateway_api/src/search_api/filters.py +++ b/datagateway_api/src/search_api/filters.py @@ -30,6 +30,58 @@ def apply_filter(self, query): # function signature return super().apply_filter(query.query.query) + def get_icat_mapping(self, panosc_entity_name, field_name): + """ + This function searches the PaNOSC mappings (from `search_api_mapping.json`, + maintained/stored by :class:`PaNOSCMappings`) and retrieves the ICAT translation + from the PaNOSC input. Fields in the same entity can be found, as well as fields + from related entities (e.g. Dataset.files.path) via recursion inside this + function. + + An edge case for ICAT has been somewhat hardcoded into this function to dea + with ICAT's different parameter value field names. The following mapping is + assumed (where order matters): + {"Parameter": {"value": ["numericValue", "stringValue", "dateTimeValue"]}} + + :param panosc_entity_name: A PaNOSC entity name e.g. "Dataset" + :type panosc_entity_name: :class:`str` + :param field_name: PaNOSC field name to fetch the ICAT version of e.g. "name" + :type field_name: :class:`str` + :return: Tuple containing the PaNOSC entity name (which will change from the + input if a related entity is found) and the ICAT field name + mapping/translation from the PaNOSC data model + """ + + try: + icat_mapping = mappings.mappings[panosc_entity_name][field_name] + except KeyError as e: + raise FilterError(f"Bad PaNOSC to ICAT mapping: {e.args}") + + print(f"ICAT Mapping: {icat_mapping}, Type: {type(icat_mapping)}") + if isinstance(icat_mapping, str): + # Field name + icat_field_name = icat_mapping + elif isinstance(icat_mapping, dict): + # Relation - JSON format: {PaNOSC entity name: ICAT related field name} + panosc_entity_name = list(icat_mapping.keys())[0] + icat_field_name = icat_mapping[panosc_entity_name] + elif isinstance(icat_mapping, list): + # Edge case for ICAT's different parameter value field names + if isinstance(self.value, int) or isinstance(self.value, float): + icat_field_name = icat_mapping[0] + elif isinstance(self.value, datetime): + icat_field_name = icat_mapping[2] + elif isinstance(self.value, str): + if DateHandler.is_str_a_date(self.value): + icat_field_name = icat_mapping[2] + else: + icat_field_name = icat_mapping[1] + else: + self.value = str(self.value) + icat_field_name = icat_mapping[1] + + return (panosc_entity_name, icat_field_name) + def __str__(self): # TODO - can't just hardcode investigation entity. Might need `icat_entity_name` # to be passed into init