NOFT test passing

This commit is contained in:
James Agnew 2017-04-08 21:19:10 -04:00
parent 90a4e2def2
commit 801ae7cb75
3 changed files with 167 additions and 94 deletions

View File

@ -46,6 +46,7 @@ import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.servlet.ThemeResolver;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
@ -117,7 +118,7 @@ public class SearchBuilder {
mySearchParamRegistry = theSearchParamRegistry;
}
private void addPredicateComposite(RuntimeSearchParam theParamDef, List<? extends IQueryParameterType> theNextAnd) {
private void addPredicateComposite(String theResourceName, RuntimeSearchParam theParamDef, List<? extends IQueryParameterType> theNextAnd) {
// TODO: fail if missing is set for a composite query
IQueryParameterType or = theNextAnd.get(0);
@ -128,15 +129,15 @@ public class SearchBuilder {
RuntimeSearchParam left = theParamDef.getCompositeOf().get(0);
IQueryParameterType leftValue = cp.getLeftValue();
myPredicates.add(createCompositeParamPart(myResourceTableRoot, left, leftValue));
myPredicates.add(createCompositeParamPart(theResourceName, myResourceTableRoot, left, leftValue));
RuntimeSearchParam right = theParamDef.getCompositeOf().get(1);
IQueryParameterType rightValue = cp.getRightValue();
myPredicates.add(createCompositeParamPart(myResourceTableRoot, right, rightValue));
myPredicates.add(createCompositeParamPart(theResourceName, myResourceTableRoot, right, rightValue));
}
private void addPredicateDate(String theParamName, List<? extends IQueryParameterType> theList) {
private void addPredicateDate(String theResourceName, String theParamName, List<? extends IQueryParameterType> theList) {
if (theList.get(0).getMissing() != null) {
addPredicateParamMissing(theParamName, theList.get(0).getMissing());
@ -148,7 +149,7 @@ public class SearchBuilder {
List<Predicate> codePredicates = new ArrayList<Predicate>();
for (IQueryParameterType nextOr : theList) {
IQueryParameterType params = nextOr;
Predicate p = createPredicateDate(params, theParamName, myBuilder, join);
Predicate p = createPredicateDate(params, theResourceName, theParamName, myBuilder, join);
codePredicates.add(p);
}
@ -206,7 +207,7 @@ public class SearchBuilder {
match = Collections.singleton(-1L);
}
Join<ResourceTable, ResourceLink> join = myResourceTableRoot.join("myResourceLinksByTarget", JoinType.LEFT);
Join<ResourceTable, ResourceLink> join = myResourceTableRoot.join("myIncomingResourceLinks", JoinType.LEFT);
Predicate predicate = join.get("mySourceResourcePid").in(match);
myPredicates.add(predicate);
@ -262,7 +263,7 @@ public class SearchBuilder {
return;
}
private void addPredicateNumber(String theParamName, List<? extends IQueryParameterType> theList) {
private void addPredicateNumber(String theResourceName, String theParamName, List<? extends IQueryParameterType> theList) {
if (theList.get(0).getMissing() != null) {
addPredicateParamMissing(theParamName, theList.get(0).getMissing());
@ -288,7 +289,7 @@ public class SearchBuilder {
String invalidMessageName = "invalidNumberPrefix";
String valueAsString = param.getValue().toPlainString();
Predicate num = createPredicateNumeric(theParamName, join, myBuilder, params, prefix, value, fromObj, invalidMessageName, valueAsString);
Predicate num = createPredicateNumeric(theResourceName, theParamName, join, myBuilder, params, prefix, value, fromObj, invalidMessageName, valueAsString);
codePredicates.add(num);
} else {
@ -309,7 +310,7 @@ public class SearchBuilder {
myPredicates.add(myBuilder.equal(paramPresentJoin.get("myPresent"), !theMissing));
}
private void addPredicateQuantity(String theParamName, List<? extends IQueryParameterType> theList) {
private void addPredicateQuantity(String theResourceName, String theParamName, List<? extends IQueryParameterType> theList) {
if (theList.get(0).getMissing() != null) {
addPredicateParamMissing(theParamName, theList.get(0).getMissing());
return;
@ -320,7 +321,7 @@ public class SearchBuilder {
List<Predicate> codePredicates = new ArrayList<Predicate>();
for (IQueryParameterType nextOr : theList) {
Predicate singleCode = createPredicateQuantity(nextOr, theParamName, myBuilder, join);
Predicate singleCode = createPredicateQuantity(nextOr, theResourceName, theParamName, myBuilder, join);
codePredicates.add(singleCode);
}
@ -511,7 +512,7 @@ public class SearchBuilder {
myPredicates.add(myBuilder.or(toArray(codePredicates)));
}
private void addPredicateString(String theParamName, List<? extends IQueryParameterType> theList) {
private void addPredicateString(String theResourceName, String theParamName, List<? extends IQueryParameterType> theList) {
if (theList.get(0).getMissing() != null) {
addPredicateParamMissing(theParamName, theList.get(0).getMissing());
return;
@ -522,7 +523,7 @@ public class SearchBuilder {
List<Predicate> codePredicates = new ArrayList<Predicate>();
for (IQueryParameterType nextOr : theList) {
IQueryParameterType theParameter = nextOr;
Predicate singleCode = createPredicateString(theParameter, theParamName, myBuilder, join);
Predicate singleCode = createPredicateString(theParameter, theResourceName, theParamName, myBuilder, join);
codePredicates.add(singleCode);
}
@ -658,7 +659,7 @@ public class SearchBuilder {
}
private void addPredicateToken(String theParamName, List<? extends IQueryParameterType> theList) {
private void addPredicateToken(String theResourceName, String theParamName, List<? extends IQueryParameterType> theList) {
if (theList.get(0).getMissing() != null) {
addPredicateParamMissing(theParamName, theList.get(0).getMissing());
@ -673,12 +674,12 @@ public class SearchBuilder {
if (nextOr instanceof TokenParam) {
TokenParam id = (TokenParam) nextOr;
if (id.isText()) {
addPredicateString(theParamName, theList);
addPredicateString(theResourceName, theParamName, theList);
continue;
}
}
Predicate singleCode = createPredicateToken(nextOr, theParamName, myBuilder, join);
Predicate singleCode = createPredicateToken(nextOr, theResourceName, theParamName, myBuilder, join);
codePredicates.add(singleCode);
}
@ -770,27 +771,27 @@ public class SearchBuilder {
myPredicates.add(outerPredicate);
}
private Predicate createCompositeParamPart(Root<ResourceTable> theRoot, RuntimeSearchParam theParam, IQueryParameterType leftValue) {
private Predicate createCompositeParamPart(String theResourceName, Root<ResourceTable> theRoot, RuntimeSearchParam theParam, IQueryParameterType leftValue) {
Predicate retVal = null;
switch (theParam.getParamType()) {
case STRING: {
From<ResourceIndexedSearchParamString, ResourceIndexedSearchParamString> stringJoin = theRoot.join("myParamsString", JoinType.INNER);
retVal = createPredicateString(leftValue, theParam.getName(), myBuilder, stringJoin);
retVal = createPredicateString(leftValue, theResourceName, theParam.getName(), myBuilder, stringJoin);
break;
}
case TOKEN: {
From<ResourceIndexedSearchParamToken, ResourceIndexedSearchParamToken> tokenJoin = theRoot.join("myParamsToken", JoinType.INNER);
retVal = createPredicateToken(leftValue, theParam.getName(), myBuilder, tokenJoin);
retVal = createPredicateToken(leftValue, theResourceName, theParam.getName(), myBuilder, tokenJoin);
break;
}
case DATE: {
From<ResourceIndexedSearchParamDate, ResourceIndexedSearchParamDate> dateJoin = theRoot.join("myParamsDate", JoinType.INNER);
retVal = createPredicateDate(leftValue, theParam.getName(), myBuilder, dateJoin);
retVal = createPredicateDate(leftValue, theResourceName, theParam.getName(), myBuilder, dateJoin);
break;
}
case QUANTITY: {
From<ResourceIndexedSearchParamQuantity, ResourceIndexedSearchParamQuantity> dateJoin = theRoot.join("myParamsQuantity", JoinType.INNER);
retVal = createPredicateQuantity(leftValue, theParam.getName(), myBuilder, dateJoin);
retVal = createPredicateQuantity(leftValue, theResourceName, theParam.getName(), myBuilder, dateJoin);
break;
}
case COMPOSITE:
@ -808,7 +809,7 @@ public class SearchBuilder {
return retVal;
}
private Predicate createPredicateDate(IQueryParameterType theParam, String theParamName, CriteriaBuilder theBuilder, From<?, ResourceIndexedSearchParamDate> theFrom) {
private Predicate createPredicateDate(IQueryParameterType theParam, String theResourceName, String theParamName, CriteriaBuilder theBuilder, From<?, ResourceIndexedSearchParamDate> theFrom) {
Predicate p;
if (theParam instanceof DateParam) {
DateParam date = (DateParam) theParam;
@ -826,7 +827,7 @@ public class SearchBuilder {
throw new IllegalArgumentException("Invalid token type: " + theParam.getClass());
}
return combineParamIndexPredicateWithParamNamePredicate(theParamName, theFrom, p);
return combineParamIndexPredicateWithParamNamePredicate(theResourceName, theParamName, theFrom, p);
}
private Predicate createPredicateDateFromRange(CriteriaBuilder theBuilder, From<?, ResourceIndexedSearchParamDate> theFrom, DateRangeParam theRange) {
@ -886,7 +887,8 @@ public class SearchBuilder {
predicates.addAll(createLastUpdatedPredicates(myParams.getLastUpdatedAndRemove(), builder, from));
}
private Predicate createPredicateNumeric(String theParamName, From<?, ? extends BaseResourceIndexedSearchParam> theFrom, CriteriaBuilder builder, IQueryParameterType theParam, ParamPrefixEnum thePrefix, BigDecimal theValue, final Expression<BigDecimal> thePath,
private Predicate createPredicateNumeric(String theResourceName, String theParamName, From<?, ? extends BaseResourceIndexedSearchParam> theFrom, CriteriaBuilder builder,
IQueryParameterType theParam, ParamPrefixEnum thePrefix, BigDecimal theValue, final Expression<BigDecimal> thePath,
String invalidMessageName, String theValueString) {
Predicate num;
switch (thePrefix) {
@ -930,10 +932,11 @@ public class SearchBuilder {
if (theParamName == null) {
return num;
}
return combineParamIndexPredicateWithParamNamePredicate(theParamName, theFrom, num);
return combineParamIndexPredicateWithParamNamePredicate(theResourceName, theParamName, theFrom, num);
}
private Predicate createPredicateQuantity(IQueryParameterType theParam, String theParamName, CriteriaBuilder theBuilder, From<?, ResourceIndexedSearchParamQuantity> theFrom) {
private Predicate createPredicateQuantity(IQueryParameterType theParam, String theResourceName, String theParamName, CriteriaBuilder theBuilder,
From<?, ResourceIndexedSearchParamQuantity> theFrom) {
String systemValue;
String unitsValue;
ParamPrefixEnum cmpValue;
@ -972,7 +975,7 @@ public class SearchBuilder {
final Expression<BigDecimal> path = theFrom.get("myValue");
String invalidMessageName = "invalidQuantityPrefix";
Predicate num = createPredicateNumeric(null, theFrom, theBuilder, theParam, cmpValue, valueValue, path, invalidMessageName, valueString);
Predicate num = createPredicateNumeric(theResourceName, null, theFrom, theBuilder, theParam, cmpValue, valueValue, path, invalidMessageName, valueString);
Predicate singleCode;
if (system == null && code == null) {
@ -985,7 +988,7 @@ public class SearchBuilder {
singleCode = theBuilder.and(system, code, num);
}
return combineParamIndexPredicateWithParamNamePredicate(theParamName, theFrom, singleCode);
return combineParamIndexPredicateWithParamNamePredicate(theResourceName, theParamName, theFrom, singleCode);
}
private void createPredicateResourceId(CriteriaBuilder builder, AbstractQuery<?> cq, List<Predicate> thePredicates, Expression<Long> theExpression) {
@ -1000,7 +1003,7 @@ public class SearchBuilder {
}
}
private Predicate createPredicateString(IQueryParameterType theParameter, String theParamName, CriteriaBuilder theBuilder,
private Predicate createPredicateString(IQueryParameterType theParameter, String theResourceName, String theParamName, CriteriaBuilder theBuilder,
From<?, ResourceIndexedSearchParamString> theFrom) {
String rawSearchTerm;
if (theParameter instanceof TokenParam) {
@ -1033,11 +1036,11 @@ public class SearchBuilder {
singleCode = theBuilder.and(singleCode, exactCode);
}
return combineParamIndexPredicateWithParamNamePredicate(theParamName, theFrom, singleCode);
return combineParamIndexPredicateWithParamNamePredicate(theResourceName, theParamName, theFrom, singleCode);
}
private Predicate combineParamIndexPredicateWithParamNamePredicate(String theParamName, From<?, ? extends BaseResourceIndexedSearchParam> theFrom, Predicate thePredicate) {
Predicate resourceTypePredicate = myBuilder.equal(theFrom.get("myResourceType"), myResourceName);
private Predicate combineParamIndexPredicateWithParamNamePredicate(String theResourceName, String theParamName, From<?, ? extends BaseResourceIndexedSearchParam> theFrom, Predicate thePredicate) {
Predicate resourceTypePredicate = myBuilder.equal(theFrom.get("myResourceType"), theResourceName);
Predicate paramNamePredicate = myBuilder.equal(theFrom.get("myParamName"), theParamName);
Predicate outerPredicate = myBuilder.and(resourceTypePredicate, paramNamePredicate, thePredicate);
return outerPredicate;
@ -1059,7 +1062,7 @@ public class SearchBuilder {
return orPredicates;
}
private Predicate createPredicateToken(IQueryParameterType theParameter, String theParamName, CriteriaBuilder theBuilder,
private Predicate createPredicateToken(IQueryParameterType theParameter, String theResourceName, String theParamName, CriteriaBuilder theBuilder,
From<?, ResourceIndexedSearchParamToken> theFrom) {
String code;
String system;
@ -1106,7 +1109,7 @@ public class SearchBuilder {
codes = myTerminologySvc.findCodesBelow(system, code);
}
ArrayList<Predicate> singleCodePredicates = (new ArrayList<Predicate>());
ArrayList<Predicate> singleCodePredicates = new ArrayList<Predicate>();
if (codes != null) {
if (codes.isEmpty()) {
@ -1156,7 +1159,7 @@ public class SearchBuilder {
}
Predicate singleCode = theBuilder.and(toArray(singleCodePredicates));
return combineParamIndexPredicateWithParamNamePredicate(theParamName, theFrom, singleCode);
return combineParamIndexPredicateWithParamNamePredicate(theResourceName, theParamName, theFrom, singleCode);
}
private Predicate createResourceLinkPathPredicate(String theParamName, From<?, ? extends ResourceLink> from) {
@ -1302,7 +1305,6 @@ public class SearchBuilder {
return system;
}
private boolean doHaveNoResults() {
return mySearchEntity.getTotalCount() == 0;
}
@ -1490,14 +1492,28 @@ public class SearchBuilder {
myResourceTableQuery.distinct(true);
myResourceTableRoot = myResourceTableQuery.from(ResourceTable.class);
myPredicates = new ArrayList<Predicate>();
if (theParams.getEverythingMode() == null) {
myPredicates.add(myBuilder.equal(myResourceTableRoot.get("myResourceType"), myResourceName));
}
myPredicates.add(myBuilder.isNull(myResourceTableRoot.get("myDeleted")));
DateRangeParam lu = theParams.getLastUpdated();
List<Predicate> lastUpdatedPredicates = createLastUpdatedPredicates(lu, myBuilder, myResourceTableRoot);
myPredicates.addAll(lastUpdatedPredicates);
if (theParams.getEverythingMode() != null) {
if (theParams.get(BaseResource.SP_RES_ID) != null) {
StringParam idParm = (StringParam) theParams.get(BaseResource.SP_RES_ID).get(0).get(0);
Long pid = BaseHapiFhirDao.translateForcedIdToPid(myResourceName, idParm.getValue(), myForcedIdDao);
Join<ResourceTable, ResourceLink> join = myResourceTableRoot.join("myResourceLinks", JoinType.LEFT);
myPredicates.add(myBuilder.equal(join.get("myTargetResourcePid").as(Long.class), pid));
}
} else {
// Normal search
searchForIdsWithAndOr(theParams);
}
myResourceTableQuery.where(myBuilder.and(SearchBuilder.toArray(myPredicates)));
@ -1649,12 +1665,12 @@ public class SearchBuilder {
switch (nextParamDef.getParamType()) {
case DATE:
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
addPredicateDate(theParamName, nextAnd);
addPredicateDate(theResourceName, theParamName, nextAnd);
}
break;
case QUANTITY:
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
addPredicateQuantity(theParamName, nextAnd);
addPredicateQuantity(theResourceName, theParamName, nextAnd);
}
break;
case REFERENCE:
@ -1664,22 +1680,22 @@ public class SearchBuilder {
break;
case STRING:
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
addPredicateString(theParamName, nextAnd);
addPredicateString(theResourceName, theParamName, nextAnd);
}
break;
case TOKEN:
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
addPredicateToken(theParamName, nextAnd);
addPredicateToken(theResourceName, theParamName, nextAnd);
}
break;
case NUMBER:
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
addPredicateNumber(theParamName, nextAnd);
addPredicateNumber(theResourceName, theParamName, nextAnd);
}
break;
case COMPOSITE:
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
addPredicateComposite(nextParamDef, nextAnd);
addPredicateComposite(theResourceName, nextParamDef, nextAnd);
}
break;
case URI:

View File

@ -229,9 +229,6 @@ public class ResourceTable extends BaseHasResource implements Serializable {
@IndexedEmbedded()
private Collection<ResourceLink> myResourceLinks;
@OneToMany(mappedBy = "myTargetResource", cascade = {}, fetch = FetchType.LAZY, orphanRemoval = false)
private Collection<ResourceLink> myResourceLinksByTarget;
@Column(name = "RES_TYPE", length = RESTYPE_LEN)
@Field
private String myResourceType;

View File

@ -9,6 +9,8 @@ import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@ -29,6 +31,7 @@ import org.hl7.fhir.dstu3.model.Bundle.BundleType;
import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb;
import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointSystem;
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
import org.hl7.fhir.dstu3.model.Subscription.SubscriptionChannelType;
import org.hl7.fhir.dstu3.model.Subscription.SubscriptionStatus;
import org.hl7.fhir.exceptions.FHIRException;
@ -43,12 +46,15 @@ import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.DaoMethodOutcome;
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.jpa.dao.SearchParameterMap.EverythingModeEnum;
import ca.uhn.fhir.jpa.dao.data.ISearchDao;
import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc;
import ca.uhn.fhir.model.api.IQueryParameterType;
@ -67,6 +73,9 @@ import ca.uhn.fhir.util.TestUtil;
public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3SearchNoFtTest.class);
@Autowired
protected ISearchDao mySearchEntityDao;
@Autowired
protected IStaleSearchDeletingSvc myStaleSearchDeletingSvc;
@ -321,6 +330,44 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
assertEquals(2, results.size());
}
@SuppressWarnings("unused")
@Test
public void testHasAndHas() {
Patient p1 = new Patient();
p1.setActive(true);
IIdType p1id = myPatientDao.create(p1).getId().toUnqualifiedVersionless();
Patient p2 = new Patient();
p2.setActive(true);
IIdType p2id = myPatientDao.create(p2).getId().toUnqualifiedVersionless();
Observation p1o1 = new Observation();
p1o1.setStatus(ObservationStatus.FINAL);
p1o1.getSubject().setReferenceElement(p1id);
IIdType p1o1id = myObservationDao.create(p1o1).getId().toUnqualifiedVersionless();
Observation p1o2 = new Observation();
p1o2.setEffective(new DateTimeType("2001-01-01"));
p1o2.getSubject().setReferenceElement(p1id);
IIdType p1o2id = myObservationDao.create(p1o2).getId().toUnqualifiedVersionless();
Observation p2o1 = new Observation();
p2o1.setStatus(ObservationStatus.FINAL);
p2o1.getSubject().setReferenceElement(p2id);
IIdType p2o1id = myObservationDao.create(p2o1).getId().toUnqualifiedVersionless();
SearchParameterMap map = new SearchParameterMap();
HasAndListParam hasAnd = new HasAndListParam();
hasAnd.addValue(new HasOrListParam().add(new HasParam("Observation", "subject", "status", "final")));
hasAnd.addValue(new HasOrListParam().add(new HasParam("Observation", "subject", "date", "2001-01-01")));
map.add("_has", hasAnd);
List<String> actual = toUnqualifiedVersionlessIdValues(myPatientDao.search(map));
assertThat(actual, containsInAnyOrder(p1id.getValue()));
}
@Test
public void testIndexNoDuplicatesNumber() {
Immunization res = new Immunization();
@ -1265,16 +1312,29 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
SearchParameterMap params;
params = new SearchParameterMap();
params.add(Patient.SP_FAMILY, new StringParam("EXPIRE"));
IBundleProvider bundleProvider = myPatientDao.search(params);
final IBundleProvider bundleProvider = myPatientDao.search(params);
assertThat(toUnqualifiedVersionlessIds(bundleProvider), containsInAnyOrder(pid1, pid2));
assertThat(toUnqualifiedVersionlessIds(bundleProvider), containsInAnyOrder(pid1, pid2));
Thread.sleep(1500);
TransactionTemplate txTemplate = new TransactionTemplate(myTxManager);
txTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus theArg0) {
assertNotNull(mySearchEntityDao.findByUuid(bundleProvider.getUuid()));
}
});
myDaoConfig.setExpireSearchResultsAfterMillis(500);
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
assertThat(toUnqualifiedVersionlessIds(bundleProvider), not(containsInAnyOrder(pid1, pid2)));
txTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus theArg0) {
assertNull(mySearchEntityDao.findByUuid(bundleProvider.getUuid()));
}
});
}
@Test