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.builder; 021 022import ca.uhn.fhir.jpa.model.dao.JpaPid; 023import ca.uhn.fhir.jpa.search.builder.models.ResolvedSearchQueryExecutor; 024import jakarta.annotation.Nonnull; 025import org.apache.commons.lang3.Validate; 026 027import java.util.Iterator; 028import java.util.List; 029 030public class SearchQueryExecutors { 031 032 public static ISearchQueryExecutor limited(ISearchQueryExecutor theExecutor, long theLimit) { 033 Validate.isTrue(theLimit >= 0, "limit must be non-negative"); 034 035 return new ISearchQueryExecutor() { 036 long myCount = 0; 037 038 @Override 039 public void close() { 040 theExecutor.close(); 041 } 042 043 @Override 044 public boolean hasNext() { 045 return theExecutor.hasNext() && myCount < theLimit; 046 } 047 048 @Override 049 public Long next() { 050 myCount += 1; 051 return theExecutor.next(); 052 } 053 }; 054 } 055 056 @Nonnull 057 public static ISearchQueryExecutor from(List<Long> rawPids) { 058 return new ResolvedSearchQueryExecutor(rawPids); 059 } 060 061 public static ISearchQueryExecutor from(Iterator<JpaPid> theIterator) { 062 return new JpaPidQueryAdaptor(theIterator); 063 } 064 065 public static ISearchQueryExecutor from(Iterable<JpaPid> theIterable) { 066 return new JpaPidQueryAdaptor(theIterable.iterator()); 067 } 068 069 static class JpaPidQueryAdaptor implements ISearchQueryExecutor { 070 final Iterator<JpaPid> myIterator; 071 072 JpaPidQueryAdaptor(Iterator<JpaPid> theIterator) { 073 myIterator = theIterator; 074 } 075 076 @Override 077 public void close() {} 078 079 @Override 080 public boolean hasNext() { 081 return myIterator.hasNext(); 082 } 083 084 @Override 085 public Long next() { 086 JpaPid next = myIterator.next(); 087 return next == null ? null : next.getId(); 088 } 089 } 090}