Support _count on JPA search in transaction

This commit is contained in:
James Agnew 2015-06-25 10:32:03 -04:00
parent 1b82b7df65
commit af33664e7c
4 changed files with 74 additions and 11 deletions

View File

@ -20,7 +20,9 @@ package ca.uhn.fhir.parser;
* #L%
*/
import static org.apache.commons.lang3.StringUtils.*;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.IOException;
import java.io.Reader;

View File

@ -125,7 +125,7 @@ public abstract class BaseFhirDao implements IDao {
private FhirContext myContext;
// @PersistenceContext(name = "FHIR_UT", type = PersistenceContextType.TRANSACTION, unitName = "FHIR_UT")
// @PersistenceContext(name = "FHIR_UT", type = PersistenceContextType.TRANSACTION, unitName = "FHIR_UT")
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
private EntityManager myEntityManager;
@ -195,8 +195,7 @@ public abstract class BaseFhirDao implements IDao {
String typeString = nextValue.getReference().getResourceType();
if (isBlank(typeString)) {
throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource type - "
+ nextValue.getReference().getValue());
throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource type - " + nextValue.getReference().getValue());
}
Class<? extends IBaseResource> type = getContext().getResourceDefinition(typeString).getImplementingClass();
String id = nextValue.getReference().getIdPart();
@ -347,7 +346,7 @@ public abstract class BaseFhirDao implements IDao {
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
CriteriaQuery<TagDefinition> cq = builder.createQuery(TagDefinition.class);
Root<TagDefinition> from = cq.from(TagDefinition.class);
//@formatter:off
if (isNotBlank(theScheme)) {
cq.where(
@ -365,7 +364,7 @@ public abstract class BaseFhirDao implements IDao {
);
}
//@formatter:on
TypedQuery<TagDefinition> q = myEntityManager.createQuery(cq);
try {
return q.getSingleResult();
@ -530,7 +529,7 @@ public abstract class BaseFhirDao implements IDao {
if (pids.isEmpty()) {
return new ArrayList<IBaseResource>();
}
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
CriteriaQuery<ResourceTable> cq = builder.createQuery(ResourceTable.class);
Root<ResourceTable> from = cq.from(ResourceTable.class);
@ -689,6 +688,18 @@ public abstract class BaseFhirDao implements IDao {
continue;
}
if (Constants.PARAM_COUNT.equals(nextParamName)) {
if (paramList.size() > 0 && paramList.get(0).size() > 0) {
String intString = paramList.get(0).get(0);
try {
paramMap.setCount(Integer.parseInt(intString));
} catch (NumberFormatException e) {
throw new InvalidRequestException("Invalid " + Constants.PARAM_COUNT + " value: " + intString);
}
}
continue;
}
RuntimeSearchParam paramDef = resourceDef.getSearchParam(nextParamName);
if (paramDef == null) {
throw new InvalidRequestException("Failed to parse match URL[" + theMatchUrl + "] - Resource type " + resourceDef.getName() + " does not have a parameter with name: " + nextParamName);
@ -886,7 +897,7 @@ public abstract class BaseFhirDao implements IDao {
RuntimeResourceDefinition type = myContext.getResourceDefinition(theEntity.getResourceType());
return toResource(type.getImplementingClass(), theEntity);
}
protected <T extends IBaseResource> T toResource(Class<T> theResourceType, BaseHasResource theEntity) {
String resourceText = null;
switch (theEntity.getEncoding()) {
@ -1067,9 +1078,9 @@ public abstract class BaseFhirDao implements IDao {
quantityParams = extractSearchParamQuantity(entity, theResource);
dateParams = extractSearchParamDates(entity, theResource);
// ourLog.info("Indexing resource: {}", entity.getId());
// ourLog.info("Indexing resource: {}", entity.getId());
ourLog.trace("Storing string indexes: {}", stringParams);
tokenParams = new ArrayList<ResourceIndexedSearchParamToken>();
for (BaseResourceIndexedSearchParam next : extractSearchParamTokens(entity, theResource)) {
if (next instanceof ResourceIndexedSearchParamToken) {

View File

@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.dao;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.emptyString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
@ -24,6 +25,7 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jmx.access.InvalidInvocationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
@ -560,11 +562,56 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
nextEntry = resp.getEntry().get(3);
assertEquals(Bundle.class, nextEntry.getResource().getClass());
Bundle respBundle = (Bundle) nextEntry.getResource();
assertEquals(1, respBundle.getTotal().intValue());
}
@Test
public void testTransactionSearchWithCount() {
String methodName = "testTransactionSearchWithCount";
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.setId("Patient/" + methodName);
IdDt idv1 = ourPatientDao.update(p).getId();
ourLog.info("Created patient, got id: {}", idv1);
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.addName().addFamily("Family Name");
p.setId("Patient/" + methodName);
IdDt idv2 = ourPatientDao.update(p).getId();
ourLog.info("Updated patient, got id: {}", idv2);
Bundle request = new Bundle();
request.addEntry().getTransaction().setMethod(HTTPVerbEnum.GET).setUrl("Patient?" + Constants.PARAM_COUNT + "=1");
Bundle resp = ourSystemDao.transaction(request);
assertEquals(2, resp.getEntry().size());
Entry nextEntry = resp.getEntry().get(1);
assertEquals(Bundle.class, nextEntry.getResource().getClass());
Bundle respBundle = (Bundle) nextEntry.getResource();
assertEquals(1, respBundle.getTotal().intValue());
// Invalid _count
request = new Bundle();
request.addEntry().getTransaction().setMethod(HTTPVerbEnum.GET).setUrl("Patient?" + Constants.PARAM_COUNT + "=GKJGKJG");
try {
ourSystemDao.transaction(request);
} catch (InvalidRequestException e) {
assertEquals(e.getMessage(), ("Invalid _count value: GKJGKJG"));
}
// Empty _count
request = new Bundle();
request.addEntry().getTransaction().setMethod(HTTPVerbEnum.GET).setUrl("Patient?" + Constants.PARAM_COUNT + "=");
respBundle = ourSystemDao.transaction(request);
assertThat(respBundle.getEntry().size(), greaterThan(0));
}
@Test
public void testTransactionReadWithIfNoneMatch() {
String methodName = "testTransactionReadWithIfNoneMatch";

View File

@ -130,6 +130,9 @@
precision than the equivalent header, but the client previously
gave the header priority.
</action>
<action type="fix">
JPA server supports _count parameter in transaction containing search URL (nested search)
</action>
</release>
<release version="1.0" date="2015-May-8">
<action type="add">