Merge remote-tracking branch 'remotes/origin/master' into ks-20200203-remove-search-lastused
This commit is contained in:
commit
3c46595e81
|
@ -65,6 +65,7 @@ import org.apache.commons.lang3.Validate;
|
|||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.query.Query;
|
||||
import org.hl7.fhir.dstu3.model.Location;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -160,6 +161,10 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
// Remove any empty parameters
|
||||
theParams.clean();
|
||||
|
||||
if (myResourceType == Location.class) {
|
||||
theParams.setLocationDistance();
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if there is a unique key associated with the set
|
||||
* of parameters passed in
|
||||
|
@ -181,7 +186,6 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Iterator<Long> createCountQuery(SearchParameterMap theParams, String theSearchUuid, RequestDetails theRequest) {
|
||||
init(theParams, theSearchUuid);
|
||||
|
|
|
@ -21,8 +21,6 @@ package ca.uhn.fhir.jpa.dao.data;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.TermValueSetConceptDesignation;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
|
@ -37,6 +35,4 @@ public interface ITermValueSetConceptDesignationDao extends JpaRepository<TermVa
|
|||
@Modifying
|
||||
void deleteByTermValueSetId(@Param("pid") Long theValueSetId);
|
||||
|
||||
@Query("SELECT vscd FROM TermValueSetConceptDesignation vscd WHERE vscd.myConcept.myId = :pid")
|
||||
Slice<TermValueSetConceptDesignation> findByTermValueSetConceptId(Pageable thePage, @Param("pid") Long theValueSetConceptId);
|
||||
}
|
||||
|
|
|
@ -33,9 +33,7 @@ import java.io.Serializable;
|
|||
import static org.apache.commons.lang3.StringUtils.left;
|
||||
import static org.apache.commons.lang3.StringUtils.length;
|
||||
|
||||
@Table(name = "TRM_VALUESET_C_DESIGNATION", indexes = {
|
||||
@Index(name = "IDX_VALUESET_C_DSGNTN_VAL", columnList = "VAL")
|
||||
})
|
||||
@Table(name = "TRM_VALUESET_C_DESIGNATION")
|
||||
@Entity()
|
||||
public class TermValueSetConceptDesignation implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
|
|
@ -5,6 +5,7 @@ import ca.uhn.fhir.jpa.dao.data.ISearchDao;
|
|||
import ca.uhn.fhir.jpa.entity.Search;
|
||||
import ca.uhn.fhir.jpa.provider.r4.ResourceProviderR4Test;
|
||||
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
|
||||
import ca.uhn.fhir.jpa.util.CoordCalculatorTest;
|
||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
|
@ -65,6 +66,7 @@ import java.math.BigDecimal;
|
|||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
|
@ -4278,6 +4280,55 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNearSearchApproximate() {
|
||||
Location loc = new Location();
|
||||
double latitude = CoordCalculatorTest.LATITUDE_UHN;
|
||||
double longitude = CoordCalculatorTest.LONGITUDE_UHN;
|
||||
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
|
||||
loc.setPosition(position);
|
||||
IIdType locId = ourClient.create().resource(loc).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
{ // In the box
|
||||
double bigEnoughDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN * 2;
|
||||
String url = "/Location?" +
|
||||
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + URLEncoder.encode(":") + CoordCalculatorTest.LONGITUDE_CHIN +
|
||||
"&" +
|
||||
Location.SP_NEAR_DISTANCE + "=" + bigEnoughDistance + URLEncoder.encode("|http://unitsofmeasure.org|km");
|
||||
|
||||
Bundle actual = ourClient
|
||||
.search()
|
||||
.byUrl(ourServerBase + "/" + url)
|
||||
.encodedJson()
|
||||
.prettyPrint()
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
|
||||
assertEquals(1, actual.getEntry().size());
|
||||
assertEquals(locId.getIdPart(), actual.getEntry().get(0).getResource().getIdElement().getIdPart());
|
||||
}
|
||||
{ // Outside the box
|
||||
double tooSmallDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN / 2;
|
||||
String url = "/Location?" +
|
||||
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + URLEncoder.encode(":") + CoordCalculatorTest.LONGITUDE_CHIN +
|
||||
"&" +
|
||||
Location.SP_NEAR_DISTANCE + "=" + tooSmallDistance + URLEncoder.encode("|http://unitsofmeasure.org|km");
|
||||
|
||||
myCaptureQueriesListener.clear();
|
||||
Bundle actual = ourClient
|
||||
.search()
|
||||
.byUrl(ourServerBase + "/" + url)
|
||||
.encodedJson()
|
||||
.prettyPrint()
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
myCaptureQueriesListener.logSelectQueries();
|
||||
|
||||
assertEquals(0, actual.getEntry().size());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String toStr(Date theDate) {
|
||||
return new InstantDt(theDate).getValueAsString();
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ public class MatchUrlServiceTest extends BaseJpaTest {
|
|||
Location.SP_NEAR + "=1000.0:2000.0" +
|
||||
"&" +
|
||||
Location.SP_NEAR_DISTANCE + "=" + kmDistance + "|http://unitsofmeasure.org|km", ourCtx.getResourceDefinition("Location"));
|
||||
map.setLocationDistance();
|
||||
|
||||
QuantityParam nearDistanceParam = map.getNearDistanceParam();
|
||||
assertEquals(1, map.size());
|
||||
|
@ -74,6 +75,8 @@ public class MatchUrlServiceTest extends BaseJpaTest {
|
|||
"&" +
|
||||
Location.SP_NEAR_DISTANCE + "=2|http://unitsofmeasure.org|km",
|
||||
ourCtx.getResourceDefinition("Location"));
|
||||
map.setLocationDistance();
|
||||
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Only one " + Location.SP_NEAR_DISTANCE + " parameter may be present", e.getMessage());
|
||||
|
@ -89,7 +92,8 @@ public class MatchUrlServiceTest extends BaseJpaTest {
|
|||
"," +
|
||||
"2|http://unitsofmeasure.org|km",
|
||||
ourCtx.getResourceDefinition("Location"));
|
||||
map.setLoadSynchronous(true);
|
||||
map.setLocationDistance();
|
||||
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Only one " + Location.SP_NEAR_DISTANCE + " parameter may be present", e.getMessage());
|
||||
|
|
|
@ -190,6 +190,10 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
|
|||
// TermConceptProperty
|
||||
version.startSectionWithMessage("Processing table: TRM_CONCEPT_PROPERTY");
|
||||
version.onTable("TRM_CONCEPT_PROPERTY").addColumn("20191002.9", "PROP_VAL_LOB").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.BLOB);
|
||||
|
||||
// TermValueSetConceptDesignation
|
||||
version.onTable("TRM_VALUESET_C_DESIGNATION").dropIndex("20200202.1", "IDX_VALUESET_C_DSGNTN_VAL").failureAllowed();
|
||||
|
||||
}
|
||||
|
||||
protected void init400() { // 20190401 - 20190814
|
||||
|
@ -328,10 +332,13 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
|
|||
termValueSetConceptDesignationTable.addColumn("USE_CODE").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, 500);
|
||||
termValueSetConceptDesignationTable.addColumn("USE_DISPLAY").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, 500);
|
||||
termValueSetConceptDesignationTable.addColumn("VAL").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, 500);
|
||||
|
||||
// This index turned out not to be needed so it is disabled
|
||||
termValueSetConceptDesignationTable
|
||||
.addIndex("20190801.6", "IDX_VALUESET_C_DSGNTN_VAL")
|
||||
.unique(false)
|
||||
.withColumns("VAL");
|
||||
.withColumns("VAL")
|
||||
.doNothing();
|
||||
|
||||
// TermCodeSystemVersion
|
||||
version.startSectionWithMessage("Processing table: TRM_CODESYSTEM_VER");
|
||||
|
|
|
@ -158,20 +158,22 @@ public class Builder {
|
|||
return myTableName;
|
||||
}
|
||||
|
||||
public void dropIndex(String theVersion, String theIndexName) {
|
||||
dropIndexOptional(false, theVersion, theIndexName);
|
||||
public BuilderCompleteTask dropIndex(String theVersion, String theIndexName) {
|
||||
BaseTask task = dropIndexOptional(false, theVersion, theIndexName);
|
||||
return new BuilderCompleteTask(task);
|
||||
}
|
||||
|
||||
public void dropIndexStub(String theVersion, String theIndexName) {
|
||||
dropIndexOptional(true, theVersion, theIndexName);
|
||||
}
|
||||
|
||||
private void dropIndexOptional(boolean theDoNothing, String theVersion, String theIndexName) {
|
||||
private DropIndexTask dropIndexOptional(boolean theDoNothing, String theVersion, String theIndexName) {
|
||||
DropIndexTask task = new DropIndexTask(myRelease, theVersion);
|
||||
task.setIndexName(theIndexName);
|
||||
task.setTableName(myTableName);
|
||||
task.setDoNothing(theDoNothing);
|
||||
addTask(task);
|
||||
return task;
|
||||
}
|
||||
|
||||
public void renameIndex(String theVersion, String theOldIndexName, String theNewIndexName) {
|
||||
|
@ -286,11 +288,12 @@ public class Builder {
|
|||
withColumnsOptional(true, theColumnNames);
|
||||
}
|
||||
|
||||
public void withColumns(String... theColumnNames) {
|
||||
withColumnsOptional(false, theColumnNames);
|
||||
public BuilderCompleteTask withColumns(String... theColumnNames) {
|
||||
BaseTask task = withColumnsOptional(false, theColumnNames);
|
||||
return new BuilderCompleteTask(task);
|
||||
}
|
||||
|
||||
private void withColumnsOptional(boolean theDoNothing, String... theColumnNames) {
|
||||
private AddIndexTask withColumnsOptional(boolean theDoNothing, String... theColumnNames) {
|
||||
AddIndexTask task = new AddIndexTask(myRelease, myVersion);
|
||||
task.setTableName(myTableName);
|
||||
task.setIndexName(myIndexName);
|
||||
|
@ -298,6 +301,7 @@ public class Builder {
|
|||
task.setColumns(theColumnNames);
|
||||
task.setDoNothing(theDoNothing);
|
||||
addTask(task);
|
||||
return task;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -463,6 +467,12 @@ public class Builder {
|
|||
myTask.setFailureAllowed(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BuilderCompleteTask doNothing() {
|
||||
myTask.setDoNothing(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,13 +26,11 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
|
|||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Location;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.QualifiedParamList;
|
||||
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.param.ParameterUtil;
|
||||
import ca.uhn.fhir.rest.param.QuantityAndListParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.util.ReflectionUtil;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
|
@ -115,9 +113,6 @@ public class MatchUrlService {
|
|||
} else if (Constants.PARAM_SOURCE.equals(nextParamName)) {
|
||||
IQueryParameterAnd<?> param = ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.TOKEN, nextParamName, paramList);
|
||||
paramMap.add(nextParamName, param);
|
||||
} else if (Location.SP_NEAR_DISTANCE.equals(nextParamName)) {
|
||||
QuantityAndListParam nearDistanceAndListParam = (QuantityAndListParam) ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.QUANTITY, nextParamName, paramList);
|
||||
paramMap.setNearDistanceParam(nearDistanceAndListParam);
|
||||
} else if (nextParamName.startsWith("_")) {
|
||||
// ignore these since they aren't search params (e.g. _sort)
|
||||
} else {
|
||||
|
|
|
@ -5,15 +5,17 @@ import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
|||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Location;
|
||||
import ca.uhn.fhir.rest.api.*;
|
||||
import ca.uhn.fhir.rest.param.*;
|
||||
import ca.uhn.fhir.rest.param.DateParam;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.param.QuantityParam;
|
||||
import ca.uhn.fhir.util.ObjectUtil;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import org.hl7.fhir.dstu3.model.Location;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
@ -495,29 +497,38 @@ public class SearchParameterMap implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
public void setNearDistanceParam(QuantityAndListParam theQuantityAndListParam) {
|
||||
List<QuantityOrListParam> orTokens = theQuantityAndListParam.getValuesAsQueryTokens();
|
||||
if (orTokens.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (orTokens.size() > 1) {
|
||||
throw new IllegalArgumentException("Only one " + Location.SP_NEAR_DISTANCE + " parameter may be present");
|
||||
}
|
||||
QuantityOrListParam quantityOrListParam = orTokens.get(0);
|
||||
List<QuantityParam> tokens = quantityOrListParam.getValuesAsQueryTokens();
|
||||
if (tokens.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (tokens.size() > 1) {
|
||||
throw new IllegalArgumentException("Only one " + Location.SP_NEAR_DISTANCE + " parameter may be present");
|
||||
}
|
||||
myNearDistanceParam = tokens.get(0);
|
||||
public void setNearDistanceParam(QuantityParam theQuantityParam) {
|
||||
myNearDistanceParam = theQuantityParam;
|
||||
}
|
||||
|
||||
public QuantityParam getNearDistanceParam() {
|
||||
return myNearDistanceParam;
|
||||
}
|
||||
|
||||
public void setLocationDistance() {
|
||||
if (containsKey(Location.SP_NEAR_DISTANCE)) {
|
||||
List<List<IQueryParameterType>> paramAndList = get(Location.SP_NEAR_DISTANCE);
|
||||
|
||||
if (paramAndList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (paramAndList.size() > 1) {
|
||||
throw new IllegalArgumentException("Only one " + ca.uhn.fhir.model.dstu2.resource.Location.SP_NEAR_DISTANCE + " parameter may be present");
|
||||
}
|
||||
List<IQueryParameterType> paramOrList = paramAndList.get(0);
|
||||
if (paramOrList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (paramOrList.size() > 1) {
|
||||
throw new IllegalArgumentException("Only one " + ca.uhn.fhir.model.dstu2.resource.Location.SP_NEAR_DISTANCE + " parameter may be present");
|
||||
}
|
||||
setNearDistanceParam((QuantityParam) paramOrList.get(0));
|
||||
|
||||
// Need to remove near-distance or it we'll get a hashcode predicate for it
|
||||
remove(Location.SP_NEAR_DISTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
public enum EverythingModeEnum {
|
||||
/*
|
||||
* Don't reorder! We rely on the ordinals
|
||||
|
|
|
@ -40,6 +40,7 @@ import ca.uhn.fhir.rest.param.StringParam;
|
|||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.util.MetaUtil;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import org.hl7.fhir.dstu3.model.Location;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
@ -88,7 +89,7 @@ public class InMemoryResourceMatcher {
|
|||
if (searchParameterMap.getLastUpdated() != null) {
|
||||
return InMemoryMatchResult.unsupportedFromParameterAndReason(Constants.PARAM_LASTUPDATED, InMemoryMatchResult.STANDARD_PARAMETER);
|
||||
}
|
||||
if (searchParameterMap.getNearDistanceParam() != null) {
|
||||
if (searchParameterMap.containsKey(Location.SP_NEAR)) {
|
||||
return InMemoryMatchResult.unsupportedFromReason(InMemoryMatchResult.LOCATION_NEAR);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue