001/*- 002 * #%L 003 * HAPI FHIR JPA Server 004 * %% 005 * Copyright (C) 2014 - 2024 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.jpa.dao.expunge; 021 022import ca.uhn.fhir.mdm.api.IMdmSettings; 023import jakarta.annotation.Nonnull; 024import org.springframework.beans.factory.annotation.Autowired; 025import org.springframework.stereotype.Service; 026 027import java.util.ArrayList; 028import java.util.List; 029 030@Service 031public class ResourceTableFKProvider { 032 @Autowired(required = false) 033 IMdmSettings myMdmSettings; 034 035 @Nonnull 036 public List<ResourceForeignKey> getResourceForeignKeys() { 037 List<ResourceForeignKey> retval = new ArrayList<>(); 038 039 // To find all the FKs that need to be included here, run the following SQL in the INFORMATION_SCHEMA: 040 // SELECT FKTABLE_NAME, FKCOLUMN_NAME FROM CROSS_REFERENCES WHERE PKTABLE_NAME = 'HFJ_RESOURCE' 041 042 // Add some secondary related records that don't have foreign keys 043 retval.add(new ResourceForeignKey("HFJ_HISTORY_TAG", "RES_ID")); // NOT covered by index. 044 retval.add(new ResourceForeignKey("HFJ_RES_VER_PROV", "RES_PID")); 045 046 // These have the possibility of touching all resource types. 047 retval.add(new ResourceForeignKey("HFJ_IDX_CMP_STRING_UNIQ", "RES_ID")); 048 retval.add(new ResourceForeignKey("HFJ_IDX_CMB_TOK_NU", "RES_ID")); 049 retval.add(new ResourceForeignKey("HFJ_RES_LINK", "SRC_RESOURCE_ID")); 050 retval.add(new ResourceForeignKey("HFJ_RES_LINK", "TARGET_RESOURCE_ID")); 051 retval.add(new ResourceForeignKey("HFJ_RES_PARAM_PRESENT", "RES_ID")); 052 retval.add(new ResourceForeignKey("HFJ_RES_TAG", "RES_ID")); 053 retval.add(new ResourceForeignKey("HFJ_RES_VER", "RES_ID")); 054 retval.add(new ResourceForeignKey("HFJ_SPIDX_COORDS", "RES_ID")); 055 retval.add(new ResourceForeignKey("HFJ_SPIDX_DATE", "RES_ID")); 056 retval.add(new ResourceForeignKey("HFJ_SPIDX_NUMBER", "RES_ID")); 057 retval.add(new ResourceForeignKey("HFJ_SPIDX_QUANTITY", "RES_ID")); 058 retval.add(new ResourceForeignKey("HFJ_SPIDX_QUANTITY_NRML", "RES_ID")); 059 retval.add(new ResourceForeignKey("HFJ_SPIDX_STRING", "RES_ID")); 060 retval.add(new ResourceForeignKey("HFJ_SPIDX_TOKEN", "RES_ID")); 061 retval.add(new ResourceForeignKey("HFJ_SPIDX_URI", "RES_ID")); 062 retval.add(new ResourceForeignKey("MPI_LINK", "GOLDEN_RESOURCE_PID")); 063 retval.add(new ResourceForeignKey("MPI_LINK", "TARGET_PID")); 064 retval.add(new ResourceForeignKey("MPI_LINK", "PERSON_PID")); 065 066 // These only touch certain resource types. 067 retval.add(new ResourceForeignKey("TRM_CODESYSTEM_VER", "RES_ID")); 068 retval.add(new ResourceForeignKey("TRM_CODESYSTEM", "RES_ID")); 069 retval.add(new ResourceForeignKey("TRM_VALUESET", "RES_ID")); 070 retval.add(new ResourceForeignKey("TRM_CONCEPT_MAP", "RES_ID")); 071 retval.add(new ResourceForeignKey("NPM_PACKAGE_VER", "BINARY_RES_ID")); 072 retval.add(new ResourceForeignKey("NPM_PACKAGE_VER_RES", "BINARY_RES_ID")); 073 074 retval.add(new ResourceForeignKey("HFJ_SUBSCRIPTION_STATS", "RES_ID")); 075 retval.add(new ResourceForeignKey("HFJ_RES_SEARCH_URL", "RES_ID")); 076 077 return retval; 078 } 079 080 @Nonnull 081 public List<ResourceForeignKey> getResourceForeignKeysByResourceType(String theResourceType) { 082 List<ResourceForeignKey> retval = new ArrayList<>(); 083 // These have the possibility of touching all resource types. 084 retval.add(new ResourceForeignKey("HFJ_HISTORY_TAG", "RES_ID")); 085 retval.add(new ResourceForeignKey("HFJ_RES_VER_PROV", "RES_PID")); 086 retval.add(new ResourceForeignKey("HFJ_IDX_CMP_STRING_UNIQ", "RES_ID")); 087 retval.add(new ResourceForeignKey("HFJ_IDX_CMB_TOK_NU", "RES_ID")); 088 retval.add(new ResourceForeignKey("HFJ_RES_LINK", "SRC_RESOURCE_ID")); 089 retval.add(new ResourceForeignKey("HFJ_RES_LINK", "TARGET_RESOURCE_ID")); 090 retval.add(new ResourceForeignKey("HFJ_RES_PARAM_PRESENT", "RES_ID")); 091 retval.add(new ResourceForeignKey("HFJ_RES_TAG", "RES_ID")); // TODO GGG: Res_ID + TAG_ID? is that enough? 092 retval.add(new ResourceForeignKey("HFJ_RES_VER", "RES_ID")); // TODO GGG: RES_ID + updated? is that enough? 093 retval.add(new ResourceForeignKey("HFJ_SPIDX_COORDS", "RES_ID")); 094 retval.add(new ResourceForeignKey("HFJ_SPIDX_DATE", "RES_ID")); 095 retval.add(new ResourceForeignKey("HFJ_SPIDX_NUMBER", "RES_ID")); 096 retval.add(new ResourceForeignKey("HFJ_SPIDX_QUANTITY", "RES_ID")); 097 retval.add(new ResourceForeignKey("HFJ_SPIDX_QUANTITY_NRML", "RES_ID")); 098 retval.add(new ResourceForeignKey("HFJ_SPIDX_STRING", "RES_ID")); 099 retval.add(new ResourceForeignKey("HFJ_SPIDX_TOKEN", "RES_ID")); 100 retval.add(new ResourceForeignKey("HFJ_SPIDX_URI", "RES_ID")); 101 102 if (myMdmSettings != null && myMdmSettings.isEnabled()) { 103 retval.add(new ResourceForeignKey("MPI_LINK", "GOLDEN_RESOURCE_PID")); // NOT covered by index. 104 retval.add(new ResourceForeignKey("MPI_LINK", "TARGET_PID")); // Possibly covered, partial index 105 retval.add(new ResourceForeignKey( 106 "MPI_LINK", 107 "PERSON_PID")); // TODO GGG: I don't even think we need this... this field is deprecated, and the 108 // deletion is covered by GOLDEN_RESOURCE_PID 109 } 110 111 switch (theResourceType.toLowerCase()) { 112 case "binary": 113 retval.add(new ResourceForeignKey("NPM_PACKAGE_VER", "BINARY_RES_ID")); // Not covered 114 retval.add(new ResourceForeignKey("NPM_PACKAGE_VER_RES", "BINARY_RES_ID")); // Not covered 115 break; 116 case "subscription": 117 retval.add(new ResourceForeignKey("HFJ_SUBSCRIPTION_STATS", "RES_ID")); // Covered by index. 118 break; 119 case "codesystem": 120 retval.add(new ResourceForeignKey("TRM_CODESYSTEM_VER", "RES_ID")); // Not covered 121 retval.add(new ResourceForeignKey("TRM_CODESYSTEM", "RES_ID")); // Not covered 122 break; 123 case "valueset": 124 retval.add(new ResourceForeignKey("TRM_VALUESET", "RES_ID")); // Not covered 125 break; 126 case "conceptmap": 127 retval.add(new ResourceForeignKey("TRM_CONCEPT_MAP", "RES_ID")); // Not covered 128 break; 129 default: 130 } 131 return retval; 132 } 133}