For bit of work on JPA perf enhancements
This commit is contained in:
parent
2c9a6e65e7
commit
ce73e89715
|
@ -1,5 +1,7 @@
|
||||||
package ca.uhn.fhir.model.api;
|
package ca.uhn.fhir.model.api;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR - Core Library
|
* HAPI FHIR - Core Library
|
||||||
|
@ -26,7 +28,7 @@ import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
|
||||||
public interface IQueryParameterAnd<T extends IQueryParameterOr<?>> {
|
public interface IQueryParameterAnd<T extends IQueryParameterOr<?>> extends Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package ca.uhn.fhir.model.api;
|
package ca.uhn.fhir.model.api;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR - Core Library
|
* HAPI FHIR - Core Library
|
||||||
|
@ -25,7 +27,7 @@ import java.util.List;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||||
|
|
||||||
public interface IQueryParameterOr<T extends IQueryParameterType> {
|
public interface IQueryParameterOr<T extends IQueryParameterType> extends Serializable {
|
||||||
|
|
||||||
public void setValuesAsQueryTokens(FhirContext theContext, String theParamName, QualifiedParamList theParameters);
|
public void setValuesAsQueryTokens(FhirContext theContext, String theParamName, QualifiedParamList theParameters);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package ca.uhn.fhir.model.api;
|
package ca.uhn.fhir.model.api;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -22,7 +24,7 @@ import ca.uhn.fhir.context.FhirContext;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public interface IQueryParameterType {
|
public interface IQueryParameterType extends Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is generally only called by HAPI itself, and should not need to be called from user code.
|
* This method is generally only called by HAPI itself, and should not need to be called from user code.
|
||||||
|
|
|
@ -952,8 +952,13 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBundleProvider search(final SearchParameterMap theParams) {
|
public IBundleProvider search(final SearchParameterMap theParams) {
|
||||||
|
return search(theParams, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBundleProvider search(final SearchParameterMap theParams, RequestDetails theRequestDetails) {
|
||||||
// Notify interceptors
|
// Notify interceptors
|
||||||
ActionRequestDetails requestDetails = new ActionRequestDetails(theParams.getRequestDetails(), getContext(), getResourceName(), null);
|
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getContext(), getResourceName(), null);
|
||||||
notifyInterceptors(RestOperationTypeEnum.SEARCH_TYPE, requestDetails);
|
notifyInterceptors(RestOperationTypeEnum.SEARCH_TYPE, requestDetails);
|
||||||
|
|
||||||
SearchBuilder builder = new SearchBuilder(getContext(), myEntityManager, myPlatformTransactionManager, mySearchDao, mySearchResultDao, this, myResourceIndexedSearchParamUriDao, myForcedIdDao,
|
SearchBuilder builder = new SearchBuilder(getContext(), myEntityManager, myPlatformTransactionManager, mySearchDao, mySearchResultDao, this, myResourceIndexedSearchParamUriDao, myForcedIdDao,
|
||||||
|
|
|
@ -176,6 +176,8 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
|
||||||
|
|
||||||
IBundleProvider search(SearchParameterMap theMap);
|
IBundleProvider search(SearchParameterMap theMap);
|
||||||
|
|
||||||
|
IBundleProvider search(SearchParameterMap theParams, RequestDetails theRequestDetails);
|
||||||
|
|
||||||
IBundleProvider search(String theParameterName, IQueryParameterType theValue);
|
IBundleProvider search(String theParameterName, IQueryParameterType theValue);
|
||||||
|
|
||||||
Set<Long> searchForIds(Map<String, IQueryParameterType> theParams);
|
Set<Long> searchForIds(Map<String, IQueryParameterType> theParams);
|
||||||
|
|
|
@ -36,6 +36,7 @@ import javax.persistence.TypedQuery;
|
||||||
import javax.persistence.criteria.*;
|
import javax.persistence.criteria.*;
|
||||||
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
import org.apache.commons.lang3.SerializationUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
@ -99,7 +100,8 @@ public class SearchBuilder {
|
||||||
|
|
||||||
private IHapiTerminologySvc myTerminologySvc;
|
private IHapiTerminologySvc myTerminologySvc;
|
||||||
|
|
||||||
public SearchBuilder(FhirContext theFhirContext, EntityManager theEntityManager, PlatformTransactionManager thePlatformTransactionManager, IFulltextSearchSvc theSearchDao, ISearchResultDao theSearchResultDao, BaseHapiFhirDao<?> theDao,
|
public SearchBuilder(FhirContext theFhirContext, EntityManager theEntityManager, PlatformTransactionManager thePlatformTransactionManager, IFulltextSearchSvc theSearchDao,
|
||||||
|
ISearchResultDao theSearchResultDao, BaseHapiFhirDao<?> theDao,
|
||||||
IResourceIndexedSearchParamUriDao theResourceIndexedSearchParamUriDao, IForcedIdDao theForcedIdDao, IHapiTerminologySvc theTerminologySvc, ISearchParamRegistry theSearchParamRegistry) {
|
IResourceIndexedSearchParamUriDao theResourceIndexedSearchParamUriDao, IForcedIdDao theForcedIdDao, IHapiTerminologySvc theTerminologySvc, ISearchParamRegistry theSearchParamRegistry) {
|
||||||
myContext = theFhirContext;
|
myContext = theFhirContext;
|
||||||
myEntityManager = theEntityManager;
|
myEntityManager = theEntityManager;
|
||||||
|
@ -325,7 +327,8 @@ public class SearchBuilder {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean addPredicateMissingFalseIfPresent(CriteriaBuilder theBuilder, String theParamName, Root<? extends BaseResourceIndexedSearchParam> from, List<Predicate> codePredicates, IQueryParameterType nextOr) {
|
private boolean addPredicateMissingFalseIfPresent(CriteriaBuilder theBuilder, String theParamName, Root<? extends BaseResourceIndexedSearchParam> from, List<Predicate> codePredicates,
|
||||||
|
IQueryParameterType nextOr) {
|
||||||
boolean missingFalse = false;
|
boolean missingFalse = false;
|
||||||
if (nextOr.getMissing() != null) {
|
if (nextOr.getMissing() != null) {
|
||||||
if (nextOr.getMissing().booleanValue() == true) {
|
if (nextOr.getMissing().booleanValue() == true) {
|
||||||
|
@ -339,7 +342,8 @@ public class SearchBuilder {
|
||||||
return missingFalse;
|
return missingFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean addPredicateMissingFalseIfPresentForResourceLink(CriteriaBuilder theBuilder, String theParamName, Root<? extends ResourceLink> from, List<Predicate> codePredicates, IQueryParameterType nextOr) {
|
private boolean addPredicateMissingFalseIfPresentForResourceLink(CriteriaBuilder theBuilder, String theParamName, Root<? extends ResourceLink> from, List<Predicate> codePredicates,
|
||||||
|
IQueryParameterType nextOr) {
|
||||||
boolean missingFalse = false;
|
boolean missingFalse = false;
|
||||||
if (nextOr.getMissing() != null) {
|
if (nextOr.getMissing() != null) {
|
||||||
if (nextOr.getMissing().booleanValue() == true) {
|
if (nextOr.getMissing().booleanValue() == true) {
|
||||||
|
@ -1132,7 +1136,8 @@ public class SearchBuilder {
|
||||||
predicates.addAll(createLastUpdatedPredicates(myParams.getLastUpdatedAndRemove(), builder, from));
|
predicates.addAll(createLastUpdatedPredicates(myParams.getLastUpdatedAndRemove(), builder, from));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate createPredicateNumeric(CriteriaBuilder builder, IQueryParameterType params, ParamPrefixEnum cmpValue, BigDecimal valueValue, final Expression<BigDecimal> path, String invalidMessageName, String theValueString) {
|
private Predicate createPredicateNumeric(CriteriaBuilder builder, IQueryParameterType params, ParamPrefixEnum cmpValue, BigDecimal valueValue, final Expression<BigDecimal> path,
|
||||||
|
String invalidMessageName, String theValueString) {
|
||||||
Predicate num;
|
Predicate num;
|
||||||
switch (cmpValue) {
|
switch (cmpValue) {
|
||||||
case GREATERTHAN:
|
case GREATERTHAN:
|
||||||
|
@ -1230,7 +1235,6 @@ public class SearchBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createPredicateResourceId(CriteriaBuilder builder, CriteriaQuery<?> cq, List<Predicate> thePredicates, Expression<Long> theExpression) {
|
private void createPredicateResourceId(CriteriaBuilder builder, CriteriaQuery<?> cq, List<Predicate> thePredicates, Expression<Long> theExpression) {
|
||||||
if (myParams.isPersistResults()) {
|
|
||||||
if (mySearchEntity.getTotalCount() > -1) {
|
if (mySearchEntity.getTotalCount() > -1) {
|
||||||
Subquery<Long> subQ = cq.subquery(Long.class);
|
Subquery<Long> subQ = cq.subquery(Long.class);
|
||||||
Root<SearchResult> subQfrom = subQ.from(SearchResult.class);
|
Root<SearchResult> subQfrom = subQ.from(SearchResult.class);
|
||||||
|
@ -1240,15 +1244,10 @@ public class SearchBuilder {
|
||||||
|
|
||||||
thePredicates.add(theExpression.in(subQ));
|
thePredicates.add(theExpression.in(subQ));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (myPids != null) {
|
|
||||||
thePredicates.add(theExpression.in(myPids));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
private Predicate createPredicateString(IQueryParameterType theParameter, String theParamName, CriteriaBuilder theBuilder,
|
||||||
|
From<ResourceIndexedSearchParamString, ResourceIndexedSearchParamString> theFrom) {
|
||||||
private Predicate createPredicateString(IQueryParameterType theParameter, String theParamName, CriteriaBuilder theBuilder, From<ResourceIndexedSearchParamString, ResourceIndexedSearchParamString> theFrom) {
|
|
||||||
String rawSearchTerm;
|
String rawSearchTerm;
|
||||||
if (theParameter instanceof TokenParam) {
|
if (theParameter instanceof TokenParam) {
|
||||||
TokenParam id = (TokenParam) theParameter;
|
TokenParam id = (TokenParam) theParameter;
|
||||||
|
@ -1267,7 +1266,8 @@ public class SearchBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rawSearchTerm.length() > ResourceIndexedSearchParamString.MAX_LENGTH) {
|
if (rawSearchTerm.length() > ResourceIndexedSearchParamString.MAX_LENGTH) {
|
||||||
throw new InvalidRequestException("Parameter[" + theParamName + "] has length (" + rawSearchTerm.length() + ") that is longer than maximum allowed (" + ResourceIndexedSearchParamString.MAX_LENGTH + "): " + rawSearchTerm);
|
throw new InvalidRequestException("Parameter[" + theParamName + "] has length (" + rawSearchTerm.length() + ") that is longer than maximum allowed ("
|
||||||
|
+ ResourceIndexedSearchParamString.MAX_LENGTH + "): " + rawSearchTerm);
|
||||||
}
|
}
|
||||||
|
|
||||||
String likeExpression = BaseHapiFhirDao.normalizeString(rawSearchTerm);
|
String likeExpression = BaseHapiFhirDao.normalizeString(rawSearchTerm);
|
||||||
|
@ -1297,7 +1297,8 @@ public class SearchBuilder {
|
||||||
return orPredicates;
|
return orPredicates;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate createPredicateToken(IQueryParameterType theParameter, String theParamName, CriteriaBuilder theBuilder, From<ResourceIndexedSearchParamToken, ResourceIndexedSearchParamToken> theFrom) {
|
private Predicate createPredicateToken(IQueryParameterType theParameter, String theParamName, CriteriaBuilder theBuilder,
|
||||||
|
From<ResourceIndexedSearchParamToken, ResourceIndexedSearchParamToken> theFrom) {
|
||||||
String code;
|
String code;
|
||||||
String system;
|
String system;
|
||||||
TokenParamModifier modifier = null;
|
TokenParamModifier modifier = null;
|
||||||
|
@ -1319,11 +1320,13 @@ public class SearchBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (system != null && system.length() > ResourceIndexedSearchParamToken.MAX_LENGTH) {
|
if (system != null && system.length() > ResourceIndexedSearchParamToken.MAX_LENGTH) {
|
||||||
throw new InvalidRequestException("Parameter[" + theParamName + "] has system (" + system.length() + ") that is longer than maximum allowed (" + ResourceIndexedSearchParamToken.MAX_LENGTH + "): " + system);
|
throw new InvalidRequestException(
|
||||||
|
"Parameter[" + theParamName + "] has system (" + system.length() + ") that is longer than maximum allowed (" + ResourceIndexedSearchParamToken.MAX_LENGTH + "): " + system);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code != null && code.length() > ResourceIndexedSearchParamToken.MAX_LENGTH) {
|
if (code != null && code.length() > ResourceIndexedSearchParamToken.MAX_LENGTH) {
|
||||||
throw new InvalidRequestException("Parameter[" + theParamName + "] has code (" + code.length() + ") that is longer than maximum allowed (" + ResourceIndexedSearchParamToken.MAX_LENGTH + "): " + code);
|
throw new InvalidRequestException(
|
||||||
|
"Parameter[" + theParamName + "] has code (" + code.length() + ") that is longer than maximum allowed (" + ResourceIndexedSearchParamToken.MAX_LENGTH + "): " + code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1533,25 +1536,16 @@ public class SearchBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Long> doGetPids() {
|
public Set<Long> doGetPids() {
|
||||||
if (myParams.isPersistResults()) {
|
|
||||||
HashSet<Long> retVal = new HashSet<Long>();
|
HashSet<Long> retVal = new HashSet<Long>();
|
||||||
|
|
||||||
for (SearchResult next : mySearchResultDao.findWithSearchUuid(mySearchEntity)) {
|
for (SearchResult next : mySearchResultDao.findWithSearchUuid(mySearchEntity)) {
|
||||||
retVal.add(next.getResourcePid());
|
retVal.add(next.getResourcePid());
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
|
|
||||||
} else {
|
|
||||||
return new HashSet<Long>(myPids);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean doHaveNoResults() {
|
private boolean doHaveNoResults() {
|
||||||
if (myParams.isPersistResults()) {
|
|
||||||
return mySearchEntity.getTotalCount() == 0;
|
return mySearchEntity.getTotalCount() == 0;
|
||||||
} else {
|
|
||||||
return myPids != null && myPids.isEmpty();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doInitializeSearch() {
|
private void doInitializeSearch() {
|
||||||
|
@ -1561,19 +1555,10 @@ public class SearchBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private IBundleProvider doReturnProvider() {
|
private IBundleProvider doReturnProvider() {
|
||||||
if (myParams.isPersistResults()) {
|
|
||||||
return new PersistedJpaBundleProvider(mySearchEntity.getUuid(), myCallingDao);
|
return new PersistedJpaBundleProvider(mySearchEntity.getUuid(), myCallingDao);
|
||||||
} else {
|
|
||||||
if (myPids == null) {
|
|
||||||
return new SimpleBundleProvider();
|
|
||||||
} else {
|
|
||||||
return new BundleProviderInMemory(myPids);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doSetPids(Collection<Long> thePids) {
|
private void doSetPids(Collection<Long> thePids) {
|
||||||
if (myParams.isPersistResults()) {
|
|
||||||
if (mySearchEntity.getTotalCount() != null) {
|
if (mySearchEntity.getTotalCount() != null) {
|
||||||
reinitializeSearch();
|
reinitializeSearch();
|
||||||
}
|
}
|
||||||
|
@ -1593,10 +1578,6 @@ public class SearchBuilder {
|
||||||
mySearchEntity = myEntityManager.merge(mySearchEntity);
|
mySearchEntity = myEntityManager.merge(mySearchEntity);
|
||||||
|
|
||||||
myEntityManager.flush();
|
myEntityManager.flush();
|
||||||
|
|
||||||
} else {
|
|
||||||
myPids = thePids;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void filterResourceIdsByLastUpdated(final DateRangeParam theLastUpdated) {
|
private void filterResourceIdsByLastUpdated(final DateRangeParam theLastUpdated) {
|
||||||
|
@ -1675,6 +1656,7 @@ public class SearchBuilder {
|
||||||
mySearchEntity.setUuid(UUID.randomUUID().toString());
|
mySearchEntity.setUuid(UUID.randomUUID().toString());
|
||||||
mySearchEntity.setCreated(new Date());
|
mySearchEntity.setCreated(new Date());
|
||||||
mySearchEntity.setTotalCount(-1);
|
mySearchEntity.setTotalCount(-1);
|
||||||
|
mySearchEntity.setSearchParamMap(SerializationUtils.serialize(myParams));
|
||||||
mySearchEntity.setPreferredPageSize(myParams.getCount());
|
mySearchEntity.setPreferredPageSize(myParams.getCount());
|
||||||
mySearchEntity.setSearchType(myParams.getEverythingMode() != null ? SearchTypeEnum.EVERYTHING : SearchTypeEnum.SEARCH);
|
mySearchEntity.setSearchType(myParams.getEverythingMode() != null ? SearchTypeEnum.EVERYTHING : SearchTypeEnum.SEARCH);
|
||||||
mySearchEntity.setLastUpdated(myParams.getLastUpdated());
|
mySearchEntity.setLastUpdated(myParams.getLastUpdated());
|
||||||
|
@ -1686,13 +1668,11 @@ public class SearchBuilder {
|
||||||
mySearchEntity.getIncludes().add(new SearchInclude(mySearchEntity, next.getValue(), true, next.isRecurse()));
|
mySearchEntity.getIncludes().add(new SearchInclude(mySearchEntity, next.getValue(), true, next.isRecurse()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myParams.isPersistResults()) {
|
|
||||||
myEntityManager.persist(mySearchEntity);
|
myEntityManager.persist(mySearchEntity);
|
||||||
for (SearchInclude next : mySearchEntity.getIncludes()) {
|
for (SearchInclude next : mySearchEntity.getIncludes()) {
|
||||||
myEntityManager.persist(next);
|
myEntityManager.persist(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public IBundleProvider search(final SearchParameterMap theParams) {
|
public IBundleProvider search(final SearchParameterMap theParams) {
|
||||||
myParams = theParams;
|
myParams = theParams;
|
||||||
|
@ -2038,7 +2018,8 @@ public class SearchBuilder {
|
||||||
return likeExpression.replace("%", "[%]") + "%";
|
return likeExpression.replace("%", "[%]") + "%";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Predicate createResourceLinkPathPredicate(IDao theCallingDao, FhirContext theContext, String theParamName, Root<? extends ResourceLink> from, Class<? extends IBaseResource> resourceType) {
|
private static Predicate createResourceLinkPathPredicate(IDao theCallingDao, FhirContext theContext, String theParamName, Root<? extends ResourceLink> from,
|
||||||
|
Class<? extends IBaseResource> resourceType) {
|
||||||
RuntimeResourceDefinition resourceDef = theContext.getResourceDefinition(resourceType);
|
RuntimeResourceDefinition resourceDef = theContext.getResourceDefinition(resourceType);
|
||||||
RuntimeSearchParam param = theCallingDao.getSearchParamByName(resourceDef, theParamName);
|
RuntimeSearchParam param = theCallingDao.getSearchParamByName(resourceDef, theParamName);
|
||||||
List<String> path = param.getPathsSplit();
|
List<String> path = param.getPathsSplit();
|
||||||
|
@ -2062,7 +2043,8 @@ public class SearchBuilder {
|
||||||
return resultList;
|
return resultList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadResourcesByPid(Collection<Long> theIncludePids, List<IBaseResource> theResourceListToPopulate, Set<Long> theRevIncludedPids, boolean theForHistoryOperation, EntityManager entityManager, FhirContext context, IDao theDao) {
|
public static void loadResourcesByPid(Collection<Long> theIncludePids, List<IBaseResource> theResourceListToPopulate, Set<Long> theRevIncludedPids, boolean theForHistoryOperation,
|
||||||
|
EntityManager entityManager, FhirContext context, IDao theDao) {
|
||||||
if (theIncludePids.isEmpty()) {
|
if (theIncludePids.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2111,7 +2093,8 @@ public class SearchBuilder {
|
||||||
*
|
*
|
||||||
* @param theLastUpdated
|
* @param theLastUpdated
|
||||||
*/
|
*/
|
||||||
public static HashSet<Long> loadReverseIncludes(IDao theCallingDao, FhirContext theContext, EntityManager theEntityManager, Collection<Long> theMatches, Set<Include> theRevIncludes, boolean theReverseMode, DateRangeParam theLastUpdated) {
|
public static HashSet<Long> loadReverseIncludes(IDao theCallingDao, FhirContext theContext, EntityManager theEntityManager, Collection<Long> theMatches, Set<Include> theRevIncludes,
|
||||||
|
boolean theReverseMode, DateRangeParam theLastUpdated) {
|
||||||
if (theMatches.size() == 0) {
|
if (theMatches.size() == 0) {
|
||||||
return new HashSet<Long>();
|
return new HashSet<Long>();
|
||||||
}
|
}
|
||||||
|
@ -2253,65 +2236,4 @@ public class SearchBuilder {
|
||||||
return thePredicates.toArray(new Predicate[thePredicates.size()]);
|
return thePredicates.toArray(new Predicate[thePredicates.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class BundleProviderInMemory implements IBundleProvider {
|
|
||||||
private final ArrayList<Long> myPids;
|
|
||||||
|
|
||||||
private BundleProviderInMemory(Collection<Long> thePids) {
|
|
||||||
final ArrayList<Long> pids;
|
|
||||||
if (!(thePids instanceof List)) {
|
|
||||||
pids = new ArrayList<Long>(thePids);
|
|
||||||
} else {
|
|
||||||
pids = (ArrayList<Long>) thePids;
|
|
||||||
}
|
|
||||||
myPids = pids;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InstantDt getPublished() {
|
|
||||||
return new InstantDt(mySearchEntity.getCreated());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<IBaseResource> getResources(final int theFromIndex, final int theToIndex) {
|
|
||||||
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
|
||||||
return template.execute(new TransactionCallback<List<IBaseResource>>() {
|
|
||||||
@Override
|
|
||||||
public List<IBaseResource> doInTransaction(TransactionStatus theStatus) {
|
|
||||||
List<Long> pidsSubList = myPids.subList(theFromIndex, theToIndex);
|
|
||||||
|
|
||||||
// Load includes
|
|
||||||
pidsSubList = new ArrayList<Long>(pidsSubList);
|
|
||||||
|
|
||||||
Set<Long> revIncludedPids = new HashSet<Long>();
|
|
||||||
if (myParams.getEverythingMode() == null) {
|
|
||||||
revIncludedPids.addAll(loadReverseIncludes(myCallingDao, myContext, myEntityManager, pidsSubList, myParams.getRevIncludes(), true, myParams.getLastUpdated()));
|
|
||||||
}
|
|
||||||
revIncludedPids.addAll(loadReverseIncludes(myCallingDao, myContext, myEntityManager, pidsSubList, myParams.getIncludes(), false, myParams.getLastUpdated()));
|
|
||||||
|
|
||||||
// Execute the query and make sure we return distinct results
|
|
||||||
List<IBaseResource> resources = new ArrayList<IBaseResource>();
|
|
||||||
loadResourcesByPid(pidsSubList, resources, revIncludedPids, false);
|
|
||||||
|
|
||||||
return resources;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer preferredPageSize() {
|
|
||||||
return myParams.getCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return myPids.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUuid() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package ca.uhn.fhir.jpa.dao;
|
package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR JPA Server
|
* HAPI FHIR JPA Server
|
||||||
|
@ -38,7 +40,7 @@ import ca.uhn.fhir.rest.method.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
|
|
||||||
public class SearchParameterMap extends LinkedHashMap<String, List<List<? extends IQueryParameterType>>> {
|
public class SearchParameterMap extends LinkedHashMap<String, List<List<? extends IQueryParameterType>>> implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@ -46,8 +48,6 @@ public class SearchParameterMap extends LinkedHashMap<String, List<List<? extend
|
||||||
private EverythingModeEnum myEverythingMode = null;
|
private EverythingModeEnum myEverythingMode = null;
|
||||||
private Set<Include> myIncludes;
|
private Set<Include> myIncludes;
|
||||||
private DateRangeParam myLastUpdated;
|
private DateRangeParam myLastUpdated;
|
||||||
private boolean myPersistResults = true;
|
|
||||||
private RequestDetails myRequestDetails;
|
|
||||||
private Set<Include> myRevIncludes;
|
private Set<Include> myRevIncludes;
|
||||||
private SortSpec mySort;
|
private SortSpec mySort;
|
||||||
|
|
||||||
|
@ -137,10 +137,6 @@ public class SearchParameterMap extends LinkedHashMap<String, List<List<? extend
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RequestDetails getRequestDetails() {
|
|
||||||
return myRequestDetails;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Include> getRevIncludes() {
|
public Set<Include> getRevIncludes() {
|
||||||
if (myRevIncludes == null) {
|
if (myRevIncludes == null) {
|
||||||
myRevIncludes = new HashSet<Include>();
|
myRevIncludes = new HashSet<Include>();
|
||||||
|
@ -152,10 +148,6 @@ public class SearchParameterMap extends LinkedHashMap<String, List<List<? extend
|
||||||
return mySort;
|
return mySort;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPersistResults() {
|
|
||||||
return myPersistResults;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCount(Integer theCount) {
|
public void setCount(Integer theCount) {
|
||||||
myCount = theCount;
|
myCount = theCount;
|
||||||
}
|
}
|
||||||
|
@ -173,14 +165,11 @@ public class SearchParameterMap extends LinkedHashMap<String, List<List<? extend
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should results be persisted into a table for paging
|
* @deprecated As of HAPI FHIR 2.4 this method no longer does anything
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public void setPersistResults(boolean thePersistResults) {
|
public void setPersistResults(boolean thePersistResults) {
|
||||||
myPersistResults = thePersistResults;
|
// does nothing as of HAPI FHIR 2.4
|
||||||
}
|
|
||||||
|
|
||||||
public void setRequestDetails(RequestDetails theRequestDetails) {
|
|
||||||
myRequestDetails = theRequestDetails;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRevIncludes(Set<Include> theRevIncludes) {
|
public void setRevIncludes(Set<Include> theRevIncludes) {
|
||||||
|
|
|
@ -28,20 +28,7 @@ import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.*;
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.EnumType;
|
|
||||||
import javax.persistence.Enumerated;
|
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.GenerationType;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.Index;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import javax.persistence.SequenceGenerator;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
import javax.persistence.Temporal;
|
|
||||||
import javax.persistence.TemporalType;
|
|
||||||
import javax.persistence.UniqueConstraint;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.Include;
|
import ca.uhn.fhir.model.api.Include;
|
||||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||||
|
@ -91,6 +78,10 @@ public class Search implements Serializable {
|
||||||
@OneToMany(mappedBy="mySearch")
|
@OneToMany(mappedBy="mySearch")
|
||||||
private Collection<SearchResult> myResults;
|
private Collection<SearchResult> myResults;
|
||||||
|
|
||||||
|
@Lob
|
||||||
|
@Column(name="SEARCH_PARAM_MAP", nullable=true)
|
||||||
|
private byte[] mySearchParamMap;
|
||||||
|
|
||||||
@Enumerated(EnumType.ORDINAL)
|
@Enumerated(EnumType.ORDINAL)
|
||||||
@Column(name="SEARCH_TYPE", nullable=false)
|
@Column(name="SEARCH_TYPE", nullable=false)
|
||||||
private SearchTypeEnum mySearchType;
|
private SearchTypeEnum mySearchType;
|
||||||
|
@ -116,14 +107,6 @@ public class Search implements Serializable {
|
||||||
return myIncludes;
|
return myIncludes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getLastUpdatedHigh() {
|
|
||||||
return myLastUpdatedHigh;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getLastUpdatedLow() {
|
|
||||||
return myLastUpdatedLow;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DateRangeParam getLastUpdated() {
|
public DateRangeParam getLastUpdated() {
|
||||||
if (myLastUpdatedLow == null && myLastUpdatedHigh == null) {
|
if (myLastUpdatedLow == null && myLastUpdatedHigh == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -132,6 +115,14 @@ public class Search implements Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Date getLastUpdatedHigh() {
|
||||||
|
return myLastUpdatedHigh;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getLastUpdatedLow() {
|
||||||
|
return myLastUpdatedLow;
|
||||||
|
}
|
||||||
|
|
||||||
public Integer getPreferredPageSize() {
|
public Integer getPreferredPageSize() {
|
||||||
return myPreferredPageSize;
|
return myPreferredPageSize;
|
||||||
}
|
}
|
||||||
|
@ -144,15 +135,19 @@ public class Search implements Serializable {
|
||||||
return myResourceType;
|
return myResourceType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] getSearchParamMap() {
|
||||||
|
return mySearchParamMap;
|
||||||
|
}
|
||||||
|
|
||||||
public SearchTypeEnum getSearchType() {
|
public SearchTypeEnum getSearchType() {
|
||||||
return mySearchType;
|
return mySearchType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Integer getTotalCount() {
|
public Integer getTotalCount() {
|
||||||
return myTotalCount;
|
return myTotalCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getUuid() {
|
public String getUuid() {
|
||||||
return myUuid;
|
return myUuid;
|
||||||
}
|
}
|
||||||
|
@ -160,11 +155,11 @@ public class Search implements Serializable {
|
||||||
public void setCreated(Date theCreated) {
|
public void setCreated(Date theCreated) {
|
||||||
myCreated = theCreated;
|
myCreated = theCreated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastUpdated(Date theLowerBound, Date theUpperBound) {
|
public void setLastUpdated(Date theLowerBound, Date theUpperBound) {
|
||||||
myLastUpdatedLow = theLowerBound;
|
myLastUpdatedLow = theLowerBound;
|
||||||
myLastUpdatedHigh = theUpperBound;
|
myLastUpdatedHigh = theUpperBound;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastUpdated(DateRangeParam theLastUpdated) {
|
public void setLastUpdated(DateRangeParam theLastUpdated) {
|
||||||
if (theLastUpdated == null) {
|
if (theLastUpdated == null) {
|
||||||
myLastUpdatedLow = null;
|
myLastUpdatedLow = null;
|
||||||
|
@ -183,11 +178,15 @@ public class Search implements Serializable {
|
||||||
myResourceId = theResourceId;
|
myResourceId = theResourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setResourceType(String theResourceType) {
|
public void setResourceType(String theResourceType) {
|
||||||
myResourceType = theResourceType;
|
myResourceType = theResourceType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setSearchParamMap(byte[] theSearchParamMap) {
|
||||||
|
mySearchParamMap = theSearchParamMap;
|
||||||
|
}
|
||||||
|
|
||||||
public void setSearchType(SearchTypeEnum theSearchType) {
|
public void setSearchType(SearchTypeEnum theSearchType) {
|
||||||
mySearchType = theSearchType;
|
mySearchType = theSearchType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,11 +152,10 @@ public class ${className}ResourceProvider extends
|
||||||
paramMap.setIncludes(theIncludes);
|
paramMap.setIncludes(theIncludes);
|
||||||
paramMap.setSort(theSort);
|
paramMap.setSort(theSort);
|
||||||
paramMap.setCount(theCount);
|
paramMap.setCount(theCount);
|
||||||
paramMap.setRequestDetails(theRequestDetails);
|
|
||||||
|
|
||||||
getDao().translateRawParameters(theAdditionalRawParams, paramMap);
|
getDao().translateRawParameters(theAdditionalRawParams, paramMap);
|
||||||
|
|
||||||
ca.uhn.fhir.rest.server.IBundleProvider retVal = getDao().search(paramMap);
|
ca.uhn.fhir.rest.server.IBundleProvider retVal = getDao().search(paramMap, theRequestDetails);
|
||||||
return retVal;
|
return retVal;
|
||||||
} finally {
|
} finally {
|
||||||
endRequest(theServletRequest);
|
endRequest(theServletRequest);
|
||||||
|
|
Loading…
Reference in New Issue