Work on sort support in JPA
This commit is contained in:
parent
da1d49a108
commit
5fd987c497
|
@ -107,18 +107,20 @@ public class SortSpec {
|
|||
* Sets the chained sort specification, or <code>null</code> if none. If multiple sort parameters are chained
|
||||
* (indicating a sub-sort), the second level sort is chained via this property.
|
||||
*/
|
||||
public void setChain(SortSpec theChain) {
|
||||
public SortSpec setChain(SortSpec theChain) {
|
||||
if (theChain == this) {
|
||||
throw new IllegalArgumentException("Can not chain this to itself");
|
||||
}
|
||||
myChain = theChain;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the actual name of the search param to sort by
|
||||
*/
|
||||
public void setParamName(String theFieldName) {
|
||||
public SortSpec setParamName(String theFieldName) {
|
||||
myParamName = theFieldName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,8 +128,9 @@ public class SortSpec {
|
|||
* means {@link SortOrderEnum#ASC} according to the <a
|
||||
* href="http://hl7.org/implement/standards/fhir/search.html#sort">FHIR specification</a>)
|
||||
*/
|
||||
public void setOrder(SortOrderEnum theOrder) {
|
||||
public SortSpec setOrder(SortOrderEnum theOrder) {
|
||||
myOrder = theOrder;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ import javax.persistence.criteria.Path;
|
|||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -96,6 +97,7 @@ import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
|||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
|
||||
import ca.uhn.fhir.rest.api.SortOrderEnum;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.param.CompositeParam;
|
||||
import ca.uhn.fhir.rest.param.DateParam;
|
||||
|
@ -871,21 +873,34 @@ public class FhirResourceDao<T extends IResource> extends BaseFhirDao implements
|
|||
throw new InvalidRequestException("Unknown sort parameter '" + theSort.getParamName() + "'");
|
||||
}
|
||||
|
||||
String joinAttrName = "myParamsString";
|
||||
String sortAttrName = "myValueExact";
|
||||
String joinAttrName;
|
||||
String sortAttrName;
|
||||
|
||||
switch (param.getParamType()) {
|
||||
case STRING: {
|
||||
From<?, ?> stringJoin = theFrom.join(joinAttrName, JoinType.LEFT);
|
||||
Predicate p = theBuilder.equal(stringJoin.get("myParamName"), theSort.getParamName());
|
||||
Predicate pn = theBuilder.isNull(stringJoin.get("myParamName"));
|
||||
thePredicates.add(theBuilder.or(p, pn));
|
||||
theOrders.add(theBuilder.asc(stringJoin.get(sortAttrName)));
|
||||
case STRING:
|
||||
joinAttrName = "myParamsString";
|
||||
sortAttrName = "myValueExact";
|
||||
break;
|
||||
}
|
||||
case DATE:
|
||||
joinAttrName = "myParamsDate";
|
||||
sortAttrName = "myValueLow";
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException("This server does not support _sort specifications of type " + param.getParamType() + " - Can't serve _sort=" + theSort.getParamName());
|
||||
}
|
||||
|
||||
createSort(theBuilder, theFrom, theSort.getChain(), theOrders, thePredicates);
|
||||
From<?, ?> stringJoin = theFrom.join(joinAttrName, JoinType.LEFT);
|
||||
// Predicate p = theBuilder.equal(stringJoin.get("myParamName"), theSort.getParamName());
|
||||
// Predicate pn = theBuilder.isNull(stringJoin.get("myParamName"));
|
||||
// thePredicates.add(theBuilder.or(p, pn));
|
||||
|
||||
if (theSort.getOrder() == null || theSort.getOrder() == SortOrderEnum.ASC) {
|
||||
theOrders.add(theBuilder.asc(stringJoin.get(sortAttrName)));
|
||||
}else {
|
||||
theOrders.add(theBuilder.desc(stringJoin.get(sortAttrName)));
|
||||
}
|
||||
|
||||
createSort(theBuilder, theFrom, theSort.getChain(), theOrders, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -28,9 +28,13 @@ import javax.persistence.Table;
|
|||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
//@formatter:off
|
||||
@Entity
|
||||
@Table(name = "HFJ_SPIDX_DATE" /*, indexes= {@Index(name="IDX_SP_DATE", columnList= "SP_VALUE_LOW,SP_VALUE_HIGH")}*/)
|
||||
@org.hibernate.annotations.Table(appliesTo = "HFJ_SPIDX_DATE", indexes= {@org.hibernate.annotations.Index(name="IDX_SP_DATE", columnNames= {"RES_TYPE", "SP_NAME", "SP_VALUE_LOW","SP_VALUE_HIGH"})})
|
||||
@org.hibernate.annotations.Table(appliesTo = "HFJ_SPIDX_DATE", indexes= {
|
||||
@org.hibernate.annotations.Index(name="IDX_SP_DATE", columnNames= {"RES_TYPE", "SP_NAME", "SP_VALUE_LOW","SP_VALUE_HIGH"})
|
||||
})
|
||||
//@formatter:on
|
||||
public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchParam {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.endsWith;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
@ -60,6 +55,7 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
|||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.SortOrderEnum;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.param.CompositeParam;
|
||||
import ca.uhn.fhir.rest.param.DateParam;
|
||||
|
@ -303,11 +299,11 @@ public class FhirResourceDaoTest {
|
|||
|
||||
{
|
||||
Set<Long> found = ourObservationDao.searchForIds(Observation.SP_DATE, new DateParam(">2001-01-02"));
|
||||
assertThat(found, contains(id2.getIdPartAsLong()));
|
||||
assertThat(found, hasItem(id2.getIdPartAsLong()));
|
||||
}
|
||||
{
|
||||
Set<Long> found = ourObservationDao.searchForIds(Observation.SP_DATE, new DateParam(">2016-01-02"));
|
||||
assertThat(found, not(contains(id2.getIdPartAsLong())));
|
||||
assertThat(found, not(hasItem(id2.getIdPartAsLong())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -722,14 +718,23 @@ public class FhirResourceDaoTest {
|
|||
|
||||
@Test
|
||||
public void testPersistSearchParamDate() {
|
||||
List<Patient> found = toList(ourPatientDao.search(Patient.SP_BIRTHDATE, new DateParam(QuantityCompararatorEnum.GREATERTHAN, "2000-01-01")));
|
||||
int initialSize2000 = found.size();
|
||||
|
||||
found = toList(ourPatientDao.search(Patient.SP_BIRTHDATE, new DateParam(QuantityCompararatorEnum.GREATERTHAN, "2002-01-01")));
|
||||
int initialSize2002 = found.size();
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
patient.setBirthDate(new DateDt("2001-01-01"));
|
||||
|
||||
ourPatientDao.create(patient);
|
||||
|
||||
List<Patient> found = toList(ourPatientDao.search(Patient.SP_BIRTHDATE, new DateParam(QuantityCompararatorEnum.GREATERTHAN, "2000-01-01")));
|
||||
assertEquals(1, found.size());
|
||||
found = toList(ourPatientDao.search(Patient.SP_BIRTHDATE, new DateParam(QuantityCompararatorEnum.GREATERTHAN, "2000-01-01")));
|
||||
assertEquals(1 + initialSize2000, found.size());
|
||||
|
||||
found = toList(ourPatientDao.search(Patient.SP_BIRTHDATE, new DateParam(QuantityCompararatorEnum.GREATERTHAN, "2002-01-01")));
|
||||
assertEquals(initialSize2002, found.size());
|
||||
|
||||
// If this throws an exception, that would be an acceptable outcome as well..
|
||||
found = toList(ourPatientDao.search(Patient.SP_BIRTHDATE + "AAAA", new DateParam(QuantityCompararatorEnum.GREATERTHAN, "2000-01-01")));
|
||||
|
@ -1487,35 +1492,86 @@ public class FhirResourceDaoTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testSort() {
|
||||
public void testSortByString() {
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testSort001");
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
|
||||
p.addName().addFamily("testSortF1").addGiven("testSortG1");
|
||||
IdDt id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
// Create out of order
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testSort001");
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
|
||||
p.addName().addFamily("testSortF3").addGiven("testSortG3");
|
||||
IdDt id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testSort001");
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
|
||||
p.addName().addFamily("testSortF2").addGiven("testSortG2");
|
||||
IdDt id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testSort001");
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
|
||||
IdDt id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchParameterMap pm = new SearchParameterMap();
|
||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", "testSort001"));
|
||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", "testSortByString"));
|
||||
pm.setSort(new SortSpec(Patient.SP_FAMILY));
|
||||
List<IdDt> actual = toUnqualifiedVersionlessIds(ourPatientDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual, contains(id1, id2, id3, id4));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSortByDate() {
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
|
||||
p.addName().addFamily("testSortF1").addGiven("testSortG1");
|
||||
p.setBirthDate(new DateDt("2001-01-01"));
|
||||
IdDt id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
// Create out of order
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
|
||||
p.addName().addFamily("testSortF2").addGiven("testSortG2");
|
||||
p.setBirthDate(new DateDt("2001-01-03"));
|
||||
IdDt id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
|
||||
p.addName().addFamily("testSortF3").addGiven("testSortG3");
|
||||
p.setBirthDate(new DateDt("2001-01-02"));
|
||||
IdDt id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
|
||||
IdDt id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
List<IdDt> actual;
|
||||
SearchParameterMap pm;
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", "testtestSortByDate"));
|
||||
pm.setSort(new SortSpec(Patient.SP_BIRTHDATE));
|
||||
actual = toUnqualifiedVersionlessIds(ourPatientDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual, contains(id1, id2, id3, id4));
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", "testtestSortByDate"));
|
||||
pm.setSort(new SortSpec(Patient.SP_BIRTHDATE).setOrder(SortOrderEnum.ASC));
|
||||
actual = toUnqualifiedVersionlessIds(ourPatientDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual, contains(id1, id2, id3, id4));
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", "testtestSortByDate"));
|
||||
pm.setSort(new SortSpec(Patient.SP_BIRTHDATE).setOrder(SortOrderEnum.DESC));
|
||||
actual = toUnqualifiedVersionlessIds(ourPatientDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual, contains(id4, id3, id2, id1));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoreUnversionedResources() {
|
||||
Organization o1 = new Organization();
|
||||
|
|
|
@ -113,7 +113,10 @@
|
|||
});
|
||||
$("#outerForm").attr("action", "search").submit();
|
||||
});
|
||||
$(document).ready(function() {
|
||||
// If the user clicks "back", re-activate the button
|
||||
$('#search-btn').prop('disabled', false);
|
||||
});
|
||||
</script>
|
||||
<br clear="all"/>
|
||||
|
||||
|
|
Loading…
Reference in New Issue