001package ca.uhn.fhir.jpa.batch.reader;
002
003/*-
004 * #%L
005 * HAPI FHIR JPA Server
006 * %%
007 * Copyright (C) 2014 - 2022 Smile CDR, Inc.
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
024import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
025import ca.uhn.fhir.jpa.dao.IResultIterator;
026import ca.uhn.fhir.jpa.searchparam.ResourceSearch;
027import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
028import org.hl7.fhir.instance.model.api.IBaseResource;
029import org.springframework.beans.factory.annotation.Autowired;
030
031import java.util.LinkedHashSet;
032import java.util.List;
033import java.util.Set;
034import java.util.stream.Collectors;
035
036
037public class ReverseCronologicalBatchResourcePidReader extends BaseReverseCronologicalBatchPidReader {
038        @Autowired
039        private DaoRegistry myDaoRegistry;
040        @Autowired
041        private BatchResourceSearcher myBatchResourceSearcher;
042
043        @Override
044        protected Set<Long> getNextPidBatch(ResourceSearch resourceSearch) {
045                Set<Long> retval = new LinkedHashSet<>();
046                addDateCountAndSortToSearch(resourceSearch);
047
048                // Perform the search
049                Integer batchSize = getBatchSize();
050                IResultIterator resultIter = myBatchResourceSearcher.performSearch(resourceSearch, batchSize);
051                Set<Long> alreadySeenPids = getAlreadySeenPids();
052
053                do {
054                        List<Long> pids = resultIter.getNextResultBatch(batchSize).stream().map(ResourcePersistentId::getIdAsLong).collect(Collectors.toList());
055                        retval.addAll(pids);
056                        retval.removeAll(alreadySeenPids);
057                } while (retval.size() < batchSize && resultIter.hasNext());
058
059                return retval;
060        }
061
062        @Override
063        protected void setDateFromPidFunction(ResourceSearch resourceSearch) {
064                final IFhirResourceDao dao = myDaoRegistry.getResourceDao(resourceSearch.getResourceName());
065
066                setDateExtractorFunction(pid -> {
067                        IBaseResource oldestResource = dao.readByPid(new ResourcePersistentId(pid));
068                        return oldestResource.getMeta().getLastUpdated();
069                });
070        }
071}