Work on multitenancy
This commit is contained in:
parent
2e43c57032
commit
ea1f35beaa
|
@ -351,8 +351,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
* If we have any joins to index tables, we get this behaviour already guaranteed so we don't
|
||||
* need an explicit predicate for it.
|
||||
*/
|
||||
boolean haveNoIndexSearchParams = myParams.size() == 0 || myParams.keySet().stream().allMatch(t -> t.startsWith("_"));
|
||||
if (haveNoIndexSearchParams) {
|
||||
if (!myQueryRoot.hasIndexJoins()) {
|
||||
if (myParams.getEverythingMode() == null) {
|
||||
myQueryRoot.addPredicate(myCriteriaBuilder.equal(myQueryRoot.get("myResourceType"), myResourceName));
|
||||
}
|
||||
|
@ -895,7 +894,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
myQueryRoot.addPredicate(predicate);
|
||||
}
|
||||
|
||||
myQueryRoot.setHasIndexJoins(true);
|
||||
myQueryRoot.setHasIndexJoins();
|
||||
Predicate predicate = myCriteriaBuilder.equal(join.get("myIndexString"), theIndexedString);
|
||||
myQueryRoot.addPredicate(predicate);
|
||||
|
||||
|
|
|
@ -53,6 +53,10 @@ public class RequestPartitionHelperService {
|
|||
*/
|
||||
@Nullable
|
||||
public PartitionId determineReadPartitionForRequest(@Nullable RequestDetails theRequest, String theResourceType) {
|
||||
if (myPartitioningBlacklist.contains(theResourceType)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PartitionId partitionId = null;
|
||||
|
||||
if (myDaoConfig.isPartitioningEnabled()) {
|
||||
|
@ -73,6 +77,10 @@ public class RequestPartitionHelperService {
|
|||
*/
|
||||
@Nullable
|
||||
public PartitionId determineCreatePartitionForRequest(@Nullable RequestDetails theRequest, @Nonnull IBaseResource theResource) {
|
||||
String resourceType = myFhirContext.getResourceDefinition(theResource).getName();
|
||||
if (myPartitioningBlacklist.contains(resourceType)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PartitionId partitionId = null;
|
||||
if (myDaoConfig.isPartitioningEnabled()) {
|
||||
|
|
|
@ -25,11 +25,9 @@ import ca.uhn.fhir.jpa.dao.DaoConfig;
|
|||
import ca.uhn.fhir.jpa.dao.IDao;
|
||||
import ca.uhn.fhir.jpa.dao.SearchBuilder;
|
||||
import ca.uhn.fhir.jpa.model.entity.BasePartitionable;
|
||||
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndex;
|
||||
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.model.entity.PartitionId;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamUri;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.model.entity.SearchParamPresent;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
|
@ -45,6 +43,7 @@ import javax.annotation.PostConstruct;
|
|||
import javax.persistence.criteria.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
abstract class BasePredicateBuilder {
|
||||
|
@ -112,30 +111,29 @@ abstract class BasePredicateBuilder {
|
|||
return (Join<ResourceTable, T>) join;
|
||||
}
|
||||
|
||||
void addPredicateParamMissing(String theResourceName, String theParamName, boolean theMissing) {
|
||||
// if (myDontUseHashesForSearch) {
|
||||
// Join<ResourceTable, SearchParamPresent> paramPresentJoin = myQueryRoot.join("mySearchParamPresents", JoinType.LEFT);
|
||||
// Join<Object, Object> paramJoin = paramPresentJoin.join("mySearchParam", JoinType.LEFT);
|
||||
//
|
||||
// myQueryRoot.addPredicate(myBuilder.equal(paramJoin.get("myResourceName"), theResourceName));
|
||||
// myQueryRoot.addPredicate(myBuilder.equal(paramJoin.get("myParamName"), theParamName));
|
||||
// myQueryRoot.addPredicate(myBuilder.equal(paramPresentJoin.get("myPresent"), !theMissing));
|
||||
// }
|
||||
|
||||
void addPredicateParamMissingForReference(String theResourceName, String theParamName, boolean theMissing, PartitionId thePartitionId) {
|
||||
Join<ResourceTable, SearchParamPresent> paramPresentJoin = myQueryRoot.join("mySearchParamPresents", JoinType.LEFT);
|
||||
|
||||
Expression<Long> hashPresence = paramPresentJoin.get("myHashPresence").as(Long.class);
|
||||
Long hash = SearchParamPresent.calculateHashPresence(theResourceName, theParamName, !theMissing);
|
||||
myQueryRoot.addPredicate(myCriteriaBuilder.equal(hashPresence, hash));
|
||||
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
predicates.add(myCriteriaBuilder.equal(hashPresence, hash));
|
||||
|
||||
addPartitionIdPredicate(thePartitionId, paramPresentJoin, predicates);
|
||||
|
||||
myQueryRoot.setHasIndexJoins();
|
||||
myQueryRoot.addPredicates(predicates);
|
||||
}
|
||||
|
||||
void addPredicateParamMissing(String theResourceName, String theParamName, boolean theMissing, Join<ResourceTable, ? extends BaseResourceIndexedSearchParam> theJoin, PartitionId thePartitionId) {
|
||||
void addPredicateParamMissingForNonReference(String theResourceName, String theParamName, boolean theMissing, Join<ResourceTable, ? extends BaseResourceIndexedSearchParam> theJoin, PartitionId thePartitionId) {
|
||||
if (thePartitionId != null) {
|
||||
myQueryRoot.addPredicate(myCriteriaBuilder.equal(theJoin.get("myPartitionIdValue"), thePartitionId.getPartitionId()));
|
||||
}
|
||||
myQueryRoot.addPredicate(myCriteriaBuilder.equal(theJoin.get("myResourceType"), theResourceName));
|
||||
myQueryRoot.addPredicate(myCriteriaBuilder.equal(theJoin.get("myParamName"), theParamName));
|
||||
myQueryRoot.addPredicate(myCriteriaBuilder.equal(theJoin.get("myMissing"), theMissing));
|
||||
myQueryRoot.setHasIndexJoins();
|
||||
}
|
||||
|
||||
Predicate combineParamIndexPredicateWithParamNamePredicate(String theResourceName, String theParamName, From<?, ? extends BaseResourceIndexedSearchParam> theFrom, Predicate thePredicate) {
|
||||
|
|
|
@ -153,7 +153,7 @@ public class PredicateBuilderCoords extends BasePredicateBuilder implements IPre
|
|||
Join<ResourceTable, ResourceIndexedSearchParamCoords> join = createJoin(SearchBuilderJoinEnum.COORDS, theParamName);
|
||||
|
||||
if (theList.get(0).getMissing() != null) {
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
addPredicateParamMissingForNonReference(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -173,6 +173,7 @@ public class PredicateBuilderCoords extends BasePredicateBuilder implements IPre
|
|||
|
||||
Predicate retVal = myCriteriaBuilder.or(toArray(codePredicates));
|
||||
myQueryRoot.addPredicate(retVal);
|
||||
myQueryRoot.setHasIndexJoins();
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
|
|||
|
||||
if (theList.get(0).getMissing() != null) {
|
||||
Boolean missing = theList.get(0).getMissing();
|
||||
addPredicateParamMissing(theResourceName, theParamName, missing, join, thePartitionId);
|
||||
addPredicateParamMissingForNonReference(theResourceName, theParamName, missing, join, thePartitionId);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,7 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
|
|||
|
||||
Predicate orPredicates = myCriteriaBuilder.or(toArray(codePredicates));
|
||||
|
||||
myQueryRoot.setHasIndexJoins();
|
||||
if (newJoin) {
|
||||
Predicate identityAndValuePredicate = combineParamIndexPredicateWithParamNamePredicate(theResourceName, theParamName, join, orPredicates);
|
||||
myQueryRoot.addPredicate(identityAndValuePredicate);
|
||||
|
|
|
@ -60,7 +60,7 @@ class PredicateBuilderNumber extends BasePredicateBuilder implements IPredicateB
|
|||
Join<ResourceTable, ResourceIndexedSearchParamNumber> join = createJoin(SearchBuilderJoinEnum.NUMBER, theParamName);
|
||||
|
||||
if (theList.get(0).getMissing() != null) {
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
addPredicateParamMissingForNonReference(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,7 @@ class PredicateBuilderNumber extends BasePredicateBuilder implements IPredicateB
|
|||
}
|
||||
|
||||
Predicate predicate = myCriteriaBuilder.or(toArray(codePredicates));
|
||||
myQueryRoot.setHasIndexJoins();
|
||||
myQueryRoot.addPredicate(predicate);
|
||||
return predicate;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ class PredicateBuilderQuantity extends BasePredicateBuilder implements IPredicat
|
|||
Join<ResourceTable, ResourceIndexedSearchParamQuantity> join = createJoin(SearchBuilderJoinEnum.QUANTITY, theParamName);
|
||||
|
||||
if (theList.get(0).getMissing() != null) {
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
addPredicateParamMissingForNonReference(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,7 @@ class PredicateBuilderQuantity extends BasePredicateBuilder implements IPredicat
|
|||
}
|
||||
|
||||
Predicate retVal = myCriteriaBuilder.or(toArray(codePredicates));
|
||||
myQueryRoot.setHasIndexJoins();
|
||||
myQueryRoot.addPredicate(retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ class PredicateBuilderReference extends BasePredicateBuilder {
|
|||
}
|
||||
|
||||
if (theList.get(0).getMissing() != null) {
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing());
|
||||
addPredicateParamMissingForReference(theResourceName, theParamName, theList.get(0).getMissing(), thePartitionId);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -227,6 +227,7 @@ class PredicateBuilderReference extends BasePredicateBuilder {
|
|||
codePredicates.add(myCriteriaBuilder.and(pathPredicate, pidPredicate));
|
||||
}
|
||||
|
||||
myQueryRoot.setHasIndexJoins();
|
||||
if (codePredicates.size() > 0) {
|
||||
Predicate predicate = myCriteriaBuilder.or(toArray(codePredicates));
|
||||
myQueryRoot.addPredicate(predicate);
|
||||
|
|
|
@ -63,7 +63,7 @@ class PredicateBuilderString extends BasePredicateBuilder implements IPredicateB
|
|||
Join<ResourceTable, ResourceIndexedSearchParamString> join = createJoin(SearchBuilderJoinEnum.STRING, theParamName);
|
||||
|
||||
if (theList.get(0).getMissing() != null) {
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
addPredicateParamMissingForNonReference(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,10 @@ class PredicateBuilderString extends BasePredicateBuilder implements IPredicateB
|
|||
}
|
||||
|
||||
Predicate retVal = myCriteriaBuilder.or(toArray(codePredicates));
|
||||
|
||||
myQueryRoot.setHasIndexJoins();
|
||||
myQueryRoot.addPredicate(retVal);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -134,7 +134,6 @@ class PredicateBuilderTag extends BasePredicateBuilder {
|
|||
continue;
|
||||
}
|
||||
|
||||
// FIXME: add test for tag:not
|
||||
// FIXME: add test for :missing
|
||||
if (paramInverted) {
|
||||
ourLog.debug("Searching for _tag:not");
|
||||
|
@ -173,6 +172,7 @@ class PredicateBuilderTag extends BasePredicateBuilder {
|
|||
addPartitionIdPredicate(thePartitionId, tagJoin, predicates);
|
||||
}
|
||||
|
||||
myQueryRoot.setHasIndexJoins();
|
||||
myQueryRoot.addPredicates(predicates);
|
||||
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ class PredicateBuilderToken extends BasePredicateBuilder implements IPredicateBu
|
|||
|
||||
if (theList.get(0).getMissing() != null) {
|
||||
Join<ResourceTable, ResourceIndexedSearchParamToken> join = createJoin(SearchBuilderJoinEnum.TOKEN, theParamName);
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
addPredicateParamMissingForNonReference(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,10 @@ class PredicateBuilderToken extends BasePredicateBuilder implements IPredicateBu
|
|||
codePredicates.addAll(singleCode);
|
||||
|
||||
Predicate spPredicate = myCriteriaBuilder.or(toArray(codePredicates));
|
||||
|
||||
myQueryRoot.setHasIndexJoins();
|
||||
myQueryRoot.addPredicate(spPredicate);
|
||||
|
||||
return spPredicate;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ class PredicateBuilderUri extends BasePredicateBuilder implements IPredicateBuil
|
|||
Join<ResourceTable, ResourceIndexedSearchParamUri> join = createJoin(SearchBuilderJoinEnum.URI, theParamName);
|
||||
|
||||
if (theList.get(0).getMissing() != null) {
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
addPredicateParamMissingForNonReference(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -169,6 +169,7 @@ class PredicateBuilderUri extends BasePredicateBuilder implements IPredicateBuil
|
|||
*/
|
||||
if (codePredicates.isEmpty()) {
|
||||
Predicate predicate = myCriteriaBuilder.isNull(join.get("myMissing").as(String.class));
|
||||
myQueryRoot.setHasIndexJoins();
|
||||
myQueryRoot.addPredicate(predicate);
|
||||
return null;
|
||||
}
|
||||
|
@ -179,6 +180,7 @@ class PredicateBuilderUri extends BasePredicateBuilder implements IPredicateBuil
|
|||
theParamName,
|
||||
join,
|
||||
orPredicate);
|
||||
myQueryRoot.setHasIndexJoins();
|
||||
myQueryRoot.addPredicate(outerPredicate);
|
||||
return outerPredicate;
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ public class QueryRoot {
|
|||
return myHasIndexJoins;
|
||||
}
|
||||
|
||||
public void setHasIndexJoins(boolean theHasIndexJoins) {
|
||||
public void setHasIndexJoins() {
|
||||
myHasIndexJoins = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,11 @@ import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
|||
import ca.uhn.fhir.rest.param.DateParam;
|
||||
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.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
@ -79,11 +79,14 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
|||
myPartitionId = 3;
|
||||
|
||||
myPartitionInterceptor = new MyInterceptor();
|
||||
myInterceptorRegistry.registerInterceptor(myPartitionInterceptor);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateResourceNoPartition() {
|
||||
addCreatePartition(null, null);
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("system").setValue("value");
|
||||
p.setBirthDate(new Date());
|
||||
|
@ -343,6 +346,142 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearch_MissingParamString_SearchAllPartitions() {
|
||||
IIdType patientIdNull = createPatient(null, withFamily("FAMILY"));
|
||||
IIdType patientId1 = createPatient(1, withFamily("FAMILY"));
|
||||
IIdType patientId2 = createPatient(2, withFamily("FAMILY"));
|
||||
|
||||
// :missing=true
|
||||
{
|
||||
addReadPartition(null);
|
||||
myCaptureQueriesListener.clear();
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Patient.SP_ACTIVE, new StringParam().setMissing(true));
|
||||
map.setLoadSynchronous(true);
|
||||
IBundleProvider results = myPatientDao.search(map);
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(results);
|
||||
assertThat(ids, Matchers.contains(patientIdNull, patientId1, patientId2));
|
||||
|
||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||
ourLog.info("Search SQL:\n{}", searchSql);
|
||||
assertEquals(0, StringUtils.countMatches(searchSql, "PARTITION_ID"));
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "SP_MISSING='true'"));
|
||||
}
|
||||
|
||||
// :missing=false
|
||||
{
|
||||
addReadPartition(null);
|
||||
myCaptureQueriesListener.clear();
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Patient.SP_FAMILY, new StringParam().setMissing(false));
|
||||
map.setLoadSynchronous(true);
|
||||
IBundleProvider results = myPatientDao.search(map);
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(results);
|
||||
assertThat(ids, Matchers.contains(patientIdNull, patientId1, patientId2));
|
||||
|
||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||
ourLog.info("Search SQL:\n{}", searchSql);
|
||||
assertEquals(0, StringUtils.countMatches(searchSql, "PARTITION_ID"));
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "SP_MISSING='false'"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearch_MissingParamReference_SearchAllPartitions() {
|
||||
IIdType patientIdNull = createPatient(null, withFamily("FAMILY"));
|
||||
IIdType patientId1 = createPatient(1, withFamily("FAMILY"));
|
||||
IIdType patientId2 = createPatient(2, withFamily("FAMILY"));
|
||||
|
||||
// :missing=true
|
||||
{
|
||||
addReadPartition(null);
|
||||
myCaptureQueriesListener.clear();
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Patient.SP_GENERAL_PRACTITIONER, new StringParam().setMissing(true));
|
||||
map.setLoadSynchronous(true);
|
||||
IBundleProvider results = myPatientDao.search(map);
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(results);
|
||||
assertThat(ids, Matchers.contains(patientIdNull, patientId1, patientId2));
|
||||
|
||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||
ourLog.info("Search SQL:\n{}", searchSql);
|
||||
assertEquals(0, StringUtils.countMatches(searchSql, "PARTITION_ID"));
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "HFJ_RES_PARAM_PRESENT"));
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "HASH_PRESENCE='1919227773735728687'"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSearch_MissingParamString_SearchOnePartition() {
|
||||
createPatient(null, withFamily("FAMILY"));
|
||||
IIdType patientId1 = createPatient(1, withFamily("FAMILY"));
|
||||
createPatient(2, withFamily("FAMILY"));
|
||||
|
||||
// :missing=true
|
||||
{
|
||||
addReadPartition(1);
|
||||
myCaptureQueriesListener.clear();
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Patient.SP_ACTIVE, new StringParam().setMissing(true));
|
||||
map.setLoadSynchronous(true);
|
||||
IBundleProvider results = myPatientDao.search(map);
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(results);
|
||||
assertThat(ids, Matchers.contains(patientId1));
|
||||
|
||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||
ourLog.info("Search SQL:\n{}", searchSql);
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "myparamsto1_.PARTITION_ID='1'"));
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "SP_MISSING='true'"));
|
||||
}
|
||||
|
||||
// :missing=false
|
||||
{
|
||||
addReadPartition(1);
|
||||
myCaptureQueriesListener.clear();
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Patient.SP_FAMILY, new StringParam().setMissing(false));
|
||||
map.setLoadSynchronous(true);
|
||||
IBundleProvider results = myPatientDao.search(map);
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(results);
|
||||
assertThat(ids, Matchers.contains(patientId1));
|
||||
|
||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||
ourLog.info("Search SQL:\n{}", searchSql);
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "myparamsst1_.PARTITION_ID='1'"));
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "SP_MISSING='false'"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearch_MissingParamReference_SearchOnePartition() {
|
||||
createPatient(null, withFamily("FAMILY"));
|
||||
IIdType patientId1 = createPatient(1, withFamily("FAMILY"));
|
||||
createPatient(2, withFamily("FAMILY"));
|
||||
|
||||
// :missing=true
|
||||
{
|
||||
addReadPartition(1);
|
||||
myCaptureQueriesListener.clear();
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Patient.SP_GENERAL_PRACTITIONER, new StringParam().setMissing(true));
|
||||
map.setLoadSynchronous(true);
|
||||
IBundleProvider results = myPatientDao.search(map);
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(results);
|
||||
assertThat(ids, Matchers.contains(patientId1));
|
||||
|
||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||
ourLog.info("Search SQL:\n{}", searchSql);
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID"));
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "mysearchpa1_.PARTITION_ID='1'"));
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "HFJ_RES_PARAM_PRESENT"));
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "HASH_PRESENCE='1919227773735728687'"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testSearch_NoParams_SearchAllPartitions() {
|
||||
IIdType patientIdNull = createPatient(null, withActiveTrue());
|
||||
|
@ -452,9 +591,9 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
|||
|
||||
@Test
|
||||
public void testSearch_TagParam_SearchOnePartition() {
|
||||
IIdType patientIdNull = createPatient(null, withActiveTrue(), withTag("http://system", "code"));
|
||||
createPatient(null, withActiveTrue(), withTag("http://system", "code"));
|
||||
IIdType patientId1 = createPatient(1, withActiveTrue(), withTag("http://system", "code"));
|
||||
IIdType patientId2 = createPatient(2, withActiveTrue(), withTag("http://system", "code"));
|
||||
createPatient(2, withActiveTrue(), withTag("http://system", "code"));
|
||||
|
||||
addReadPartition(1);
|
||||
|
||||
|
@ -472,6 +611,56 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
|||
assertEquals(1, StringUtils.countMatches(searchSql, "TAG_SYSTEM='http://system'"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearch_TagParamNot_SearchAllPartitions() {
|
||||
IIdType patientIdNull = createPatient(null, withActiveTrue(), withTag("http://system", "code"));
|
||||
IIdType patientId1 = createPatient(1, withActiveTrue(), withTag("http://system", "code"));
|
||||
IIdType patientId2 = createPatient(2, withActiveTrue(), withTag("http://system", "code"));
|
||||
createPatient(null, withActiveTrue(), withTag("http://system", "code"), withTag("http://system", "code2"));
|
||||
createPatient(1, withActiveTrue(), withTag("http://system", "code"), withTag("http://system", "code2"));
|
||||
createPatient(2, withActiveTrue(), withTag("http://system", "code"), withTag("http://system", "code2"));
|
||||
|
||||
addReadPartition(null);
|
||||
|
||||
myCaptureQueriesListener.clear();
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Constants.PARAM_TAG, new TokenParam("http://system", "code2").setModifier(TokenParamModifier.NOT));
|
||||
map.setLoadSynchronous(true);
|
||||
IBundleProvider results = myPatientDao.search(map);
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(results);
|
||||
assertThat(ids, Matchers.contains(patientIdNull, patientId1, patientId2));
|
||||
|
||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||
ourLog.info("Search SQL:\n{}", searchSql);
|
||||
assertEquals(0, StringUtils.countMatches(searchSql, "PARTITION_ID"));
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "TAG_SYSTEM='http://system'"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearch_TagParamNot_SearchOnePartition() {
|
||||
createPatient(null, withActiveTrue(), withTag("http://system", "code"));
|
||||
IIdType patientId1 = createPatient(1, withActiveTrue(), withTag("http://system", "code"));
|
||||
createPatient(2, withActiveTrue(), withTag("http://system", "code"));
|
||||
createPatient(null, withActiveTrue(), withTag("http://system", "code"), withTag("http://system", "code2"));
|
||||
createPatient(1, withActiveTrue(), withTag("http://system", "code"), withTag("http://system", "code2"));
|
||||
createPatient(2, withActiveTrue(), withTag("http://system", "code"), withTag("http://system", "code2"));
|
||||
|
||||
addReadPartition(1);
|
||||
|
||||
myCaptureQueriesListener.clear();
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Constants.PARAM_TAG, new TokenParam("http://system", "code2").setModifier(TokenParamModifier.NOT));
|
||||
map.setLoadSynchronous(true);
|
||||
IBundleProvider results = myPatientDao.search(map);
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(results);
|
||||
assertThat(ids, Matchers.contains(patientId1));
|
||||
|
||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||
ourLog.info("Search SQL:\n{}", searchSql);
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID"));
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "TAG_SYSTEM='http://system'"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearch_UniqueParam_SearchAllPartitions() {
|
||||
createUniqueCompositeSp();
|
||||
|
@ -557,13 +746,15 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
|||
}
|
||||
|
||||
|
||||
private void addCreatePartition(int thePartitionId, LocalDate thePartitionDate) {
|
||||
registerInterceptorIfNeeded();
|
||||
myPartitionInterceptor.addCreatePartition(new PartitionId(thePartitionId, thePartitionDate));
|
||||
private void addCreatePartition(Integer thePartitionId, LocalDate thePartitionDate) {
|
||||
PartitionId partitionId = null;
|
||||
if (thePartitionId != null) {
|
||||
partitionId = new PartitionId(thePartitionId, thePartitionDate);
|
||||
}
|
||||
myPartitionInterceptor.addCreatePartition(partitionId);
|
||||
}
|
||||
|
||||
private void addReadPartition(Integer thePartitionId) {
|
||||
registerInterceptorIfNeeded();
|
||||
PartitionId partitionId = null;
|
||||
if (thePartitionId != null) {
|
||||
partitionId = new PartitionId(thePartitionId, null);
|
||||
|
@ -571,16 +762,8 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
|||
myPartitionInterceptor.addReadPartition(partitionId);
|
||||
}
|
||||
|
||||
private void registerInterceptorIfNeeded() {
|
||||
if (!myInterceptorRegistry.getAllRegisteredInterceptors().contains(myPartitionInterceptor)) {
|
||||
myInterceptorRegistry.registerInterceptor(myPartitionInterceptor);
|
||||
}
|
||||
}
|
||||
|
||||
public IIdType createPatient(Integer thePartitionId, Consumer<Patient>... theModifiers) {
|
||||
if (thePartitionId != null) {
|
||||
addCreatePartition(thePartitionId, null);
|
||||
}
|
||||
addCreatePartition(thePartitionId, null);
|
||||
|
||||
Patient p = new Patient();
|
||||
for (Consumer<Patient> next : theModifiers) {
|
||||
|
@ -614,7 +797,7 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
|||
}
|
||||
|
||||
private Consumer<Patient> withTag(String theSystem, String theCode) {
|
||||
return t->t.getMeta().addTag(theSystem, theCode, theCode);
|
||||
return t -> t.getMeta().addTag(theSystem, theCode, theCode);
|
||||
}
|
||||
|
||||
|
||||
|
@ -626,7 +809,6 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
|||
private final List<PartitionId> myReadPartitionIds = new ArrayList<>();
|
||||
|
||||
public void addCreatePartition(PartitionId thePartitionId) {
|
||||
Validate.notNull(thePartitionId);
|
||||
myCreatePartitionIds.add(thePartitionId);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ import java.io.Serializable;
|
|||
@Index(name = "IDX_RESPARMPRESENT_RESID", columnList = "RES_ID"),
|
||||
@Index(name = "IDX_RESPARMPRESENT_HASHPRES", columnList = "HASH_PRESENCE")
|
||||
})
|
||||
public class SearchParamPresent implements Serializable {
|
||||
public class SearchParamPresent extends BasePartitionable implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
@ -52,8 +52,6 @@ public class SearchParamPresent implements Serializable {
|
|||
private transient String myParamName;
|
||||
@Column(name = "HASH_PRESENCE")
|
||||
private Long myHashPresence;
|
||||
@Embedded
|
||||
private PartitionId myPartitionId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -112,18 +110,10 @@ public class SearchParamPresent implements Serializable {
|
|||
b.append("resPid", myResource.getIdDt().toUnqualifiedVersionless().getValue());
|
||||
b.append("paramName", myParamName);
|
||||
b.append("present", myPresent);
|
||||
b.append("tenant", myPartitionId);
|
||||
b.append("partition", getPartitionId());
|
||||
return b.build();
|
||||
}
|
||||
|
||||
public PartitionId getPartitionId() {
|
||||
return myPartitionId;
|
||||
}
|
||||
|
||||
public void setPartitionId(PartitionId thePartitionId) {
|
||||
myPartitionId = thePartitionId;
|
||||
}
|
||||
|
||||
public static long calculateHashPresence(String theResourceType, String theParamName, Boolean thePresent) {
|
||||
String string = thePresent != null ? Boolean.toString(thePresent) : Boolean.toString(false);
|
||||
return BaseResourceIndexedSearchParam.hash(theResourceType, theParamName, string);
|
||||
|
|
Loading…
Reference in New Issue