Work on _tag:not=foo
This commit is contained in:
parent
e30ebf69ba
commit
ad34e38dee
|
@ -58,6 +58,7 @@ import javax.persistence.criteria.Subquery;
|
|||
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
@ -66,6 +67,8 @@ import org.springframework.transaction.TransactionStatus;
|
|||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
|
@ -118,6 +121,7 @@ import ca.uhn.fhir.rest.param.QuantityParam;
|
|||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.rest.param.TokenParamModifier;
|
||||
import ca.uhn.fhir.rest.param.UriParam;
|
||||
import ca.uhn.fhir.rest.param.UriParamQualifierEnum;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
|
@ -711,6 +715,64 @@ public class SearchBuilder {
|
|||
throw new IllegalArgumentException("Param name: " + theParamName); // shouldn't happen
|
||||
}
|
||||
|
||||
/*
|
||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
||||
Root<ResourceTable> from = cq.from(ResourceTable.class);
|
||||
cq.select(from.get("myId").as(Long.class));
|
||||
|
||||
Subquery<Long> subQ = cq.subquery(Long.class);
|
||||
Root<? extends BaseResourceIndexedSearchParam> subQfrom = subQ.from(theParamTable);
|
||||
subQ.select(subQfrom.get("myResourcePid").as(Long.class));
|
||||
Predicate subQname = builder.equal(subQfrom.get("myParamName"), theParamName);
|
||||
Predicate subQtype = builder.equal(subQfrom.get("myResourceType"), myResourceName);
|
||||
subQ.where(builder.and(subQtype, subQname));
|
||||
|
||||
List<Predicate> predicates = new ArrayList<Predicate>();
|
||||
predicates.add(builder.not(builder.in(from.get("myId")).value(subQ)));
|
||||
predicates.add(builder.equal(from.get("myResourceType"), myResourceName));
|
||||
predicates.add(builder.isNull(from.get("myDeleted")));
|
||||
createPredicateResourceId(builder, cq, predicates, from.get("myId").as(Long.class));
|
||||
*/
|
||||
|
||||
List<Pair<String, String>> notTags = Lists.newArrayList();
|
||||
for (List<? extends IQueryParameterType> nextAndParams : theList) {
|
||||
for (IQueryParameterType nextOrParams : nextAndParams) {
|
||||
if (nextOrParams instanceof TokenParam) {
|
||||
TokenParam param = (TokenParam)nextOrParams;
|
||||
if (param.getModifier() == TokenParamModifier.NOT) {
|
||||
if (isNotBlank(param.getSystem()) || isNotBlank(param.getValue())) {
|
||||
notTags.add(Pair.of(param.getSystem(), param.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a parameter of ResourceType?_tag:not=foo
|
||||
* This means match resources that don't have the given tag(s)
|
||||
*/
|
||||
if (notTags.isEmpty() == false) {
|
||||
// CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||
// CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
||||
// Root<ResourceTable> from = cq.from(ResourceTable.class);
|
||||
// cq.select(from.get("myId").as(Long.class));
|
||||
//
|
||||
// Subquery<Long> subQ = cq.subquery(Long.class);
|
||||
// Root<ResourceTag> subQfrom = subQ.from(ResourceTag.class);
|
||||
// subQ.select(subQfrom.get("myResourceId").as(Long.class));
|
||||
// Predicate subQname = builder.equal(subQfrom.get("myParamName"), theParamName);
|
||||
// Predicate subQtype = builder.equal(subQfrom.get("myResourceType"), myResourceName);
|
||||
// subQ.where(builder.and(subQtype, subQname));
|
||||
//
|
||||
// List<Predicate> predicates = new ArrayList<Predicate>();
|
||||
// predicates.add(builder.not(builder.in(from.get("myId")).value(subQ)));
|
||||
// predicates.add(builder.equal(from.get("myResourceType"), myResourceName));
|
||||
// predicates.add(builder.isNull(from.get("myDeleted")));
|
||||
// createPredicateResourceId(builder, cq, predicates, from.get("myId").as(Long.class));
|
||||
}
|
||||
|
||||
for (List<? extends IQueryParameterType> nextAndParams : theList) {
|
||||
boolean haveTags = false;
|
||||
for (IQueryParameterType nextParamUncasted : nextAndParams) {
|
||||
|
@ -735,12 +797,12 @@ public class SearchBuilder {
|
|||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
||||
Root<ResourceTag> from = cq.from(ResourceTag.class);
|
||||
cq.select(from.get("myResourceId").as(Long.class));
|
||||
|
||||
List<Predicate> andPredicates = new ArrayList<Predicate>();
|
||||
andPredicates.add(builder.equal(from.get("myResourceType"), myResourceName));
|
||||
|
||||
List<Predicate> orPredicates = new ArrayList<Predicate>();
|
||||
boolean paramInverted = false;
|
||||
for (IQueryParameterType nextOrParams : nextAndParams) {
|
||||
String code;
|
||||
String system;
|
||||
|
@ -748,6 +810,9 @@ public class SearchBuilder {
|
|||
TokenParam nextParam = (TokenParam) nextOrParams;
|
||||
code = nextParam.getValue();
|
||||
system = nextParam.getSystem();
|
||||
if (nextParam.getModifier() == TokenParamModifier.NOT) {
|
||||
paramInverted = true;
|
||||
}
|
||||
} else {
|
||||
UriParam nextParam = (UriParam) nextOrParams;
|
||||
code = nextParam.getValue();
|
||||
|
@ -768,12 +833,40 @@ public class SearchBuilder {
|
|||
|
||||
}
|
||||
if (orPredicates.isEmpty() == false) {
|
||||
andPredicates.add(builder.or(toArray(orPredicates)));
|
||||
Predicate tagOptions = builder.or(toArray(orPredicates));
|
||||
andPredicates.add(tagOptions);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
From<?, ResourceTable> defJoin;
|
||||
if (paramInverted) {
|
||||
Subquery<Long> subQ = cq.subquery(Long.class);
|
||||
Root<ResourceTag> subQfrom = cq.from(ResourceTag.class);
|
||||
subQ.select(subQfrom.get("myResourceId").as(Long.class));
|
||||
subQ.where(builder.and(toArray(andPredicates)));
|
||||
|
||||
Root<ResourceTable> newFrom = cq.from(ResourceTable.class);
|
||||
cq.select(newFrom.get("myId").as(Long.class)).where(builder.not(builder.in(newFrom.get("myId")).value(subQ)));
|
||||
|
||||
andPredicates = new ArrayList<Predicate>();
|
||||
andPredicates.add(builder.equal(from.get("myResourceType"), myResourceName));
|
||||
defJoin = newFrom;
|
||||
|
||||
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
||||
Set<Long> pids = new HashSet<Long>(q.getResultList());
|
||||
doSetPids(pids);
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
defJoin = from.join("myResource");
|
||||
}
|
||||
|
||||
From<ResourceTag, ResourceTable> defJoin = from.join("myResource");
|
||||
Predicate notDeletedPredicatePrediate = builder.isNull(defJoin.get("myDeleted"));
|
||||
andPredicates.add(notDeletedPredicatePrediate);
|
||||
|
||||
if (theLastUpdated != null) {
|
||||
andPredicates.addAll(createLastUpdatedPredicates(theLastUpdated, builder, defJoin));
|
||||
}
|
||||
|
@ -781,6 +874,7 @@ public class SearchBuilder {
|
|||
createPredicateResourceId(builder, cq, andPredicates, from.get("myResourceId").as(Long.class));
|
||||
Predicate masterCodePredicate = builder.and(toArray(andPredicates));
|
||||
|
||||
cq.select(from.get("myResourceId").as(Long.class));
|
||||
cq.where(masterCodePredicate);
|
||||
|
||||
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
||||
|
|
|
@ -84,6 +84,7 @@ import ca.uhn.fhir.rest.param.StringParam;
|
|||
import ca.uhn.fhir.rest.param.TokenAndListParam;
|
||||
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.rest.param.TokenParamModifier;
|
||||
import ca.uhn.fhir.rest.param.UriParam;
|
||||
import ca.uhn.fhir.rest.param.UriParamQualifierEnum;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
|
@ -2087,6 +2088,37 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithTagParameterMissing() {
|
||||
String methodName = "testSearchWithTagParameterMissing";
|
||||
|
||||
IIdType tag1id;
|
||||
{
|
||||
Organization org = new Organization();
|
||||
org.getNameElement().setValue("FOO");
|
||||
org.getMeta().addTag("urn:taglist", methodName + "1a", null);
|
||||
org.getMeta().addTag("urn:taglist", methodName + "1b", null);
|
||||
tag1id = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
IIdType tag2id;
|
||||
{
|
||||
Organization org = new Organization();
|
||||
org.getNameElement().setValue("FOO");
|
||||
org.getMeta().addTag("urn:taglist", methodName + "1b", null);
|
||||
tag2id = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
{
|
||||
// One tag
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
params.add("_tag", new TokenParam("urn:taglist", methodName + "1a").setModifier(TokenParamModifier.NOT));
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(myOrganizationDao.search(params));
|
||||
assertThat(patients, containsInAnyOrder(tag2id));
|
||||
assertThat(patients, not(containsInAnyOrder(tag1id)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithToken() {
|
||||
IIdType notMissing;
|
||||
|
|
Loading…
Reference in New Issue