parse nearDistance into a special search parameter field so it's available when we're adding the near parameter

This commit is contained in:
Ken Stevens 2020-01-21 15:38:25 -05:00
parent a961a7c022
commit b463929c28
5 changed files with 69 additions and 11 deletions

View File

@ -2770,6 +2770,8 @@ public class SearchBuilder implements ISearchBuilder {
myParams.isAllParametersHaveNoModifier(); myParams.isAllParametersHaveNoModifier();
if (couldBeEligibleForCompositeUniqueSpProcessing) { if (couldBeEligibleForCompositeUniqueSpProcessing) {
// FIXME KHS method
// Since we're going to remove elements below // Since we're going to remove elements below
theParams.values().forEach(nextAndList -> ensureSubListsAreWritable(nextAndList)); theParams.values().forEach(nextAndList -> ensureSubListsAreWritable(nextAndList));
@ -2846,7 +2848,6 @@ public class SearchBuilder implements ISearchBuilder {
} }
private <T> void ensureSubListsAreWritable(List<List<T>> theListOfLists) { private <T> void ensureSubListsAreWritable(List<List<T>> theListOfLists) {
for (int i = 0; i < theListOfLists.size(); i++) { for (int i = 0; i < theListOfLists.size(); i++) {
List<T> oldSubList = theListOfLists.get(i); List<T> oldSubList = theListOfLists.get(i);

View File

@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.dao.dstu3;
import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.model.entity.*; import ca.uhn.fhir.jpa.model.entity.*;
import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
import ca.uhn.fhir.jpa.searchparam.SearchParamConstants; import ca.uhn.fhir.jpa.searchparam.SearchParamConstants;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
@ -35,6 +36,7 @@ import org.junit.AfterClass;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
@ -56,6 +58,9 @@ import static org.mockito.Mockito.mock;
public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3SearchNoFtTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3SearchNoFtTest.class);
@Autowired
MatchUrlService myMatchUrlService;
@Before @Before
public void beforeDisableResultReuse() { public void beforeDisableResultReuse() {
myDaoConfig.setReuseCachedSearchResultsForMillis(null); myDaoConfig.setReuseCachedSearchResultsForMillis(null);
@ -3494,10 +3499,17 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
loc.setPosition(position); loc.setPosition(position);
String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue(); String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue();
SearchParameterMap map = new SearchParameterMap(); SearchParameterMap map = myMatchUrlService.translateMatchUrl(
map.add(Location.SP_NEAR, new TokenParam((latitude + offset) + ":" + (longitude - offset))); "Location?" +
QuantityParam distance = new QuantityParam(ParamPrefixEnum.LESSTHAN_OR_EQUALS, offset * 2, "http://unitsofmeasure.org", "km"); Location.SP_NEAR + "=" + (latitude + offset) + ":" + (longitude - offset) +
map.add(Location.SP_NEAR_DISTANCE, distance); "&" +
Location.SP_NEAR_DISTANCE + "=" + (offset * 2) + "|http://unitsofmeasure.org|km", myFhirCtx.getResourceDefinition("Location"));
// FIXME KHS
// new SearchParameterMap();
// map.add(Location.SP_NEAR, new TokenParam());
// QuantityParam distance = new QuantityParam(ParamPrefixEnum.LESSTHAN_OR_EQUALS, );
// map.add(Location.SP_NEAR_DISTANCE, distance);
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map)); List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId)); assertThat(ids, contains(locId));

View File

@ -2,12 +2,16 @@ package ca.uhn.fhir.jpa.searchparam;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.jpa.config.TestDstu3Config;
import ca.uhn.fhir.jpa.config.TestR4Config; import ca.uhn.fhir.jpa.config.TestR4Config;
import ca.uhn.fhir.jpa.dao.BaseJpaTest; import ca.uhn.fhir.jpa.dao.BaseJpaTest;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.model.dstu2.resource.Condition; import ca.uhn.fhir.rest.param.QuantityParam;
import ca.uhn.fhir.rest.param.ReferenceParam; import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
import org.hl7.fhir.dstu3.model.Condition;
import org.hl7.fhir.dstu3.model.Location;
import org.hl7.fhir.dstu3.model.Quantity;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -17,16 +21,17 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestR4Config.class}) @ContextConfiguration(classes = {TestDstu3Config.class})
public class MatchUrlServiceTest extends BaseJpaTest { public class MatchUrlServiceTest extends BaseJpaTest {
private static FhirContext ourCtx = FhirContext.forDstu2(); private static FhirContext ourCtx = FhirContext.forDstu3();
@Autowired @Autowired
MatchUrlService myMatchUrlService; MatchUrlService myMatchUrlService;
@ -47,6 +52,21 @@ public class MatchUrlServiceTest extends BaseJpaTest {
assertEquals("304", ((ReferenceParam)match.get("patient").get(0).get(0)).getIdPart()); assertEquals("304", ((ReferenceParam)match.get("patient").get(0).get(0)).getIdPart());
} }
@Test
public void testPullOutNearDistance() {
Double kmDistance = 123.4;
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=1000.0:2000.0" +
"&" +
Location.SP_NEAR_DISTANCE + "=" + kmDistance + "|http://unitsofmeasure.org|km", ourCtx.getResourceDefinition("Location"));
QuantityParam nearDistanceParam = map.getNearDistanceParam();
assertNotNull(nearDistanceParam);
// FIXME KHS assert
}
@Override @Override
protected FhirContext getContext() { protected FhirContext getContext() {
return ourCtx; return ourCtx;

View File

@ -26,11 +26,14 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.model.api.IQueryParameterAnd; import ca.uhn.fhir.model.api.IQueryParameterAnd;
import ca.uhn.fhir.model.api.IQueryParameterType; 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.Constants;
import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.api.QualifiedParamList;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.ParameterUtil; import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.param.QuantityAndListParam;
import ca.uhn.fhir.rest.param.QuantityParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.ReflectionUtil; import ca.uhn.fhir.util.ReflectionUtil;
import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.util.UrlUtil;
@ -113,6 +116,10 @@ public class MatchUrlService {
} else if (Constants.PARAM_SOURCE.equals(nextParamName)) { } else if (Constants.PARAM_SOURCE.equals(nextParamName)) {
IQueryParameterAnd<?> param = ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.TOKEN, nextParamName, paramList); IQueryParameterAnd<?> param = ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.TOKEN, nextParamName, paramList);
paramMap.add(nextParamName, param); paramMap.add(nextParamName, param);
} else if (Location.SP_NEAR_DISTANCE.equals(nextParamName)) {
QuantityAndListParam nearDistanceAndListParam = (QuantityAndListParam) ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.QUANTITY, nextParamName, paramList);
// FIXME KHS
paramMap.setNearDistanceParam(nearDistanceAndListParam);
} else if (nextParamName.startsWith("_")) { } else if (nextParamName.startsWith("_")) {
// ignore these since they aren't search params (e.g. _sort) // ignore these since they aren't search params (e.g. _sort)
} else { } else {

View File

@ -6,9 +6,7 @@ import ca.uhn.fhir.model.api.IQueryParameterOr;
import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.param.DateParam; import ca.uhn.fhir.rest.param.*;
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.ObjectUtil;
import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.util.UrlUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -59,6 +57,7 @@ public class SearchParameterMap implements Serializable {
private SortSpec mySort; private SortSpec mySort;
private SummaryEnum mySummaryMode; private SummaryEnum mySummaryMode;
private SearchTotalModeEnum mySearchTotalMode; private SearchTotalModeEnum mySearchTotalMode;
private QuantityParam myNearDistanceParam;
/** /**
* Constructor * Constructor
@ -495,6 +494,25 @@ public class SearchParameterMap implements Serializable {
} }
} }
public void setNearDistanceParam(QuantityAndListParam theQuantityAndListParam) {
List<QuantityOrListParam> orTokens = theQuantityAndListParam.getValuesAsQueryTokens();
if (orTokens.isEmpty()) {
return;
}
// FIXME KHS error if size > 0
QuantityOrListParam quantityOrListParam = orTokens.get(0);
List<QuantityParam> tokens = quantityOrListParam.getValuesAsQueryTokens();
if (tokens.isEmpty()) {
return;
}
// FIXME KHS error if size > 0
myNearDistanceParam = tokens.get(0);
}
public QuantityParam getNearDistanceParam() {
return myNearDistanceParam;
}
public enum EverythingModeEnum { public enum EverythingModeEnum {
/* /*
* Don't reorder! We rely on the ordinals * Don't reorder! We rely on the ordinals