More work on perf
This commit is contained in:
parent
f48d0d677b
commit
660c2bde72
|
@ -3,19 +3,30 @@ root = true
|
||||||
[*]
|
[*]
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
tab_width = 3
|
||||||
|
indent_size = 3
|
||||||
|
|
||||||
[*.java]
|
[*.java]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
tab_width = 3
|
||||||
|
indent_size = 3
|
||||||
|
|
||||||
[*.xml]
|
[*.xml]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
tab_width = 3
|
||||||
|
indent_size = 3
|
||||||
|
|
||||||
[*.json]
|
[*.json]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
tab_width = 3
|
||||||
|
indent_size = 3
|
||||||
|
|
||||||
[*.vm]
|
[*.vm]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
tab_width = 3
|
||||||
|
indent_size = 3
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@ package ca.uhn.fhir.model.api;
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -33,8 +35,10 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
* upgrading servers.
|
* upgrading servers.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class Include {
|
public class Include implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final boolean myImmutable;
|
private final boolean myImmutable;
|
||||||
private boolean myRecurse;
|
private boolean myRecurse;
|
||||||
private String myValue;
|
private String myValue;
|
||||||
|
|
|
@ -104,9 +104,9 @@ public class TagList implements Set<Tag>, Serializable, IBase {
|
||||||
* Add a new tag instance
|
* Add a new tag instance
|
||||||
*
|
*
|
||||||
* @param theScheme
|
* @param theScheme
|
||||||
* The tag scheme
|
* The tag scheme (the system)
|
||||||
* @param theTerm
|
* @param theTerm
|
||||||
* The tag term
|
* The tag term (the code)
|
||||||
* @return Returns the newly created tag instance. Note that the tag is added to the list by this method, so you
|
* @return Returns the newly created tag instance. Note that the tag is added to the list by this method, so you
|
||||||
* generally do not need to interact directly with the added tag.
|
* generally do not need to interact directly with the added tag.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1235,6 +1235,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
Set<ResourceIndexedSearchParamCoords> coordsParams = null;
|
Set<ResourceIndexedSearchParamCoords> coordsParams = null;
|
||||||
Set<ResourceLink> links = null;
|
Set<ResourceLink> links = null;
|
||||||
|
|
||||||
|
Set<String> populatedResourceLinkParameters = null;
|
||||||
if (theDeletedTimestampOrNull != null) {
|
if (theDeletedTimestampOrNull != null) {
|
||||||
|
|
||||||
stringParams = Collections.emptySet();
|
stringParams = Collections.emptySet();
|
||||||
|
@ -1334,7 +1335,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
}
|
}
|
||||||
|
|
||||||
links = new HashSet<ResourceLink>();
|
links = new HashSet<ResourceLink>();
|
||||||
Set<String> populatedResourceLinkParameters = extractResourceLinks(theEntity, theResource, links, theUpdateTime);
|
populatedResourceLinkParameters = extractResourceLinks(theEntity, theResource, links, theUpdateTime);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the existing resource already has links and those match links we still want, use them instead of removing them and re adding them
|
* If the existing resource already has links and those match links we still want, use them instead of removing them and re adding them
|
||||||
|
@ -1374,28 +1375,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
theEntity.setIndexStatus(INDEX_STATUS_INDEXED);
|
theEntity.setIndexStatus(INDEX_STATUS_INDEXED);
|
||||||
populateFullTextFields(theResource, theEntity);
|
populateFullTextFields(theResource, theEntity);
|
||||||
|
|
||||||
/*
|
|
||||||
* Update the "search param present" table which is used for the
|
|
||||||
* ?foo:missing=true queries
|
|
||||||
*/
|
|
||||||
Map<String, Boolean> presentSearchParams = new HashMap<String, Boolean>();
|
|
||||||
for (String nextKey : populatedResourceLinkParameters) {
|
|
||||||
presentSearchParams.put(nextKey, Boolean.TRUE);
|
|
||||||
}
|
|
||||||
updateSearchParamPresent(presentSearchParams, stringParams);
|
|
||||||
updateSearchParamPresent(presentSearchParams, tokenParams);
|
|
||||||
updateSearchParamPresent(presentSearchParams, numberParams);
|
|
||||||
updateSearchParamPresent(presentSearchParams, quantityParams);
|
|
||||||
updateSearchParamPresent(presentSearchParams, dateParams);
|
|
||||||
updateSearchParamPresent(presentSearchParams, uriParams);
|
|
||||||
updateSearchParamPresent(presentSearchParams, coordsParams);
|
|
||||||
Set<String> activeSearchParamNames = mySearchParamRegistry.getActiveSearchParams(theEntity.getResourceType()).keySet();
|
|
||||||
for (String nextSpName : activeSearchParamNames) {
|
|
||||||
if (!presentSearchParams.containsKey(nextSpName)) {
|
|
||||||
presentSearchParams.put(nextSpName, Boolean.FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mySearchParamPresenceSvc.updatePresence(theEntity, presentSearchParams);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -1426,6 +1405,31 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
postUpdate(theEntity, (T) theResource);
|
postUpdate(theEntity, (T) theResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update the "search param present" table which is used for the
|
||||||
|
* ?foo:missing=true queries
|
||||||
|
*/
|
||||||
|
if (thePerformIndexing) {
|
||||||
|
Map<String, Boolean> presentSearchParams = new HashMap<String, Boolean>();
|
||||||
|
for (String nextKey : populatedResourceLinkParameters) {
|
||||||
|
presentSearchParams.put(nextKey, Boolean.TRUE);
|
||||||
|
}
|
||||||
|
updateSearchParamPresent(presentSearchParams, stringParams);
|
||||||
|
updateSearchParamPresent(presentSearchParams, tokenParams);
|
||||||
|
updateSearchParamPresent(presentSearchParams, numberParams);
|
||||||
|
updateSearchParamPresent(presentSearchParams, quantityParams);
|
||||||
|
updateSearchParamPresent(presentSearchParams, dateParams);
|
||||||
|
updateSearchParamPresent(presentSearchParams, uriParams);
|
||||||
|
updateSearchParamPresent(presentSearchParams, coordsParams);
|
||||||
|
Set<String> activeSearchParamNames = mySearchParamRegistry.getActiveSearchParams(theEntity.getResourceType()).keySet();
|
||||||
|
for (String nextSpName : activeSearchParamNames) {
|
||||||
|
if (!presentSearchParams.containsKey(nextSpName)) {
|
||||||
|
presentSearchParams.put(nextSpName, Boolean.FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mySearchParamPresenceSvc.updatePresence(theEntity, presentSearchParams);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create history entry
|
* Create history entry
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -88,8 +88,6 @@ public class SearchBuilder {
|
||||||
private EntityManager myEntityManager;
|
private EntityManager myEntityManager;
|
||||||
private IForcedIdDao myForcedIdDao;
|
private IForcedIdDao myForcedIdDao;
|
||||||
private SearchParameterMap myParams;
|
private SearchParameterMap myParams;
|
||||||
private Collection<Long> myPids;
|
|
||||||
private PlatformTransactionManager myPlatformTransactionManager;
|
|
||||||
private IResourceIndexedSearchParamUriDao myResourceIndexedSearchParamUriDao;
|
private IResourceIndexedSearchParamUriDao myResourceIndexedSearchParamUriDao;
|
||||||
private String myResourceName;
|
private String myResourceName;
|
||||||
private Class<? extends IBaseResource> myResourceType;
|
private Class<? extends IBaseResource> myResourceType;
|
||||||
|
@ -97,16 +95,12 @@ public class SearchBuilder {
|
||||||
private Search mySearchEntity;
|
private Search mySearchEntity;
|
||||||
private ISearchResultDao mySearchResultDao;
|
private ISearchResultDao mySearchResultDao;
|
||||||
private ISearchParamRegistry mySearchParamRegistry;
|
private ISearchParamRegistry mySearchParamRegistry;
|
||||||
|
|
||||||
private IHapiTerminologySvc myTerminologySvc;
|
private IHapiTerminologySvc myTerminologySvc;
|
||||||
|
|
||||||
private Root<ResourceTable> myResourceTableRoot;
|
private Root<ResourceTable> myResourceTableRoot;
|
||||||
|
|
||||||
private ArrayList<Predicate> myPredicates;
|
private ArrayList<Predicate> myPredicates;
|
||||||
|
|
||||||
private CriteriaBuilder myBuilder;
|
private CriteriaBuilder myBuilder;
|
||||||
|
|
||||||
private CriteriaQuery<Tuple> myResourceTableQuery;
|
private CriteriaQuery<Tuple> myResourceTableQuery;
|
||||||
|
private PlatformTransactionManager myPlatformTransactionManager;
|
||||||
|
|
||||||
public SearchBuilder(FhirContext theFhirContext, EntityManager theEntityManager, PlatformTransactionManager thePlatformTransactionManager, IFulltextSearchSvc theFulltextSearchSvc,
|
public SearchBuilder(FhirContext theFhirContext, EntityManager theEntityManager, PlatformTransactionManager thePlatformTransactionManager, IFulltextSearchSvc theFulltextSearchSvc,
|
||||||
ISearchResultDao theSearchResultDao, BaseHapiFhirDao<?> theDao,
|
ISearchResultDao theSearchResultDao, BaseHapiFhirDao<?> theDao,
|
||||||
|
@ -158,8 +152,8 @@ public class SearchBuilder {
|
||||||
|
|
||||||
private void addPredicateDate(String theParamName, List<? extends IQueryParameterType> theList) {
|
private void addPredicateDate(String theParamName, List<? extends IQueryParameterType> theList) {
|
||||||
|
|
||||||
if (Boolean.TRUE.equals(theList.get(0).getMissing())) {
|
if (theList.get(0).getMissing() != null) {
|
||||||
addPredicateParamMissing("myParamsDate", theParamName, ResourceIndexedSearchParamDate.class);
|
addPredicateParamMissing(theParamName, theList.get(0).getMissing());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,10 +161,6 @@ public class SearchBuilder {
|
||||||
|
|
||||||
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
||||||
for (IQueryParameterType nextOr : theList) {
|
for (IQueryParameterType nextOr : theList) {
|
||||||
if (addPredicateMissingFalseIfPresent(myBuilder, theParamName, join, codePredicates, nextOr)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
IQueryParameterType params = nextOr;
|
IQueryParameterType params = nextOr;
|
||||||
Predicate p = createPredicateDate(myBuilder, join, params);
|
Predicate p = createPredicateDate(myBuilder, join, params);
|
||||||
codePredicates.add(p);
|
codePredicates.add(p);
|
||||||
|
@ -304,40 +294,10 @@ public class SearchBuilder {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean addPredicateMissingFalseIfPresent(CriteriaBuilder theBuilder, String theParamName, From<?, ? extends BaseResourceIndexedSearchParam> from, List<Predicate> codePredicates,
|
|
||||||
IQueryParameterType nextOr) {
|
|
||||||
boolean missingFalse = false;
|
|
||||||
if (nextOr.getMissing() != null) {
|
|
||||||
if (nextOr.getMissing().booleanValue() == true) {
|
|
||||||
throw new InvalidRequestException(myContext.getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "multipleParamsWithSameNameOneIsMissingTrue", theParamName));
|
|
||||||
}
|
|
||||||
Predicate singleCode = from.get("myId").isNotNull();
|
|
||||||
Predicate name = theBuilder.equal(from.get("myParamName"), theParamName);
|
|
||||||
codePredicates.add(theBuilder.and(name, singleCode));
|
|
||||||
missingFalse = true;
|
|
||||||
}
|
|
||||||
return missingFalse;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean addPredicateMissingFalseIfPresentForResourceLink(CriteriaBuilder theBuilder, String theParamName, From<?,? extends ResourceLink> from, List<Predicate> codePredicates,
|
|
||||||
IQueryParameterType nextOr) {
|
|
||||||
boolean missingFalse = false;
|
|
||||||
if (nextOr.getMissing() != null) {
|
|
||||||
if (nextOr.getMissing().booleanValue() == true) {
|
|
||||||
throw new InvalidRequestException(myContext.getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "multipleParamsWithSameNameOneIsMissingTrue", theParamName));
|
|
||||||
}
|
|
||||||
Predicate singleCode = from.get("mySourceResource").isNotNull();
|
|
||||||
Predicate name = createResourceLinkPathPredicate(theParamName, from);
|
|
||||||
codePredicates.add(theBuilder.and(name, singleCode));
|
|
||||||
missingFalse = true;
|
|
||||||
}
|
|
||||||
return missingFalse;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addPredicateNumber(String theParamName, List<? extends IQueryParameterType> theList) {
|
private void addPredicateNumber(String theParamName, List<? extends IQueryParameterType> theList) {
|
||||||
|
|
||||||
if (Boolean.TRUE.equals(theList.get(0).getMissing())) {
|
if (theList.get(0).getMissing() != null) {
|
||||||
addPredicateParamMissing("myParamsNumber", theParamName, ResourceIndexedSearchParamNumber.class);
|
addPredicateParamMissing(theParamName, theList.get(0).getMissing());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,10 +307,6 @@ public class SearchBuilder {
|
||||||
for (IQueryParameterType nextOr : theList) {
|
for (IQueryParameterType nextOr : theList) {
|
||||||
IQueryParameterType params = nextOr;
|
IQueryParameterType params = nextOr;
|
||||||
|
|
||||||
if (addPredicateMissingFalseIfPresent(myBuilder, theParamName, join, codePredicates, nextOr)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params instanceof NumberParam) {
|
if (params instanceof NumberParam) {
|
||||||
NumberParam param = (NumberParam) params;
|
NumberParam param = (NumberParam) params;
|
||||||
|
|
||||||
|
@ -376,62 +332,18 @@ public class SearchBuilder {
|
||||||
myPredicates.add(myBuilder.or(toArray(codePredicates)));
|
myPredicates.add(myBuilder.or(toArray(codePredicates)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addPredicateParamMissing(String joinName, String theParamName, Class<? extends BaseResourceIndexedSearchParam> theParamTable) {
|
private void addPredicateParamMissing(String theParamName, boolean theMissing) {
|
||||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
Join<ResourceTable, SearchParamPresent> paramPresentJoin = myResourceTableRoot.join("mySearchParamPresents", JoinType.LEFT);
|
||||||
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
Join<SearchParamPresent, SearchParam> paramJoin = paramPresentJoin.join("mySearchParam", JoinType.LEFT);
|
||||||
Root<ResourceTable> from = cq.from(ResourceTable.class);
|
|
||||||
cq.select(from.get("myId").as(Long.class));
|
|
||||||
|
|
||||||
Subquery<Long> subQ = cq.subquery(Long.class);
|
myPredicates.add(myBuilder.equal(paramJoin.get("myResourceName"), myResourceName));
|
||||||
Root<? extends BaseResourceIndexedSearchParam> subQfrom = subQ.from(theParamTable);
|
myPredicates.add(myBuilder.equal(paramJoin.get("myParamName"), theParamName));
|
||||||
subQ.select(subQfrom.get("myResourcePid").as(Long.class));
|
myPredicates.add(myBuilder.equal(paramPresentJoin.get("myPresent"), !theMissing));
|
||||||
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));
|
|
||||||
|
|
||||||
cq.where(builder.and(toArray(predicates)));
|
|
||||||
|
|
||||||
ourLog.info("Adding :missing qualifier for parameter '{}'", theParamName);
|
|
||||||
|
|
||||||
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
|
||||||
doSetPids(q.getResultList());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addPredicateParamMissingResourceLink(String joinName, String theParamName) {
|
|
||||||
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<ResourceLink> subQfrom = subQ.from(ResourceLink.class);
|
|
||||||
subQ.select(subQfrom.get("mySourceResourcePid").as(Long.class));
|
|
||||||
|
|
||||||
// subQ.where(builder.equal(subQfrom.get("myParamName"), theParamName));
|
|
||||||
Predicate path = createResourceLinkPathPredicate(theParamName, subQfrom);
|
|
||||||
subQ.where(path);
|
|
||||||
|
|
||||||
List<Predicate> predicates = new ArrayList<Predicate>();
|
|
||||||
createPredicateResourceId(builder, cq, predicates, from.get("myId").as(Long.class));
|
|
||||||
predicates.add(builder.not(builder.in(from.get("myId")).value(subQ)));
|
|
||||||
predicates.add(builder.equal(from.get("myResourceType"), myResourceName));
|
|
||||||
|
|
||||||
cq.where(builder.and(toArray(predicates)));
|
|
||||||
|
|
||||||
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
|
||||||
List<Long> resultList = q.getResultList();
|
|
||||||
doSetPids(new HashSet<Long>(resultList));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addPredicateQuantity(String theParamName, List<? extends IQueryParameterType> theList) {
|
private void addPredicateQuantity(String theParamName, List<? extends IQueryParameterType> theList) {
|
||||||
if (Boolean.TRUE.equals(theList.get(0).getMissing())) {
|
if (theList.get(0).getMissing() != null) {
|
||||||
addPredicateParamMissing("myParamsQuantity", theParamName, ResourceIndexedSearchParamQuantity.class);
|
addPredicateParamMissing(theParamName, theList.get(0).getMissing());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,9 +351,6 @@ public class SearchBuilder {
|
||||||
|
|
||||||
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
||||||
for (IQueryParameterType nextOr : theList) {
|
for (IQueryParameterType nextOr : theList) {
|
||||||
if (addPredicateMissingFalseIfPresent(myBuilder, theParamName, join, codePredicates, nextOr)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Predicate singleCode = createPredicateQuantity(myBuilder, join, nextOr);
|
Predicate singleCode = createPredicateQuantity(myBuilder, join, nextOr);
|
||||||
codePredicates.add(singleCode);
|
codePredicates.add(singleCode);
|
||||||
|
@ -453,8 +362,8 @@ public class SearchBuilder {
|
||||||
private void addPredicateReference(String theParamName, List<? extends IQueryParameterType> theList) {
|
private void addPredicateReference(String theParamName, List<? extends IQueryParameterType> theList) {
|
||||||
assert theParamName.contains(".") == false;
|
assert theParamName.contains(".") == false;
|
||||||
|
|
||||||
if (Boolean.TRUE.equals(theList.get(0).getMissing())) {
|
if (theList.get(0).getMissing() != null) {
|
||||||
addPredicateParamMissingResourceLink("myResourceLinks", theParamName);
|
addPredicateParamMissing(theParamName, theList.get(0).getMissing());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,10 +374,6 @@ public class SearchBuilder {
|
||||||
for (IQueryParameterType nextOr : theList) {
|
for (IQueryParameterType nextOr : theList) {
|
||||||
IQueryParameterType params = nextOr;
|
IQueryParameterType params = nextOr;
|
||||||
|
|
||||||
if (addPredicateMissingFalseIfPresentForResourceLink(myBuilder, theParamName, join, codePredicates, nextOr)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params instanceof ReferenceParam) {
|
if (params instanceof ReferenceParam) {
|
||||||
ReferenceParam ref = (ReferenceParam) params;
|
ReferenceParam ref = (ReferenceParam) params;
|
||||||
|
|
||||||
|
@ -585,34 +490,34 @@ public class SearchBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
foundChainMatch = true;
|
foundChainMatch = true;
|
||||||
// Set<Long> pids = dao.searchForIds(chain, chainValue);
|
// Set<Long> pids = dao.searchForIds(chain, chainValue);
|
||||||
|
|
||||||
Subquery<Long> subQ = myResourceTableQuery.subquery(Long.class);
|
Subquery<Long> subQ = myResourceTableQuery.subquery(Long.class);
|
||||||
Root<ResourceTable> subQfrom = subQ.from(ResourceTable.class);
|
Root<ResourceTable> subQfrom = subQ.from(ResourceTable.class);
|
||||||
subQ.select(subQfrom.get("myId").as(Long.class));
|
subQ.select(subQfrom.get("myId").as(Long.class));
|
||||||
|
|
||||||
List<List<? extends IQueryParameterType>> andOrParams = new ArrayList<List<? extends IQueryParameterType>>();
|
List<List<? extends IQueryParameterType>> andOrParams = new ArrayList<List<? extends IQueryParameterType>>();
|
||||||
andOrParams.add(Collections.singletonList(chainValue));
|
andOrParams.add(Collections.singletonList(chainValue));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're doing a chain call, so push the current query root
|
* We're doing a chain call, so push the current query root
|
||||||
* and predicate list down and put new ones at the top of the
|
* and predicate list down and put new ones at the top of the
|
||||||
* stack and run a subuery
|
* stack and run a subuery
|
||||||
*/
|
*/
|
||||||
Root<ResourceTable> stackRoot = myResourceTableRoot;
|
Root<ResourceTable> stackRoot = myResourceTableRoot;
|
||||||
ArrayList<Predicate> stackPredicates = myPredicates;
|
ArrayList<Predicate> stackPredicates = myPredicates;
|
||||||
myResourceTableRoot = subQfrom;
|
myResourceTableRoot = subQfrom;
|
||||||
myPredicates = new ArrayList<Predicate>();
|
myPredicates = new ArrayList<Predicate>();
|
||||||
|
|
||||||
searchForIdsWithAndOr(chain, andOrParams);
|
searchForIdsWithAndOr(chain, andOrParams);
|
||||||
subQ.where(toArray(myPredicates));
|
subQ.where(toArray(myPredicates));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pop the old query root and predicate list back
|
* Pop the old query root and predicate list back
|
||||||
*/
|
*/
|
||||||
myResourceTableRoot = stackRoot;
|
myResourceTableRoot = stackRoot;
|
||||||
myPredicates = stackPredicates;
|
myPredicates = stackPredicates;
|
||||||
|
|
||||||
Predicate eq = join.get("myTargetResourcePid").in(subQ);
|
Predicate eq = join.get("myTargetResourcePid").in(subQ);
|
||||||
codePredicates.add(eq);
|
codePredicates.add(eq);
|
||||||
|
|
||||||
|
@ -633,20 +538,16 @@ public class SearchBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addPredicateString(String theParamName, List<? extends IQueryParameterType> theList) {
|
private void addPredicateString(String theParamName, List<? extends IQueryParameterType> theList) {
|
||||||
if (Boolean.TRUE.equals(theList.get(0).getMissing())) {
|
if (theList.get(0).getMissing() != null) {
|
||||||
addPredicateParamMissing("myParamsString", theParamName, ResourceIndexedSearchParamString.class);
|
addPredicateParamMissing(theParamName, theList.get(0).getMissing());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Join<ResourceTable, ResourceIndexedSearchParamString> join = myResourceTableRoot.join("myParamsString", JoinType.LEFT);
|
Join<ResourceTable, ResourceIndexedSearchParamString> join = myResourceTableRoot.join("myParamsString", JoinType.LEFT);
|
||||||
|
|
||||||
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
||||||
for (IQueryParameterType nextOr : theList) {
|
for (IQueryParameterType nextOr : theList) {
|
||||||
IQueryParameterType theParameter = nextOr;
|
IQueryParameterType theParameter = nextOr;
|
||||||
if (addPredicateMissingFalseIfPresent(myBuilder, theParamName, join, codePredicates, nextOr)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Predicate singleCode = createPredicateString(theParameter, theParamName, myBuilder, join);
|
Predicate singleCode = createPredicateString(theParameter, theParamName, myBuilder, join);
|
||||||
codePredicates.add(singleCode);
|
codePredicates.add(singleCode);
|
||||||
}
|
}
|
||||||
|
@ -775,7 +676,7 @@ public class SearchBuilder {
|
||||||
|
|
||||||
Join<ResourceTable, ResourceTag> tagJoin = myResourceTableRoot.join("myTags", JoinType.LEFT);
|
Join<ResourceTable, ResourceTag> tagJoin = myResourceTableRoot.join("myTags", JoinType.LEFT);
|
||||||
From<ResourceTag, TagDefinition> defJoin = tagJoin.join("myTag");
|
From<ResourceTag, TagDefinition> defJoin = tagJoin.join("myTag");
|
||||||
|
|
||||||
List<Predicate> orPredicates = createPredicateTagList(defJoin, myBuilder, tagType, tokens);
|
List<Predicate> orPredicates = createPredicateTagList(defJoin, myBuilder, tagType, tokens);
|
||||||
myPredicates.add(myBuilder.or(toArray(orPredicates)));
|
myPredicates.add(myBuilder.or(toArray(orPredicates)));
|
||||||
|
|
||||||
|
@ -785,8 +686,8 @@ public class SearchBuilder {
|
||||||
|
|
||||||
private void addPredicateToken(String theParamName, List<? extends IQueryParameterType> theList) {
|
private void addPredicateToken(String theParamName, List<? extends IQueryParameterType> theList) {
|
||||||
|
|
||||||
if (Boolean.TRUE.equals(theList.get(0).getMissing())) {
|
if (theList.get(0).getMissing() != null) {
|
||||||
addPredicateParamMissing("myParamsToken", theParamName, ResourceIndexedSearchParamToken.class);
|
addPredicateParamMissing(theParamName, theList.get(0).getMissing());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,9 +695,6 @@ public class SearchBuilder {
|
||||||
|
|
||||||
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
||||||
for (IQueryParameterType nextOr : theList) {
|
for (IQueryParameterType nextOr : theList) {
|
||||||
if (addPredicateMissingFalseIfPresent(myBuilder, theParamName, join, codePredicates, nextOr)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextOr instanceof TokenParam) {
|
if (nextOr instanceof TokenParam) {
|
||||||
TokenParam id = (TokenParam) nextOr;
|
TokenParam id = (TokenParam) nextOr;
|
||||||
|
@ -822,8 +720,8 @@ public class SearchBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addPredicateUri(String theParamName, List<? extends IQueryParameterType> theList) {
|
private void addPredicateUri(String theParamName, List<? extends IQueryParameterType> theList) {
|
||||||
if (Boolean.TRUE.equals(theList.get(0).getMissing())) {
|
if (theList.get(0).getMissing() != null) {
|
||||||
addPredicateParamMissing("myParamsUri", theParamName, ResourceIndexedSearchParamUri.class);
|
addPredicateParamMissing(theParamName, theList.get(0).getMissing());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -833,10 +731,6 @@ public class SearchBuilder {
|
||||||
for (IQueryParameterType nextOr : theList) {
|
for (IQueryParameterType nextOr : theList) {
|
||||||
IQueryParameterType params = nextOr;
|
IQueryParameterType params = nextOr;
|
||||||
|
|
||||||
if (addPredicateMissingFalseIfPresent(myBuilder, theParamName, join, codePredicates, nextOr)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params instanceof UriParam) {
|
if (params instanceof UriParam) {
|
||||||
UriParam param = (UriParam) params;
|
UriParam param = (UriParam) params;
|
||||||
|
|
||||||
|
@ -1265,7 +1159,7 @@ public class SearchBuilder {
|
||||||
return singleCode;
|
return singleCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate createResourceLinkPathPredicate(String theParamName, From<?,? extends ResourceLink> from) {
|
private Predicate createResourceLinkPathPredicate(String theParamName, From<?, ? extends ResourceLink> from) {
|
||||||
return createResourceLinkPathPredicate(myCallingDao, myContext, theParamName, from, myResourceType);
|
return createResourceLinkPathPredicate(myCallingDao, myContext, theParamName, from, myResourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1368,10 +1262,6 @@ public class SearchBuilder {
|
||||||
thePredicates.add(theBuilder.equal(stringJoin.get("myParamName"), theSort.getParamName()));
|
thePredicates.add(theBuilder.equal(stringJoin.get("myParamName"), theSort.getParamName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Predicate p = theBuilder.equal(stringJoin.get("myParamName"), theSort.getParamName());
|
|
||||||
// Predicate pn = theBuilder.isNull(stringJoin.get("myParamName"));
|
|
||||||
// thePredicates.add(theBuilder.or(p, pn));
|
|
||||||
|
|
||||||
for (String next : sortAttrName) {
|
for (String next : sortAttrName) {
|
||||||
if (theSort.getOrder() == null || theSort.getOrder() == SortOrderEnum.ASC) {
|
if (theSort.getOrder() == null || theSort.getOrder() == SortOrderEnum.ASC) {
|
||||||
theOrders.add(theBuilder.asc(stringJoin.get(next)));
|
theOrders.add(theBuilder.asc(stringJoin.get(next)));
|
||||||
|
@ -1565,30 +1455,30 @@ public class SearchBuilder {
|
||||||
mySearchEntity.setSearchType(myParams.getEverythingMode() != null ? SearchTypeEnum.EVERYTHING : SearchTypeEnum.SEARCH);
|
mySearchEntity.setSearchType(myParams.getEverythingMode() != null ? SearchTypeEnum.EVERYTHING : SearchTypeEnum.SEARCH);
|
||||||
mySearchEntity.setLastUpdated(myParams.getLastUpdated());
|
mySearchEntity.setLastUpdated(myParams.getLastUpdated());
|
||||||
mySearchEntity.setResourceType(myResourceName);
|
mySearchEntity.setResourceType(myResourceName);
|
||||||
|
|
||||||
for (Include next : myParams.getIncludes()) {
|
for (Include next : myParams.getIncludes()) {
|
||||||
mySearchEntity.getIncludes().add(new SearchInclude(mySearchEntity, next.getValue(), false, next.isRecurse()));
|
mySearchEntity.getIncludes().add(new SearchInclude(mySearchEntity, next.getValue(), false, next.isRecurse()));
|
||||||
}
|
}
|
||||||
for (Include next : myParams.getRevIncludes()) {
|
for (Include next : myParams.getRevIncludes()) {
|
||||||
mySearchEntity.getIncludes().add(new SearchInclude(mySearchEntity, next.getValue(), true, next.isRecurse()));
|
mySearchEntity.getIncludes().add(new SearchInclude(mySearchEntity, next.getValue(), true, next.isRecurse()));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Long> firstPage = loadSearchPage(theParams, 0, 999);
|
List<Long> firstPage = loadSearchPage(theParams, 0, 999);
|
||||||
mySearchEntity.setTotalCount(firstPage.size());
|
mySearchEntity.setTotalCount(firstPage.size());
|
||||||
|
|
||||||
myEntityManager.persist(mySearchEntity);
|
myEntityManager.persist(mySearchEntity);
|
||||||
for (SearchInclude next : mySearchEntity.getIncludes()) {
|
for (SearchInclude next : mySearchEntity.getIncludes()) {
|
||||||
myEntityManager.persist(next);
|
myEntityManager.persist(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
IBundleProvider retVal = doReturnProvider();
|
IBundleProvider retVal = doReturnProvider();
|
||||||
|
|
||||||
ourLog.info("Search initial phase completed in {}ms", w);
|
ourLog.info("Search initial phase completed in {}ms", w);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Long> loadSearchPage(SearchParameterMap theParams, int theFromIndex, int theToIndex) {
|
public List<Long> loadSearchPage(SearchParameterMap theParams, int theFromIndex, int theToIndex) {
|
||||||
|
|
||||||
if (myFulltextSearchSvc == null) {
|
if (myFulltextSearchSvc == null) {
|
||||||
if (theParams.containsKey(Constants.PARAM_TEXT)) {
|
if (theParams.containsKey(Constants.PARAM_TEXT)) {
|
||||||
throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_TEXT);
|
throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_TEXT);
|
||||||
|
@ -1613,28 +1503,28 @@ public class SearchBuilder {
|
||||||
myPredicates = new ArrayList<Predicate>();
|
myPredicates = new ArrayList<Predicate>();
|
||||||
myPredicates.add(myBuilder.equal(myResourceTableRoot.get("myResourceType"), myResourceName));
|
myPredicates.add(myBuilder.equal(myResourceTableRoot.get("myResourceType"), myResourceName));
|
||||||
myPredicates.add(myBuilder.isNull(myResourceTableRoot.get("myDeleted")));
|
myPredicates.add(myBuilder.isNull(myResourceTableRoot.get("myDeleted")));
|
||||||
|
|
||||||
DateRangeParam lu = theParams.getLastUpdated();
|
DateRangeParam lu = theParams.getLastUpdated();
|
||||||
List<Predicate> lastUpdatedPredicates = createLastUpdatedPredicates(lu, myBuilder, myResourceTableRoot);
|
List<Predicate> lastUpdatedPredicates = createLastUpdatedPredicates(lu, myBuilder, myResourceTableRoot);
|
||||||
myPredicates.addAll(lastUpdatedPredicates);
|
myPredicates.addAll(lastUpdatedPredicates);
|
||||||
|
|
||||||
searchForIdsWithAndOr(theParams);
|
searchForIdsWithAndOr(theParams);
|
||||||
|
|
||||||
myResourceTableQuery.where(myBuilder.and(SearchBuilder.toArray(myPredicates)));
|
myResourceTableQuery.where(myBuilder.and(SearchBuilder.toArray(myPredicates)));
|
||||||
|
|
||||||
myResourceTableQuery.multiselect(myResourceTableRoot.get("myId").as(Long.class));
|
myResourceTableQuery.multiselect(myResourceTableRoot.get("myId").as(Long.class));
|
||||||
TypedQuery<Tuple> query = myEntityManager.createQuery(myResourceTableQuery);
|
TypedQuery<Tuple> query = myEntityManager.createQuery(myResourceTableQuery);
|
||||||
query.setFirstResult(theFromIndex);
|
query.setFirstResult(theFromIndex);
|
||||||
query.setMaxResults(theToIndex - theFromIndex);
|
query.setMaxResults(theToIndex - theFromIndex);
|
||||||
|
|
||||||
List<Long> pids = new ArrayList<Long>();
|
List<Long> pids = new ArrayList<Long>();
|
||||||
for (Tuple next : query.getResultList()) {
|
for (Tuple next : query.getResultList()) {
|
||||||
pids.add(next.get(0, Long.class));
|
pids.add(next.get(0, Long.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
return pids;
|
return pids;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IBundleProvider loadPage(SearchParameterMap theParams, int theFromIndex, int theToIndex) {
|
public IBundleProvider loadPage(SearchParameterMap theParams, int theFromIndex, int theToIndex) {
|
||||||
StopWatch sw = new StopWatch();
|
StopWatch sw = new StopWatch();
|
||||||
DateRangeParam lu = theParams.getLastUpdated();
|
DateRangeParam lu = theParams.getLastUpdated();
|
||||||
|
@ -1702,9 +1592,8 @@ public class SearchBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!theParams.isEmpty()) {
|
if (!theParams.isEmpty()) {
|
||||||
// searchForIdsWithAndOr(theParams, lu);
|
// searchForIdsWithAndOr(theParams, lu);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1729,7 +1618,7 @@ public class SearchBuilder {
|
||||||
return doReturnProvider();
|
return doReturnProvider();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void searchForIdsWithAndOr(SearchParameterMap theParams) {
|
private void searchForIdsWithAndOr(SearchParameterMap theParams) {
|
||||||
SearchParameterMap params = theParams;
|
SearchParameterMap params = theParams;
|
||||||
if (params == null) {
|
if (params == null) {
|
||||||
|
@ -1810,7 +1699,7 @@ public class SearchBuilder {
|
||||||
addPredicateUri(nextParamName, nextAnd);
|
addPredicateUri(nextParamName, nextAnd);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HAS:
|
case HAS:
|
||||||
// should not happen
|
// should not happen
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1834,21 +1723,20 @@ public class SearchBuilder {
|
||||||
orPids.add(entity.getId());
|
orPids.add(entity.getId());
|
||||||
}
|
}
|
||||||
} catch (ResourceNotFoundException e) {
|
} catch (ResourceNotFoundException e) {
|
||||||
/*
|
/*
|
||||||
* This isn't an error, just means no result found
|
* This isn't an error, just means no result found
|
||||||
* that matches the ID the client provided
|
* that matches the ID the client provided
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (orPids.size() > 0) {
|
|
||||||
Predicate nextPredicate = myResourceTableRoot.get("myId").as(Long.class).in(orPids);
|
|
||||||
myPredicates.add(nextPredicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (orPids.size() > 0) {
|
||||||
|
Predicate nextPredicate = myResourceTableRoot.get("myId").as(Long.class).in(orPids);
|
||||||
|
myPredicates.add(nextPredicate);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1942,7 +1830,7 @@ public class SearchBuilder {
|
||||||
return likeExpression.replace("%", "[%]") + "%";
|
return likeExpression.replace("%", "[%]") + "%";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Predicate createResourceLinkPathPredicate(IDao theCallingDao, FhirContext theContext, String theParamName, From<?,? extends ResourceLink> from,
|
private static Predicate createResourceLinkPathPredicate(IDao theCallingDao, FhirContext theContext, String theParamName, From<?, ? extends ResourceLink> from,
|
||||||
Class<? extends IBaseResource> resourceType) {
|
Class<? extends IBaseResource> resourceType) {
|
||||||
RuntimeResourceDefinition resourceDef = theContext.getResourceDefinition(resourceType);
|
RuntimeResourceDefinition resourceDef = theContext.getResourceDefinition(resourceType);
|
||||||
RuntimeSearchParam param = theCallingDao.getSearchParamByName(resourceDef, theParamName);
|
RuntimeSearchParam param = theCallingDao.getSearchParamByName(resourceDef, theParamName);
|
||||||
|
|
|
@ -32,7 +32,7 @@ import ca.uhn.fhir.jpa.entity.SearchParamPresent;
|
||||||
|
|
||||||
public interface ISearchParamPresentDao extends JpaRepository<SearchParamPresent, Long> {
|
public interface ISearchParamPresentDao extends JpaRepository<SearchParamPresent, Long> {
|
||||||
|
|
||||||
@Query("SELECT s FROM SearchParamPresent s WHERE s.myResourceTable = :res")
|
@Query("SELECT s FROM SearchParamPresent s WHERE s.myResource = :res")
|
||||||
public Collection<SearchParamPresent> findAllForResource(@Param("res") ResourceTable theResource);
|
public Collection<SearchParamPresent> findAllForResource(@Param("res") ResourceTable theResource);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,6 +236,9 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
||||||
@OneToMany(mappedBy = "myResource", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
|
@OneToMany(mappedBy = "myResource", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
|
||||||
private Set<ResourceTag> myTags;
|
private Set<ResourceTag> myTags;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "myResource", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
|
||||||
|
private Collection<SearchParamPresent> mySearchParamPresents;
|
||||||
|
|
||||||
@Column(name = "RES_VER")
|
@Column(name = "RES_VER")
|
||||||
private long myVersion;
|
private long myVersion;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ public class SearchParam {
|
||||||
@Id
|
@Id
|
||||||
@SequenceGenerator(name = "SEQ_SEARCHPARM_ID", sequenceName = "SEQ_SEARCHPARM_ID")
|
@SequenceGenerator(name = "SEQ_SEARCHPARM_ID", sequenceName = "SEQ_SEARCHPARM_ID")
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_SEARCHPARM_ID")
|
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_SEARCHPARM_ID")
|
||||||
@Column(name = "RES_ID")
|
@Column(name = "PID")
|
||||||
private Long myId;
|
private Long myId;
|
||||||
|
|
||||||
@Column(name="PARAM_NAME", length=BaseResourceIndexedSearchParam.MAX_SP_NAME, nullable=false, updatable=false)
|
@Column(name="PARAM_NAME", length=BaseResourceIndexedSearchParam.MAX_SP_NAME, nullable=false, updatable=false)
|
||||||
|
|
|
@ -25,14 +25,14 @@ public class SearchParamPresent implements Serializable {
|
||||||
|
|
||||||
@ManyToOne()
|
@ManyToOne()
|
||||||
@JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID", nullable = false, foreignKey = @ForeignKey(name = "FK_RESPARMPRES_RESID"))
|
@JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID", nullable = false, foreignKey = @ForeignKey(name = "FK_RESPARMPRES_RESID"))
|
||||||
private ResourceTable myResourceTable;
|
private ResourceTable myResource;
|
||||||
|
|
||||||
@ManyToOne()
|
@ManyToOne()
|
||||||
@JoinColumn(name = "SP_ID", referencedColumnName = "PID", nullable = false, foreignKey = @ForeignKey(name = "FK_RESPARMPRES_SPID"))
|
@JoinColumn(name = "SP_ID", referencedColumnName = "PID", nullable = false, foreignKey = @ForeignKey(name = "FK_RESPARMPRES_SPID"))
|
||||||
private SearchParam mySearchParam;
|
private SearchParam mySearchParam;
|
||||||
|
|
||||||
public ResourceTable getResourceTable() {
|
public ResourceTable getResource() {
|
||||||
return myResourceTable;
|
return myResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchParam getSearchParam() {
|
public SearchParam getSearchParam() {
|
||||||
|
@ -47,8 +47,8 @@ public class SearchParamPresent implements Serializable {
|
||||||
myPresent = thePresent;
|
myPresent = thePresent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResourceTable(ResourceTable theResourceTable) {
|
public void setResource(ResourceTable theResourceTable) {
|
||||||
myResourceTable = theResourceTable;
|
myResource = theResourceTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSearchParam(SearchParam theSearchParam) {
|
public void setSearchParam(SearchParam theSearchParam) {
|
||||||
|
|
|
@ -16,23 +16,29 @@ import ca.uhn.fhir.jpa.entity.SearchParamPresent;
|
||||||
public class SearchParamPresenceSvcImpl implements ISearchParamPresenceSvc {
|
public class SearchParamPresenceSvcImpl implements ISearchParamPresenceSvc {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchParamPresenceSvcImpl.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchParamPresenceSvcImpl.class);
|
||||||
|
|
||||||
private Map<Pair<String, String>, SearchParam> myResourceTypeToSearchParamToEntity = new ConcurrentHashMap<Pair<String,String>, SearchParam>();
|
private Map<Pair<String, String>, SearchParam> myResourceTypeToSearchParamToEntity = new ConcurrentHashMap<Pair<String, String>, SearchParam>();
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISearchParamDao mySearchParamDao;
|
private ISearchParamDao mySearchParamDao;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISearchParamPresentDao mySearchParamPresentDao;
|
private ISearchParamPresentDao mySearchParamPresentDao;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updatePresence(ResourceTable theResource, Map<String, Boolean> theParamNameToPresence) {
|
public void updatePresence(ResourceTable theResource, Map<String, Boolean> theParamNameToPresence) {
|
||||||
|
|
||||||
Map<String, Boolean> presenceMap = new HashMap<String, Boolean>(theParamNameToPresence);
|
Map<String, Boolean> presenceMap = new HashMap<String, Boolean>(theParamNameToPresence);
|
||||||
List<SearchParamPresent> entitiesToSave = new ArrayList<SearchParamPresent>();
|
List<SearchParamPresent> entitiesToSave = new ArrayList<SearchParamPresent>();
|
||||||
List<SearchParamPresent> entitiesToDelete = new ArrayList<SearchParamPresent>();
|
List<SearchParamPresent> entitiesToDelete = new ArrayList<SearchParamPresent>();
|
||||||
|
|
||||||
Collection<SearchParamPresent> existing = mySearchParamPresentDao.findAllForResource(theResource);
|
Collection<SearchParamPresent> existing;
|
||||||
|
// if (theResource.getId() != null) {
|
||||||
|
existing = mySearchParamPresentDao.findAllForResource(theResource);
|
||||||
|
// } else {
|
||||||
|
// existing = Collections.emptyList();
|
||||||
|
// }
|
||||||
|
|
||||||
for (SearchParamPresent nextExistingEntity : existing) {
|
for (SearchParamPresent nextExistingEntity : existing) {
|
||||||
String nextSearchParamName = nextExistingEntity.getSearchParam().getParamName();
|
String nextSearchParamName = nextExistingEntity.getSearchParam().getParamName();
|
||||||
Boolean existingValue = presenceMap.remove(nextSearchParamName);
|
Boolean existingValue = presenceMap.remove(nextSearchParamName);
|
||||||
|
@ -45,12 +51,12 @@ public class SearchParamPresenceSvcImpl implements ISearchParamPresenceSvc {
|
||||||
entitiesToSave.add(nextExistingEntity);
|
entitiesToSave.add(nextExistingEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Entry<String, Boolean> next : presenceMap.entrySet()) {
|
for (Entry<String, Boolean> next : presenceMap.entrySet()) {
|
||||||
String resourceType = theResource.getResourceType();
|
String resourceType = theResource.getResourceType();
|
||||||
String paramName = next.getKey();
|
String paramName = next.getKey();
|
||||||
Pair<String, String> key = Pair.of(resourceType, paramName);
|
Pair<String, String> key = Pair.of(resourceType, paramName);
|
||||||
|
|
||||||
SearchParam searchParam = myResourceTypeToSearchParamToEntity.get(key);
|
SearchParam searchParam = myResourceTypeToSearchParamToEntity.get(key);
|
||||||
if (searchParam == null) {
|
if (searchParam == null) {
|
||||||
searchParam = mySearchParamDao.findForResource(resourceType, paramName);
|
searchParam = mySearchParamDao.findForResource(resourceType, paramName);
|
||||||
|
@ -63,19 +69,19 @@ public class SearchParamPresenceSvcImpl implements ISearchParamPresenceSvc {
|
||||||
mySearchParamDao.save(searchParam);
|
mySearchParamDao.save(searchParam);
|
||||||
// Don't add the newly saved entity to the map in case the save fails
|
// Don't add the newly saved entity to the map in case the save fails
|
||||||
}
|
}
|
||||||
|
|
||||||
SearchParamPresent present = new SearchParamPresent();
|
SearchParamPresent present = new SearchParamPresent();
|
||||||
present.setResourceTable(theResource);
|
present.setResource(theResource);
|
||||||
present.setSearchParam(searchParam);
|
present.setSearchParam(searchParam);
|
||||||
present.setPresent(next.getValue());
|
present.setPresent(next.getValue());
|
||||||
entitiesToSave.add(present);
|
entitiesToSave.add(present);
|
||||||
}
|
}
|
||||||
|
|
||||||
mySearchParamPresentDao.deleteInBatch(entitiesToDelete);
|
mySearchParamPresentDao.deleteInBatch(entitiesToDelete);
|
||||||
mySearchParamPresentDao.save(entitiesToSave);
|
mySearchParamPresentDao.save(entitiesToSave);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,28 +30,7 @@ import org.springframework.transaction.support.TransactionCallback;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.entity.ForcedId;
|
import ca.uhn.fhir.jpa.entity.*;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceHistoryTag;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamCoords;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamDate;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamNumber;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamQuantity;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamToken;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamUri;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceLink;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTag;
|
|
||||||
import ca.uhn.fhir.jpa.entity.SearchInclude;
|
|
||||||
import ca.uhn.fhir.jpa.entity.SearchResult;
|
|
||||||
import ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource;
|
|
||||||
import ca.uhn.fhir.jpa.entity.SubscriptionTable;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TagDefinition;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
|
|
||||||
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
|
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
|
||||||
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
|
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||||
|
@ -225,6 +204,9 @@ public abstract class BaseJpaTest {
|
||||||
txTemplate.execute(new TransactionCallback<Void>() {
|
txTemplate.execute(new TransactionCallback<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void doInTransaction(TransactionStatus theStatus) {
|
public Void doInTransaction(TransactionStatus theStatus) {
|
||||||
|
entityManager.createQuery("DELETE from " + SearchParamPresent.class.getSimpleName() + " d").executeUpdate();
|
||||||
|
entityManager.createQuery("DELETE from " + SearchParam.class.getSimpleName() + " d").executeUpdate();
|
||||||
|
entityManager.createQuery("DELETE from " + SubscriptionFlaggedResource.class.getSimpleName() + " d").executeUpdate();
|
||||||
entityManager.createQuery("DELETE from " + SubscriptionFlaggedResource.class.getSimpleName() + " d").executeUpdate();
|
entityManager.createQuery("DELETE from " + SubscriptionFlaggedResource.class.getSimpleName() + " d").executeUpdate();
|
||||||
entityManager.createQuery("DELETE from " + ForcedId.class.getSimpleName() + " d").executeUpdate();
|
entityManager.createQuery("DELETE from " + ForcedId.class.getSimpleName() + " d").executeUpdate();
|
||||||
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamDate.class.getSimpleName() + " d").executeUpdate();
|
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamDate.class.getSimpleName() + " d").executeUpdate();
|
||||||
|
|
|
@ -1747,27 +1747,27 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
String methodName = "testSearchValueQuantity";
|
String methodName = "testSearchValueQuantity";
|
||||||
|
|
||||||
String id1;
|
String id1;
|
||||||
{
|
{
|
||||||
Observation o = new Observation();
|
Observation o = new Observation();
|
||||||
o.getCode().addCoding().setSystem("urn:foo").setCode(methodName + "code");
|
o.getCode().addCoding().setSystem("urn:foo").setCode(methodName + "code");
|
||||||
Quantity q = new Quantity().setSystem("urn:bar:" + methodName).setCode(methodName + "units").setValue(100);
|
Quantity q = new Quantity().setSystem("urn:bar:" + methodName).setCode(methodName + "units").setValue(100);
|
||||||
o.setValue(q);
|
o.setValue(q);
|
||||||
id1 = myObservationDao.create(o, mySrd).getId().toUnqualifiedVersionless().getValue();
|
id1 = myObservationDao.create(o, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
String id2;
|
String id2;
|
||||||
{
|
{
|
||||||
Observation o = new Observation();
|
Observation o = new Observation();
|
||||||
o.getCode().addCoding().setSystem("urn:foo").setCode(methodName + "code");
|
o.getCode().addCoding().setSystem("urn:foo").setCode(methodName + "code");
|
||||||
Quantity q = new Quantity().setSystem("urn:bar:" + methodName).setCode(methodName + "units").setValue(5);
|
Quantity q = new Quantity().setSystem("urn:bar:" + methodName).setCode(methodName + "units").setValue(5);
|
||||||
o.setValue(q);
|
o.setValue(q);
|
||||||
id2 = myObservationDao.create(o, mySrd).getId().toUnqualifiedVersionless().getValue();
|
id2 = myObservationDao.create(o, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, IQueryParameterType> map = new HashMap<String, IQueryParameterType>();
|
Map<String, IQueryParameterType> map = new HashMap<String, IQueryParameterType>();
|
||||||
IBundleProvider found;
|
IBundleProvider found;
|
||||||
QuantityParam param;
|
QuantityParam param;
|
||||||
|
|
||||||
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, null);
|
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, null);
|
||||||
map.put(Observation.SP_VALUE_QUANTITY, param);
|
map.put(Observation.SP_VALUE_QUANTITY, param);
|
||||||
found = myObservationDao.search(map);
|
found = myObservationDao.search(map);
|
||||||
|
@ -2146,8 +2146,8 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
param.setMissing(false);
|
param.setMissing(false);
|
||||||
params.put(Patient.SP_BIRTHDATE, param);
|
params.put(Patient.SP_BIRTHDATE, param);
|
||||||
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
|
||||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
|
||||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||||
|
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||||
|
@ -2158,6 +2158,14 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
assertThat(patients, containsInRelativeOrder(missing));
|
assertThat(patients, containsInRelativeOrder(missing));
|
||||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||||
}
|
}
|
||||||
|
// {
|
||||||
|
// Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||||
|
// DateParam param = new DateParam();
|
||||||
|
// param.setMissing(true);
|
||||||
|
// params.put(Patient.SP_DECEASED, param);
|
||||||
|
// List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
|
||||||
|
// assertThat(patients, containsInRelativeOrder(missing, notMissing));
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue