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.search.cache; 021 022import ca.uhn.fhir.interceptor.model.RequestPartitionId; 023import ca.uhn.fhir.jpa.dao.data.ISearchResultDao; 024import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService; 025import ca.uhn.fhir.jpa.entity.Search; 026import ca.uhn.fhir.jpa.entity.SearchResult; 027import ca.uhn.fhir.jpa.model.dao.JpaPid; 028import ca.uhn.fhir.rest.api.server.RequestDetails; 029import com.google.common.collect.Lists; 030import org.slf4j.Logger; 031import org.slf4j.LoggerFactory; 032import org.springframework.beans.factory.annotation.Autowired; 033import org.springframework.data.domain.Pageable; 034 035import java.util.Collections; 036import java.util.List; 037 038import static ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl.toPage; 039 040public class DatabaseSearchResultCacheSvcImpl implements ISearchResultCacheSvc { 041 private static final Logger ourLog = LoggerFactory.getLogger(DatabaseSearchResultCacheSvcImpl.class); 042 043 @Autowired 044 private ISearchResultDao mySearchResultDao; 045 046 @Autowired 047 private IHapiTransactionService myTransactionService; 048 049 @Override 050 public List<JpaPid> fetchResultPids( 051 Search theSearch, 052 int theFrom, 053 int theTo, 054 RequestDetails theRequestDetails, 055 RequestPartitionId theRequestPartitionId) { 056 return myTransactionService 057 .withRequest(theRequestDetails) 058 .withRequestPartitionId(theRequestPartitionId) 059 .execute(() -> { 060 final Pageable page = toPage(theFrom, theTo); 061 if (page == null) { 062 return Collections.emptyList(); 063 } 064 065 List<Long> retVal = mySearchResultDao 066 .findWithSearchPid(theSearch.getId(), page) 067 .getContent(); 068 069 ourLog.debug("fetchResultPids for range {}-{} returned {} pids", theFrom, theTo, retVal.size()); 070 071 return ISearchResultDao.toJpaPidList(retVal); 072 }); 073 } 074 075 @Override 076 public List<JpaPid> fetchAllResultPids( 077 Search theSearch, RequestDetails theRequestDetails, RequestPartitionId theRequestPartitionId) { 078 return myTransactionService 079 .withRequest(theRequestDetails) 080 .withRequestPartitionId(theRequestPartitionId) 081 .execute(() -> { 082 List<Long> retVal = mySearchResultDao.findWithSearchPidOrderIndependent(theSearch.getId()); 083 ourLog.trace("fetchAllResultPids returned {} pids", retVal.size()); 084 return ISearchResultDao.toJpaPidList(retVal); 085 }); 086 } 087 088 @Override 089 public void storeResults( 090 Search theSearch, 091 List<JpaPid> thePreviouslyStoredResourcePids, 092 List<JpaPid> theNewResourcePids, 093 RequestDetails theRequestDetails, 094 RequestPartitionId theRequestPartitionId) { 095 myTransactionService 096 .withRequest(theRequestDetails) 097 .withRequestPartitionId(theRequestPartitionId) 098 .execute(() -> { 099 List<SearchResult> resultsToSave = Lists.newArrayList(); 100 101 ourLog.debug( 102 "Storing {} results with {} previous for search", 103 theNewResourcePids.size(), 104 thePreviouslyStoredResourcePids.size()); 105 106 int order = thePreviouslyStoredResourcePids.size(); 107 for (JpaPid nextPid : theNewResourcePids) { 108 SearchResult nextResult = new SearchResult(theSearch); 109 nextResult.setResourcePid(nextPid.getId()); 110 nextResult.setOrder(order); 111 resultsToSave.add(nextResult); 112 ourLog.trace("Saving ORDER[{}] Resource {}", order, nextResult.getResourcePid()); 113 114 order++; 115 } 116 117 mySearchResultDao.saveAll(resultsToSave); 118 }); 119 } 120}