001/*-
002 * #%L
003 * HAPI FHIR JPA Server
004 * %%
005 * Copyright (C) 2014 - 2023 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 org.springframework.beans.factory.annotation.Autowired;
024import org.springframework.stereotype.Service;
025
026import java.util.ArrayList;
027import java.util.List;
028import javax.annotation.Nonnull;
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_FORCED_ID", "RESOURCE_PID"));
048                retval.add(new ResourceForeignKey("HFJ_IDX_CMP_STRING_UNIQ", "RES_ID"));
049                retval.add(new ResourceForeignKey("HFJ_IDX_CMB_TOK_NU", "RES_ID"));
050                retval.add(new ResourceForeignKey("HFJ_RES_LINK", "SRC_RESOURCE_ID"));
051                retval.add(new ResourceForeignKey("HFJ_RES_LINK", "TARGET_RESOURCE_ID"));
052                retval.add(new ResourceForeignKey("HFJ_RES_PARAM_PRESENT", "RES_ID"));
053                retval.add(new ResourceForeignKey("HFJ_RES_TAG", "RES_ID"));
054                retval.add(new ResourceForeignKey("HFJ_RES_VER", "RES_ID"));
055                retval.add(new ResourceForeignKey("HFJ_SPIDX_COORDS", "RES_ID"));
056                retval.add(new ResourceForeignKey("HFJ_SPIDX_DATE", "RES_ID"));
057                retval.add(new ResourceForeignKey("HFJ_SPIDX_NUMBER", "RES_ID"));
058                retval.add(new ResourceForeignKey("HFJ_SPIDX_QUANTITY", "RES_ID"));
059                retval.add(new ResourceForeignKey("HFJ_SPIDX_QUANTITY_NRML", "RES_ID"));
060                retval.add(new ResourceForeignKey("HFJ_SPIDX_STRING", "RES_ID"));
061                retval.add(new ResourceForeignKey("HFJ_SPIDX_TOKEN", "RES_ID"));
062                retval.add(new ResourceForeignKey("HFJ_SPIDX_URI", "RES_ID"));
063                retval.add(new ResourceForeignKey("MPI_LINK", "GOLDEN_RESOURCE_PID"));
064                retval.add(new ResourceForeignKey("MPI_LINK", "TARGET_PID"));
065                retval.add(new ResourceForeignKey("MPI_LINK", "PERSON_PID"));
066
067                // These only touch certain resource types.
068                retval.add(new ResourceForeignKey("TRM_CODESYSTEM_VER", "RES_ID"));
069                retval.add(new ResourceForeignKey("TRM_CODESYSTEM", "RES_ID"));
070                retval.add(new ResourceForeignKey("TRM_VALUESET", "RES_ID"));
071                retval.add(new ResourceForeignKey("TRM_CONCEPT_MAP", "RES_ID"));
072                retval.add(new ResourceForeignKey("NPM_PACKAGE_VER", "BINARY_RES_ID"));
073                retval.add(new ResourceForeignKey("NPM_PACKAGE_VER_RES", "BINARY_RES_ID"));
074
075                retval.add(new ResourceForeignKey("HFJ_SUBSCRIPTION_STATS", "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_FORCED_ID", "RESOURCE_PID"));
087                retval.add(new ResourceForeignKey("HFJ_IDX_CMP_STRING_UNIQ", "RES_ID"));
088                retval.add(new ResourceForeignKey("HFJ_IDX_CMB_TOK_NU", "RES_ID"));
089                retval.add(new ResourceForeignKey("HFJ_RES_LINK", "SRC_RESOURCE_ID"));
090                retval.add(new ResourceForeignKey("HFJ_RES_LINK", "TARGET_RESOURCE_ID"));
091                retval.add(new ResourceForeignKey("HFJ_RES_PARAM_PRESENT", "RES_ID"));
092                retval.add(new ResourceForeignKey("HFJ_RES_TAG", "RES_ID")); // TODO GGG: Res_ID + TAG_ID? is that enough?
093                retval.add(new ResourceForeignKey("HFJ_RES_VER", "RES_ID")); // TODO GGG: RES_ID + updated? is that enough?
094                retval.add(new ResourceForeignKey("HFJ_SPIDX_COORDS", "RES_ID"));
095                retval.add(new ResourceForeignKey("HFJ_SPIDX_DATE", "RES_ID"));
096                retval.add(new ResourceForeignKey("HFJ_SPIDX_NUMBER", "RES_ID"));
097                retval.add(new ResourceForeignKey("HFJ_SPIDX_QUANTITY", "RES_ID"));
098                retval.add(new ResourceForeignKey("HFJ_SPIDX_QUANTITY_NRML", "RES_ID"));
099                retval.add(new ResourceForeignKey("HFJ_SPIDX_STRING", "RES_ID"));
100                retval.add(new ResourceForeignKey("HFJ_SPIDX_TOKEN", "RES_ID"));
101                retval.add(new ResourceForeignKey("HFJ_SPIDX_URI", "RES_ID"));
102
103                if (myMdmSettings != null && myMdmSettings.isEnabled()) {
104                        retval.add(new ResourceForeignKey("MPI_LINK", "GOLDEN_RESOURCE_PID")); // NOT covered by index.
105                        retval.add(new ResourceForeignKey("MPI_LINK", "TARGET_PID")); // Possibly covered, partial index
106                        retval.add(new ResourceForeignKey(
107                                        "MPI_LINK",
108                                        "PERSON_PID")); // TODO GGG: I don't even think we need this... this field is deprecated, and the
109                        // deletion is covered by GOLDEN_RESOURCE_PID
110                }
111
112                switch (theResourceType.toLowerCase()) {
113                        case "binary":
114                                retval.add(new ResourceForeignKey("NPM_PACKAGE_VER", "BINARY_RES_ID")); // Not covered
115                                retval.add(new ResourceForeignKey("NPM_PACKAGE_VER_RES", "BINARY_RES_ID")); // Not covered
116                                break;
117                        case "subscription":
118                                retval.add(new ResourceForeignKey("HFJ_SUBSCRIPTION_STATS", "RES_ID")); // Covered by index.
119                                break;
120                        case "codesystem":
121                                retval.add(new ResourceForeignKey("TRM_CODESYSTEM_VER", "RES_ID")); // Not covered
122                                retval.add(new ResourceForeignKey("TRM_CODESYSTEM", "RES_ID")); // Not covered
123                                break;
124                        case "valueset":
125                                retval.add(new ResourceForeignKey("TRM_VALUESET", "RES_ID")); // Not covered
126                                break;
127                        case "conceptmap":
128                                retval.add(new ResourceForeignKey("TRM_CONCEPT_MAP", "RES_ID")); // Not covered
129                                break;
130                        default:
131                }
132                return retval;
133        }
134}