From 51f58f616557ffd0a4033991dc2e4b827d6f24b2 Mon Sep 17 00:00:00 2001 From: jamesagnew Date: Sat, 10 Jan 2015 11:39:41 -0500 Subject: [PATCH] Fix #79 - Support _include=* in JPA --- .../ca/uhn/fhir/jpa/dao/FhirResourceDao.java | 9 ++- .../uhn/fhir/jpa/dao/SearchParameterMap.java | 2 - .../uhn/fhir/jpa/dao/FhirResourceDaoTest.java | 81 +++++++++++++++---- src/changes/changes.xml | 6 ++ 4 files changed, 77 insertions(+), 21 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDao.java index 74bcddf756b..0c5b19e00b7 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDao.java @@ -502,11 +502,16 @@ public class FhirResourceDao extends BaseFhirDao implements for (Include next : theParams.getIncludes()) { for (IResource nextResource : resources) { RuntimeResourceDefinition def = getContext().getResourceDefinition(nextResource); - if (!next.getValue().startsWith(def.getName() + ".")) { + List values; + if ("*".equals(next.getValue())) { + values = new ArrayList(); + values.addAll(t.getAllPopulatedChildElementsOfType(nextResource, ResourceReferenceDt.class)); + } else if (next.getValue().startsWith(def.getName() + ".")) { + values = t.getValues(nextResource, next.getValue()); + } else { continue; } - List values = t.getValues(nextResource, next.getValue()); for (Object object : values) { if (object == null) { continue; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParameterMap.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParameterMap.java index ae15d54fd6a..98978870ffc 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParameterMap.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParameterMap.java @@ -20,9 +20,7 @@ public class SearchParameterMap extends HashMap myIncludes; - private SortSpec mySort; public void add(String theName, IQueryParameterAnd theAnd) { diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoTest.java index 1aa44188146..d5e8371a72f 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoTest.java @@ -31,6 +31,7 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString; import ca.uhn.fhir.model.api.IQueryParameterType; 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.TagList; 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"))); @@ -1057,8 +1059,7 @@ public class FhirResourceDaoTest { Patient patient = new Patient(); patient.addIdentifier().setSystem("urn:system").setValue("testSearchTokenParam001"); patient.addName().addFamily("Tester").addGiven("testSearchTokenParam1"); - patient.addCommunication().setText("testSearchTokenParamComText").addCoding().setCode("testSearchTokenParamCode").setSystem("testSearchTokenParamSystem") - .setDisplay("testSearchTokenParamDisplay"); + patient.addCommunication().setText("testSearchTokenParamComText").addCoding().setCode("testSearchTokenParamCode").setSystem("testSearchTokenParamSystem").setDisplay("testSearchTokenParamDisplay"); ourPatientDao.create(patient); patient = new Patient(); @@ -1115,9 +1116,16 @@ public class FhirResourceDaoTest { @Test public void testSearchWithIncludes() { + IdDt parentOrgId; + { + Organization org = new Organization(); + org.getName().setValue("testSearchWithIncludes_O1Parent"); + parentOrgId = ourOrganizationDao.create(org).getId(); + } { Organization org = new Organization(); org.getName().setValue("testSearchWithIncludes_O1"); + org.setPartOf(new ResourceReferenceDt(parentOrgId)); IdDt orgId = ourOrganizationDao.create(org).getId(); Patient patient = new Patient(); @@ -1133,20 +1141,59 @@ public class FhirResourceDaoTest { ourPatientDao.create(patient); } - SearchParameterMap params = new SearchParameterMap(); - params.add(Patient.SP_FAMILY, new StringDt("Tester_testSearchWithIncludes_P1")); - params.addInclude(Patient.INCLUDE_MANAGINGORGANIZATION); - IBundleProvider search = ourPatientDao.search(params); - List patients = toList(search); - assertEquals(2, patients.size()); - assertEquals(Patient.class, patients.get(0).getClass()); - assertEquals(Organization.class, patients.get(1).getClass()); - - params = new SearchParameterMap(); - params.add(Patient.SP_FAMILY, new StringDt("Tester_testSearchWithIncludes_P1")); - patients = toList(ourPatientDao.search(params)); - assertEquals(1, patients.size()); - + { + // No includes + SearchParameterMap params = new SearchParameterMap(); + params.add(Patient.SP_FAMILY, new StringDt("Tester_testSearchWithIncludes_P1")); + List patients = toList(ourPatientDao.search(params)); + assertEquals(1, patients.size()); + } + { + // Named include + SearchParameterMap params = new SearchParameterMap(); + params.add(Patient.SP_FAMILY, new StringDt("Tester_testSearchWithIncludes_P1")); + params.addInclude(Patient.INCLUDE_MANAGINGORGANIZATION); + IBundleProvider search = ourPatientDao.search(params); + List 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 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 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 patients = toList(search); + assertEquals(1, patients.size()); + assertEquals(Patient.class, patients.get(0).getClass()); + } } /** diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 2f925da7530..f92868736c2 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -50,6 +50,12 @@ the method type was a custom resource definition type (instead of a built-in HAPI type). Thanks to Neal Acharya for the analysis. + + JPA server module now supports + _include]]> + value of + *]]>. Thanks to Bill de Beaubien for reporting! +