001/*- 002 * #%L 003 * HAPI FHIR JPA Server 004 * %% 005 * Copyright (C) 2014 - 2025 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.term.api; 021 022import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao; 023import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao; 024import ca.uhn.fhir.jpa.dao.data.ITermConceptDao; 025import ca.uhn.fhir.jpa.dao.data.ITermConceptDesignationDao; 026import ca.uhn.fhir.jpa.dao.data.ITermConceptParentChildLinkDao; 027import ca.uhn.fhir.jpa.dao.data.ITermConceptPropertyDao; 028import ca.uhn.fhir.jpa.entity.TermCodeSystem; 029import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion; 030import ca.uhn.fhir.jpa.model.entity.IdAndPartitionId; 031import ca.uhn.fhir.jpa.term.models.CodeSystemConceptsDeleteResult; 032import org.slf4j.Logger; 033import org.slf4j.LoggerFactory; 034import org.springframework.beans.factory.annotation.Autowired; 035import org.springframework.transaction.annotation.Transactional; 036 037import java.text.DecimalFormat; 038import java.util.Collections; 039import java.util.Iterator; 040import java.util.List; 041import java.util.Optional; 042import java.util.stream.Collectors; 043 044@Transactional 045public class TermCodeSystemDeleteJobSvc implements ITermCodeSystemDeleteJobSvc { 046 private static final Logger ourLog = LoggerFactory.getLogger(TermCodeSystemDeleteJobSvc.class); 047 048 private static final DecimalFormat ourDecimalFormat = new DecimalFormat("#,###"); 049 050 @Autowired 051 private ITermConceptDao myConceptDao; 052 053 @Autowired 054 private ITermCodeSystemDao myCodeSystemDao; 055 056 @Autowired 057 private ITermCodeSystemVersionDao myTermCodeSystemVersionDao; 058 059 @Autowired 060 private ITermConceptParentChildLinkDao myConceptParentChildLinkDao; 061 062 @Autowired 063 private ITermConceptPropertyDao myConceptPropertyDao; 064 065 @Autowired 066 private ITermConceptDesignationDao myConceptDesignationDao; 067 068 @Autowired 069 private ITermCodeSystemDao myTermCodeSystemDao; 070 071 @Autowired 072 private ITermDeferredStorageSvc myDeferredStorageSvc; 073 074 @Override 075 public Iterator<IdAndPartitionId> getAllCodeSystemVersionForCodeSystemPid(long thePid) { 076 // TODO - make this a pageable iterator 077 List<Object[]> pids = myTermCodeSystemVersionDao.findSortedPidsByCodeSystemPid(thePid); 078 079 if (pids == null) { 080 return Collections.emptyIterator(); 081 } 082 083 return pids.stream() 084 .map(t -> new IdAndPartitionId((Long) t[1], (Integer) t[0])) 085 .collect(Collectors.toList()) 086 .iterator(); 087 } 088 089 @Override 090 public CodeSystemConceptsDeleteResult deleteCodeSystemConceptsByCodeSystemVersionPid(long theCodeSystemVersionPid) { 091 CodeSystemConceptsDeleteResult result = new CodeSystemConceptsDeleteResult(); 092 093 // code system links delete 094 ourLog.info("Deleting term code links"); 095 int deletedLinks = myConceptParentChildLinkDao.deleteByCodeSystemVersion(theCodeSystemVersionPid); 096 ourLog.info("Deleted {} term code links", ourDecimalFormat.format(deletedLinks)); 097 result.setDeletedLinks(deletedLinks); 098 099 // code system concept properties 100 ourLog.info("Deleting term code properties"); 101 int deletedProperties = myConceptPropertyDao.deleteByCodeSystemVersion(theCodeSystemVersionPid); 102 ourLog.info("Deleted {} term code properties", ourDecimalFormat.format(deletedProperties)); 103 result.setDeletedProperties(deletedProperties); 104 105 // code system concept designations 106 ourLog.info("Deleting concept designations"); 107 int deletedDesignations = myConceptDesignationDao.deleteByCodeSystemVersion(theCodeSystemVersionPid); 108 ourLog.info("Deleted {} concept designations", ourDecimalFormat.format(deletedDesignations)); 109 result.setDeletedDesignations(deletedDesignations); 110 111 // code system concept 112 ourLog.info("Deleting concepts"); 113 int deletedConcepts = myConceptDao.deleteByCodeSystemVersion(theCodeSystemVersionPid); 114 ourLog.info("Deleted {} concepts", ourDecimalFormat.format(deletedConcepts)); 115 result.setCodeSystemConceptDelete(deletedConcepts); 116 117 return result; 118 } 119 120 @Override 121 public void deleteCodeSystemVersion(long theVersionPid) { 122 ourLog.debug("Executing for codeSystemVersionId: {}", theVersionPid); 123 124 // if TermCodeSystemVersion being deleted is current, disconnect it form TermCodeSystem 125 Optional<TermCodeSystem> codeSystemOpt = 126 myCodeSystemDao.findWithCodeSystemVersionAsCurrentVersion(theVersionPid); 127 if (codeSystemOpt.isPresent()) { 128 TermCodeSystem codeSystem = codeSystemOpt.get(); 129 ourLog.info( 130 "Removing code system version: {} as current version of code system: {}", 131 theVersionPid, 132 codeSystem.getPid()); 133 codeSystem.setCurrentVersion(null); 134 myCodeSystemDao.save(codeSystem); 135 } 136 137 ourLog.info("Deleting code system version: {}", theVersionPid); 138 Optional<TermCodeSystemVersion> csv = myTermCodeSystemVersionDao.findByPid(theVersionPid); 139 csv.ifPresent(theTermCodeSystemVersion -> { 140 myTermCodeSystemVersionDao.delete(theTermCodeSystemVersion); 141 ourLog.info("Code system version: {} deleted", theVersionPid); 142 }); 143 } 144 145 @Override 146 public void deleteCodeSystem(long thePid) { 147 ourLog.info("Deleting code system by id : {}", thePid); 148 149 Optional<TermCodeSystem> csop = myTermCodeSystemDao.findByPid(thePid); 150 if (csop.isPresent()) { 151 TermCodeSystem cs = csop.get(); 152 153 ourLog.info("Deleting code system {} / {}", thePid, cs.getCodeSystemUri()); 154 155 myTermCodeSystemDao.deleteById(cs.getPartitionedId()); 156 157 ourLog.info("Code system {} deleted", thePid); 158 } 159 } 160 161 @Override 162 public void notifyJobComplete(String theJobId) { 163 myDeferredStorageSvc.notifyJobEnded(theJobId); 164 } 165}