FIx #225 - Support and/or in JPA on _id and _language params

This commit is contained in:
jamesagnew 2015-09-21 21:29:04 -04:00
parent 04c2cce13f
commit f2118df9b8
6 changed files with 219 additions and 33 deletions

View File

@ -245,9 +245,10 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
HashSet<Long> found = new HashSet<Long>(q.getResultList());
if (!theExistingPids.isEmpty()) {
theExistingPids.retainAll(found);
return theExistingPids;
} else {
return found;
}
return found;
}
// private Set<Long> addPredicateComposite(String theParamName, Set<Long> thePids, List<? extends
@ -2127,42 +2128,41 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
if (nextParamEntry.getValue().isEmpty()) {
continue;
} else if (nextParamEntry.getValue().size() > 1) {
throw new InvalidRequestException("AND queries not supported for _id (Multiple instances of this param found)");
} else {
Set<Long> joinPids = new HashSet<Long>();
List<? extends IQueryParameterType> nextValue = nextParamEntry.getValue().get(0);
if (nextValue == null || nextValue.size() == 0) {
continue;
} else {
for (IQueryParameterType next : nextValue) {
String value = next.getValueAsQueryToken();
IIdType valueId = new IdDt(value);
for (List<? extends IQueryParameterType> nextValue : nextParamEntry.getValue()) {
Set<Long> joinPids = new HashSet<Long>();
if (nextValue == null || nextValue.size() == 0) {
continue;
} else {
for (IQueryParameterType next : nextValue) {
String value = next.getValueAsQueryToken();
IIdType valueId = new IdDt(value);
try {
BaseHasResource entity = readEntity(valueId);
if (entity.getDeleted() != null) {
continue;
try {
BaseHasResource entity = readEntity(valueId);
if (entity.getDeleted() != null) {
continue;
}
joinPids.add(entity.getId());
} catch (ResourceNotFoundException e) {
// This isn't an error, just means no result found
}
joinPids.add(entity.getId());
} catch (ResourceNotFoundException e) {
// This isn't an error, just means no result found
}
if (joinPids.isEmpty()) {
return new HashSet<Long>();
}
}
if (joinPids.isEmpty()) {
pids = addPredicateId(pids, joinPids);
if (pids.isEmpty()) {
return new HashSet<Long>();
}
}
pids = addPredicateId(pids, joinPids);
if (pids.isEmpty()) {
return new HashSet<Long>();
}
if (pids.isEmpty()) {
pids.addAll(joinPids);
} else {
pids.retainAll(joinPids);
if (pids.isEmpty()) {
pids.addAll(joinPids);
} else {
pids.retainAll(joinPids);
}
}
}

View File

@ -19,6 +19,7 @@ import org.springframework.transaction.annotation.Transactional;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.jpa.entity.ResourceTable;
import ca.uhn.fhir.jpa.entity.SubscriptionCandidateResource;
import ca.uhn.fhir.jpa.entity.SubscriptionTable;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
@ -76,6 +77,8 @@ public class FhirResourceDaoSubscriptionDstu2 extends FhirResourceDaoDstu2<Subsc
}
ourLog.trace("Beginning pollForNewUndeliveredResources()");
// SubscriptionCandidateResource
TypedQuery<SubscriptionTable> q = myEntityManager.createNamedQuery("Q_HFJ_SUBSCRIPTION_NEXT_CHECK", SubscriptionTable.class);
q.setParameter("next_check", new Date());
q.setParameter("status", SubscriptionStatusEnum.ACTIVE);

View File

@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.dao;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsInRelativeOrder;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.not;
@ -68,6 +69,8 @@ import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.NumberParam;
import ca.uhn.fhir.rest.param.QuantityParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.StringOrListParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenAndListParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
@ -297,6 +300,104 @@ public class FhirResourceDaoDstu2SearchTest extends BaseJpaDstu2Test {
}
@Test
public void testSearchByIdParamWrongType() {
IIdType id1;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
id1 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
}
IIdType id2;
{
Organization patient = new Organization();
patient.addIdentifier().setSystem("urn:system").setValue("001");
id2 = myOrganizationDao.create(patient).getId().toUnqualifiedVersionless();
}
SearchParameterMap params = new SearchParameterMap();
params.add("_id", new StringOrListParam().addOr(new StringParam(id1.getIdPart())).addOr(new StringParam(id2.getIdPart())));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
@Test
public void testSearchByIdParamOr() {
IIdType id1;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
id1 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
}
IIdType id2;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
id2 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
}
SearchParameterMap params = new SearchParameterMap();
params.add("_id", new StringOrListParam().addOr(new StringParam(id1.getIdPart())).addOr(new StringParam(id2.getIdPart())));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1, id2));
params = new SearchParameterMap();
params.add("_id", new StringOrListParam().addOr(new StringParam(id1.getIdPart())).addOr(new StringParam(id1.getIdPart())));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
params = new SearchParameterMap();
params.add("_id", new StringOrListParam().addOr(new StringParam(id1.getIdPart())).addOr(new StringParam("999999999999")));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
@Test
public void testSearchByIdParamAnd() {
IIdType id1;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
id1 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
}
IIdType id2;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
id2 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
}
SearchParameterMap params;
StringAndListParam param;
params = new SearchParameterMap();
param = new StringAndListParam();
param.addAnd(new StringOrListParam().addOr(new StringParam(id1.getIdPart())).addOr(new StringParam(id2.getIdPart())));
param.addAnd(new StringOrListParam().addOr(new StringParam(id1.getIdPart())));
params.add("_id", param);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
params = new SearchParameterMap();
param = new StringAndListParam();
param.addAnd(new StringOrListParam().addOr(new StringParam(id2.getIdPart())));
param.addAnd(new StringOrListParam().addOr(new StringParam(id1.getIdPart())));
params.add("_id", param);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
params = new SearchParameterMap();
param = new StringAndListParam();
param.addAnd(new StringOrListParam().addOr(new StringParam(id2.getIdPart())));
param.addAnd(new StringOrListParam().addOr(new StringParam("9999999999999")));
params.add("_id", param);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
params = new SearchParameterMap();
param = new StringAndListParam();
param.addAnd(new StringOrListParam().addOr(new StringParam("9999999999999")));
param.addAnd(new StringOrListParam().addOr(new StringParam(id2.getIdPart())));
params.add("_id", param);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
}
@Test
public void testSearchCompositeParam() {
Observation o1 = new Observation();
@ -368,7 +469,6 @@ public class FhirResourceDaoDstu2SearchTest extends BaseJpaDstu2Test {
assertEquals(0, retrieved.size());
}
}
@Test
public void testSearchLanguageParam() {
IIdType id1;
@ -407,7 +507,60 @@ public class FhirResourceDaoDstu2SearchTest extends BaseJpaDstu2Test {
List<Patient> patients = toList(myPatientDao.search(params));
assertEquals(0, patients.size());
}
}
@Test
public void testSearchLanguageParamAndOr() {
IIdType id1;
{
Patient patient = new Patient();
patient.getLanguage().setValue("en_CA");
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().addFamily("testSearchLanguageParam").addGiven("Joe");
id1 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
}
IIdType id2;
{
Patient patient = new Patient();
patient.getLanguage().setValue("en_US");
patient.addIdentifier().setSystem("urn:system").setValue("002");
patient.addName().addFamily("testSearchLanguageParam").addGiven("John");
id2 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
}
{
SearchParameterMap params = new SearchParameterMap();
params.add(Patient.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1, id2));
}
{
SearchParameterMap params = new SearchParameterMap();
params.add(Patient.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")));
params.add(Patient.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
params.add(Patient.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
params.add(Patient.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
}
}
@Test

View File

@ -151,6 +151,33 @@ public class ResourceProviderDstu2Test extends BaseJpaDstu2Test {
// }
// }
@Test
public void testSearchByIdOr() {
IIdType id1;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
id1 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
}
IIdType id2;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
id2 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
}
//@formatter:off
Bundle found = ourClient
.search()
.forResource(Patient.class)
.where(Patient.RES_ID.matches().values(id1.getIdPart(), id2.getIdPart()))
.and(Patient.RES_ID.matches().value(id1.getIdPart()))
.execute();
//@formatter:on
assertThat(toIdListUnqualifiedVersionless(found), containsInAnyOrder(id1));
}
@Test
public void testBundleCreate() throws Exception {
IGenericClient client = ourClient;

View File

@ -44,11 +44,11 @@ public class ${className}ResourceProvider extends
@Description(shortDefinition="The resource identity")
@OptionalParam(name="_id")
StringParam theId,
StringAndListParam theId,
@Description(shortDefinition="The resource language")
@OptionalParam(name="_language")
StringParam theResourceLanguage,
StringAndListParam theResourceLanguage,
@Description(shortDefinition="Search for resources which have the given tag")
@OptionalParam(name=ca.uhn.fhir.rest.server.Constants.PARAM_TAG)

View File

@ -30,6 +30,9 @@
JPA server _history operations (server, type, instance) not correctly set the
Bundle.entry.request.method to POST or PUT for create and updates of the resource.
</action>
<action type="add" issue="225">
Support AND/OR on _id search parameter in JPA
</action>
</release>
<release version="1.2" date="2015-09-18">
<action type="add">