Make quantity indexes use double datatype (#2290)
* Make quantity indexes use double datatype * Add changelog * Test fixes * Test fixes * Disable test
This commit is contained in:
parent
24ac055b50
commit
1dc4fb2206
|
@ -23,6 +23,7 @@ package ca.uhn.fhir.rest.param;
|
|||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.base.composite.BaseQuantityDt;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
@ -301,4 +302,22 @@ public class QuantityParam extends BaseParamWithPrefix<QuantityParam> implements
|
|||
return b.toString();
|
||||
}
|
||||
|
||||
public static QuantityParam toQuantityParam(IQueryParameterType theParam) {
|
||||
if (theParam instanceof BaseQuantityDt) {
|
||||
BaseQuantityDt param = (BaseQuantityDt) theParam;
|
||||
String systemValue = param.getSystemElement().getValueAsString();
|
||||
String unitsValue = param.getUnitsElement().getValueAsString();
|
||||
ParamPrefixEnum cmpValue = ParamPrefixEnum.forValue(param.getComparatorElement().getValueAsString());
|
||||
BigDecimal valueValue = param.getValueElement().getValue();
|
||||
return new QuantityParam()
|
||||
.setSystem(systemValue)
|
||||
.setUnits(unitsValue)
|
||||
.setPrefix(cmpValue)
|
||||
.setValue(valueValue);
|
||||
} else if (theParam instanceof QuantityParam) {
|
||||
return (QuantityParam) theParam;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid quantity type: " + theParam.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
type: change
|
||||
issue: 2290
|
||||
title: "In the JPA server. the SQL datatype used to index quantities has been changed from `NUMBER(19,2)` to
|
||||
`double precision` (or equivalents depending on platform). This improves the query support for ssearching on
|
||||
very small quantities."
|
|
@ -2,18 +2,18 @@
|
|||
- item:
|
||||
type: "add"
|
||||
title: "The version of a few dependencies have been bumped to the latest versions
|
||||
(dependent HAPI modules listed in brackets):
|
||||
<ul>
|
||||
<li>SLF4j (All Modules): 1.7.28 -> 1.7.30</li>
|
||||
<li>Woodstox (XML FHIR Parser): 4.4.1 -> 6.2.3 (Note that the Maven groupId has changed from <code>org.codehaus.woodstox</code> to <code>com.fasterxml.woodstox</code> and the Maven artifactId has changed from <code>woodstox-core-asl</code> to <code>woodstox-core</code> for this library)</li>
|
||||
<li>Spring (JPA): 5.2.3.RELEASE -> 5.2.9.RELEASE</li>
|
||||
<li>Datasource-Proxy (JPA): 1.5.1 -> 1.7</li>
|
||||
<li>Jetty (JPA Starter): 9.4.30.v20200611 -> 9.4.35.v20201120</li>
|
||||
<li>Guava (JP): 29.0-jre -> 30.1-jre</li>
|
||||
<li>Hibernate ORM (JPA Server): 5.4.22.FINAL -> 5.4.26.FINAL</li>
|
||||
<li>Spring (JPA Server): 5.2.9.RELEASE -> 5.3.2</li>
|
||||
<li>Spring Data (JPA Server): 2.2.0.RELEASE -> 2.4.2</li>
|
||||
<li>Hibernate Search (JPA Server): 5.11.5.FINAL -> 6.0.0.Final</li>
|
||||
<li>Lucene(HAPI FHIR JPA Server): 5.5.5 -> 8.7.0</li>
|
||||
<li>Spring Boot (JPA Starter): 2.2.6.RELEASE -> 2.4.1</li>
|
||||
</ul>"
|
||||
(dependent HAPI modules listed in brackets):
|
||||
* SLF4j (All Modules): 1.7.28 -> 1.7.30
|
||||
* Jackson (All Modules): 2.11.2 -> 2.12.1
|
||||
* Woodstox (XML FHIR Parser): 4.4.1 -> 6.2.3 (Note that the Maven groupId has changed from `org.codehaus.woodstox` to `com.fasterxml.woodstox` and the Maven artifactId has changed from `woodstox-core-asl` to `woodstox-core` for this library)
|
||||
* Spring (JPA): 5.2.3.RELEASE -> 5.2.9.RELEASE
|
||||
* Datasource-Proxy (JPA): 1.5.1 -> 1.7
|
||||
* Jetty (JPA Starter): 9.4.30.v20200611 -> 9.4.35.v20201120
|
||||
* Guava (JP): 29.0-jre -> 30.1-jre
|
||||
* Hibernate ORM (JPA Server): 5.4.22.FINAL -> 5.4.26.FINAL
|
||||
* Spring (JPA Server): 5.2.9.RELEASE -> 5.3.2
|
||||
* Spring Data (JPA Server): 2.2.0.RELEASE -> 2.4.2
|
||||
* Hibernate Search (JPA Server): 5.11.5.FINAL -> 6.0.0.Final
|
||||
* Lucene(HAPI FHIR JPA Server): 5.5.5 -> 8.7.0
|
||||
* Spring Boot (JPA Starter): 2.2.6.RELEASE -> 2.4.1
|
||||
"
|
||||
|
|
|
@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.dao.data;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantityNormalized;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantity;
|
||||
|
@ -27,7 +28,7 @@ import org.springframework.data.jpa.repository.Modifying;
|
|||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface IResourceIndexedSearchParamQuantityNormalizedDao extends JpaRepository<ResourceIndexedSearchParamQuantity, Long> {
|
||||
public interface IResourceIndexedSearchParamQuantityNormalizedDao extends JpaRepository<ResourceIndexedSearchParamQuantityNormalized, Long> {
|
||||
@Modifying
|
||||
@Query("delete from ResourceIndexedSearchParamQuantityNormalized t WHERE t.myResourcePid = :resid")
|
||||
void deleteByResourceId(@Param("resid") Long theResourcePid);
|
||||
|
|
|
@ -31,7 +31,9 @@ import ca.uhn.fhir.jpa.dao.predicate.PredicateBuilderToken;
|
|||
import ca.uhn.fhir.jpa.dao.predicate.SearchFilterParser;
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
|
||||
import ca.uhn.fhir.jpa.model.entity.TagTypeEnum;
|
||||
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
|
||||
import ca.uhn.fhir.jpa.search.builder.predicate.BaseJoiningPredicateBuilder;
|
||||
import ca.uhn.fhir.jpa.search.builder.predicate.CompositeUniqueSearchParameterPredicateBuilder;
|
||||
import ca.uhn.fhir.jpa.search.builder.predicate.CoordsPredicateBuilder;
|
||||
|
@ -43,12 +45,12 @@ import ca.uhn.fhir.jpa.search.builder.predicate.ResourceIdPredicateBuilder;
|
|||
import ca.uhn.fhir.jpa.search.builder.predicate.ResourceLinkPredicateBuilder;
|
||||
import ca.uhn.fhir.jpa.search.builder.predicate.ResourceTablePredicateBuilder;
|
||||
import ca.uhn.fhir.jpa.search.builder.predicate.SearchParamPresentPredicateBuilder;
|
||||
import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryBuilder;
|
||||
import ca.uhn.fhir.jpa.search.builder.predicate.SourcePredicateBuilder;
|
||||
import ca.uhn.fhir.jpa.search.builder.predicate.StringPredicateBuilder;
|
||||
import ca.uhn.fhir.jpa.search.builder.predicate.TagPredicateBuilder;
|
||||
import ca.uhn.fhir.jpa.search.builder.predicate.TokenPredicateBuilder;
|
||||
import ca.uhn.fhir.jpa.search.builder.predicate.UriPredicateBuilder;
|
||||
import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryBuilder;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.searchparam.extractor.BaseSearchParamExtractor;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||
|
@ -185,14 +187,9 @@ public class QueryStack {
|
|||
|
||||
public void addSortOnQuantity(String theResourceName, String theParamName, boolean theAscending) {
|
||||
BaseJoiningPredicateBuilder firstPredicateBuilder = mySqlBuilder.getOrCreateFirstPredicateBuilder();
|
||||
|
||||
QuantityBasePredicateBuilder sortPredicateBuilder = null;
|
||||
if (myModelConfig.isNormalizedQuantitySearchSupported()) {
|
||||
sortPredicateBuilder = mySqlBuilder.addQuantityNormalizedPredicateBuilder(firstPredicateBuilder.getResourceIdColumn());
|
||||
} else {
|
||||
sortPredicateBuilder = mySqlBuilder.addQuantityPredicateBuilder(firstPredicateBuilder.getResourceIdColumn());
|
||||
|
||||
}
|
||||
QuantityBasePredicateBuilder sortPredicateBuilder;
|
||||
sortPredicateBuilder = mySqlBuilder.addQuantityPredicateBuilder(firstPredicateBuilder.getResourceIdColumn());
|
||||
|
||||
Condition hashIdentityPredicate = sortPredicateBuilder.createHashIdentityPredicate(theResourceName, theParamName);
|
||||
mySqlBuilder.addPredicate(hashIdentityPredicate);
|
||||
|
@ -272,33 +269,33 @@ public class QueryStack {
|
|||
return new PredicateBuilderCacheLookupResult<>(cacheHit, (T) retVal);
|
||||
}
|
||||
|
||||
private Condition createPredicateComposite(@Nullable DbColumn theSourceJoinColumn, String theResourceName, RuntimeSearchParam theParamDef, List<? extends IQueryParameterType> theNextAnd, RequestPartitionId theRequestPartitionId) {
|
||||
private Condition createPredicateComposite(@Nullable DbColumn theSourceJoinColumn, String theResourceName, RuntimeSearchParam theParamDef, List<? extends IQueryParameterType> theNextAnd, RequestPartitionId theRequestPartitionId) {
|
||||
|
||||
Condition orCondidtion = null;
|
||||
Condition orCondidtion = null;
|
||||
for (IQueryParameterType next : theNextAnd) {
|
||||
|
||||
|
||||
if (!(next instanceof CompositeParam<?, ?>)) {
|
||||
throw new InvalidRequestException("Invalid type for composite param (must be " + CompositeParam.class.getSimpleName() + ": " + next.getClass());
|
||||
}
|
||||
CompositeParam<?, ?> cp = (CompositeParam<?, ?>) next;
|
||||
|
||||
|
||||
RuntimeSearchParam left = theParamDef.getCompositeOf().get(0);
|
||||
IQueryParameterType leftValue = cp.getLeftValue();
|
||||
Condition leftPredicate = createPredicateCompositePart(theSourceJoinColumn, theResourceName, left, leftValue, theRequestPartitionId);
|
||||
|
||||
|
||||
RuntimeSearchParam right = theParamDef.getCompositeOf().get(1);
|
||||
IQueryParameterType rightValue = cp.getRightValue();
|
||||
Condition rightPredicate = createPredicateCompositePart(theSourceJoinColumn, theResourceName, right, rightValue, theRequestPartitionId);
|
||||
|
||||
|
||||
Condition andCondition = toAndPredicate(leftPredicate, rightPredicate);
|
||||
|
||||
|
||||
if (orCondidtion == null) {
|
||||
orCondidtion = toOrPredicate(andCondition);
|
||||
} else {
|
||||
orCondidtion = toOrPredicate(orCondidtion, andCondition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return orCondidtion;
|
||||
}
|
||||
|
||||
|
@ -414,11 +411,11 @@ public class QueryStack {
|
|||
param.setValueAsQueryToken(null, null, null, theFilter.getValue());
|
||||
return theQueryStack3.createPredicateResourceId(null, Collections.singletonList(Collections.singletonList(param)), theResourceName, theFilter.getOperation(), theRequestPartitionId);
|
||||
} else if (paramName.equals(IAnyResource.SP_RES_LANGUAGE)) {
|
||||
return theQueryStack3.createPredicateLanguage(Collections.singletonList(Collections.singletonList(new StringParam(theFilter.getValue()))), theFilter.getOperation());
|
||||
return theQueryStack3.createPredicateLanguage(Collections.singletonList(Collections.singletonList(new StringParam(theFilter.getValue()))), theFilter.getOperation());
|
||||
} else if (paramName.equals(Constants.PARAM_SOURCE)) {
|
||||
TokenParam param = new TokenParam();
|
||||
param.setValueAsQueryToken(null, null, null, theFilter.getValue());
|
||||
return createPredicateSource(null, Collections.singletonList(param));
|
||||
TokenParam param = new TokenParam();
|
||||
param.setValueAsQueryToken(null, null, null, theFilter.getValue());
|
||||
return createPredicateSource(null, Collections.singletonList(param));
|
||||
} else {
|
||||
RuntimeSearchParam searchParam = mySearchParamRegistry.getActiveSearchParam(theResourceName, paramName);
|
||||
if (searchParam == null) {
|
||||
|
@ -642,20 +639,38 @@ public class QueryStack {
|
|||
List<? extends IQueryParameterType> theList,
|
||||
SearchFilterParser.CompareOperation theOperation,
|
||||
RequestPartitionId theRequestPartitionId) {
|
||||
|
||||
QuantityBasePredicateBuilder join = null;
|
||||
|
||||
if (myModelConfig.isNormalizedQuantitySearchSupported()) {
|
||||
join = createOrReusePredicateBuilder(PredicateBuilderTypeEnum.QUANTITY, theSourceJoinColumn, theSearchParam.getName(), () -> mySqlBuilder.addQuantityNormalizedPredicateBuilder(theSourceJoinColumn)).getResult();
|
||||
} else {
|
||||
join = createOrReusePredicateBuilder(PredicateBuilderTypeEnum.QUANTITY, theSourceJoinColumn, theSearchParam.getName(), () -> mySqlBuilder.addQuantityPredicateBuilder(theSourceJoinColumn)).getResult();
|
||||
}
|
||||
|
||||
if (theList.get(0).getMissing() != null) {
|
||||
QuantityBasePredicateBuilder join = createOrReusePredicateBuilder(PredicateBuilderTypeEnum.QUANTITY, theSourceJoinColumn, theSearchParam.getName(), () -> mySqlBuilder.addQuantityPredicateBuilder(theSourceJoinColumn)).getResult();
|
||||
return join.createPredicateParamMissingForNonReference(theResourceName, theSearchParam.getName(), theList.get(0).getMissing(), theRequestPartitionId);
|
||||
}
|
||||
|
||||
List<QuantityParam> quantityParams = theList
|
||||
.stream()
|
||||
.map(t -> QuantityParam.toQuantityParam(t))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
QuantityBasePredicateBuilder join = null;
|
||||
boolean normalizedSearchEnabled = myModelConfig.getNormalizedQuantitySearchLevel().equals(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
if (normalizedSearchEnabled) {
|
||||
List<QuantityParam> normalizedQuantityParams = quantityParams
|
||||
.stream()
|
||||
.map(t -> UcumServiceUtil.toCanonicalQuantityOrNull(t))
|
||||
.filter(t -> t != null)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (normalizedQuantityParams.size() == quantityParams.size()) {
|
||||
join = createOrReusePredicateBuilder(PredicateBuilderTypeEnum.QUANTITY, theSourceJoinColumn, theSearchParam.getName(), () -> mySqlBuilder.addQuantityNormalizedPredicateBuilder(theSourceJoinColumn)).getResult();
|
||||
quantityParams = normalizedQuantityParams;
|
||||
}
|
||||
}
|
||||
|
||||
if (join == null) {
|
||||
join = createOrReusePredicateBuilder(PredicateBuilderTypeEnum.QUANTITY, theSourceJoinColumn, theSearchParam.getName(), () -> mySqlBuilder.addQuantityPredicateBuilder(theSourceJoinColumn)).getResult();
|
||||
}
|
||||
|
||||
List<Condition> codePredicates = new ArrayList<>();
|
||||
for (IQueryParameterType nextOr : theList) {
|
||||
for (QuantityParam nextOr : quantityParams) {
|
||||
Condition singleCode = join.createPredicateQuantity(nextOr, theResourceName, theSearchParam.getName(), null, join, theOperation, theRequestPartitionId);
|
||||
codePredicates.add(singleCode);
|
||||
}
|
||||
|
@ -923,7 +938,7 @@ public class QueryStack {
|
|||
|
||||
@Nullable
|
||||
public Condition searchForIdsWithAndOr(@Nullable DbColumn theSourceJoinColumn, String theResourceName, String theParamName, List<List<IQueryParameterType>> theAndOrParams, RequestDetails theRequest, RequestPartitionId theRequestPartitionId) {
|
||||
|
||||
|
||||
if (theAndOrParams.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
@ -1054,7 +1069,7 @@ public class QueryStack {
|
|||
return toAndPredicate(andPredicates);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void addPredicateCompositeUnique(String theIndexString, RequestPartitionId theRequestPartitionId) {
|
||||
|
|
|
@ -20,27 +20,10 @@ package ca.uhn.fhir.jpa.search.builder.predicate;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
|
||||
import org.fhir.ucum.Pair;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.healthmarketscience.sqlbuilder.BinaryCondition;
|
||||
import com.healthmarketscience.sqlbuilder.ComboCondition;
|
||||
import com.healthmarketscience.sqlbuilder.Condition;
|
||||
import com.healthmarketscience.sqlbuilder.dbspec.basic.DbColumn;
|
||||
import com.healthmarketscience.sqlbuilder.dbspec.basic.DbTable;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||
import ca.uhn.fhir.jpa.dao.predicate.SearchFilterParser;
|
||||
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamBaseQuantity;
|
||||
import ca.uhn.fhir.jpa.search.builder.QueryStack;
|
||||
import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryBuilder;
|
||||
|
@ -48,7 +31,18 @@ import ca.uhn.fhir.model.api.IQueryParameterType;
|
|||
import ca.uhn.fhir.model.base.composite.BaseQuantityDt;
|
||||
import ca.uhn.fhir.rest.param.ParamPrefixEnum;
|
||||
import ca.uhn.fhir.rest.param.QuantityParam;
|
||||
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
|
||||
import com.healthmarketscience.sqlbuilder.BinaryCondition;
|
||||
import com.healthmarketscience.sqlbuilder.ComboCondition;
|
||||
import com.healthmarketscience.sqlbuilder.Condition;
|
||||
import com.healthmarketscience.sqlbuilder.dbspec.basic.DbColumn;
|
||||
import com.healthmarketscience.sqlbuilder.dbspec.basic.DbTable;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
|
||||
public abstract class QuantityBasePredicateBuilder extends BaseSearchParamPredicateBuilder {
|
||||
|
@ -59,11 +53,7 @@ public abstract class QuantityBasePredicateBuilder extends BaseSearchParamPredic
|
|||
|
||||
@Autowired
|
||||
private FhirContext myFhirContext;
|
||||
|
||||
@Autowired
|
||||
private ModelConfig myModelConfig;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
@ -71,38 +61,13 @@ public abstract class QuantityBasePredicateBuilder extends BaseSearchParamPredic
|
|||
super(theSearchSqlBuilder, theTable);
|
||||
}
|
||||
|
||||
public Condition createPredicateQuantity(IQueryParameterType theParam, String theResourceName, String theParamName, CriteriaBuilder theBuilder, QuantityBasePredicateBuilder theFrom, SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) {
|
||||
|
||||
String systemValue;
|
||||
String unitsValue;
|
||||
ParamPrefixEnum cmpValue;
|
||||
BigDecimal valueValue;
|
||||
public Condition createPredicateQuantity(QuantityParam theParam, String theResourceName, String theParamName, CriteriaBuilder theBuilder, QuantityBasePredicateBuilder theFrom, SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) {
|
||||
|
||||
if (theParam instanceof BaseQuantityDt) {
|
||||
BaseQuantityDt param = (BaseQuantityDt) theParam;
|
||||
systemValue = param.getSystemElement().getValueAsString();
|
||||
unitsValue = param.getUnitsElement().getValueAsString();
|
||||
cmpValue = ParamPrefixEnum.forValue(param.getComparatorElement().getValueAsString());
|
||||
valueValue = param.getValueElement().getValue();
|
||||
} else if (theParam instanceof QuantityParam) {
|
||||
QuantityParam param = (QuantityParam) theParam;
|
||||
systemValue = param.getSystem();
|
||||
unitsValue = param.getUnits();
|
||||
cmpValue = param.getPrefix();
|
||||
valueValue = param.getValue();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid quantity type: " + theParam.getClass());
|
||||
}
|
||||
String systemValue = theParam.getSystem();
|
||||
String unitsValue = theParam.getUnits();
|
||||
ParamPrefixEnum cmpValue = theParam.getPrefix();
|
||||
BigDecimal valueValue = theParam.getValue();
|
||||
|
||||
if (myModelConfig.isNormalizedQuantitySearchSupported()) {
|
||||
//-- convert the value/unit to the canonical form if any to use by the search
|
||||
Pair canonicalForm = UcumServiceUtil.getCanonicalForm(systemValue, valueValue, unitsValue);
|
||||
if (canonicalForm != null) {
|
||||
valueValue = new BigDecimal(canonicalForm.getValue().asDecimal());
|
||||
unitsValue = canonicalForm.getCode();
|
||||
}
|
||||
}
|
||||
|
||||
Condition hashPredicate;
|
||||
if (!isBlank(systemValue) && !isBlank(unitsValue)) {
|
||||
long hash = ResourceIndexedSearchParamBaseQuantity.calculateHashSystemAndUnits(getPartitionSettings(), theRequestPartitionId, theResourceName, theParamName, systemValue, unitsValue);
|
||||
|
@ -127,5 +92,6 @@ public abstract class QuantityBasePredicateBuilder extends BaseSearchParamPredic
|
|||
|
||||
public DbColumn getColumnValue() {
|
||||
return myColumnValue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
package ca.uhn.fhir.jpa.dao.r4;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.matchesPattern;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantity;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantityNormalized;
|
||||
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.param.QuantityParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
@ -33,15 +32,20 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
|
||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.param.QuantityParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.matchesPattern;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class FhirResourceDaoR4CreateTest extends BaseJpaR4Test {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(FhirResourceDaoR4CreateTest.class);
|
||||
|
@ -51,7 +55,7 @@ public class FhirResourceDaoR4CreateTest extends BaseJpaR4Test {
|
|||
myDaoConfig.setResourceServerIdStrategy(new DaoConfig().getResourceServerIdStrategy());
|
||||
myDaoConfig.setResourceClientIdStrategy(new DaoConfig().getResourceClientIdStrategy());
|
||||
myDaoConfig.setDefaultSearchParamsCanBeOverridden(new DaoConfig().isDefaultSearchParamsCanBeOverridden());
|
||||
myModelConfig.setNormalizedQuantitySearchNotSupported();
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -337,9 +341,9 @@ public class FhirResourceDaoR4CreateTest extends BaseJpaR4Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithNormalizedQuantitySearchSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
public void testCreateWithNormalizedQuantitySearchSupported_AlreadyCanonicalUnit() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
Observation obs = new Observation();
|
||||
obs.setStatus(Observation.ObservationStatus.FINAL);
|
||||
Quantity q = new Quantity();
|
||||
|
@ -348,34 +352,38 @@ public class FhirResourceDaoR4CreateTest extends BaseJpaR4Test {
|
|||
q.setSystem("http://unitsofmeasure.org");
|
||||
q.setCode("cm");
|
||||
obs.setValue(q);
|
||||
|
||||
|
||||
ourLog.info("Observation1: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||
|
||||
|
||||
assertTrue(myObservationDao.create(obs).getCreated());
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
QuantityParam qp = new QuantityParam();
|
||||
qp.setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL);
|
||||
qp.setValue(new BigDecimal("0.012"));
|
||||
qp.setUnits("m");
|
||||
|
||||
map.add(Observation.SP_VALUE_QUANTITY, qp);
|
||||
|
||||
IBundleProvider found = myObservationDao.search(map);
|
||||
List<String> ids = toUnqualifiedVersionlessIdValues(found);
|
||||
|
||||
List<IBaseResource> resources = found.getResources(0, found.size());
|
||||
|
||||
assertEquals(1, ids.size());
|
||||
|
||||
ourLog.info("Observation2: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(resources.get(0)));
|
||||
|
||||
// Same value should be placed in both quantity tables
|
||||
runInTransaction(()->{
|
||||
List<ResourceIndexedSearchParamQuantity> quantityIndexes = myResourceIndexedSearchParamQuantityDao.findAll().stream().filter(t->t.getParamName().equals("value-quantity")).collect(Collectors.toList());
|
||||
assertEquals(1, quantityIndexes.size());
|
||||
assertEquals("1.2", Double.toString(quantityIndexes.get(0).getValue().doubleValue()));
|
||||
assertEquals("http://unitsofmeasure.org", quantityIndexes.get(0).getSystem());
|
||||
assertEquals("cm", quantityIndexes.get(0).getUnits());
|
||||
|
||||
List<ResourceIndexedSearchParamQuantityNormalized> normalizedQuantityIndexes = myResourceIndexedSearchParamQuantityNormalizedDao.findAll().stream().filter(t->t.getParamName().equals("value-quantity")).collect(Collectors.toList());
|
||||
assertEquals(1, normalizedQuantityIndexes.size());
|
||||
assertEquals("0.012", Double.toString(normalizedQuantityIndexes.get(0).getValue()));
|
||||
assertEquals("http://unitsofmeasure.org", normalizedQuantityIndexes.get(0).getSystem());
|
||||
assertEquals("m", normalizedQuantityIndexes.get(0).getUnits());
|
||||
});
|
||||
|
||||
SearchParameterMap map = SearchParameterMap.newSynchronous(Observation.SP_VALUE_QUANTITY, new QuantityParam()
|
||||
.setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL)
|
||||
.setValue(new BigDecimal("0.012"))
|
||||
.setUnits("m")
|
||||
);
|
||||
assertEquals(1, toUnqualifiedVersionlessIdValues(myObservationDao.search(map)).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithNormalizedQuantitySearchSupportedWithVerySmallNumber() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
public void testCreateWithNormalizedQuantitySearchSupported_SmallerThanCanonicalUnit() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
Observation obs = new Observation();
|
||||
obs.setStatus(Observation.ObservationStatus.FINAL);
|
||||
Quantity q = new Quantity();
|
||||
|
@ -384,102 +392,358 @@ public class FhirResourceDaoR4CreateTest extends BaseJpaR4Test {
|
|||
q.setSystem("http://unitsofmeasure.org");
|
||||
q.setCode("mm");
|
||||
obs.setValue(q);
|
||||
|
||||
|
||||
ourLog.info("Observation1: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||
|
||||
|
||||
myCaptureQueriesListener.clear();
|
||||
assertTrue(myObservationDao.create(obs).getCreated());
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
QuantityParam qp = new QuantityParam();
|
||||
qp.setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL);
|
||||
qp.setValue(new BigDecimal("0.0000000012"));
|
||||
qp.setUnits("m");
|
||||
|
||||
map.add(Observation.SP_VALUE_QUANTITY, qp);
|
||||
|
||||
IBundleProvider found = myObservationDao.search(map);
|
||||
List<String> ids = toUnqualifiedVersionlessIdValues(found);
|
||||
|
||||
List<IBaseResource> resources = found.getResources(0, found.size());
|
||||
|
||||
myCaptureQueriesListener.logInsertQueries();
|
||||
|
||||
// Original value should be in Quantity index, normalized should be in normalized table
|
||||
runInTransaction(()->{
|
||||
List<ResourceIndexedSearchParamQuantity> quantityIndexes = myResourceIndexedSearchParamQuantityDao.findAll().stream().filter(t->t.getParamName().equals("value-quantity")).collect(Collectors.toList());
|
||||
assertEquals(1, quantityIndexes.size());
|
||||
double d = quantityIndexes.get(0).getValue().doubleValue();
|
||||
assertEquals("1.2E-6", Double.toString(d));
|
||||
assertEquals("http://unitsofmeasure.org", quantityIndexes.get(0).getSystem());
|
||||
assertEquals("mm", quantityIndexes.get(0).getUnits());
|
||||
|
||||
List<ResourceIndexedSearchParamQuantityNormalized> normalizedQuantityIndexes = myResourceIndexedSearchParamQuantityNormalizedDao.findAll().stream().filter(t->t.getParamName().equals("value-quantity")).collect(Collectors.toList());
|
||||
assertEquals(1, normalizedQuantityIndexes.size());
|
||||
assertEquals("1.2E-9", Double.toString(normalizedQuantityIndexes.get(0).getValue()));
|
||||
assertEquals("http://unitsofmeasure.org", normalizedQuantityIndexes.get(0).getSystem());
|
||||
assertEquals("m", normalizedQuantityIndexes.get(0).getUnits());
|
||||
});
|
||||
|
||||
String searchSql;
|
||||
SearchParameterMap map;
|
||||
List<String> ids;
|
||||
|
||||
// Try with normalized value
|
||||
myCaptureQueriesListener.clear();
|
||||
map = SearchParameterMap.newSynchronous(Observation.SP_VALUE_QUANTITY, new QuantityParam()
|
||||
.setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL)
|
||||
.setValue(new BigDecimal("0.0000000012"))
|
||||
.setUnits("m")
|
||||
);
|
||||
ids = toUnqualifiedVersionlessIdValues(myObservationDao.search(map));
|
||||
searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true,true);
|
||||
assertThat(searchSql, containsString("HFJ_SPIDX_QUANTITY_NRML t0"));
|
||||
assertThat(searchSql, containsString("t0.SP_VALUE = '1.2E-9'"));
|
||||
assertEquals(1, ids.size());
|
||||
|
||||
// Try with non-normalized value
|
||||
myCaptureQueriesListener.clear();
|
||||
map = SearchParameterMap.newSynchronous(Observation.SP_VALUE_QUANTITY, new QuantityParam()
|
||||
.setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL)
|
||||
.setValue(new BigDecimal("0.0000012"))
|
||||
.setUnits("mm")
|
||||
);
|
||||
ids = toUnqualifiedVersionlessIdValues(myObservationDao.search(map));
|
||||
searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true,true);
|
||||
assertThat(searchSql, containsString("HFJ_SPIDX_QUANTITY_NRML t0"));
|
||||
assertThat(searchSql, containsString("t0.SP_VALUE = '1.2E-9'"));
|
||||
assertEquals(1, ids.size());
|
||||
|
||||
// Try with no units value
|
||||
myCaptureQueriesListener.clear();
|
||||
map = SearchParameterMap.newSynchronous(Observation.SP_VALUE_QUANTITY, new QuantityParam()
|
||||
.setValue(new BigDecimal("0.0000012"))
|
||||
);
|
||||
ids = toUnqualifiedVersionlessIdValues(myObservationDao.search(map));
|
||||
searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true,true);
|
||||
assertThat(searchSql, containsString("HFJ_SPIDX_QUANTITY t0"));
|
||||
assertThat(searchSql, containsString("t0.SP_VALUE = '0.0000012'"));
|
||||
assertEquals(1, ids.size());
|
||||
|
||||
ourLog.info("Observation2: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(resources.get(0)));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithNormalizedQuantitySearchSupportedWithVerySmallNumber2() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
public void testCreateWithNormalizedQuantitySearchSupported_SmallerThanCanonicalUnit2() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
Observation obs = new Observation();
|
||||
obs.setStatus(Observation.ObservationStatus.FINAL);
|
||||
Quantity q = new Quantity();
|
||||
q.setValueElement(new DecimalType(149597.870691));
|
||||
q.setValueElement(new DecimalType("149597.870691"));
|
||||
q.setUnit("MM");
|
||||
q.setSystem("http://unitsofmeasure.org");
|
||||
q.setCode("mm");
|
||||
obs.setValue(q);
|
||||
|
||||
|
||||
ourLog.info("Observation1: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||
|
||||
|
||||
assertTrue(myObservationDao.create(obs).getCreated());
|
||||
|
||||
|
||||
// Original value should be in Quantity index, normalized should be in normalized table
|
||||
runInTransaction(()->{
|
||||
List<ResourceIndexedSearchParamQuantity> quantityIndexes = myResourceIndexedSearchParamQuantityDao.findAll().stream().filter(t->t.getParamName().equals("value-quantity")).collect(Collectors.toList());
|
||||
assertEquals(1, quantityIndexes.size());
|
||||
assertEquals("149597.870691", Double.toString(quantityIndexes.get(0).getValue().doubleValue()));
|
||||
assertEquals("http://unitsofmeasure.org", quantityIndexes.get(0).getSystem());
|
||||
assertEquals("mm", quantityIndexes.get(0).getUnits());
|
||||
|
||||
List<ResourceIndexedSearchParamQuantityNormalized> normalizedQuantityIndexes = myResourceIndexedSearchParamQuantityNormalizedDao.findAll().stream().filter(t->t.getParamName().equals("value-quantity")).collect(Collectors.toList());
|
||||
assertEquals(1, normalizedQuantityIndexes.size());
|
||||
assertEquals("149.597870691", Double.toString(normalizedQuantityIndexes.get(0).getValue()));
|
||||
assertEquals("http://unitsofmeasure.org", normalizedQuantityIndexes.get(0).getSystem());
|
||||
assertEquals("m", normalizedQuantityIndexes.get(0).getUnits());
|
||||
});
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
QuantityParam qp = new QuantityParam();
|
||||
qp.setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL);
|
||||
qp.setValue(new BigDecimal("149.597870691"));
|
||||
qp.setUnits("m");
|
||||
|
||||
|
||||
map.add(Observation.SP_VALUE_QUANTITY, qp);
|
||||
|
||||
|
||||
IBundleProvider found = myObservationDao.search(map);
|
||||
List<String> ids = toUnqualifiedVersionlessIdValues(found);
|
||||
|
||||
List<IBaseResource> resources = found.getResources(0, found.size());
|
||||
|
||||
|
||||
List<IBaseResource> resources = found.getResources(0, found.sizeOrThrowNpe());
|
||||
|
||||
assertEquals(1, ids.size());
|
||||
|
||||
|
||||
ourLog.info("Observation2: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(resources.get(0)));
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithNormalizedQuantitySearchSupportedWithLargeNumber() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
public void testCreateWithNormalizedQuantitySearchSupported_LargerThanCanonicalUnit() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
Observation obs = new Observation();
|
||||
obs.setStatus(Observation.ObservationStatus.FINAL);
|
||||
Quantity q = new Quantity();
|
||||
q.setValueElement(new DecimalType("95.7412345"));
|
||||
q.setUnit("kg/dL");
|
||||
q.setSystem("http://unitsofmeasure.org");
|
||||
q.setCode("kg/dL");
|
||||
obs.setValue(q);
|
||||
|
||||
ourLog.info("Observation1: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||
|
||||
assertTrue(myObservationDao.create(obs).getCreated());
|
||||
|
||||
// Original value should be in Quantity index, normalized should be in normalized table
|
||||
runInTransaction(()->{
|
||||
List<ResourceIndexedSearchParamQuantity> quantityIndexes = myResourceIndexedSearchParamQuantityDao.findAll().stream().filter(t->t.getParamName().equals("value-quantity")).collect(Collectors.toList());
|
||||
assertEquals(1, quantityIndexes.size());
|
||||
assertEquals("95.7412345", Double.toString(quantityIndexes.get(0).getValue().doubleValue()));
|
||||
assertEquals("http://unitsofmeasure.org", quantityIndexes.get(0).getSystem());
|
||||
assertEquals("kg/dL", quantityIndexes.get(0).getUnits());
|
||||
|
||||
List<ResourceIndexedSearchParamQuantityNormalized> normalizedQuantityIndexes = myResourceIndexedSearchParamQuantityNormalizedDao.findAll().stream().filter(t->t.getParamName().equals("value-quantity")).collect(Collectors.toList());
|
||||
assertEquals(1, normalizedQuantityIndexes.size());
|
||||
assertEquals("9.57412345E8", Double.toString(normalizedQuantityIndexes.get(0).getValue()));
|
||||
assertEquals("http://unitsofmeasure.org", normalizedQuantityIndexes.get(0).getSystem());
|
||||
assertEquals("g.m-3", normalizedQuantityIndexes.get(0).getUnits());
|
||||
});
|
||||
|
||||
SearchParameterMap map = SearchParameterMap.newSynchronous(Observation.SP_VALUE_QUANTITY, new QuantityParam()
|
||||
.setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL)
|
||||
.setValue(new BigDecimal("957412345"))
|
||||
.setUnits("g.m-3")
|
||||
);
|
||||
assertEquals(1, toUnqualifiedVersionlessIdValues(myObservationDao.search(map)).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithNormalizedQuantitySearchSupported_NonCanonicalUnit() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
Observation obs = new Observation();
|
||||
obs.setStatus(Observation.ObservationStatus.FINAL);
|
||||
Quantity q = new Quantity();
|
||||
q.setValueElement(new DecimalType(95.7412345));
|
||||
q.setUnit("kg/dL");
|
||||
q.setSystem("http://unitsofmeasure.org");
|
||||
q.setSystem("http://example.com");
|
||||
q.setCode("kg/dL");
|
||||
obs.setValue(q);
|
||||
|
||||
|
||||
ourLog.info("Observation1: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||
|
||||
|
||||
assertTrue(myObservationDao.create(obs).getCreated());
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
QuantityParam qp = new QuantityParam();
|
||||
qp.setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL);
|
||||
qp.setValue(new BigDecimal("957412345"));
|
||||
qp.setUnits("g.m-3");
|
||||
|
||||
map.add(Observation.SP_VALUE_QUANTITY, qp);
|
||||
|
||||
IBundleProvider found = myObservationDao.search(map);
|
||||
List<String> ids = toUnqualifiedVersionlessIdValues(found);
|
||||
|
||||
List<IBaseResource> resources = found.getResources(0, found.size());
|
||||
|
||||
|
||||
// Original value should be in Quantity index, normalized should be in normalized table
|
||||
runInTransaction(() -> {
|
||||
List<ResourceIndexedSearchParamQuantity> quantityIndexes = myResourceIndexedSearchParamQuantityDao.findAll().stream().filter(t -> t.getParamName().equals("value-quantity")).collect(Collectors.toList());
|
||||
assertEquals(1, quantityIndexes.size());
|
||||
assertEquals("95.7412345", Double.toString(quantityIndexes.get(0).getValue().doubleValue()));
|
||||
assertEquals("http://example.com", quantityIndexes.get(0).getSystem());
|
||||
assertEquals("kg/dL", quantityIndexes.get(0).getUnits());
|
||||
|
||||
List<ResourceIndexedSearchParamQuantityNormalized> normalizedQuantityIndexes = myResourceIndexedSearchParamQuantityNormalizedDao.findAll().stream().filter(t -> t.getParamName().equals("value-quantity")).collect(Collectors.toList());
|
||||
assertEquals(0, normalizedQuantityIndexes.size());
|
||||
});
|
||||
|
||||
List<String> ids;
|
||||
|
||||
// Search should succeed using non-normalized table
|
||||
myCaptureQueriesListener.clear();
|
||||
SearchParameterMap map = SearchParameterMap.newSynchronous(Observation.SP_VALUE_QUANTITY, new QuantityParam()
|
||||
.setSystem("http://example.com")
|
||||
.setValue(95.7412345)
|
||||
.setUnits("kg/dL")
|
||||
);
|
||||
ids = toUnqualifiedVersionlessIdValues(myObservationDao.search(map));
|
||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true,true);
|
||||
assertThat(searchSql, containsString("HFJ_SPIDX_QUANTITY t0"));
|
||||
assertThat(searchSql, containsString("t0.SP_VALUE = '95.7412345'"));
|
||||
assertEquals(1, ids.size());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateWithNormalizedQuantityStorageSupported_SmallerThanCanonicalUnit() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED);
|
||||
Observation obs = new Observation();
|
||||
obs.setStatus(Observation.ObservationStatus.FINAL);
|
||||
Quantity q = new Quantity();
|
||||
q.setValueElement(new DecimalType(0.0000012));
|
||||
q.setUnit("MM");
|
||||
q.setSystem("http://unitsofmeasure.org");
|
||||
q.setCode("mm");
|
||||
obs.setValue(q);
|
||||
|
||||
ourLog.info("Observation1: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||
|
||||
myCaptureQueriesListener.clear();
|
||||
assertTrue(myObservationDao.create(obs).getCreated());
|
||||
myCaptureQueriesListener.logInsertQueries();
|
||||
|
||||
// Original value should be in Quantity index, normalized should be in normalized table
|
||||
runInTransaction(()->{
|
||||
List<ResourceIndexedSearchParamQuantity> quantityIndexes = myResourceIndexedSearchParamQuantityDao.findAll().stream().filter(t->t.getParamName().equals("value-quantity")).collect(Collectors.toList());
|
||||
assertEquals(1, quantityIndexes.size());
|
||||
double d = quantityIndexes.get(0).getValue().doubleValue();
|
||||
assertEquals("1.2E-6", Double.toString(d));
|
||||
assertEquals("http://unitsofmeasure.org", quantityIndexes.get(0).getSystem());
|
||||
assertEquals("mm", quantityIndexes.get(0).getUnits());
|
||||
|
||||
List<ResourceIndexedSearchParamQuantityNormalized> normalizedQuantityIndexes = myResourceIndexedSearchParamQuantityNormalizedDao.findAll().stream().filter(t->t.getParamName().equals("value-quantity")).collect(Collectors.toList());
|
||||
assertEquals(1, normalizedQuantityIndexes.size());
|
||||
assertEquals("1.2E-9", Double.toString(normalizedQuantityIndexes.get(0).getValue()));
|
||||
assertEquals("http://unitsofmeasure.org", normalizedQuantityIndexes.get(0).getSystem());
|
||||
assertEquals("m", normalizedQuantityIndexes.get(0).getUnits());
|
||||
});
|
||||
|
||||
String searchSql;
|
||||
SearchParameterMap map;
|
||||
List<String> ids;
|
||||
|
||||
// Try with normalized value
|
||||
myCaptureQueriesListener.clear();
|
||||
map = SearchParameterMap.newSynchronous(Observation.SP_VALUE_QUANTITY, new QuantityParam()
|
||||
.setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL)
|
||||
.setValue(new BigDecimal("0.0000000012"))
|
||||
.setUnits("m")
|
||||
);
|
||||
ids = toUnqualifiedVersionlessIdValues(myObservationDao.search(map));
|
||||
searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true,true);
|
||||
assertThat(searchSql, containsString("HFJ_SPIDX_QUANTITY t0"));
|
||||
assertThat(searchSql, containsString("t0.SP_VALUE = '1.2E-9'"));
|
||||
assertEquals(0, ids.size());
|
||||
|
||||
// Try with non-normalized value
|
||||
myCaptureQueriesListener.clear();
|
||||
map = SearchParameterMap.newSynchronous(Observation.SP_VALUE_QUANTITY, new QuantityParam()
|
||||
.setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL)
|
||||
.setValue(new BigDecimal("0.0000012"))
|
||||
.setUnits("mm")
|
||||
);
|
||||
ids = toUnqualifiedVersionlessIdValues(myObservationDao.search(map));
|
||||
searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true,true);
|
||||
assertThat(searchSql, containsString("HFJ_SPIDX_QUANTITY t0"));
|
||||
assertThat(searchSql, containsString("t0.SP_VALUE = '0.0000012'"));
|
||||
assertEquals(1, ids.size());
|
||||
|
||||
// Try with no units value
|
||||
myCaptureQueriesListener.clear();
|
||||
map = SearchParameterMap.newSynchronous(Observation.SP_VALUE_QUANTITY, new QuantityParam()
|
||||
.setValue(new BigDecimal("0.0000012"))
|
||||
);
|
||||
ids = toUnqualifiedVersionlessIdValues(myObservationDao.search(map));
|
||||
searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true,true);
|
||||
assertThat(searchSql, containsString("HFJ_SPIDX_QUANTITY t0"));
|
||||
assertThat(searchSql, containsString("t0.SP_VALUE = '0.0000012'"));
|
||||
assertEquals(1, ids.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithNormalizedQuantitySearchNotSupported_SmallerThanCanonicalUnit() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
|
||||
Observation obs = new Observation();
|
||||
obs.setStatus(Observation.ObservationStatus.FINAL);
|
||||
Quantity q = new Quantity();
|
||||
q.setValueElement(new DecimalType(0.0000012));
|
||||
q.setUnit("MM");
|
||||
q.setSystem("http://unitsofmeasure.org");
|
||||
q.setCode("mm");
|
||||
obs.setValue(q);
|
||||
|
||||
ourLog.info("Observation1: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||
|
||||
myCaptureQueriesListener.clear();
|
||||
assertTrue(myObservationDao.create(obs).getCreated());
|
||||
myCaptureQueriesListener.logInsertQueries();
|
||||
|
||||
// Original value should be in Quantity index, no normalized should be in normalized table
|
||||
runInTransaction(()->{
|
||||
List<ResourceIndexedSearchParamQuantity> quantityIndexes = myResourceIndexedSearchParamQuantityDao.findAll().stream().filter(t->t.getParamName().equals("value-quantity")).collect(Collectors.toList());
|
||||
assertEquals(1, quantityIndexes.size());
|
||||
double d = quantityIndexes.get(0).getValue().doubleValue();
|
||||
assertEquals("1.2E-6", Double.toString(d));
|
||||
assertEquals("http://unitsofmeasure.org", quantityIndexes.get(0).getSystem());
|
||||
assertEquals("mm", quantityIndexes.get(0).getUnits());
|
||||
|
||||
List<ResourceIndexedSearchParamQuantityNormalized> normalizedQuantityIndexes = myResourceIndexedSearchParamQuantityNormalizedDao.findAll().stream().filter(t->t.getParamName().equals("value-quantity")).collect(Collectors.toList());
|
||||
assertEquals(0, normalizedQuantityIndexes.size());
|
||||
});
|
||||
|
||||
String searchSql;
|
||||
SearchParameterMap map;
|
||||
List<String> ids;
|
||||
|
||||
// Try with normalized value
|
||||
myCaptureQueriesListener.clear();
|
||||
map = SearchParameterMap.newSynchronous(Observation.SP_VALUE_QUANTITY, new QuantityParam()
|
||||
.setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL)
|
||||
.setValue(new BigDecimal("0.0000000012"))
|
||||
.setUnits("m")
|
||||
);
|
||||
ids = toUnqualifiedVersionlessIdValues(myObservationDao.search(map));
|
||||
searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true,true);
|
||||
assertThat(searchSql, containsString("HFJ_SPIDX_QUANTITY t0"));
|
||||
assertThat(searchSql, containsString("t0.SP_VALUE = '1.2E-9'"));
|
||||
assertEquals(0, ids.size());
|
||||
|
||||
// Try with non-normalized value
|
||||
myCaptureQueriesListener.clear();
|
||||
map = SearchParameterMap.newSynchronous(Observation.SP_VALUE_QUANTITY, new QuantityParam()
|
||||
.setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL)
|
||||
.setValue(new BigDecimal("0.0000012"))
|
||||
.setUnits("mm")
|
||||
);
|
||||
ids = toUnqualifiedVersionlessIdValues(myObservationDao.search(map));
|
||||
searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true,true);
|
||||
assertThat(searchSql, containsString("HFJ_SPIDX_QUANTITY t0"));
|
||||
assertThat(searchSql, containsString("t0.SP_VALUE = '0.0000012'"));
|
||||
assertEquals(1, ids.size());
|
||||
|
||||
// Try with no units value
|
||||
myCaptureQueriesListener.clear();
|
||||
map = SearchParameterMap.newSynchronous(Observation.SP_VALUE_QUANTITY, new QuantityParam()
|
||||
.setValue(new BigDecimal("0.0000012"))
|
||||
);
|
||||
ids = toUnqualifiedVersionlessIdValues(myObservationDao.search(map));
|
||||
searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true,true);
|
||||
assertThat(searchSql, containsString("HFJ_SPIDX_QUANTITY t0"));
|
||||
assertThat(searchSql, containsString("t0.SP_VALUE = '0.0000012'"));
|
||||
assertEquals(1, ids.size());
|
||||
|
||||
ourLog.info("Observation2: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(resources.get(0)));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import ca.uhn.fhir.interceptor.api.IAnonymousInterceptor;
|
|||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
|
||||
import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
|
@ -86,8 +87,8 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
|
|||
@AfterEach
|
||||
public void after() {
|
||||
myDaoConfig.setValidateSearchParameterExpressionsOnSave(new DaoConfig().isValidateSearchParameterExpressionsOnSave());
|
||||
myModelConfig.setNormalizedQuantitySearchNotSupported();
|
||||
}
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void beforeDisableResultReuse() {
|
||||
|
@ -117,8 +118,8 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
|
|||
|
||||
@Test
|
||||
public void testStoreSearchParamWithBracketsInExpressionNormalizedQuantitySearchSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
myDaoConfig.setMarkResourcesForReindexingUponSearchParameterChange(true);
|
||||
|
||||
SearchParameter fooSp = new SearchParameter();
|
||||
|
@ -138,8 +139,8 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
|
|||
|
||||
@Test
|
||||
public void testStoreSearchParamWithBracketsInExpressionNormalizedQuantityStorageSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantityStorageSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED);
|
||||
myDaoConfig.setMarkResourcesForReindexingUponSearchParameterChange(true);
|
||||
|
||||
SearchParameter fooSp = new SearchParameter();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package ca.uhn.fhir.jpa.dao.r4;
|
||||
|
||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.param.DateParam;
|
||||
|
@ -10,7 +11,16 @@ import ca.uhn.fhir.rest.param.StringParam;
|
|||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
import org.hl7.fhir.r4.model.DateType;
|
||||
import org.hl7.fhir.r4.model.DecimalType;
|
||||
import org.hl7.fhir.r4.model.Location;
|
||||
import org.hl7.fhir.r4.model.MedicationRequest;
|
||||
import org.hl7.fhir.r4.model.Observation;
|
||||
import org.hl7.fhir.r4.model.Organization;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.Quantity;
|
||||
import org.hl7.fhir.r4.model.Reference;
|
||||
import org.hl7.fhir.r4.model.Task;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -21,8 +31,12 @@ import java.util.List;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsInRelativeOrder;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(FhirResourceDaoR4SearchMissingTest.class);
|
||||
|
@ -31,10 +45,10 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
|
|||
public void beforeResetMissing() {
|
||||
myDaoConfig.setIndexMissingFields(DaoConfig.IndexEnabledEnum.ENABLED);
|
||||
}
|
||||
|
||||
|
||||
@AfterEach
|
||||
public void afterResetSearch() {
|
||||
myModelConfig.setNormalizedQuantitySearchNotSupported();
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -80,9 +94,9 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testIndexMissingFieldsDisabledDontCreateIndexesWithNormalizedQuantitySearchSupported() {
|
||||
|
||||
|
||||
myDaoConfig.setIndexMissingFields(DaoConfig.IndexEnabledEnum.DISABLED);
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
Organization org = new Organization();
|
||||
org.setActive(true);
|
||||
myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
@ -94,12 +108,12 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
|
|||
assertThat(myResourceIndexedSearchParamQuantityDao.findAll(), empty());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testIndexMissingFieldsDisabledDontCreateIndexesWithNormalizedQuantityStorageSupported() {
|
||||
|
||||
|
||||
myDaoConfig.setIndexMissingFields(DaoConfig.IndexEnabledEnum.DISABLED);
|
||||
myModelConfig.setNormalizedQuantityStorageSupported();
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED);
|
||||
Organization org = new Organization();
|
||||
org.setActive(true);
|
||||
myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
@ -111,7 +125,7 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
|
|||
assertThat(myResourceIndexedSearchParamQuantityDao.findAll(), empty());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void testSearchResourceReferenceMissingChain() {
|
||||
|
@ -221,8 +235,8 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
|
|||
String locId = myLocationDao.create(new Location(), mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||
String locId2 = myLocationDao.create(new Location().setPosition(new Location.LocationPositionComponent(new DecimalType(10), new DecimalType(10))), mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
runInTransaction(()->{
|
||||
ourLog.info("Coords:\n * {}", myResourceIndexedSearchParamCoordsDao.findAll().stream().map(t->t.toString()).collect(Collectors.joining("\n * ")));
|
||||
runInTransaction(() -> {
|
||||
ourLog.info("Coords:\n * {}", myResourceIndexedSearchParamCoordsDao.findAll().stream().map(t -> t.toString()).collect(Collectors.joining("\n * ")));
|
||||
});
|
||||
|
||||
{
|
||||
|
@ -309,8 +323,8 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testSearchWithMissingQuantityWithNormalizedQuantitySearchSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
IIdType notMissing;
|
||||
IIdType missing;
|
||||
{
|
||||
|
@ -324,6 +338,12 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
|
|||
obs.setValue(new Quantity(123));
|
||||
notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
runInTransaction(() -> {
|
||||
ourLog.info("Quantity Indexes:\n * {}", myResourceIndexedSearchParamQuantityDao.findAll().stream().filter(t -> t.getParamName().equals("value-quantity")).map(t -> t.toString()).collect(Collectors.joining("\n * ")));
|
||||
ourLog.info("Normalized Quantity Indexes:\n * {}", myResourceIndexedSearchParamQuantityNormalizedDao.findAll().stream().filter(t -> t.getParamName().equals("value-quantity")).map(t -> t.toString()).collect(Collectors.joining("\n * ")));
|
||||
});
|
||||
|
||||
// Quantity Param
|
||||
{
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
|
@ -341,17 +361,19 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
|
|||
QuantityParam param = new QuantityParam();
|
||||
param.setMissing(true);
|
||||
params.add(Observation.SP_VALUE_QUANTITY, param);
|
||||
myCaptureQueriesListener.clear();
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(myObservationDao.search(params));
|
||||
myCaptureQueriesListener.logSelectQueries();
|
||||
assertThat(patients, containsInRelativeOrder(missing));
|
||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSearchWithMissingQuantityWithNormalizedQuantityStorageSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantityStorageSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED);
|
||||
IIdType notMissing;
|
||||
IIdType missing;
|
||||
{
|
||||
|
@ -386,10 +408,10 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test {
|
|||
assertThat(patients, containsInRelativeOrder(missing));
|
||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testSearchWithMissingReference() {
|
||||
IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId().toUnqualifiedVersionless();
|
||||
|
|
|
@ -34,6 +34,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
|
@ -185,8 +186,8 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
myDaoConfig.setAllowContainsSearches(new DaoConfig().isAllowContainsSearches());
|
||||
myDaoConfig.setSearchPreFetchThresholds(new DaoConfig().getSearchPreFetchThresholds());
|
||||
myDaoConfig.setIndexMissingFields(new DaoConfig().getIndexMissingFields());
|
||||
myModelConfig.setNormalizedQuantitySearchNotSupported();
|
||||
}
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void beforeDisableCacheReuse() {
|
||||
|
@ -1236,8 +1237,8 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testIndexNoDuplicatesQuantityWithNormalizedQuantitySearchSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
Substance res = new Substance();
|
||||
res.addInstance().getQuantity().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("m").setValue(123);
|
||||
res.addInstance().getQuantity().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("m").setValue(123);
|
||||
|
@ -1246,20 +1247,6 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
|
||||
IIdType id = mySubstanceDao.create(res, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
||||
runInTransaction(() -> {
|
||||
Class<ResourceIndexedSearchParamQuantity> type = ResourceIndexedSearchParamQuantity.class;
|
||||
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
|
||||
ourLog.info(toStringMultiline(results));
|
||||
assertEquals(2, results.size());
|
||||
});
|
||||
|
||||
runInTransaction(() -> {
|
||||
Class<ResourceIndexedSearchParamQuantityNormalized> type = ResourceIndexedSearchParamQuantityNormalized.class;
|
||||
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
|
||||
ourLog.info(toStringMultiline(results));
|
||||
assertEquals(2, results.size());
|
||||
});
|
||||
|
||||
List<IIdType> actual = toUnqualifiedVersionlessIds(
|
||||
mySubstanceDao.search(new SearchParameterMap().setLoadSynchronous(true).add(Substance.SP_QUANTITY, new QuantityParam(null, 12300, UcumServiceUtil.UCUM_CODESYSTEM_URL, "cm"))));
|
||||
assertThat(actual, contains(id));
|
||||
|
@ -1268,26 +1255,12 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testQuantityWithNormalizedQuantitySearchSupported_InvalidUCUMCode() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
Substance res = new Substance();
|
||||
res.addInstance().getQuantity().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("FOO").setValue(123);
|
||||
|
||||
IIdType id = mySubstanceDao.create(res, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
||||
runInTransaction(() -> {
|
||||
Class<ResourceIndexedSearchParamQuantity> type = ResourceIndexedSearchParamQuantity.class;
|
||||
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
|
||||
ourLog.info(toStringMultiline(results));
|
||||
assertEquals(1, results.size());
|
||||
});
|
||||
|
||||
runInTransaction(() -> {
|
||||
Class<ResourceIndexedSearchParamQuantityNormalized> type = ResourceIndexedSearchParamQuantityNormalized.class;
|
||||
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
|
||||
ourLog.info(toStringMultiline(results));
|
||||
assertEquals(1, results.size());
|
||||
});
|
||||
|
||||
List<IIdType> actual = toUnqualifiedVersionlessIds(
|
||||
mySubstanceDao.search(new SearchParameterMap().setLoadSynchronous(true).add(Substance.SP_QUANTITY, new QuantityParam(null, 123, UcumServiceUtil.UCUM_CODESYSTEM_URL, "FOO"))));
|
||||
|
@ -1297,27 +1270,13 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testQuantityWithNormalizedQuantitySearchSupported_NotUCUM() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
Substance res = new Substance();
|
||||
res.addInstance().getQuantity().setSystem("http://bar").setCode("FOO").setValue(123);
|
||||
|
||||
IIdType id = mySubstanceDao.create(res, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
||||
runInTransaction(() -> {
|
||||
Class<ResourceIndexedSearchParamQuantity> type = ResourceIndexedSearchParamQuantity.class;
|
||||
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
|
||||
ourLog.info(toStringMultiline(results));
|
||||
assertEquals(1, results.size());
|
||||
});
|
||||
|
||||
runInTransaction(() -> {
|
||||
Class<ResourceIndexedSearchParamQuantityNormalized> type = ResourceIndexedSearchParamQuantityNormalized.class;
|
||||
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
|
||||
ourLog.info(toStringMultiline(results));
|
||||
assertEquals(1, results.size());
|
||||
});
|
||||
|
||||
List<IIdType> actual = toUnqualifiedVersionlessIds(
|
||||
mySubstanceDao.search(new SearchParameterMap().setLoadSynchronous(true).add(Substance.SP_QUANTITY, new QuantityParam(null, 123, "http://bar", "FOO"))));
|
||||
assertThat(actual, contains(id));
|
||||
|
@ -1326,8 +1285,8 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testIndexNoDuplicatesQuantityWithNormalizedQuantityStorageSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantityStorageSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED);
|
||||
Substance res = new Substance();
|
||||
res.addInstance().getQuantity().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("m").setValue(123);
|
||||
res.addInstance().getQuantity().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("m").setValue(123);
|
||||
|
@ -1336,20 +1295,6 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
|
||||
IIdType id = mySubstanceDao.create(res, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
||||
runInTransaction(() -> {
|
||||
Class<ResourceIndexedSearchParamQuantity> type = ResourceIndexedSearchParamQuantity.class;
|
||||
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
|
||||
ourLog.info(toStringMultiline(results));
|
||||
assertEquals(2, results.size());
|
||||
});
|
||||
|
||||
runInTransaction(() -> {
|
||||
Class<ResourceIndexedSearchParamQuantityNormalized> type = ResourceIndexedSearchParamQuantityNormalized.class;
|
||||
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
|
||||
ourLog.info(toStringMultiline(results));
|
||||
assertEquals(2, results.size());
|
||||
});
|
||||
|
||||
List<IIdType> actual = toUnqualifiedVersionlessIds(
|
||||
mySubstanceDao.search(new SearchParameterMap().setLoadSynchronous(true).add(Substance.SP_QUANTITY, new QuantityParam(null, 123, UcumServiceUtil.UCUM_CODESYSTEM_URL, "m"))));
|
||||
assertThat(actual, contains(id));
|
||||
|
@ -2753,8 +2698,8 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testSearchByMoneyParamWithNormalizedQuantitySearchSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
ChargeItem ci = new ChargeItem();
|
||||
ci.getPriceOverride().setValue(123).setCurrency("$");
|
||||
|
||||
|
@ -3119,8 +3064,8 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testSearchQuantityWithNormalizedQuantitySearchSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
Condition c1 = new Condition();
|
||||
c1.setAbatement(new Range().setLow(new SimpleQuantity().setValue(1L)).setHigh(new SimpleQuantity().setValue(1L)));
|
||||
String id1 = myConditionDao.create(c1).getId().toUnqualifiedVersionless().getValue();
|
||||
|
|
|
@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.dao.r4;
|
|||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.data.ISearchDao;
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamNumber;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantity;
|
||||
|
@ -143,8 +144,8 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
|
|||
myDaoConfig.setFetchSizeDefaultMaximum(new DaoConfig().getFetchSizeDefaultMaximum());
|
||||
myDaoConfig.setAllowContainsSearches(new DaoConfig().isAllowContainsSearches());
|
||||
myDaoConfig.setDisableHashBasedSearches(false);
|
||||
myModelConfig.setNormalizedQuantitySearchNotSupported();
|
||||
}
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void beforeInitialize() {
|
||||
|
@ -1193,8 +1194,8 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testComponentQuantityWithNormalizedQuantitySearchSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
Observation o1 = new Observation();
|
||||
o1.addComponent()
|
||||
.setCode(new CodeableConcept().addCoding(new Coding().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm")))
|
||||
|
@ -1216,8 +1217,8 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testComponentQuantityWithNormalizedQuantityStorageSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantityStorageSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED);
|
||||
Observation o1 = new Observation();
|
||||
o1.addComponent()
|
||||
.setCode(new CodeableConcept().addCoding(new Coding().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm")))
|
||||
|
@ -1292,8 +1293,8 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testSearchCompositeParamQuantityWithNormalizedQuantitySearchSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
Observation o1 = new Observation();
|
||||
o1.addComponent()
|
||||
.setCode(new CodeableConcept().addCoding(new Coding().setSystem("http://foo").setCode("code1")))
|
||||
|
|
|
@ -7,6 +7,7 @@ import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
|||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.dao.JpaResourceDao;
|
||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
|
||||
|
@ -161,8 +162,8 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
|||
myDaoConfig.setEnforceReferentialIntegrityOnDelete(new DaoConfig().isEnforceReferentialIntegrityOnDelete());
|
||||
myDaoConfig.setEnforceReferenceTargetTypes(new DaoConfig().isEnforceReferenceTargetTypes());
|
||||
myDaoConfig.setIndexMissingFields(new DaoConfig().getIndexMissingFields());
|
||||
myModelConfig.setNormalizedQuantitySearchNotSupported();
|
||||
}
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void before() {
|
||||
|
@ -581,8 +582,8 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testChoiceParamQuantityWithNormalizedQuantitySearchSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
Observation o3 = new Observation();
|
||||
o3.getCode().addCoding().setSystem("foo").setCode("testChoiceParam03");
|
||||
o3.setValue(new Quantity(QuantityComparator.GREATER_THAN, 123.0, UcumServiceUtil.UCUM_CODESYSTEM_URL, "cm", "cm")); // 0.0123m
|
||||
|
@ -682,8 +683,8 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testChoiceParamQuantityPrecisionWithNormalizedQuantitySearchSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
Observation o3 = new Observation();
|
||||
o3.getCode().addCoding().setSystem("foo").setCode("testChoiceParam03");
|
||||
o3.setValue(new Quantity(null, 123.01, UcumServiceUtil.UCUM_CODESYSTEM_URL, "cm", "cm")); // 0.012301 m
|
||||
|
@ -3500,9 +3501,10 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testSortByQuantityWithNormalizedQuantitySearchSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
@Disabled
|
||||
public void testSortByQuantityWithNormalizedQuantitySearchFullSupported() {
|
||||
|
||||
// myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_FULL_SUPPORTED);
|
||||
Observation res;
|
||||
|
||||
res = new Observation();
|
||||
|
|
|
@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.dao.r4;
|
|||
|
||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
||||
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
|
||||
|
@ -23,7 +24,6 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
|||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
|
@ -61,7 +61,6 @@ import org.hl7.fhir.r4.model.Reference;
|
|||
import org.hl7.fhir.r4.model.Resource;
|
||||
import org.hl7.fhir.r4.model.ValueSet;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
|
@ -110,8 +109,8 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
|
|||
public void after() {
|
||||
myDaoConfig.setAllowInlineMatchUrlReferences(false);
|
||||
myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete());
|
||||
myModelConfig.setNormalizedQuantitySearchNotSupported();
|
||||
}
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void beforeDisableResultReuse() {
|
||||
|
@ -3131,7 +3130,7 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
|
|||
@Test
|
||||
public void testTransactionWithConditionalUpdateDoesntUpdateIfNoChangeWithNormalizedQuantitySearchSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
Observation obs = new Observation();
|
||||
obs.addIdentifier()
|
||||
.setSystem("http://acme.org")
|
||||
|
|
|
@ -1,20 +1,29 @@
|
|||
package ca.uhn.fhir.jpa.dao.r4;
|
||||
|
||||
import static java.util.Comparator.comparing;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.hl7.fhir.dstu2.model.SimpleQuantity;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.context.phonetic.IPhoneticEncoder;
|
||||
import ca.uhn.fhir.jpa.cache.ResourceChangeResult;
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantity;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantityNormalized;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
|
||||
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
|
||||
import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam;
|
||||
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
|
||||
import ca.uhn.fhir.jpa.searchparam.extractor.PathAndRef;
|
||||
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorR4;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ReadOnlySearchParamCache;
|
||||
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
|
||||
import ca.uhn.fhir.util.HapiExtensions;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.hl7.fhir.r4.model.BooleanType;
|
||||
import org.hl7.fhir.r4.model.CodeableConcept;
|
||||
import org.hl7.fhir.r4.model.Coding;
|
||||
|
@ -24,47 +33,30 @@ import org.hl7.fhir.r4.model.Extension;
|
|||
import org.hl7.fhir.r4.model.Observation;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.Quantity;
|
||||
import org.hl7.fhir.r4.model.Range;
|
||||
import org.hl7.fhir.r4.model.Reference;
|
||||
import org.hl7.fhir.r4.model.SearchParameter;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.context.phonetic.IPhoneticEncoder;
|
||||
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport;
|
||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.jpa.cache.ResourceChangeResult;
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantity;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantityNormalized;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
|
||||
import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam;
|
||||
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
|
||||
import ca.uhn.fhir.jpa.searchparam.extractor.PathAndRef;
|
||||
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorR4;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ReadOnlySearchParamCache;
|
||||
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
|
||||
import ca.uhn.fhir.util.HapiExtensions;
|
||||
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
|
||||
import static java.util.Comparator.comparing;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
public class SearchParamExtractorR4Test {
|
||||
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(SearchParamExtractorR4Test.class);
|
||||
private static FhirContext ourCtx = FhirContext.forCached(FhirVersionEnum.R4);
|
||||
private static IValidationSupport ourValidationSupport;
|
||||
private MySearchParamRegistry mySearchParamRegistry;
|
||||
private PartitionSettings myPartitionSettings;
|
||||
|
||||
|
@ -81,7 +73,7 @@ public class SearchParamExtractorR4Test {
|
|||
Observation obs = new Observation();
|
||||
obs.addCategory().addCoding().setSystem("SYSTEM").setCode("CODE");
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), new PartitionSettings(), ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), new PartitionSettings(), ourCtx, mySearchParamRegistry);
|
||||
Set<BaseResourceIndexedSearchParam> tokens = extractor.extractSearchParamTokens(obs);
|
||||
assertEquals(1, tokens.size());
|
||||
ResourceIndexedSearchParamToken token = (ResourceIndexedSearchParamToken) tokens.iterator().next();
|
||||
|
@ -95,7 +87,7 @@ public class SearchParamExtractorR4Test {
|
|||
SearchParameter sp = new SearchParameter();
|
||||
sp.addUseContext().setCode(new Coding().setSystem("http://system").setCode("code"));
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), new PartitionSettings(), ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), new PartitionSettings(), ourCtx, mySearchParamRegistry);
|
||||
Set<BaseResourceIndexedSearchParam> tokens = extractor.extractSearchParamTokens(sp);
|
||||
assertEquals(1, tokens.size());
|
||||
ResourceIndexedSearchParamToken token = (ResourceIndexedSearchParamToken) tokens.iterator().next();
|
||||
|
@ -109,7 +101,7 @@ public class SearchParamExtractorR4Test {
|
|||
Observation obs = new Observation();
|
||||
obs.getCode().addCoding().setSystem("http://system").setCode("code").setDisplay("Help Im a Bug");
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), myPartitionSettings, ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), myPartitionSettings, ourCtx, mySearchParamRegistry);
|
||||
|
||||
List<BaseResourceIndexedSearchParam> tokens = extractor.extractSearchParamTokens(obs)
|
||||
.stream()
|
||||
|
@ -138,7 +130,7 @@ public class SearchParamExtractorR4Test {
|
|||
Observation obs = new Observation();
|
||||
obs.getCode().addCoding().setSystem("http://system").setCode("code").setDisplay("Help Im a Bug");
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), myPartitionSettings, ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), myPartitionSettings, ourCtx, mySearchParamRegistry);
|
||||
|
||||
List<BaseResourceIndexedSearchParam> tokens = extractor.extractSearchParamTokens(obs)
|
||||
.stream()
|
||||
|
@ -162,7 +154,7 @@ public class SearchParamExtractorR4Test {
|
|||
Observation obs = new Observation();
|
||||
obs.getCode().addCoding().setSystem("http://system").setCode("code").setDisplay("Help Im a Bug");
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(modelConfig, myPartitionSettings, ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(modelConfig, myPartitionSettings, ourCtx, mySearchParamRegistry);
|
||||
|
||||
List<BaseResourceIndexedSearchParam> tokens = extractor.extractSearchParamTokens(obs)
|
||||
.stream()
|
||||
|
@ -191,7 +183,7 @@ public class SearchParamExtractorR4Test {
|
|||
Observation obs = new Observation();
|
||||
obs.getCode().addCoding().setSystem("http://system").setCode("code").setDisplay("Help Im a Bug");
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(modelConfig, myPartitionSettings, ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(modelConfig, myPartitionSettings, ourCtx, mySearchParamRegistry);
|
||||
|
||||
List<BaseResourceIndexedSearchParam> tokens = extractor.extractSearchParamTokens(obs)
|
||||
.stream()
|
||||
|
@ -216,7 +208,7 @@ public class SearchParamExtractorR4Test {
|
|||
Observation obs = new Observation();
|
||||
obs.addIdentifier().setSystem("sys").setValue("val").getType().setText("Help Im a Bug");
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), myPartitionSettings, ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), myPartitionSettings, ourCtx, mySearchParamRegistry);
|
||||
|
||||
List<BaseResourceIndexedSearchParam> tokens = extractor.extractSearchParamTokens(obs)
|
||||
.stream()
|
||||
|
@ -246,7 +238,7 @@ public class SearchParamExtractorR4Test {
|
|||
Observation obs = new Observation();
|
||||
obs.addIdentifier().setSystem("sys").setValue("val").getType().setText("Help Im a Bug");
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), myPartitionSettings, ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), myPartitionSettings, ourCtx, mySearchParamRegistry);
|
||||
|
||||
List<BaseResourceIndexedSearchParam> tokens = extractor.extractSearchParamTokens(obs)
|
||||
.stream()
|
||||
|
@ -267,7 +259,7 @@ public class SearchParamExtractorR4Test {
|
|||
Encounter enc = new Encounter();
|
||||
enc.addLocation().setLocation(new Reference("Location/123"));
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), new PartitionSettings(), ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), new PartitionSettings(), ourCtx, mySearchParamRegistry);
|
||||
RuntimeSearchParam param = mySearchParamRegistry.getActiveSearchParam("Encounter", "location");
|
||||
assertNotNull(param);
|
||||
ISearchParamExtractor.SearchParamSet<PathAndRef> links = extractor.extractResourceLinks(enc);
|
||||
|
@ -282,7 +274,7 @@ public class SearchParamExtractorR4Test {
|
|||
Consent consent = new Consent();
|
||||
consent.setSource(new Reference().setReference("Consent/999"));
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), new PartitionSettings(), ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), new PartitionSettings(), ourCtx, mySearchParamRegistry);
|
||||
RuntimeSearchParam param = mySearchParamRegistry.getActiveSearchParam("Consent", Consent.SP_SOURCE_REFERENCE);
|
||||
assertNotNull(param);
|
||||
ISearchParamExtractor.SearchParamSet<PathAndRef> links = extractor.extractResourceLinks(consent);
|
||||
|
@ -297,7 +289,7 @@ public class SearchParamExtractorR4Test {
|
|||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("sys").setValue("val");
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), new PartitionSettings(), ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), new PartitionSettings(), ourCtx, mySearchParamRegistry);
|
||||
RuntimeSearchParam param = mySearchParamRegistry.getActiveSearchParam("Patient", Patient.SP_IDENTIFIER);
|
||||
assertNotNull(param);
|
||||
ISearchParamExtractor.SearchParamSet<BaseResourceIndexedSearchParam> params = extractor.extractSearchParamTokens(p, param);
|
||||
|
@ -319,7 +311,7 @@ public class SearchParamExtractorR4Test {
|
|||
Patient patient = new Patient();
|
||||
patient.addExtension("http://patext", new Reference("Organization/AAA"));
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), new PartitionSettings(), ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), new PartitionSettings(), ourCtx, mySearchParamRegistry);
|
||||
ISearchParamExtractor.SearchParamSet<PathAndRef> links = extractor.extractResourceLinks(patient);
|
||||
assertEquals(1, links.size());
|
||||
|
||||
|
@ -335,7 +327,7 @@ public class SearchParamExtractorR4Test {
|
|||
.setCode(new CodeableConcept().addCoding(new Coding().setSystem("http://foo").setCode("code2")))
|
||||
.setValue(new Quantity().setSystem("http://bar").setCode("code2").setValue(200));
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), new PartitionSettings(), ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), new PartitionSettings(), ourCtx, mySearchParamRegistry);
|
||||
Set<ResourceIndexedSearchParamQuantity> links = extractor.extractSearchParamQuantity(o1);
|
||||
ourLog.info("Links:\n {}", links.stream().map(t -> t.toString()).collect(Collectors.joining("\n ")));
|
||||
assertEquals(4, links.size());
|
||||
|
@ -343,44 +335,44 @@ public class SearchParamExtractorR4Test {
|
|||
|
||||
@Test
|
||||
public void testExtractComponentQuantityWithNormalizedQuantitySearchSupported() {
|
||||
|
||||
|
||||
ModelConfig modelConfig = new ModelConfig();
|
||||
|
||||
modelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
|
||||
modelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
|
||||
Observation o1 = new Observation();
|
||||
o1.addComponent()
|
||||
.setCode(new CodeableConcept().addCoding(new Coding().setSystem("http://foo").setCode("code1")))
|
||||
.setValue(new Quantity().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm").setValue(200));
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(modelConfig, new PartitionSettings(), ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(modelConfig, new PartitionSettings(), ourCtx, mySearchParamRegistry);
|
||||
Set<ResourceIndexedSearchParamQuantityNormalized> links = extractor.extractSearchParamQuantityNormalized(o1);
|
||||
ourLog.info("Links:\n {}", links.stream().map(t -> t.toString()).collect(Collectors.joining("\n ")));
|
||||
assertEquals(2, links.size());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testExtractComponentQuantityValueWithNormalizedQuantitySearchSupported() {
|
||||
|
||||
|
||||
ModelConfig modelConfig = new ModelConfig();
|
||||
|
||||
modelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
|
||||
modelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
|
||||
Observation o1 = new Observation();
|
||||
|
||||
|
||||
o1.addComponent()
|
||||
.setCode(new CodeableConcept().addCoding(new Coding().setSystem("http://foo").setCode("code1")))
|
||||
.setValue(new Quantity().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm").setValue(200));
|
||||
|
||||
RuntimeSearchParam existingCodeSp = mySearchParamRegistry.getActiveSearchParams("Observation").get("component-value-quantity");
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(modelConfig, new PartitionSettings(), ourCtx, ourValidationSupport, mySearchParamRegistry);
|
||||
|
||||
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(modelConfig, new PartitionSettings(), ourCtx, mySearchParamRegistry);
|
||||
List<String> list = extractor.extractParamValuesAsStrings(existingCodeSp, o1);
|
||||
|
||||
assertEquals(1, list.size());
|
||||
|
||||
assertEquals(2, list.size());
|
||||
}
|
||||
|
||||
|
||||
private static class MySearchParamRegistry implements ISearchParamRegistry {
|
||||
|
||||
|
||||
|
@ -457,9 +449,4 @@ public class SearchParamExtractorR4Test {
|
|||
}
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
public static void beforeClass() {
|
||||
ourValidationSupport = new DefaultProfileValidationSupport(ourCtx);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
|||
import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
|
||||
import ca.uhn.fhir.jpa.dao.data.ISearchDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
|
||||
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
|
||||
import ca.uhn.fhir.jpa.search.PersistedJpaSearchFirstPageBundleProvider;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
|
@ -62,8 +63,8 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
|
|||
@AfterEach
|
||||
public void afterDisableExpunge() {
|
||||
myDaoConfig.setExpungeEnabled(new DaoConfig().isExpungeEnabled());
|
||||
myModelConfig.setNormalizedQuantitySearchNotSupported();
|
||||
}
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEnableExpunge() {
|
||||
|
@ -402,7 +403,7 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
|
|||
|
||||
@Test
|
||||
public void testExpungeSystemEverythingWithNormalizedQuantitySearchSupported() {
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
createStandardPatients();
|
||||
|
||||
mySystemDao.expunge(new ExpungeOptions()
|
||||
|
@ -424,7 +425,7 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
|
|||
|
||||
@Test
|
||||
public void testExpungeSystemEverythingWithNormalizedQuantityStorageSupported() {
|
||||
myModelConfig.setNormalizedQuantityStorageSupported();
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED);
|
||||
createStandardPatients();
|
||||
|
||||
mySystemDao.expunge(new ExpungeOptions()
|
||||
|
|
|
@ -47,6 +47,7 @@ import java.util.Set;
|
|||
import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
@ -217,9 +218,9 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
|||
mySearchCoordinatorSvcRaw.setSyncSizeForUnitTests(SearchCoordinatorSvcImpl.DEFAULT_SYNC_SIZE);
|
||||
mySearchCoordinatorSvcRaw.setNeverUseLocalSearchForUnitTests(false);
|
||||
mySearchCoordinatorSvcRaw.cancelAllActiveSearches();
|
||||
myDaoConfig.getModelConfig().setNormalizedQuantitySearchNotSupported();
|
||||
myDaoConfig.getModelConfig().setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
|
||||
|
||||
myClient.unregisterInterceptor(myCapturingInterceptor);
|
||||
myClient.unregisterInterceptor(myCapturingInterceptor);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
|
@ -4085,8 +4086,8 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
|||
|
||||
@Test
|
||||
public void testSearchWithNormalizedQuantitySearchSupported() throws Exception {
|
||||
|
||||
myDaoConfig.getModelConfig().setNormalizedQuantitySearchSupported();
|
||||
|
||||
myDaoConfig.getModelConfig().setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
IIdType pid0;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
|
@ -4167,8 +4168,8 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
|||
|
||||
@Test
|
||||
public void testSearchWithNormalizedQuantitySearchSupported_CombineUCUMOrNonUCUM() throws Exception {
|
||||
|
||||
myDaoConfig.getModelConfig().setNormalizedQuantitySearchSupported();
|
||||
|
||||
myDaoConfig.getModelConfig().setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
IIdType pid0;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
|
@ -4222,11 +4223,17 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
|||
ourLog.info("Observation: \n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||
}
|
||||
|
||||
// > 1m
|
||||
String uri = ourServerBase + "/Observation?value-quantity=" + UrlUtil.escapeUrlParam("100|http://unitsofmeasure.org|cm,100|http://foo|cm");
|
||||
|
||||
ourLog.info("uri = " + uri);
|
||||
List<String> ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
||||
String uri;
|
||||
List<String> ids;
|
||||
|
||||
// With non-normalized
|
||||
uri = ourServerBase + "/Observation?value-quantity=" + UrlUtil.escapeUrlParam("100|http://unitsofmeasure.org|cm,100|http://foo|cm");
|
||||
ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
||||
assertEquals(1, ids.size());
|
||||
|
||||
// With normalized
|
||||
uri = ourServerBase + "/Observation?value-quantity=" + UrlUtil.escapeUrlParam("1|http://unitsofmeasure.org|m,100|http://foo|cm");
|
||||
ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
||||
assertEquals(2, ids.size());
|
||||
}
|
||||
|
||||
|
@ -6044,8 +6051,8 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
|||
|
||||
@Test
|
||||
public void testUpdateWithNormalizedQuantitySearchSupported() throws Exception {
|
||||
|
||||
myDaoConfig.getModelConfig().setNormalizedQuantitySearchSupported();
|
||||
|
||||
myDaoConfig.getModelConfig().setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
IIdType pid0;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
|
|
|
@ -4,6 +4,7 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
|
||||
import ca.uhn.fhir.jpa.config.TestR4Config;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
|
||||
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
|
||||
import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
|
||||
|
@ -103,8 +104,8 @@ public class InMemorySubscriptionMatcherR4Test {
|
|||
|
||||
@AfterEach
|
||||
public void after() throws Exception {
|
||||
myModelConfig.setNormalizedQuantitySearchNotSupported();
|
||||
}
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
private void assertMatched(Resource resource, SearchParameterMap params) {
|
||||
InMemoryMatchResult result = match(resource, params);
|
||||
|
@ -249,8 +250,8 @@ public class InMemorySubscriptionMatcherR4Test {
|
|||
|
||||
@Test
|
||||
public void testSearchWithNormalizedQuantitySearchSupported() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
|
||||
Observation o1 = new Observation();
|
||||
o1.addComponent()
|
||||
|
@ -282,8 +283,8 @@ public class InMemorySubscriptionMatcherR4Test {
|
|||
|
||||
@Test
|
||||
public void testSearchWithNormalizedQuantitySearchSupported_InvalidUCUMUnit() {
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
|
||||
Observation o1 = new Observation();
|
||||
o1.addComponent()
|
||||
.setCode(new CodeableConcept().addCoding(new Coding().setSystem("http://bar").setCode("foo")))
|
||||
|
@ -298,8 +299,8 @@ public class InMemorySubscriptionMatcherR4Test {
|
|||
|
||||
@Test
|
||||
public void testSearchWithNormalizedQuantitySearchSupported_NoSystem() {
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
|
||||
Observation o1 = new Observation();
|
||||
o1.addComponent()
|
||||
.setCode(new CodeableConcept().addCoding(new Coding().setSystem("http://bar").setCode("foo")))
|
||||
|
@ -314,9 +315,9 @@ public class InMemorySubscriptionMatcherR4Test {
|
|||
|
||||
@Test
|
||||
public void testSearchWithNormalizedQuantitySearchSupported_NotUcumSystem() {
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchSupported();
|
||||
|
||||
|
||||
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
|
||||
Observation o1 = new Observation();
|
||||
o1.addComponent()
|
||||
.setCode(new CodeableConcept().addCoding(new Coding().setSystem("http://foo").setCode("cm")))
|
||||
|
|
|
@ -22,14 +22,14 @@ package ca.uhn.fhir.jpa.migrate.taskdef;
|
|||
|
||||
public enum ColumnTypeEnum {
|
||||
|
||||
LONG,
|
||||
STRING,
|
||||
DATE_ONLY,
|
||||
DATE_TIMESTAMP,
|
||||
BOOLEAN,
|
||||
FLOAT,
|
||||
INT,
|
||||
BLOB,
|
||||
CLOB
|
||||
|
||||
LONG,
|
||||
STRING,
|
||||
DATE_ONLY,
|
||||
DATE_TIMESTAMP,
|
||||
BOOLEAN,
|
||||
FLOAT,
|
||||
INT,
|
||||
BLOB,
|
||||
CLOB,
|
||||
DOUBLE;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,14 @@ public class ColumnTypeToDriverTypeToSqlType {
|
|||
setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.ORACLE_12C, "float");
|
||||
setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.POSTGRES_9_4, "float");
|
||||
|
||||
setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.H2_EMBEDDED, "double");
|
||||
setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.DERBY_EMBEDDED, "double");
|
||||
setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.MARIADB_10_1, "double precision");
|
||||
setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.MYSQL_5_7, "double precision");
|
||||
setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.MSSQL_2012, "double precision");
|
||||
setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.ORACLE_12C, "double precision");
|
||||
setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.POSTGRES_9_4, "float8");
|
||||
|
||||
setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.H2_EMBEDDED, "bigint");
|
||||
setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.DERBY_EMBEDDED, "bigint");
|
||||
setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.MARIADB_10_1, "bigint");
|
||||
|
|
|
@ -119,6 +119,10 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
|
|||
.addForeignKey("20210111.3", "FKRCJOVMUH5KC0O6FVBLE319PYV")
|
||||
.toColumn("RES_ID")
|
||||
.references("HFJ_RESOURCE", "RES_ID");
|
||||
|
||||
Builder.BuilderWithTableName quantityTable = version.onTable("HFJ_SPIDX_QUANTITY");
|
||||
quantityTable.modifyColumn("20210116.1", "SP_VALUE").nullable().failureAllowed().withType(ColumnTypeEnum.DOUBLE);
|
||||
|
||||
}
|
||||
|
||||
protected void init520() {
|
||||
|
|
|
@ -90,7 +90,7 @@ public class ModelConfig {
|
|||
private IPrimitiveType<Date> myPeriodIndexEndOfTime;
|
||||
|
||||
private NormalizedQuantitySearchLevel myNormalizedQuantitySearchLevel;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
@ -576,6 +576,47 @@ public class ModelConfig {
|
|||
myPeriodIndexEndOfTime = thePeriodIndexEndOfTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles whether Quantity searches support value normalization when using valid UCUM coded values.
|
||||
*
|
||||
* <p>
|
||||
* The default value is {@link NormalizedQuantitySearchLevel#NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED} which is current behavior.
|
||||
* </p>
|
||||
* <p>
|
||||
* Here is the UCUM service support level
|
||||
* <ul>
|
||||
* <li>{@link NormalizedQuantitySearchLevel#NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED}, default, Quantity is stored in {@link ResourceIndexedSearchParamQuantity} only and it is used by searching.</li>
|
||||
* <li>{@link NormalizedQuantitySearchLevel#NORMALIZED_QUANTITY_STORAGE_SUPPORTED}, Quantity is stored in both {@link ResourceIndexedSearchParamQuantity} and {@link ResourceIndexedSearchParamQuantityNormalized}, but {@link ResourceIndexedSearchParamQuantity} is used by searching.</li>
|
||||
* <li>{@link NormalizedQuantitySearchLevel#NORMALIZED_QUANTITY_SEARCH_SUPPORTED}, Quantity is stored in both {@link ResourceIndexedSearchParamQuantity} and {@link ResourceIndexedSearchParamQuantityNormalized}, {@link ResourceIndexedSearchParamQuantityNormalized} is used by searching.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @since 5.3.0
|
||||
*/
|
||||
public NormalizedQuantitySearchLevel getNormalizedQuantitySearchLevel() {
|
||||
return myNormalizedQuantitySearchLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles whether Quantity searches support value normalization when using valid UCUM coded values.
|
||||
*
|
||||
* <p>
|
||||
* The default value is {@link NormalizedQuantitySearchLevel#NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED} which is current behavior.
|
||||
* </p>
|
||||
* <p>
|
||||
* Here is the UCUM service support level
|
||||
* <ul>
|
||||
* <li>{@link NormalizedQuantitySearchLevel#NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED}, default, Quantity is stored in {@link ResourceIndexedSearchParamQuantity} only and it is used by searching.</li>
|
||||
* <li>{@link NormalizedQuantitySearchLevel#NORMALIZED_QUANTITY_STORAGE_SUPPORTED}, Quantity is stored in both {@link ResourceIndexedSearchParamQuantity} and {@link ResourceIndexedSearchParamQuantityNormalized}, but {@link ResourceIndexedSearchParamQuantity} is used by searching.</li>
|
||||
* <li>{@link NormalizedQuantitySearchLevel#NORMALIZED_QUANTITY_SEARCH_SUPPORTED}, Quantity is stored in both {@link ResourceIndexedSearchParamQuantity} and {@link ResourceIndexedSearchParamQuantityNormalized}, {@link ResourceIndexedSearchParamQuantityNormalized} is used by searching.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @since 5.3.0
|
||||
*/
|
||||
public void setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel theNormalizedQuantitySearchLevel) {
|
||||
myNormalizedQuantitySearchLevel = theNormalizedQuantitySearchLevel;
|
||||
}
|
||||
|
||||
private static void validateTreatBaseUrlsAsLocal(String theUrl) {
|
||||
Validate.notBlank(theUrl, "Base URL must not be null or empty");
|
||||
|
@ -589,43 +630,4 @@ public class ModelConfig {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the UCUM service support level
|
||||
*
|
||||
* <p>
|
||||
* The default value is {@link NormalizedQuantitySearchLevel#NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED} which is current behavior.
|
||||
* </p>
|
||||
* <p>
|
||||
* Here is the UCUM service support level
|
||||
* <ul>
|
||||
* <li>{@link NormalizedQuantitySearchLevel#NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED}, default, Quantity is stored in {@link ResourceIndexedSearchParamQuantity} only and it is used by searching.</li>
|
||||
* <li>{@link NormalizedQuantitySearchLevel#NORMALIZED_QUANTITY_STORAGE_SUPPORTED}, Quantity is stored in both {@link ResourceIndexedSearchParamQuantity} and {@link ResourceIndexedSearchParamQuantityNormalized}, but {@link ResourceIndexedSearchParamQuantity} is used by searching.</li>
|
||||
* <li>{@link NormalizedQuantitySearchLevel#NORMALIZED_QUANTITY_SEARCH_SUPPORTED}, Quantity is stored in both {@link ResourceIndexedSearchParamQuantity} and {@link ResourceIndexedSearchParamQuantityNormalized}, {@link ResourceIndexedSearchParamQuantityNormalized} is used by searching.</li>
|
||||
* <li>{@link NormalizedQuantitySearchLevel#NORMALIZED_QUANTITY_SEARCH_FULL_SUPPORTED}, Quantity is stored in only in {@link ResourceIndexedSearchParamQuantityNormalized}, {@link ResourceIndexedSearchParamQuantityNormalized} is used by searching. NOTE: this option is not supported yet.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @since 5.3.0
|
||||
*/
|
||||
public NormalizedQuantitySearchLevel getNormalizedQuantitySearchLevel() {
|
||||
return myNormalizedQuantitySearchLevel;
|
||||
}
|
||||
public void setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel theNormalizedQuantitySearchLevel) {
|
||||
myNormalizedQuantitySearchLevel = theNormalizedQuantitySearchLevel;
|
||||
}
|
||||
public boolean isNormalizedQuantitySearchSupported() {
|
||||
return myNormalizedQuantitySearchLevel.equals(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED);
|
||||
}
|
||||
public boolean isNormalizedQuantityStorageSupported() {
|
||||
return myNormalizedQuantitySearchLevel.equals(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED);
|
||||
}
|
||||
public void setNormalizedQuantitySearchNotSupported() {
|
||||
myNormalizedQuantitySearchLevel = NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED;
|
||||
}
|
||||
public void setNormalizedQuantityStorageSupported() {
|
||||
myNormalizedQuantitySearchLevel = NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED;
|
||||
}
|
||||
public void setNormalizedQuantitySearchSupported() {
|
||||
myNormalizedQuantitySearchLevel = NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,5 +53,6 @@ public enum NormalizedQuantitySearchLevel {
|
|||
* The existing non normalized quantity will be not supported
|
||||
* NOTE: this option is not supported in this release
|
||||
*/
|
||||
// When this is enabled, we can enable testSortByQuantityWithNormalizedQuantitySearchFullSupported()
|
||||
//NORMALIZED_QUANTITY_SEARCH_FULL_SUPPORTED,
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ public class ResourceIndexedSearchParamQuantity extends ResourceIndexedSearchPar
|
|||
|
||||
@Column(name = "SP_VALUE", nullable = true)
|
||||
@ScaledNumberField
|
||||
public BigDecimal myValue;
|
||||
public Double myValue;
|
||||
|
||||
public ResourceIndexedSearchParamQuantity() {
|
||||
super();
|
||||
|
@ -99,11 +99,11 @@ public class ResourceIndexedSearchParamQuantity extends ResourceIndexedSearchPar
|
|||
}
|
||||
|
||||
public BigDecimal getValue() {
|
||||
return myValue;
|
||||
return myValue != null ? new BigDecimal(myValue) : null;
|
||||
}
|
||||
|
||||
public ResourceIndexedSearchParamQuantity setValue(BigDecimal theValue) {
|
||||
myValue = theValue;
|
||||
myValue = theValue != null ? theValue.doubleValue() : null;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ import org.apache.commons.lang3.builder.EqualsBuilder;
|
|||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import org.fhir.ucum.Pair;
|
||||
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField;
|
||||
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.ScaledNumberField;
|
||||
|
||||
|
||||
|
@ -84,23 +83,14 @@ public class ResourceIndexedSearchParamQuantityNormalized extends ResourceIndexe
|
|||
super();
|
||||
}
|
||||
|
||||
public ResourceIndexedSearchParamQuantityNormalized(PartitionSettings thePartitionSettings, String theResourceType, String theParamName, BigDecimal theValue, String theSystem, String theUnits) {
|
||||
public ResourceIndexedSearchParamQuantityNormalized(PartitionSettings thePartitionSettings, String theResourceType, String theParamName, double theValue, String theSystem, String theUnits) {
|
||||
this();
|
||||
setPartitionSettings(thePartitionSettings);
|
||||
setResourceType(theResourceType);
|
||||
setParamName(theParamName);
|
||||
setSystem(theSystem);
|
||||
|
||||
//-- convert the value/unit to the canonical form if any, otherwise store the original value/units pair
|
||||
Pair canonicalForm = UcumServiceUtil.getCanonicalForm(theSystem, theValue, theUnits);
|
||||
if (canonicalForm != null) {
|
||||
setValue(Double.parseDouble(canonicalForm.getValue().asDecimal()));
|
||||
setUnits(canonicalForm.getCode());
|
||||
} else {
|
||||
setValue(theValue);
|
||||
setUnits(theUnits);
|
||||
}
|
||||
|
||||
setValue(theValue);
|
||||
setUnits(theUnits);
|
||||
calculateHashes();
|
||||
}
|
||||
|
||||
|
@ -123,17 +113,13 @@ public class ResourceIndexedSearchParamQuantityNormalized extends ResourceIndexe
|
|||
public ResourceIndexedSearchParamQuantityNormalized setValue(Double theValue) {
|
||||
myValue = theValue;
|
||||
return this;
|
||||
}
|
||||
public void setValue(BigDecimal theValue) {
|
||||
if (theValue != null)
|
||||
myValue = theValue.doubleValue();
|
||||
}
|
||||
public BigDecimal getValueBigDecimal() {
|
||||
if (myValue == null)
|
||||
return null;
|
||||
return new BigDecimal(myValue);
|
||||
|
||||
public ResourceIndexedSearchParamQuantityNormalized setValue(double theValue) {
|
||||
myValue = theValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
//-- myId
|
||||
@Override
|
||||
public Long getId() {
|
||||
|
|
|
@ -23,6 +23,7 @@ package ca.uhn.fhir.jpa.model.util;
|
|||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import ca.uhn.fhir.rest.param.QuantityParam;
|
||||
import org.fhir.ucum.Decimal;
|
||||
import org.fhir.ucum.Pair;
|
||||
import org.fhir.ucum.UcumEssenceService;
|
||||
|
@ -32,6 +33,8 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import ca.uhn.fhir.util.ClasspathUtil;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* It's a wrapper of UcumEssenceService
|
||||
*
|
||||
|
@ -85,7 +88,7 @@ public class UcumServiceUtil {
|
|||
return null;
|
||||
|
||||
init();
|
||||
Pair theCanonicalPair = null;
|
||||
Pair theCanonicalPair;
|
||||
|
||||
try {
|
||||
Decimal theDecimal = new Decimal(theValue.toPlainString(), theValue.precision());
|
||||
|
@ -97,4 +100,19 @@ public class UcumServiceUtil {
|
|||
return theCanonicalPair;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static QuantityParam toCanonicalQuantityOrNull(QuantityParam theQuantityParam) {
|
||||
Pair canonicalForm = getCanonicalForm(theQuantityParam.getSystem(), theQuantityParam.getValue(), theQuantityParam.getUnits());
|
||||
if (canonicalForm != null) {
|
||||
BigDecimal valueValue = new BigDecimal(canonicalForm.getValue().asDecimal());
|
||||
String unitsValue = canonicalForm.getCode();
|
||||
return new QuantityParam()
|
||||
.setSystem(theQuantityParam.getSystem())
|
||||
.setValue(valueValue)
|
||||
.setUnits(unitsValue)
|
||||
.setPrefix(theQuantityParam.getPrefix());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,34 +1,13 @@
|
|||
package ca.uhn.fhir.jpa.model.entity;
|
||||
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
|
||||
public class ResourceIndexedSearchParamQuantityNormalizedTest {
|
||||
|
||||
private ResourceIndexedSearchParamQuantityNormalized createParam(String theParamName, String theValue, String theSystem, String theUnits) {
|
||||
ResourceIndexedSearchParamQuantityNormalized token = new ResourceIndexedSearchParamQuantityNormalized(new PartitionSettings(), "Observation", theParamName, new BigDecimal(theValue), theSystem, theUnits);
|
||||
token.setResource(new ResourceTable().setResourceType("Patient"));
|
||||
return token;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHashFunctions() {
|
||||
ResourceIndexedSearchParamQuantityNormalized token = createParam("Quanity", "123.001", UcumServiceUtil.UCUM_CODESYSTEM_URL, "cm");
|
||||
token.calculateHashes();
|
||||
|
||||
// Make sure our hashing function gives consistent results
|
||||
assertEquals(5219730978980909111L, token.getHashIdentity().longValue());
|
||||
assertEquals(-2454931617586657338L, token.getHashIdentityAndUnits().longValue());
|
||||
assertEquals(878263047209296227L, token.getHashIdentitySystemAndUnits().longValue());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEquals() {
|
||||
|
@ -46,37 +25,5 @@ public class ResourceIndexedSearchParamQuantityNormalizedTest {
|
|||
assertNotEquals(val1, "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUcum() {
|
||||
|
||||
//-- system is ucum
|
||||
ResourceIndexedSearchParamQuantityNormalized token1 = createParam("Quanity", "123.001", UcumServiceUtil.UCUM_CODESYSTEM_URL, "cm");
|
||||
token1.calculateHashes();
|
||||
|
||||
assertEquals("m", token1.getUnits());
|
||||
assertEquals(Double.parseDouble("1.23001"), token1.getValue());
|
||||
|
||||
//-- small number
|
||||
token1 = createParam("Quanity", "0.000001", UcumServiceUtil.UCUM_CODESYSTEM_URL, "mm");
|
||||
token1.calculateHashes();
|
||||
|
||||
assertEquals("m", token1.getUnits());
|
||||
assertEquals(Double.parseDouble("0.000000001"), token1.getValue());
|
||||
|
||||
|
||||
// -- non ucum system
|
||||
ResourceIndexedSearchParamQuantityNormalized token2 = createParam("Quanity", "123.001", "http://abc.org", "cm");
|
||||
token2.calculateHashes();
|
||||
|
||||
assertEquals("cm", token2.getUnits());
|
||||
assertEquals(Double.parseDouble("123.001"), token2.getValue());
|
||||
|
||||
// -- unsupported ucum code
|
||||
ResourceIndexedSearchParamQuantityNormalized token3 = createParam("Quanity", "123.001", UcumServiceUtil.UCUM_CODESYSTEM_URL, "unknown");
|
||||
token3.calculateHashes();
|
||||
|
||||
assertEquals("unknown", token3.getUnits());
|
||||
assertEquals(Double.parseDouble("123.001"), token3.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
|
|||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamCoords;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamNumber;
|
||||
|
@ -38,6 +39,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantityNormalized
|
|||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamUri;
|
||||
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParamConstants;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||
import ca.uhn.fhir.model.primitive.BoundCodeDt;
|
||||
|
@ -49,7 +51,7 @@ import com.google.common.collect.Sets;
|
|||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hibernate.search.engine.spatial.GeoPoint;
|
||||
import org.fhir.ucum.Pair;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
import org.hl7.fhir.instance.model.api.IBaseEnumeration;
|
||||
|
@ -78,7 +80,6 @@ import java.util.TreeSet;
|
|||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static ca.uhn.fhir.jpa.searchparam.extractor.GeopointNormalizer.normalizeLongitude;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.trim;
|
||||
|
@ -199,12 +200,16 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
break;
|
||||
case REFERENCE:
|
||||
extractor = createReferenceExtractor();
|
||||
return extractReferenceParamsAsQueryTokens(theSearchParam, theResource, extractor);
|
||||
break;
|
||||
case QUANTITY:
|
||||
if (myModelConfig.isNormalizedQuantitySearchSupported())
|
||||
extractor = createQuantityNormalizedExtractor(theResource);
|
||||
else
|
||||
if (myModelConfig.getNormalizedQuantitySearchLevel().equals(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED)) {
|
||||
extractor = new CompositeExtractor(
|
||||
createQuantityExtractor(theResource),
|
||||
createQuantityNormalizedExtractor(theResource)
|
||||
);
|
||||
} else {
|
||||
extractor = createQuantityExtractor(theResource);
|
||||
}
|
||||
break;
|
||||
case URI:
|
||||
extractor = createUriExtractor(theResource);
|
||||
|
@ -216,6 +221,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
default:
|
||||
throw new UnsupportedOperationException("Type " + theSearchParam.getParamType() + " not supported for extraction");
|
||||
}
|
||||
|
||||
return extractParamsAsQueryTokens(theSearchParam, theResource, extractor);
|
||||
}
|
||||
|
||||
|
@ -377,14 +383,14 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
return extractSearchParams(theResource, extractor, RestSearchParameterTypeEnum.QUANTITY);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public SearchParamSet<ResourceIndexedSearchParamQuantityNormalized> extractSearchParamQuantityNormalized(IBaseResource theResource) {
|
||||
IExtractor<ResourceIndexedSearchParamQuantityNormalized> extractor = createQuantityNormalizedExtractor(theResource);
|
||||
return extractSearchParams(theResource, extractor, RestSearchParameterTypeEnum.QUANTITY);
|
||||
}
|
||||
|
||||
private IExtractor<ResourceIndexedSearchParamQuantity> createQuantityExtractor(IBaseResource theResource) {
|
||||
|
||||
private IExtractor<ResourceIndexedSearchParamQuantity> createQuantityExtractor(IBaseResource theResource) {
|
||||
return (params, searchParam, value, path) -> {
|
||||
if (value.getClass().equals(myLocationPositionDefinition.getImplementingClass())) {
|
||||
return;
|
||||
|
@ -394,7 +400,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
String resourceType = toRootTypeName(theResource);
|
||||
switch (nextType) {
|
||||
case "Quantity":
|
||||
addQuantity_Quantity(resourceType, params, searchParam, value);
|
||||
addQuantity_Quantity(resourceType, params, searchParam, value);
|
||||
break;
|
||||
case "Money":
|
||||
addQuantity_Money(resourceType, params, searchParam, value);
|
||||
|
@ -406,11 +412,11 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
addUnexpectedDatatypeWarning(params, searchParam, value);
|
||||
break;
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private IExtractor<ResourceIndexedSearchParamQuantityNormalized> createQuantityNormalizedExtractor(IBaseResource theResource) {
|
||||
|
||||
|
||||
return (params, searchParam, value, path) -> {
|
||||
if (value.getClass().equals(myLocationPositionDefinition.getImplementingClass())) {
|
||||
return;
|
||||
|
@ -434,7 +440,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SearchParamSet<ResourceIndexedSearchParamString> extractSearchParamStrings(IBaseResource theResource) {
|
||||
IExtractor<ResourceIndexedSearchParamString> extractor = createStringExtractor(theResource);
|
||||
|
@ -546,24 +552,31 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
String code = extractValueAsString(myQuantityCodeValueChild, theValue);
|
||||
|
||||
ResourceIndexedSearchParamQuantity nextEntity = new ResourceIndexedSearchParamQuantity(myPartitionSettings, theResourceType, theSearchParam.getName(), nextValueValue, system, code);
|
||||
|
||||
theParams.add(nextEntity);
|
||||
|
||||
theParams.add(nextEntity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void addQuantity_QuantityNormalized(String theResourceType, Set<ResourceIndexedSearchParamQuantityNormalized> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
|
||||
|
||||
|
||||
private void addQuantity_QuantityNormalized(String theResourceType, Set<ResourceIndexedSearchParamQuantityNormalized> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
|
||||
Optional<IPrimitiveType<BigDecimal>> valueField = myQuantityValueValueChild.getAccessor().getFirstValueOrNull(theValue);
|
||||
if (valueField.isPresent() && valueField.get().getValue() != null) {
|
||||
BigDecimal nextValueValue = valueField.get().getValue();
|
||||
String system = extractValueAsString(myQuantitySystemValueChild, theValue);
|
||||
String code = extractValueAsString(myQuantityCodeValueChild, theValue);
|
||||
|
||||
ResourceIndexedSearchParamQuantityNormalized nextEntity = new ResourceIndexedSearchParamQuantityNormalized(myPartitionSettings, theResourceType, theSearchParam.getName(), nextValueValue, system, code);
|
||||
theParams.add(nextEntity);
|
||||
//-- convert the value/unit to the canonical form if any
|
||||
Pair canonicalForm = UcumServiceUtil.getCanonicalForm(system, nextValueValue, code);
|
||||
if (canonicalForm != null) {
|
||||
double canonicalValue = Double.parseDouble(canonicalForm.getValue().asDecimal());
|
||||
String canonicalUnits = canonicalForm.getCode();
|
||||
ResourceIndexedSearchParamQuantityNormalized nextEntity = new ResourceIndexedSearchParamQuantityNormalized(myPartitionSettings, theResourceType, theSearchParam.getName(), canonicalValue, system, canonicalUnits);
|
||||
theParams.add(nextEntity);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void addQuantity_Money(String theResourceType, Set<ResourceIndexedSearchParamQuantity> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
|
||||
Optional<IPrimitiveType<BigDecimal>> valueField = myMoneyValueChild.getAccessor().getFirstValueOrNull(theValue);
|
||||
if (valueField.isPresent() && valueField.get().getValue() != null) {
|
||||
|
@ -572,14 +585,14 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
String nextValueString = "urn:iso:std:iso:4217";
|
||||
String nextValueCode = extractValueAsString(myMoneyCurrencyChild, theValue);
|
||||
String searchParamName = theSearchParam.getName();
|
||||
|
||||
|
||||
ResourceIndexedSearchParamQuantity nextEntity = new ResourceIndexedSearchParamQuantity(myPartitionSettings, theResourceType, searchParamName, nextValueValue, nextValueString, nextValueCode);
|
||||
theParams.add(nextEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void addQuantity_MoneyNormalized(String theResourceType, Set<ResourceIndexedSearchParamQuantityNormalized> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
|
||||
|
||||
private void addQuantity_MoneyNormalized(String theResourceType, Set<ResourceIndexedSearchParamQuantityNormalized> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
|
||||
Optional<IPrimitiveType<BigDecimal>> valueField = myMoneyValueChild.getAccessor().getFirstValueOrNull(theValue);
|
||||
if (valueField.isPresent() && valueField.get().getValue() != null) {
|
||||
BigDecimal nextValueValue = valueField.get().getValue();
|
||||
|
@ -587,22 +600,22 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
String nextValueString = "urn:iso:std:iso:4217";
|
||||
String nextValueCode = extractValueAsString(myMoneyCurrencyChild, theValue);
|
||||
String searchParamName = theSearchParam.getName();
|
||||
|
||||
ResourceIndexedSearchParamQuantityNormalized nextEntityNormalized = new ResourceIndexedSearchParamQuantityNormalized(myPartitionSettings, theResourceType, searchParamName, nextValueValue, nextValueString, nextValueCode);
|
||||
theParams.add(nextEntityNormalized);
|
||||
|
||||
ResourceIndexedSearchParamQuantityNormalized nextEntityNormalized = new ResourceIndexedSearchParamQuantityNormalized(myPartitionSettings, theResourceType, searchParamName, nextValueValue.doubleValue(), nextValueString, nextValueCode);
|
||||
theParams.add(nextEntityNormalized);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void addQuantity_Range(String theResourceType, Set<ResourceIndexedSearchParamQuantity> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
|
||||
Optional<IBase> low = myRangeLowValueChild.getAccessor().getFirstValueOrNull(theValue);
|
||||
low.ifPresent(theIBase -> addQuantity_Quantity(theResourceType, theParams, theSearchParam, theIBase));
|
||||
|
||||
Optional<IBase> high = myRangeHighValueChild.getAccessor().getFirstValueOrNull(theValue);
|
||||
high.ifPresent(theIBase -> addQuantity_Quantity(theResourceType, theParams, theSearchParam, theIBase));
|
||||
high.ifPresent(theIBase -> addQuantity_Quantity(theResourceType, theParams, theSearchParam, theIBase));
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void addQuantity_RangeNormalized(String theResourceType, Set<ResourceIndexedSearchParamQuantityNormalized> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
|
||||
Optional<IBase> low = myRangeLowValueChild.getAccessor().getFirstValueOrNull(theValue);
|
||||
low.ifPresent(theIBase -> addQuantity_QuantityNormalized(theResourceType, theParams, theSearchParam, theIBase));
|
||||
|
@ -610,7 +623,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
Optional<IBase> high = myRangeHighValueChild.getAccessor().getFirstValueOrNull(theValue);
|
||||
high.ifPresent(theIBase -> addQuantity_QuantityNormalized(theResourceType, theParams, theSearchParam, theIBase));
|
||||
}
|
||||
|
||||
|
||||
private void addToken_Identifier(String theResourceType, Set<BaseResourceIndexedSearchParam> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
|
||||
String system = extractValueAsString(myIdentifierSystemValueChild, theValue);
|
||||
String value = extractValueAsString(myIdentifierValueValueChild, theValue);
|
||||
|
@ -1163,11 +1176,27 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
@FunctionalInterface
|
||||
private interface IExtractor<T> {
|
||||
|
||||
|
||||
void extract(SearchParamSet<T> theParams, RuntimeSearchParam theSearchParam, IBase theValue, String thePath);
|
||||
|
||||
}
|
||||
|
||||
private static class CompositeExtractor<T> implements IExtractor<T> {
|
||||
|
||||
private final IExtractor<T> myExtractor0;
|
||||
private final IExtractor<T> myExtractor1;
|
||||
|
||||
private CompositeExtractor(IExtractor<T> theExtractor0, IExtractor<T> theExtractor1) {
|
||||
myExtractor0 = theExtractor0;
|
||||
myExtractor1 = theExtractor1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void extract(SearchParamSet<T> theParams, RuntimeSearchParam theSearchParam, IBase theValue, String thePath) {
|
||||
myExtractor0.extract(theParams, theSearchParam, theValue, thePath);
|
||||
myExtractor1.extract(theParams, theSearchParam, theValue, thePath);
|
||||
}
|
||||
}
|
||||
|
||||
private class ResourceLinkExtractor implements IExtractor<PathAndRef> {
|
||||
|
||||
private PathAndRef myPathAndRef = null;
|
||||
|
|
|
@ -25,6 +25,7 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
|
|||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedCompositeStringUnique;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamCoords;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate;
|
||||
|
@ -36,9 +37,14 @@ import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
|
|||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamUri;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceLink;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
|
||||
import ca.uhn.fhir.rest.param.QuantityParam;
|
||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Streams;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -51,6 +57,7 @@ import java.util.Map;
|
|||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.compare;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
@ -158,21 +165,30 @@ public final class ResourceIndexedSearchParams {
|
|||
return myPopulatedResourceLinkParameters;
|
||||
}
|
||||
|
||||
public boolean matchParam(ModelConfig theModelConfig, String theResourceName, String theParamName, RuntimeSearchParam theParamDef, IQueryParameterType theParam) {
|
||||
public boolean matchParam(ModelConfig theModelConfig, String theResourceName, String theParamName, RuntimeSearchParam theParamDef, IQueryParameterType theValue) {
|
||||
|
||||
if (theParamDef == null) {
|
||||
return false;
|
||||
}
|
||||
Collection<? extends BaseResourceIndexedSearchParam> resourceParams;
|
||||
Collection<? extends BaseResourceIndexedSearchParam> resourceParams = null;
|
||||
IQueryParameterType value = theValue;
|
||||
switch (theParamDef.getParamType()) {
|
||||
case TOKEN:
|
||||
resourceParams = myTokenParams;
|
||||
break;
|
||||
case QUANTITY:
|
||||
if (theModelConfig.isNormalizedQuantitySearchSupported())
|
||||
resourceParams = myQuantityNormalizedParams;
|
||||
else
|
||||
resourceParams = myQuantityParams;
|
||||
if (theModelConfig.getNormalizedQuantitySearchLevel().equals(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED)) {
|
||||
QuantityParam quantity = QuantityParam.toQuantityParam(theValue);
|
||||
QuantityParam normalized = UcumServiceUtil.toCanonicalQuantityOrNull(quantity);
|
||||
if (normalized != null) {
|
||||
resourceParams = myQuantityNormalizedParams;
|
||||
value = normalized;
|
||||
}
|
||||
}
|
||||
|
||||
if (resourceParams == null) {
|
||||
resourceParams = myQuantityParams;
|
||||
}
|
||||
break;
|
||||
case STRING:
|
||||
resourceParams = myStringParams;
|
||||
|
@ -187,7 +203,7 @@ public final class ResourceIndexedSearchParams {
|
|||
resourceParams = myDateParams;
|
||||
break;
|
||||
case REFERENCE:
|
||||
return matchResourceLinks(theModelConfig, theResourceName, theParamName, theParam, theParamDef.getPath());
|
||||
return matchResourceLinks(theModelConfig, theResourceName, theParamName, value, theParamDef.getPath());
|
||||
case COMPOSITE:
|
||||
case HAS:
|
||||
case SPECIAL:
|
||||
|
@ -197,11 +213,16 @@ public final class ResourceIndexedSearchParams {
|
|||
if (resourceParams == null) {
|
||||
return false;
|
||||
}
|
||||
Predicate<BaseResourceIndexedSearchParam> namedParamPredicate = param ->
|
||||
param.getParamName().equalsIgnoreCase(theParamName) &&
|
||||
param.matches(theParam);
|
||||
|
||||
return resourceParams.stream().anyMatch(namedParamPredicate);
|
||||
for (BaseResourceIndexedSearchParam nextParam : resourceParams) {
|
||||
if (nextParam.getParamName().equalsIgnoreCase(theParamName)) {
|
||||
if (nextParam.matches(value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -275,10 +296,7 @@ public final class ResourceIndexedSearchParams {
|
|||
public void findMissingSearchParams(PartitionSettings thePartitionSettings, ModelConfig theModelConfig, ResourceTable theEntity, Set<Entry<String, RuntimeSearchParam>> theActiveSearchParams) {
|
||||
findMissingSearchParams(thePartitionSettings, theModelConfig, theEntity, theActiveSearchParams, RestSearchParameterTypeEnum.STRING, myStringParams);
|
||||
findMissingSearchParams(thePartitionSettings, theModelConfig, theEntity, theActiveSearchParams, RestSearchParameterTypeEnum.NUMBER, myNumberParams);
|
||||
if (theModelConfig.isNormalizedQuantitySearchSupported())
|
||||
findMissingSearchParams(thePartitionSettings, theModelConfig, theEntity, theActiveSearchParams, RestSearchParameterTypeEnum.QUANTITY, myQuantityNormalizedParams);
|
||||
else
|
||||
findMissingSearchParams(thePartitionSettings, theModelConfig, theEntity, theActiveSearchParams, RestSearchParameterTypeEnum.QUANTITY, myQuantityParams);
|
||||
findMissingSearchParams(thePartitionSettings, theModelConfig, theEntity, theActiveSearchParams, RestSearchParameterTypeEnum.QUANTITY, myQuantityParams);
|
||||
findMissingSearchParams(thePartitionSettings, theModelConfig, theEntity, theActiveSearchParams, RestSearchParameterTypeEnum.DATE, myDateParams);
|
||||
findMissingSearchParams(thePartitionSettings, theModelConfig, theEntity, theActiveSearchParams, RestSearchParameterTypeEnum.URI, myUriParams);
|
||||
findMissingSearchParams(thePartitionSettings, theModelConfig, theEntity, theActiveSearchParams, RestSearchParameterTypeEnum.TOKEN, myTokenParams);
|
||||
|
@ -309,10 +327,7 @@ public final class ResourceIndexedSearchParams {
|
|||
param = new ResourceIndexedSearchParamNumber();
|
||||
break;
|
||||
case QUANTITY:
|
||||
if (theModelConfig.isNormalizedQuantitySearchSupported())
|
||||
param = new ResourceIndexedSearchParamQuantityNormalized();
|
||||
else
|
||||
param = new ResourceIndexedSearchParamQuantity();
|
||||
param = new ResourceIndexedSearchParamQuantity();
|
||||
break;
|
||||
case STRING:
|
||||
param = new ResourceIndexedSearchParamString()
|
||||
|
|
|
@ -21,7 +21,6 @@ package ca.uhn.fhir.jpa.searchparam.extractor;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||
|
@ -50,9 +49,9 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
|
||||
// This constructor is used by tests
|
||||
@VisibleForTesting
|
||||
public SearchParamExtractorDstu3(ModelConfig theModelConfig, PartitionSettings thePartitionSettings, FhirContext theCtx, IValidationSupport theValidationSupport, ISearchParamRegistry theSearchParamRegistry) {
|
||||
public SearchParamExtractorDstu3(ModelConfig theModelConfig, PartitionSettings thePartitionSettings, FhirContext theCtx, ISearchParamRegistry theSearchParamRegistry) {
|
||||
super(theModelConfig, thePartitionSettings, theCtx, theSearchParamRegistry);
|
||||
initFhirPathEngine(theValidationSupport);
|
||||
initFhirPathEngine();
|
||||
start();
|
||||
}
|
||||
|
||||
|
@ -75,13 +74,12 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
public void start() {
|
||||
super.start();
|
||||
if (myFhirPathEngine == null) {
|
||||
IValidationSupport support = myApplicationContext.getBean(IValidationSupport.class);
|
||||
initFhirPathEngine(support);
|
||||
initFhirPathEngine();
|
||||
}
|
||||
}
|
||||
|
||||
public void initFhirPathEngine(IValidationSupport theSupport) {
|
||||
IWorkerContext worker = new HapiWorkerContext(getContext(), theSupport);
|
||||
public void initFhirPathEngine() {
|
||||
IWorkerContext worker = new HapiWorkerContext(getContext(), getContext().getValidationSupport());
|
||||
myFhirPathEngine = new FHIRPathEngine(worker);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ package ca.uhn.fhir.jpa.searchparam.extractor;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||
|
@ -62,9 +61,9 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
|
|||
|
||||
// This constructor is used by tests
|
||||
@VisibleForTesting
|
||||
public SearchParamExtractorR4(ModelConfig theModelConfig, PartitionSettings thePartitionSettings, FhirContext theCtx, IValidationSupport theValidationSupport, ISearchParamRegistry theSearchParamRegistry) {
|
||||
public SearchParamExtractorR4(ModelConfig theModelConfig, PartitionSettings thePartitionSettings, FhirContext theCtx, ISearchParamRegistry theSearchParamRegistry) {
|
||||
super(theModelConfig, thePartitionSettings, theCtx, theSearchParamRegistry);
|
||||
initFhirPath(theValidationSupport);
|
||||
initFhirPath();
|
||||
start();
|
||||
}
|
||||
|
||||
|
@ -82,13 +81,12 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
|
|||
public void start() {
|
||||
super.start();
|
||||
if (myFhirPathEngine == null) {
|
||||
IValidationSupport support = myApplicationContext.getBean(IValidationSupport.class);
|
||||
initFhirPath(support);
|
||||
initFhirPath();
|
||||
}
|
||||
}
|
||||
|
||||
public void initFhirPath(IValidationSupport theSupport) {
|
||||
IWorkerContext worker = new HapiWorkerContext(getContext(), theSupport);
|
||||
public void initFhirPath() {
|
||||
IWorkerContext worker = new HapiWorkerContext(getContext(), getContext().getValidationSupport());
|
||||
myFhirPathEngine = new FHIRPathEngine(worker);
|
||||
myFhirPathEngine.setHostServices(new SearchParamExtractorR4HostServices());
|
||||
}
|
||||
|
@ -96,7 +94,7 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
|
|||
|
||||
private static class SearchParamExtractorR4HostServices implements FHIRPathEngine.IEvaluationContext {
|
||||
|
||||
private Map<String, Base> myResourceTypeToStub = Collections.synchronizedMap(new HashMap<>());
|
||||
private final Map<String, Base> myResourceTypeToStub = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
@Override
|
||||
public Base resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
|
||||
|
|
|
@ -21,8 +21,6 @@ package ca.uhn.fhir.jpa.searchparam.extractor;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport;
|
||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||
|
@ -58,9 +56,9 @@ public class SearchParamExtractorR5 extends BaseSearchParamExtractor implements
|
|||
/**
|
||||
* Constructor for unit tests
|
||||
*/
|
||||
public SearchParamExtractorR5(ModelConfig theModelConfig, PartitionSettings thePartitionSettings, FhirContext theCtx, DefaultProfileValidationSupport theDefaultProfileValidationSupport, ISearchParamRegistry theSearchParamRegistry) {
|
||||
public SearchParamExtractorR5(ModelConfig theModelConfig, PartitionSettings thePartitionSettings, FhirContext theCtx, ISearchParamRegistry theSearchParamRegistry) {
|
||||
super(theModelConfig, thePartitionSettings, theCtx, theSearchParamRegistry);
|
||||
initFhirPath(theDefaultProfileValidationSupport);
|
||||
initFhirPath();
|
||||
start();
|
||||
}
|
||||
|
||||
|
@ -69,13 +67,12 @@ public class SearchParamExtractorR5 extends BaseSearchParamExtractor implements
|
|||
public void start() {
|
||||
super.start();
|
||||
if (myFhirPathEngine == null) {
|
||||
IValidationSupport support = myApplicationContext.getBean(IValidationSupport.class);
|
||||
initFhirPath(support);
|
||||
initFhirPath();
|
||||
}
|
||||
}
|
||||
|
||||
public void initFhirPath(IValidationSupport theSupport) {
|
||||
IWorkerContext worker = new HapiWorkerContext(getContext(), theSupport);
|
||||
public void initFhirPath() {
|
||||
IWorkerContext worker = new HapiWorkerContext(getContext(), getContext().getValidationSupport());
|
||||
myFhirPathEngine = new FHIRPathEngine(worker);
|
||||
myFhirPathEngine.setHostServices(new SearchParamExtractorR5HostServices());
|
||||
}
|
||||
|
@ -88,7 +85,7 @@ public class SearchParamExtractorR5 extends BaseSearchParamExtractor implements
|
|||
|
||||
private static class SearchParamExtractorR5HostServices implements FHIRPathEngine.IEvaluationContext {
|
||||
|
||||
private Map<String, Base> myResourceTypeToStub = Collections.synchronizedMap(new HashMap<>());
|
||||
private final Map<String, Base> myResourceTypeToStub = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
@Override
|
||||
public Base resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
|
||||
|
|
|
@ -31,6 +31,7 @@ import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
|||
import ca.uhn.fhir.jpa.model.cross.IResourceLookup;
|
||||
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamCoords;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamNumber;
|
||||
|
@ -119,8 +120,8 @@ public class SearchParamExtractorService {
|
|||
ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamQuantity> quantities = extractSearchParamQuantity(theResource);
|
||||
handleWarnings(theRequestDetails, myInterceptorBroadcaster, quantities);
|
||||
theParams.myQuantityParams.addAll(quantities);
|
||||
|
||||
if (myModelConfig.isNormalizedQuantityStorageSupported()|| myModelConfig.isNormalizedQuantitySearchSupported()) {
|
||||
|
||||
if (myModelConfig.getNormalizedQuantitySearchLevel().equals(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED) || myModelConfig.getNormalizedQuantitySearchLevel().equals(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED)) {
|
||||
ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamQuantityNormalized> quantitiesNormalized = extractSearchParamQuantityNormalized(theResource);
|
||||
handleWarnings(theRequestDetails, myInterceptorBroadcaster, quantitiesNormalized);
|
||||
theParams.myQuantityNormalizedParams.addAll(quantitiesNormalized);
|
||||
|
|
|
@ -9,9 +9,6 @@ import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
|
|||
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorDstu3;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||
import ca.uhn.fhir.util.StopWatch;
|
||||
import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport;
|
||||
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport;
|
||||
import org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -23,7 +20,6 @@ import java.util.stream.Collectors;
|
|||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
@ -43,9 +39,8 @@ public class IndexStressTest {
|
|||
FhirContext ctx = FhirContext.forDstu3();
|
||||
IValidationSupport mockValidationSupport = mock(IValidationSupport.class);
|
||||
when(mockValidationSupport.getFhirContext()).thenReturn(ctx);
|
||||
IValidationSupport validationSupport = new CachingValidationSupport(new ValidationSupportChain(new DefaultProfileValidationSupport(ctx), mockValidationSupport));
|
||||
ISearchParamRegistry searchParamRegistry = mock(ISearchParamRegistry.class);
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ctx, validationSupport, searchParamRegistry);
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ctx, searchParamRegistry);
|
||||
extractor.start();
|
||||
|
||||
Map<String, RuntimeSearchParam> spMap = ctx
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
package ca.uhn.fhir.jpa.searchparam.extractor;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.context.phonetic.IPhoneticEncoder;
|
||||
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport;
|
||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.jpa.cache.ResourceChangeResult;
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
|
||||
|
@ -33,7 +32,6 @@ import org.hl7.fhir.dstu3.model.Observation;
|
|||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.dstu3.model.Questionnaire;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.text.Normalizer;
|
||||
|
@ -51,8 +49,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||
|
||||
public class SearchParamExtractorDstu3Test {
|
||||
|
||||
private static FhirContext ourCtx = FhirContext.forDstu3();
|
||||
private static IValidationSupport ourValidationSupport;
|
||||
private static FhirContext ourCtx = FhirContext.forCached(FhirVersionEnum.DSTU3);
|
||||
|
||||
@Test
|
||||
public void testParamWithOrInPath() {
|
||||
|
@ -61,7 +58,7 @@ public class SearchParamExtractorDstu3Test {
|
|||
|
||||
ISearchParamRegistry searchParamRegistry = new MySearchParamRegistry();
|
||||
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, ourValidationSupport, searchParamRegistry);
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, searchParamRegistry);
|
||||
extractor.start();
|
||||
Set<BaseResourceIndexedSearchParam> tokens = extractor.extractSearchParamTokens(obs);
|
||||
assertEquals(1, tokens.size());
|
||||
|
@ -84,7 +81,7 @@ public class SearchParamExtractorDstu3Test {
|
|||
|
||||
ISearchParamRegistry searchParamRegistry = new MySearchParamRegistry();
|
||||
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, ourValidationSupport, searchParamRegistry);
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, searchParamRegistry);
|
||||
extractor.start();
|
||||
Set<ResourceIndexedSearchParamString> params = extractor.extractSearchParamStrings(questionnaire);
|
||||
assertEquals(1, params.size());
|
||||
|
@ -102,7 +99,7 @@ public class SearchParamExtractorDstu3Test {
|
|||
|
||||
ISearchParamRegistry searchParamRegistry = new MySearchParamRegistry();
|
||||
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, ourValidationSupport, searchParamRegistry);
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, searchParamRegistry);
|
||||
extractor.start();
|
||||
Set<ResourceIndexedSearchParamNumber> params = extractor.extractSearchParamNumber(enc);
|
||||
assertEquals(1, params.size());
|
||||
|
@ -120,7 +117,7 @@ public class SearchParamExtractorDstu3Test {
|
|||
|
||||
ISearchParamRegistry searchParamRegistry = new MySearchParamRegistry();
|
||||
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, ourValidationSupport, searchParamRegistry);
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, searchParamRegistry);
|
||||
extractor.start();
|
||||
Set<ResourceIndexedSearchParamNumber> params = extractor.extractSearchParamNumber(enc);
|
||||
assertEquals(1, params.size());
|
||||
|
@ -132,7 +129,7 @@ public class SearchParamExtractorDstu3Test {
|
|||
public void testEmptyPath() {
|
||||
|
||||
MySearchParamRegistry searchParamRegistry = new MySearchParamRegistry();
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, ourValidationSupport, searchParamRegistry);
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, searchParamRegistry);
|
||||
extractor.start();
|
||||
|
||||
searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "", RestSearchParameterTypeEnum.STRING, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE));
|
||||
|
@ -148,7 +145,7 @@ public class SearchParamExtractorDstu3Test {
|
|||
public void testStringMissingResourceType() {
|
||||
|
||||
MySearchParamRegistry searchParamRegistry = new MySearchParamRegistry();
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, ourValidationSupport, searchParamRegistry);
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, searchParamRegistry);
|
||||
extractor.start();
|
||||
|
||||
searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "communication.language.coding.system | communication.language.coding.code", RestSearchParameterTypeEnum.STRING, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE));
|
||||
|
@ -165,7 +162,7 @@ public class SearchParamExtractorDstu3Test {
|
|||
public void testInvalidType() {
|
||||
|
||||
MySearchParamRegistry searchParamRegistry = new MySearchParamRegistry();
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, ourValidationSupport, searchParamRegistry);
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, searchParamRegistry);
|
||||
extractor.start();
|
||||
|
||||
{
|
||||
|
@ -216,7 +213,7 @@ public class SearchParamExtractorDstu3Test {
|
|||
|
||||
ISearchParamRegistry searchParamRegistry = new MySearchParamRegistry();
|
||||
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, ourValidationSupport, searchParamRegistry);
|
||||
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, searchParamRegistry);
|
||||
extractor.start();
|
||||
ISearchParamExtractor.SearchParamSet<BaseResourceIndexedSearchParam> coords = extractor.extractSearchParamTokens(loc);
|
||||
assertEquals(1, coords.size());
|
||||
|
@ -227,7 +224,7 @@ public class SearchParamExtractorDstu3Test {
|
|||
|
||||
private static class MySearchParamRegistry implements ISearchParamRegistry {
|
||||
|
||||
private List<RuntimeSearchParam> myAddedSearchParams = new ArrayList<>();
|
||||
private final List<RuntimeSearchParam> myAddedSearchParams = new ArrayList<>();
|
||||
|
||||
public void addSearchParam(RuntimeSearchParam... theSearchParam) {
|
||||
myAddedSearchParams.clear();
|
||||
|
@ -306,9 +303,4 @@ public class SearchParamExtractorDstu3Test {
|
|||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
public static void beforeClass() {
|
||||
ourValidationSupport = new DefaultProfileValidationSupport(ourCtx);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ import ca.uhn.fhir.context.RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition;
|
|||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.context.phonetic.IPhoneticEncoder;
|
||||
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport;
|
||||
import ca.uhn.fhir.jpa.cache.ResourceChangeResult;
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
|
@ -66,15 +65,15 @@ public class SearchParamExtractorMegaTest {
|
|||
|
||||
ctx = FhirContext.forDstu3();
|
||||
searchParamRegistry = new MySearchParamRegistry(ctx);
|
||||
process(ctx, new SearchParamExtractorDstu3(new ModelConfig(), partitionSettings, ctx, new DefaultProfileValidationSupport(ctx), searchParamRegistry));
|
||||
process(ctx, new SearchParamExtractorDstu3(new ModelConfig(), partitionSettings, ctx, searchParamRegistry));
|
||||
|
||||
ctx = FhirContext.forR4();
|
||||
searchParamRegistry = new MySearchParamRegistry(ctx);
|
||||
process(ctx, new SearchParamExtractorR4(new ModelConfig(), partitionSettings, ctx, new DefaultProfileValidationSupport(ctx), searchParamRegistry));
|
||||
process(ctx, new SearchParamExtractorR4(new ModelConfig(), partitionSettings, ctx, searchParamRegistry));
|
||||
|
||||
ctx = FhirContext.forR5();
|
||||
searchParamRegistry = new MySearchParamRegistry(ctx);
|
||||
process(ctx, new SearchParamExtractorR5(new ModelConfig(), partitionSettings, ctx, new DefaultProfileValidationSupport(ctx), searchParamRegistry));
|
||||
process(ctx, new SearchParamExtractorR5(new ModelConfig(), partitionSettings, ctx, searchParamRegistry));
|
||||
}
|
||||
|
||||
private void process(FhirContext theCtx, BaseSearchParamExtractor theExtractor) throws Exception {
|
||||
|
|
Loading…
Reference in New Issue