Fix #79 - Support _include=* in JPA

This commit is contained in:
jamesagnew 2015-01-10 11:39:41 -05:00
parent 6dfb5d03e4
commit 51f58f6165
4 changed files with 77 additions and 21 deletions

View File

@ -502,11 +502,16 @@ public class FhirResourceDao<T extends IResource> extends BaseFhirDao implements
for (Include next : theParams.getIncludes()) { for (Include next : theParams.getIncludes()) {
for (IResource nextResource : resources) { for (IResource nextResource : resources) {
RuntimeResourceDefinition def = getContext().getResourceDefinition(nextResource); RuntimeResourceDefinition def = getContext().getResourceDefinition(nextResource);
if (!next.getValue().startsWith(def.getName() + ".")) { List<Object> values;
if ("*".equals(next.getValue())) {
values = new ArrayList<Object>();
values.addAll(t.getAllPopulatedChildElementsOfType(nextResource, ResourceReferenceDt.class));
} else if (next.getValue().startsWith(def.getName() + ".")) {
values = t.getValues(nextResource, next.getValue());
} else {
continue; continue;
} }
List<Object> values = t.getValues(nextResource, next.getValue());
for (Object object : values) { for (Object object : values) {
if (object == null) { if (object == null) {
continue; continue;

View File

@ -20,9 +20,7 @@ public class SearchParameterMap extends HashMap<String, List<List<? extends IQue
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private Integer myCount; private Integer myCount;
private Set<Include> myIncludes; private Set<Include> myIncludes;
private SortSpec mySort; private SortSpec mySort;
public void add(String theName, IQueryParameterAnd<?> theAnd) { public void add(String theName, IQueryParameterAnd<?> theAnd) {

View File

@ -31,6 +31,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString; import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.dstu.composite.CodeableConceptDt; import ca.uhn.fhir.model.dstu.composite.CodeableConceptDt;
@ -911,7 +912,8 @@ public class FhirResourceDaoTest {
} }
/* /*
* TODO: it's kind of weird that we throw a 404 for textual IDs that don't exist, but just return an empty list for numeric IDs that don't exist * TODO: it's kind of weird that we throw a 404 for textual IDs that don't exist, but just return an empty list
* for numeric IDs that don't exist
*/ */
result = toList(ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam("999999999999999"))); result = toList(ourObservationDao.search(Observation.SP_SUBJECT, new ReferenceParam("999999999999999")));
@ -1057,8 +1059,7 @@ public class FhirResourceDaoTest {
Patient patient = new Patient(); Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("testSearchTokenParam001"); patient.addIdentifier().setSystem("urn:system").setValue("testSearchTokenParam001");
patient.addName().addFamily("Tester").addGiven("testSearchTokenParam1"); patient.addName().addFamily("Tester").addGiven("testSearchTokenParam1");
patient.addCommunication().setText("testSearchTokenParamComText").addCoding().setCode("testSearchTokenParamCode").setSystem("testSearchTokenParamSystem") patient.addCommunication().setText("testSearchTokenParamComText").addCoding().setCode("testSearchTokenParamCode").setSystem("testSearchTokenParamSystem").setDisplay("testSearchTokenParamDisplay");
.setDisplay("testSearchTokenParamDisplay");
ourPatientDao.create(patient); ourPatientDao.create(patient);
patient = new Patient(); patient = new Patient();
@ -1115,9 +1116,16 @@ public class FhirResourceDaoTest {
@Test @Test
public void testSearchWithIncludes() { public void testSearchWithIncludes() {
IdDt parentOrgId;
{
Organization org = new Organization();
org.getName().setValue("testSearchWithIncludes_O1Parent");
parentOrgId = ourOrganizationDao.create(org).getId();
}
{ {
Organization org = new Organization(); Organization org = new Organization();
org.getName().setValue("testSearchWithIncludes_O1"); org.getName().setValue("testSearchWithIncludes_O1");
org.setPartOf(new ResourceReferenceDt(parentOrgId));
IdDt orgId = ourOrganizationDao.create(org).getId(); IdDt orgId = ourOrganizationDao.create(org).getId();
Patient patient = new Patient(); Patient patient = new Patient();
@ -1133,20 +1141,59 @@ public class FhirResourceDaoTest {
ourPatientDao.create(patient); ourPatientDao.create(patient);
} }
SearchParameterMap params = new SearchParameterMap(); {
params.add(Patient.SP_FAMILY, new StringDt("Tester_testSearchWithIncludes_P1")); // No includes
params.addInclude(Patient.INCLUDE_MANAGINGORGANIZATION); SearchParameterMap params = new SearchParameterMap();
IBundleProvider search = ourPatientDao.search(params); params.add(Patient.SP_FAMILY, new StringDt("Tester_testSearchWithIncludes_P1"));
List<IResource> patients = toList(search); List<IResource> patients = toList(ourPatientDao.search(params));
assertEquals(2, patients.size()); assertEquals(1, patients.size());
assertEquals(Patient.class, patients.get(0).getClass()); }
assertEquals(Organization.class, patients.get(1).getClass()); {
// Named include
params = new SearchParameterMap(); SearchParameterMap params = new SearchParameterMap();
params.add(Patient.SP_FAMILY, new StringDt("Tester_testSearchWithIncludes_P1")); params.add(Patient.SP_FAMILY, new StringDt("Tester_testSearchWithIncludes_P1"));
patients = toList(ourPatientDao.search(params)); params.addInclude(Patient.INCLUDE_MANAGINGORGANIZATION);
assertEquals(1, patients.size()); IBundleProvider search = ourPatientDao.search(params);
List<IResource> patients = toList(search);
assertEquals(2, patients.size());
assertEquals(Patient.class, patients.get(0).getClass());
assertEquals(Organization.class, patients.get(1).getClass());
}
{
// Named include with parent
SearchParameterMap params = new SearchParameterMap();
params.add(Patient.SP_FAMILY, new StringDt("Tester_testSearchWithIncludes_P1"));
params.addInclude(Patient.INCLUDE_MANAGINGORGANIZATION);
params.addInclude(Organization.INCLUDE_PARTOF);
IBundleProvider search = ourPatientDao.search(params);
List<IResource> patients = toList(search);
assertEquals(3, patients.size());
assertEquals(Patient.class, patients.get(0).getClass());
assertEquals(Organization.class, patients.get(1).getClass());
assertEquals(Organization.class, patients.get(2).getClass());
}
{
// * include
SearchParameterMap params = new SearchParameterMap();
params.add(Patient.SP_FAMILY, new StringDt("Tester_testSearchWithIncludes_P1"));
params.addInclude(new Include("*"));
IBundleProvider search = ourPatientDao.search(params);
List<IResource> patients = toList(search);
assertEquals(3, patients.size());
assertEquals(Patient.class, patients.get(0).getClass());
assertEquals(Organization.class, patients.get(1).getClass());
assertEquals(Organization.class, patients.get(2).getClass());
}
{
// Irrelevant include
SearchParameterMap params = new SearchParameterMap();
params.add(Patient.SP_FAMILY, new StringDt("Tester_testSearchWithIncludes_P1"));
params.addInclude(Encounter.INCLUDE_INDICATION);
IBundleProvider search = ourPatientDao.search(params);
List<IResource> patients = toList(search);
assertEquals(1, patients.size());
assertEquals(Patient.class, patients.get(0).getClass());
}
} }
/** /**

View File

@ -50,6 +50,12 @@
the method type was a custom resource definition type (instead of a built-in the method type was a custom resource definition type (instead of a built-in
HAPI type). Thanks to Neal Acharya for the analysis. HAPI type). Thanks to Neal Acharya for the analysis.
</action> </action>
<action type="add" fix="79">
JPA server module now supports
<![CDATA[<code>_include</code>]]>
value of
<![CDATA[<code>*</code>]]>. Thanks to Bill de Beaubien for reporting!
</action>
</release> </release>
<release version="0.8" date="2014-Dec-17"> <release version="0.8" date="2014-Dec-17">
<action type="add"> <action type="add">