Support _count on JPA search in transaction
This commit is contained in:
parent
1b82b7df65
commit
af33664e7c
|
@ -20,7 +20,9 @@ package ca.uhn.fhir.parser;
|
||||||
* #L%
|
* #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.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
|
|
@ -125,7 +125,7 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
|
|
||||||
private FhirContext myContext;
|
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)
|
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
|
||||||
private EntityManager myEntityManager;
|
private EntityManager myEntityManager;
|
||||||
|
|
||||||
|
@ -195,8 +195,7 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
|
|
||||||
String typeString = nextValue.getReference().getResourceType();
|
String typeString = nextValue.getReference().getResourceType();
|
||||||
if (isBlank(typeString)) {
|
if (isBlank(typeString)) {
|
||||||
throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource type - "
|
throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource type - " + nextValue.getReference().getValue());
|
||||||
+ nextValue.getReference().getValue());
|
|
||||||
}
|
}
|
||||||
Class<? extends IBaseResource> type = getContext().getResourceDefinition(typeString).getImplementingClass();
|
Class<? extends IBaseResource> type = getContext().getResourceDefinition(typeString).getImplementingClass();
|
||||||
String id = nextValue.getReference().getIdPart();
|
String id = nextValue.getReference().getIdPart();
|
||||||
|
@ -347,7 +346,7 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||||
CriteriaQuery<TagDefinition> cq = builder.createQuery(TagDefinition.class);
|
CriteriaQuery<TagDefinition> cq = builder.createQuery(TagDefinition.class);
|
||||||
Root<TagDefinition> from = cq.from(TagDefinition.class);
|
Root<TagDefinition> from = cq.from(TagDefinition.class);
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
if (isNotBlank(theScheme)) {
|
if (isNotBlank(theScheme)) {
|
||||||
cq.where(
|
cq.where(
|
||||||
|
@ -365,7 +364,7 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
TypedQuery<TagDefinition> q = myEntityManager.createQuery(cq);
|
TypedQuery<TagDefinition> q = myEntityManager.createQuery(cq);
|
||||||
try {
|
try {
|
||||||
return q.getSingleResult();
|
return q.getSingleResult();
|
||||||
|
@ -530,7 +529,7 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
if (pids.isEmpty()) {
|
if (pids.isEmpty()) {
|
||||||
return new ArrayList<IBaseResource>();
|
return new ArrayList<IBaseResource>();
|
||||||
}
|
}
|
||||||
|
|
||||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||||
CriteriaQuery<ResourceTable> cq = builder.createQuery(ResourceTable.class);
|
CriteriaQuery<ResourceTable> cq = builder.createQuery(ResourceTable.class);
|
||||||
Root<ResourceTable> from = cq.from(ResourceTable.class);
|
Root<ResourceTable> from = cq.from(ResourceTable.class);
|
||||||
|
@ -689,6 +688,18 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
continue;
|
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);
|
RuntimeSearchParam paramDef = resourceDef.getSearchParam(nextParamName);
|
||||||
if (paramDef == null) {
|
if (paramDef == null) {
|
||||||
throw new InvalidRequestException("Failed to parse match URL[" + theMatchUrl + "] - Resource type " + resourceDef.getName() + " does not have a parameter with name: " + nextParamName);
|
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());
|
RuntimeResourceDefinition type = myContext.getResourceDefinition(theEntity.getResourceType());
|
||||||
return toResource(type.getImplementingClass(), theEntity);
|
return toResource(type.getImplementingClass(), theEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <T extends IBaseResource> T toResource(Class<T> theResourceType, BaseHasResource theEntity) {
|
protected <T extends IBaseResource> T toResource(Class<T> theResourceType, BaseHasResource theEntity) {
|
||||||
String resourceText = null;
|
String resourceText = null;
|
||||||
switch (theEntity.getEncoding()) {
|
switch (theEntity.getEncoding()) {
|
||||||
|
@ -1067,9 +1078,9 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
quantityParams = extractSearchParamQuantity(entity, theResource);
|
quantityParams = extractSearchParamQuantity(entity, theResource);
|
||||||
dateParams = extractSearchParamDates(entity, theResource);
|
dateParams = extractSearchParamDates(entity, theResource);
|
||||||
|
|
||||||
// ourLog.info("Indexing resource: {}", entity.getId());
|
// ourLog.info("Indexing resource: {}", entity.getId());
|
||||||
ourLog.trace("Storing string indexes: {}", stringParams);
|
ourLog.trace("Storing string indexes: {}", stringParams);
|
||||||
|
|
||||||
tokenParams = new ArrayList<ResourceIndexedSearchParamToken>();
|
tokenParams = new ArrayList<ResourceIndexedSearchParamToken>();
|
||||||
for (BaseResourceIndexedSearchParam next : extractSearchParamTokens(entity, theResource)) {
|
for (BaseResourceIndexedSearchParam next : extractSearchParamTokens(entity, theResource)) {
|
||||||
if (next instanceof ResourceIndexedSearchParamToken) {
|
if (next instanceof ResourceIndexedSearchParamToken) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.dao;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.emptyString;
|
import static org.hamcrest.Matchers.emptyString;
|
||||||
import static org.hamcrest.Matchers.endsWith;
|
import static org.hamcrest.Matchers.endsWith;
|
||||||
|
import static org.hamcrest.Matchers.greaterThan;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
@ -24,6 +25,7 @@ import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
|
import org.springframework.jmx.access.InvalidInvocationException;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
|
@ -560,11 +562,56 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
nextEntry = resp.getEntry().get(3);
|
nextEntry = resp.getEntry().get(3);
|
||||||
assertEquals(Bundle.class, nextEntry.getResource().getClass());
|
assertEquals(Bundle.class, nextEntry.getResource().getClass());
|
||||||
|
|
||||||
Bundle respBundle = (Bundle) nextEntry.getResource();
|
Bundle respBundle = (Bundle) nextEntry.getResource();
|
||||||
assertEquals(1, respBundle.getTotal().intValue());
|
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
|
@Test
|
||||||
public void testTransactionReadWithIfNoneMatch() {
|
public void testTransactionReadWithIfNoneMatch() {
|
||||||
String methodName = "testTransactionReadWithIfNoneMatch";
|
String methodName = "testTransactionReadWithIfNoneMatch";
|
||||||
|
|
|
@ -130,6 +130,9 @@
|
||||||
precision than the equivalent header, but the client previously
|
precision than the equivalent header, but the client previously
|
||||||
gave the header priority.
|
gave the header priority.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix">
|
||||||
|
JPA server supports _count parameter in transaction containing search URL (nested search)
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="1.0" date="2015-May-8">
|
<release version="1.0" date="2015-May-8">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
Loading…
Reference in New Issue