Merge branch 'master' of github.com:jamesagnew/hapi-fhir
This commit is contained in:
commit
e158d88f50
|
@ -1,5 +1,86 @@
|
||||||
package ca.uhn.fhir.jpa.dao;
|
package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.compare;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.trim;
|
||||||
|
|
||||||
|
import java.io.CharArrayWriter;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.text.Normalizer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.NoResultException;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import javax.persistence.PersistenceContextType;
|
||||||
|
import javax.persistence.Tuple;
|
||||||
|
import javax.persistence.TypedQuery;
|
||||||
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
|
import javax.persistence.criteria.Predicate;
|
||||||
|
import javax.persistence.criteria.Root;
|
||||||
|
import javax.xml.stream.events.Characters;
|
||||||
|
import javax.xml.stream.events.XMLEvent;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
|
import org.apache.http.NameValuePair;
|
||||||
|
import org.apache.http.client.utils.URLEncodedUtils;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.internal.SessionImpl;
|
||||||
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBase;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseCoding;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseExtension;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseReference;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IDomainResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
import org.hl7.fhir.r4.model.BaseResource;
|
||||||
|
import org.hl7.fhir.r4.model.Bundle.HTTPVerb;
|
||||||
|
import org.hl7.fhir.r4.model.CanonicalType;
|
||||||
|
import org.hl7.fhir.r4.model.Reference;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.domain.Slice;
|
||||||
|
import org.springframework.data.domain.SliceImpl;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.common.hash.HashFunction;
|
||||||
|
import com.google.common.hash.Hashing;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR JPA Server
|
* HAPI FHIR JPA Server
|
||||||
|
@ -19,10 +100,70 @@ package ca.uhn.fhir.jpa.dao;
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||||
import ca.uhn.fhir.context.*;
|
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
||||||
import ca.uhn.fhir.jpa.dao.data.*;
|
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||||
import ca.uhn.fhir.jpa.entity.*;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
|
import ca.uhn.fhir.context.RuntimeChildResourceDefinition;
|
||||||
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
|
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTagDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedCompositeStringUniqueDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamCoordsDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamDateDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamNumberDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamQuantityDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamStringDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamTokenDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamUriDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IResourceSearchViewDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IResourceTagDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.ISearchDao;
|
||||||
|
import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
||||||
|
import ca.uhn.fhir.jpa.entity.BaseResourceIndexedSearchParam;
|
||||||
|
import ca.uhn.fhir.jpa.entity.BaseTag;
|
||||||
|
import ca.uhn.fhir.jpa.entity.ForcedId;
|
||||||
|
import ca.uhn.fhir.jpa.entity.IBaseResourceEntity;
|
||||||
|
import ca.uhn.fhir.jpa.entity.ResourceEncodingEnum;
|
||||||
|
import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
|
||||||
|
import ca.uhn.fhir.jpa.entity.ResourceHistoryTag;
|
||||||
|
import ca.uhn.fhir.jpa.entity.ResourceIndexedCompositeStringUnique;
|
||||||
|
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.ResourceSearchView;
|
||||||
|
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||||
|
import ca.uhn.fhir.jpa.entity.ResourceTag;
|
||||||
|
import ca.uhn.fhir.jpa.entity.Search;
|
||||||
|
import ca.uhn.fhir.jpa.entity.SearchInclude;
|
||||||
|
import ca.uhn.fhir.jpa.entity.SearchParam;
|
||||||
|
import ca.uhn.fhir.jpa.entity.SearchParamPresent;
|
||||||
|
import ca.uhn.fhir.jpa.entity.SearchResult;
|
||||||
|
import ca.uhn.fhir.jpa.entity.SearchStatusEnum;
|
||||||
|
import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
|
||||||
|
import ca.uhn.fhir.jpa.entity.SubscriptionTable;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TagDefinition;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
||||||
|
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.TermConceptDesignation;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermConceptMap;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermConceptMapGroup;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElement;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElementTarget;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermConceptProperty;
|
||||||
import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
|
import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
|
||||||
import ca.uhn.fhir.jpa.search.JpaRuntimeSearchParam;
|
import ca.uhn.fhir.jpa.search.JpaRuntimeSearchParam;
|
||||||
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
|
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
|
||||||
|
@ -32,7 +173,12 @@ import ca.uhn.fhir.jpa.util.DeleteConflict;
|
||||||
import ca.uhn.fhir.jpa.util.ExpungeOptions;
|
import ca.uhn.fhir.jpa.util.ExpungeOptions;
|
||||||
import ca.uhn.fhir.jpa.util.ExpungeOutcome;
|
import ca.uhn.fhir.jpa.util.ExpungeOutcome;
|
||||||
import ca.uhn.fhir.jpa.util.JpaConstants;
|
import ca.uhn.fhir.jpa.util.JpaConstants;
|
||||||
import ca.uhn.fhir.model.api.*;
|
import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
||||||
|
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
|
import ca.uhn.fhir.model.api.Tag;
|
||||||
|
import ca.uhn.fhir.model.api.TagList;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
@ -48,61 +194,31 @@ import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||||
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
|
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
|
||||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.param.*;
|
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.*;
|
import ca.uhn.fhir.rest.param.ParameterUtil;
|
||||||
|
import ca.uhn.fhir.rest.param.StringAndListParam;
|
||||||
|
import ca.uhn.fhir.rest.param.StringParam;
|
||||||
|
import ca.uhn.fhir.rest.param.TokenAndListParam;
|
||||||
|
import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
|
import ca.uhn.fhir.rest.param.UriAndListParam;
|
||||||
|
import ca.uhn.fhir.rest.param.UriParam;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.IServerOperationInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.IServerOperationInterceptor;
|
||||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
import ca.uhn.fhir.util.*;
|
import ca.uhn.fhir.util.CoverageIgnore;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import ca.uhn.fhir.util.FhirTerser;
|
||||||
import com.google.common.base.Charsets;
|
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
||||||
import com.google.common.collect.ArrayListMultimap;
|
import ca.uhn.fhir.util.StopWatch;
|
||||||
import com.google.common.collect.Lists;
|
import ca.uhn.fhir.util.UrlUtil;
|
||||||
import com.google.common.collect.Sets;
|
import ca.uhn.fhir.util.XmlUtil;
|
||||||
import com.google.common.hash.HashFunction;
|
|
||||||
import com.google.common.hash.Hashing;
|
|
||||||
import org.apache.commons.lang3.NotImplementedException;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.commons.lang3.Validate;
|
|
||||||
import org.apache.http.NameValuePair;
|
|
||||||
import org.apache.http.client.utils.URLEncodedUtils;
|
|
||||||
import org.hibernate.Session;
|
|
||||||
import org.hibernate.internal.SessionImpl;
|
|
||||||
import org.hl7.fhir.instance.model.api.*;
|
|
||||||
import org.hl7.fhir.r4.model.BaseResource;
|
|
||||||
import org.hl7.fhir.r4.model.Bundle.HTTPVerb;
|
|
||||||
import org.hl7.fhir.r4.model.CanonicalType;
|
|
||||||
import org.hl7.fhir.r4.model.Reference;
|
|
||||||
import org.springframework.beans.BeansException;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.context.ApplicationContextAware;
|
|
||||||
import org.springframework.data.domain.PageRequest;
|
|
||||||
import org.springframework.data.domain.Pageable;
|
|
||||||
import org.springframework.data.domain.Slice;
|
|
||||||
import org.springframework.data.domain.SliceImpl;
|
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import javax.persistence.*;
|
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
|
||||||
import javax.persistence.criteria.CriteriaQuery;
|
|
||||||
import javax.persistence.criteria.Predicate;
|
|
||||||
import javax.persistence.criteria.Root;
|
|
||||||
import javax.xml.stream.events.Characters;
|
|
||||||
import javax.xml.stream.events.XMLEvent;
|
|
||||||
import java.io.CharArrayWriter;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.text.Normalizer;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.*;
|
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
@Repository
|
@Repository
|
||||||
|
@ -186,6 +302,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
protected IResourceTableDao myResourceTableDao;
|
protected IResourceTableDao myResourceTableDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected IResourceTagDao myResourceTagDao;
|
protected IResourceTagDao myResourceTagDao;
|
||||||
|
@Autowired
|
||||||
|
protected IResourceSearchViewDao myResourceViewDao;
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
private DaoConfig myConfig;
|
private DaoConfig myConfig;
|
||||||
private FhirContext myContext;
|
private FhirContext myContext;
|
||||||
|
@ -199,8 +317,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
private ISearchParamPresenceSvc mySearchParamPresenceSvc;
|
private ISearchParamPresenceSvc mySearchParamPresenceSvc;
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISearchParamRegistry mySearchParamRegistry;
|
private ISearchParamRegistry mySearchParamRegistry;
|
||||||
@Autowired
|
//@Autowired
|
||||||
private ISearchResultDao mySearchResultDao;
|
//private ISearchResultDao mySearchResultDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
private IResourceIndexedCompositeStringUniqueDao myResourceIndexedCompositeStringUniqueDao;
|
private IResourceIndexedCompositeStringUniqueDao myResourceIndexedCompositeStringUniqueDao;
|
||||||
private ApplicationContext myApplicationContext;
|
private ApplicationContext myApplicationContext;
|
||||||
|
@ -1174,7 +1292,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
public SearchBuilder newSearchBuilder() {
|
public SearchBuilder newSearchBuilder() {
|
||||||
SearchBuilder builder = new SearchBuilder(getContext(), myEntityManager, myFulltextSearchSvc, this, myResourceIndexedSearchParamUriDao,
|
SearchBuilder builder = new SearchBuilder(getContext(), myEntityManager, myFulltextSearchSvc, this, myResourceIndexedSearchParamUriDao,
|
||||||
myForcedIdDao,
|
myForcedIdDao,
|
||||||
myTerminologySvc, mySerarchParamRegistry, myResourceHistoryTableDao, myResourceTagDao);
|
myTerminologySvc, mySerarchParamRegistry, myResourceTagDao, myResourceViewDao);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1223,7 +1341,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateResourceIdFromEntity(BaseHasResource theEntity, final IBaseResource theResource) {
|
private void populateResourceIdFromEntity(IBaseResourceEntity theEntity, final IBaseResource theResource) {
|
||||||
IIdType id = theEntity.getIdDt();
|
IIdType id = theEntity.getIdDt();
|
||||||
if (getContext().getVersion().getVersion().isRi()) {
|
if (getContext().getVersion().getVersion().isRi()) {
|
||||||
id = getContext().getVersion().newIdType().setValue(id.getValue());
|
id = getContext().getVersion().newIdType().setValue(id.getValue());
|
||||||
|
@ -1355,7 +1473,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <R extends IBaseResource> R populateResourceMetadataHapi(Class<R> theResourceType, BaseHasResource theEntity, Collection<? extends BaseTag> theTagList, boolean theForHistoryOperation, IResource res) {
|
private <R extends IBaseResource> R populateResourceMetadataHapi(Class<R> theResourceType, IBaseResourceEntity theEntity, Collection<? extends BaseTag> theTagList, boolean theForHistoryOperation, IResource res) {
|
||||||
R retVal = (R) res;
|
R retVal = (R) res;
|
||||||
if (theEntity.getDeleted() != null) {
|
if (theEntity.getDeleted() != null) {
|
||||||
res = (IResource) myContext.getResourceDefinition(theResourceType).newInstance();
|
res = (IResource) myContext.getResourceDefinition(theResourceType).newInstance();
|
||||||
|
@ -1421,7 +1539,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <R extends IBaseResource> R populateResourceMetadataRi(Class<R> theResourceType, BaseHasResource theEntity, Collection<? extends BaseTag> theTagList, boolean theForHistoryOperation, IAnyResource res) {
|
private <R extends IBaseResource> R populateResourceMetadataRi(Class<R> theResourceType, IBaseResourceEntity theEntity, Collection<? extends BaseTag> theTagList, boolean theForHistoryOperation, IAnyResource res) {
|
||||||
R retVal = (R) res;
|
R retVal = (R) res;
|
||||||
if (theEntity.getDeleted() != null) {
|
if (theEntity.getDeleted() != null) {
|
||||||
res = (IAnyResource) myContext.getResourceDefinition(theResourceType).newInstance();
|
res = (IAnyResource) myContext.getResourceDefinition(theResourceType).newInstance();
|
||||||
|
@ -1601,34 +1719,47 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
public IBaseResource toResource(BaseHasResource theEntity, boolean theForHistoryOperation) {
|
public IBaseResource toResource(BaseHasResource theEntity, boolean theForHistoryOperation) {
|
||||||
RuntimeResourceDefinition type = myContext.getResourceDefinition(theEntity.getResourceType());
|
RuntimeResourceDefinition type = myContext.getResourceDefinition(theEntity.getResourceType());
|
||||||
Class<? extends IBaseResource> resourceType = type.getImplementingClass();
|
Class<? extends IBaseResource> resourceType = type.getImplementingClass();
|
||||||
return toResource(resourceType, theEntity, null, null, theForHistoryOperation);
|
return toResource(resourceType, theEntity, null, theForHistoryOperation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public <R extends IBaseResource> R toResource(Class<R> theResourceType, BaseHasResource theEntity, ResourceHistoryTable theHistory, Collection<ResourceTag> theTagList,
|
public <R extends IBaseResource> R toResource(Class<R> theResourceType, IBaseResourceEntity theEntity, Collection<ResourceTag> theTagList, boolean theForHistoryOperation) {
|
||||||
boolean theForHistoryOperation) {
|
|
||||||
|
// 1. get resource, it's encoding and the tags if any
|
||||||
|
byte[] resourceBytes = null;
|
||||||
|
ResourceEncodingEnum resourceEncoding = null;
|
||||||
|
Collection<? extends BaseTag> myTagList = null;
|
||||||
|
|
||||||
// May 28, 2018 - #936
|
|
||||||
// Could set historyList to null, if it's not called in the loop for the backward compatibility
|
|
||||||
ResourceHistoryTable history;
|
|
||||||
if (theEntity instanceof ResourceHistoryTable) {
|
if (theEntity instanceof ResourceHistoryTable) {
|
||||||
history = (ResourceHistoryTable) theEntity;
|
ResourceHistoryTable history = (ResourceHistoryTable) theEntity;
|
||||||
} else {
|
resourceBytes = history.getResource();
|
||||||
if (theHistory == null) {
|
resourceEncoding = history.getEncoding();
|
||||||
history = myResourceHistoryTableDao.findForIdAndVersion(theEntity.getId(), theEntity.getVersion());
|
myTagList = history.getTags();
|
||||||
} else {
|
} else if (theEntity instanceof ResourceTable) {
|
||||||
history = theHistory;
|
ResourceTable resource = (ResourceTable)theEntity;
|
||||||
|
ResourceHistoryTable history = myResourceHistoryTableDao.findForIdAndVersion(theEntity.getId(), theEntity.getVersion());
|
||||||
|
if (history == null) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
resourceBytes = history.getResource();
|
||||||
|
resourceEncoding = history.getEncoding();
|
||||||
if (history == null) {
|
myTagList = resource.getTags();
|
||||||
|
} else if (theEntity instanceof ResourceSearchView) {
|
||||||
|
// This is the search View
|
||||||
|
ResourceSearchView myView = (ResourceSearchView)theEntity;
|
||||||
|
resourceBytes = myView.getResource();
|
||||||
|
resourceEncoding = myView.getEncoding();
|
||||||
|
if (theTagList == null)
|
||||||
|
myTagList = new HashSet<>();
|
||||||
|
else
|
||||||
|
myTagList = theTagList;
|
||||||
|
} else {
|
||||||
|
// something wrong
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] resourceBytes = history.getResource();
|
// 2. get The text
|
||||||
ResourceEncodingEnum resourceEncoding = history.getEncoding();
|
|
||||||
|
|
||||||
String resourceText = null;
|
String resourceText = null;
|
||||||
switch (resourceEncoding) {
|
switch (resourceEncoding) {
|
||||||
case JSON:
|
case JSON:
|
||||||
|
@ -1645,18 +1776,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get preload the tagList
|
// 3. Use the appropriate custom type if one is specified in the context
|
||||||
Collection<? extends BaseTag> myTagList;
|
|
||||||
|
|
||||||
if (theTagList == null)
|
|
||||||
myTagList = theEntity.getTags();
|
|
||||||
else
|
|
||||||
myTagList = theTagList;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Use the appropriate custom type if one is specified in the context
|
|
||||||
*/
|
|
||||||
Class<R> resourceType = theResourceType;
|
Class<R> resourceType = theResourceType;
|
||||||
if (myContext.hasDefaultTypeForProfile()) {
|
if (myContext.hasDefaultTypeForProfile()) {
|
||||||
for (BaseTag nextTag : myTagList) {
|
for (BaseTag nextTag : myTagList) {
|
||||||
|
@ -1674,6 +1794,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 4. parse the text to FHIR
|
||||||
R retVal;
|
R retVal;
|
||||||
if (resourceEncoding != ResourceEncodingEnum.DEL) {
|
if (resourceEncoding != ResourceEncodingEnum.DEL) {
|
||||||
IParser parser = resourceEncoding.newParser(getContext(theEntity.getFhirVersion()));
|
IParser parser = resourceEncoding.newParser(getContext(theEntity.getFhirVersion()));
|
||||||
|
@ -1704,6 +1825,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 5. fill MetaData
|
||||||
if (retVal instanceof IResource) {
|
if (retVal instanceof IResource) {
|
||||||
IResource res = (IResource) retVal;
|
IResource res = (IResource) retVal;
|
||||||
retVal = populateResourceMetadataHapi(resourceType, theEntity, myTagList, theForHistoryOperation, res);
|
retVal = populateResourceMetadataHapi(resourceType, theEntity, myTagList, theForHistoryOperation, res);
|
||||||
|
@ -1712,7 +1834,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
retVal = populateResourceMetadataRi(resourceType, theEntity, myTagList, theForHistoryOperation, res);
|
retVal = populateResourceMetadataRi(resourceType, theEntity, myTagList, theForHistoryOperation, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
|
|
||||||
StopWatch w = new StopWatch();
|
StopWatch w = new StopWatch();
|
||||||
|
|
||||||
T resourceToDelete = toResource(myResourceType, entity, null, null, false);
|
T resourceToDelete = toResource(myResourceType, entity, null, false);
|
||||||
|
|
||||||
// Notify IServerOperationInterceptors about pre-action call
|
// Notify IServerOperationInterceptors about pre-action call
|
||||||
if (theReques != null) {
|
if (theReques != null) {
|
||||||
|
@ -289,7 +289,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
ResourceTable entity = myEntityManager.find(ResourceTable.class, pid);
|
ResourceTable entity = myEntityManager.find(ResourceTable.class, pid);
|
||||||
deletedResources.add(entity);
|
deletedResources.add(entity);
|
||||||
|
|
||||||
T resourceToDelete = toResource(myResourceType, entity, null, null, false);
|
T resourceToDelete = toResource(myResourceType, entity, null, false);
|
||||||
|
|
||||||
// Notify IServerOperationInterceptors about pre-action call
|
// Notify IServerOperationInterceptors about pre-action call
|
||||||
if (theRequest != null) {
|
if (theRequest != null) {
|
||||||
|
@ -854,7 +854,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
BaseHasResource entity = readEntity(theId);
|
BaseHasResource entity = readEntity(theId);
|
||||||
validateResourceType(entity);
|
validateResourceType(entity);
|
||||||
|
|
||||||
T retVal = toResource(myResourceType, entity, null, null, false);
|
T retVal = toResource(myResourceType, entity, null, false);
|
||||||
|
|
||||||
IPrimitiveType<Date> deleted;
|
IPrimitiveType<Date> deleted;
|
||||||
if (retVal instanceof IResource) {
|
if (retVal instanceof IResource) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||||
import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
|
import ca.uhn.fhir.jpa.entity.IBaseResourceEntity;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTag;
|
import ca.uhn.fhir.jpa.entity.ResourceTag;
|
||||||
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
|
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
|
||||||
|
@ -59,6 +59,6 @@ public interface IDao {
|
||||||
|
|
||||||
IBaseResource toResource(BaseHasResource theEntity, boolean theForHistoryOperation);
|
IBaseResource toResource(BaseHasResource theEntity, boolean theForHistoryOperation);
|
||||||
|
|
||||||
<R extends IBaseResource> R toResource(Class<R> theResourceType, BaseHasResource theEntity, ResourceHistoryTable theHistory, Collection<ResourceTag> theTagList, boolean theForHistoryOperation);
|
<R extends IBaseResource> R toResource(Class<R> theResourceType, IBaseResourceEntity theEntity, Collection<ResourceTag> theTagList, boolean theForHistoryOperation);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,7 @@ import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamUriDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamUriDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceTagDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceTagDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IResourceSearchViewDao;
|
||||||
import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
||||||
import ca.uhn.fhir.jpa.entity.BaseResourceIndexedSearchParam;
|
import ca.uhn.fhir.jpa.entity.BaseResourceIndexedSearchParam;
|
||||||
import ca.uhn.fhir.jpa.entity.ForcedId;
|
import ca.uhn.fhir.jpa.entity.ForcedId;
|
||||||
|
@ -98,6 +99,7 @@ import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamUri;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceLink;
|
import ca.uhn.fhir.jpa.entity.ResourceLink;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTag;
|
import ca.uhn.fhir.jpa.entity.ResourceTag;
|
||||||
|
import ca.uhn.fhir.jpa.entity.ResourceSearchView;
|
||||||
import ca.uhn.fhir.jpa.entity.SearchParam;
|
import ca.uhn.fhir.jpa.entity.SearchParam;
|
||||||
import ca.uhn.fhir.jpa.entity.SearchParamPresent;
|
import ca.uhn.fhir.jpa.entity.SearchParamPresent;
|
||||||
import ca.uhn.fhir.jpa.entity.TagDefinition;
|
import ca.uhn.fhir.jpa.entity.TagDefinition;
|
||||||
|
@ -174,8 +176,8 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
private IHapiTerminologySvc myTerminologySvc;
|
private IHapiTerminologySvc myTerminologySvc;
|
||||||
private int myFetchSize;
|
private int myFetchSize;
|
||||||
|
|
||||||
protected IResourceHistoryTableDao myResourceHistoryTableDao;
|
|
||||||
protected IResourceTagDao myResourceTagDao;
|
protected IResourceTagDao myResourceTagDao;
|
||||||
|
protected IResourceSearchViewDao myResourceSearchViewDao;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -184,7 +186,7 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
IFulltextSearchSvc theFulltextSearchSvc, BaseHapiFhirDao<?> theDao,
|
IFulltextSearchSvc theFulltextSearchSvc, BaseHapiFhirDao<?> theDao,
|
||||||
IResourceIndexedSearchParamUriDao theResourceIndexedSearchParamUriDao, IForcedIdDao theForcedIdDao,
|
IResourceIndexedSearchParamUriDao theResourceIndexedSearchParamUriDao, IForcedIdDao theForcedIdDao,
|
||||||
IHapiTerminologySvc theTerminologySvc, ISearchParamRegistry theSearchParamRegistry,
|
IHapiTerminologySvc theTerminologySvc, ISearchParamRegistry theSearchParamRegistry,
|
||||||
IResourceHistoryTableDao theResourceHistoryTableDao, IResourceTagDao theResourceTagDao) {
|
IResourceTagDao theResourceTagDao, IResourceSearchViewDao theResourceViewDao) {
|
||||||
myContext = theFhirContext;
|
myContext = theFhirContext;
|
||||||
myEntityManager = theEntityManager;
|
myEntityManager = theEntityManager;
|
||||||
myFulltextSearchSvc = theFulltextSearchSvc;
|
myFulltextSearchSvc = theFulltextSearchSvc;
|
||||||
|
@ -193,8 +195,8 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
myForcedIdDao = theForcedIdDao;
|
myForcedIdDao = theForcedIdDao;
|
||||||
myTerminologySvc = theTerminologySvc;
|
myTerminologySvc = theTerminologySvc;
|
||||||
mySearchParamRegistry = theSearchParamRegistry;
|
mySearchParamRegistry = theSearchParamRegistry;
|
||||||
myResourceHistoryTableDao = theResourceHistoryTableDao;
|
|
||||||
myResourceTagDao = theResourceTagDao;
|
myResourceTagDao = theResourceTagDao;
|
||||||
|
myResourceSearchViewDao = theResourceViewDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addPredicateComposite(String theResourceName, RuntimeSearchParam theParamDef, List<? extends IQueryParameterType> theNextAnd) {
|
private void addPredicateComposite(String theResourceName, RuntimeSearchParam theParamDef, List<? extends IQueryParameterType> theNextAnd) {
|
||||||
|
@ -1675,52 +1677,39 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
|
|
||||||
private void doLoadPids(List<IBaseResource> theResourceListToPopulate, Set<Long> theRevIncludedPids, boolean theForHistoryOperation, EntityManager entityManager, FhirContext context, IDao theDao,
|
private void doLoadPids(List<IBaseResource> theResourceListToPopulate, Set<Long> theRevIncludedPids, boolean theForHistoryOperation, EntityManager entityManager, FhirContext context, IDao theDao,
|
||||||
Map<Long, Integer> position, Collection<Long> pids) {
|
Map<Long, Integer> position, Collection<Long> pids) {
|
||||||
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
|
||||||
CriteriaQuery<ResourceTable> cq = builder.createQuery(ResourceTable.class);
|
|
||||||
Root<ResourceTable> from = cq.from(ResourceTable.class);
|
|
||||||
cq.where(from.get("myId").in(pids));
|
|
||||||
TypedQuery<ResourceTable> q = entityManager.createQuery(cq);
|
|
||||||
|
|
||||||
List<ResourceTable> resultList = q.getResultList();
|
// -- get the resource from the searchView
|
||||||
|
Collection<ResourceSearchView> resourceSearchViewList = myResourceSearchViewDao.findByResourceIds(pids);
|
||||||
//-- Issue #963: Load resource histories based on pids once to improve the performance
|
|
||||||
Map<Long, ResourceHistoryTable> historyMap = getResourceHistoryMap(pids);
|
|
||||||
|
|
||||||
//-- preload all tags with tag definition if any
|
//-- preload all tags with tag definition if any
|
||||||
Map<Long, Collection<ResourceTag>> tagMap = getResourceTagMap(resultList);
|
Map<Long, Collection<ResourceTag>> tagMap = getResourceTagMap(resourceSearchViewList);
|
||||||
|
|
||||||
//-- pre-load all forcedId
|
|
||||||
Map<Long, ForcedId> forcedIdMap = getForcedIdMap(pids);
|
|
||||||
|
|
||||||
ForcedId forcedId = null;
|
|
||||||
Long resourceId = null;
|
Long resourceId = null;
|
||||||
for (ResourceTable next : resultList) {
|
for (ResourceSearchView next : resourceSearchViewList) {
|
||||||
|
|
||||||
Class<? extends IBaseResource> resourceType = context.getResourceDefinition(next.getResourceType()).getImplementingClass();
|
Class<? extends IBaseResource> resourceType = context.getResourceDefinition(next.getResourceType()).getImplementingClass();
|
||||||
|
|
||||||
resourceId = next.getId();
|
resourceId = next.getId();
|
||||||
forcedId = forcedIdMap.get(resourceId);
|
|
||||||
if (forcedId != null)
|
|
||||||
next.setForcedId(forcedId);
|
|
||||||
|
|
||||||
IBaseResource resource = theDao.toResource(resourceType, next, historyMap.get(next.getId()), tagMap.get(next.getId()), theForHistoryOperation);
|
IBaseResource resource = theDao.toResource(resourceType, next, tagMap.get(resourceId), theForHistoryOperation);
|
||||||
if (resource == null) {
|
if (resource == null) {
|
||||||
ourLog.warn("Unable to find resource {}/{}/_history/{} in database", next.getResourceType(), next.getIdDt().getIdPart(), next.getVersion());
|
ourLog.warn("Unable to find resource {}/{}/_history/{} in database", next.getResourceType(), next.getIdDt().getIdPart(), next.getVersion());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Integer index = position.get(next.getId());
|
Integer index = position.get(resourceId);
|
||||||
if (index == null) {
|
if (index == null) {
|
||||||
ourLog.warn("Got back unexpected resource PID {}", next.getId());
|
ourLog.warn("Got back unexpected resource PID {}", resourceId);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resource instanceof IResource) {
|
if (resource instanceof IResource) {
|
||||||
if (theRevIncludedPids.contains(next.getId())) {
|
if (theRevIncludedPids.contains(resourceId)) {
|
||||||
ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put((IResource) resource, BundleEntrySearchModeEnum.INCLUDE);
|
ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put((IResource) resource, BundleEntrySearchModeEnum.INCLUDE);
|
||||||
} else {
|
} else {
|
||||||
ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put((IResource) resource, BundleEntrySearchModeEnum.MATCH);
|
ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put((IResource) resource, BundleEntrySearchModeEnum.MATCH);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (theRevIncludedPids.contains(next.getId())) {
|
if (theRevIncludedPids.contains(resourceId)) {
|
||||||
ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put((IAnyResource) resource, BundleEntrySearchModeEnum.INCLUDE.getCode());
|
ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put((IAnyResource) resource, BundleEntrySearchModeEnum.INCLUDE.getCode());
|
||||||
} else {
|
} else {
|
||||||
ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put((IAnyResource) resource, BundleEntrySearchModeEnum.MATCH.getCode());
|
ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put((IAnyResource) resource, BundleEntrySearchModeEnum.MATCH.getCode());
|
||||||
|
@ -1731,30 +1720,12 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-- load all history in to the map
|
private Map<Long, Collection<ResourceTag>> getResourceTagMap(Collection<ResourceSearchView> theResourceSearchViewList) {
|
||||||
private Map<Long, ResourceHistoryTable> getResourceHistoryMap(Collection<Long> pids) {
|
|
||||||
|
|
||||||
Map<Long, ResourceHistoryTable> historyMap = new HashMap<Long, ResourceHistoryTable>();
|
List<Long> idList = new ArrayList<Long>(theResourceSearchViewList.size());
|
||||||
|
|
||||||
if (pids.size() == 0)
|
|
||||||
return historyMap;
|
|
||||||
|
|
||||||
Collection<ResourceHistoryTable> historyList = myResourceHistoryTableDao.findByResourceIds(pids);
|
|
||||||
|
|
||||||
for (ResourceHistoryTable history : historyList) {
|
|
||||||
|
|
||||||
historyMap.put(history.getResourceId(), history);
|
|
||||||
}
|
|
||||||
|
|
||||||
return historyMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<Long, Collection<ResourceTag>> getResourceTagMap(List<ResourceTable> resourceList) {
|
|
||||||
|
|
||||||
List<Long> idList = new ArrayList<Long>(resourceList.size());
|
|
||||||
|
|
||||||
//-- find all resource has tags
|
//-- find all resource has tags
|
||||||
for (ResourceTable resource: resourceList) {
|
for (ResourceSearchView resource: theResourceSearchViewList) {
|
||||||
if (resource.isHasTags())
|
if (resource.isHasTags())
|
||||||
idList.add(resource.getId());
|
idList.add(resource.getId());
|
||||||
}
|
}
|
||||||
|
@ -1787,23 +1758,6 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
return tagMap;
|
return tagMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-- load all forcedId in to the map
|
|
||||||
private Map<Long, ForcedId> getForcedIdMap(Collection<Long> pids) {
|
|
||||||
|
|
||||||
Map<Long, ForcedId> forceIdMap = new HashMap<Long, ForcedId>();
|
|
||||||
|
|
||||||
if (pids.size() == 0)
|
|
||||||
return forceIdMap;
|
|
||||||
|
|
||||||
Collection<ForcedId> forceIdList = myForcedIdDao.findByResourcePids(pids);
|
|
||||||
|
|
||||||
for (ForcedId forcedId : forceIdList) {
|
|
||||||
|
|
||||||
forceIdMap.put(forcedId.getResourcePid(), forcedId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return forceIdMap;
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public void loadResourcesByPid(Collection<Long> theIncludePids, List<IBaseResource> theResourceListToPopulate, Set<Long> theRevIncludedPids, boolean theForHistoryOperation,
|
public void loadResourcesByPid(Collection<Long> theIncludePids, List<IBaseResource> theResourceListToPopulate, Set<Long> theRevIncludedPids, boolean theForHistoryOperation,
|
||||||
EntityManager entityManager, FhirContext context, IDao theDao) {
|
EntityManager entityManager, FhirContext context, IDao theDao) {
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package ca.uhn.fhir.jpa.dao.data;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR JPA Server
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2018 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.entity.ResourceSearchView;
|
||||||
|
|
||||||
|
public interface IResourceSearchViewDao extends JpaRepository<ResourceSearchView, Long> {
|
||||||
|
|
||||||
|
@Query("SELECT v FROM ResourceSearchView v WHERE v.myResourceId in (:pids)")
|
||||||
|
Collection<ResourceSearchView> findByResourceIds(@Param("pids") Collection<Long> pids);
|
||||||
|
}
|
|
@ -30,7 +30,7 @@ import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
public abstract class BaseHasResource {
|
public abstract class BaseHasResource implements IBaseResourceEntity {
|
||||||
|
|
||||||
@Column(name = "RES_DELETED_AT", nullable = true)
|
@Column(name = "RES_DELETED_AT", nullable = true)
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package ca.uhn.fhir.jpa.entity;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR JPA Server
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2018 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
|
|
||||||
|
public interface IBaseResourceEntity {
|
||||||
|
|
||||||
|
Date getDeleted();
|
||||||
|
FhirVersionEnum getFhirVersion();
|
||||||
|
Long getId();
|
||||||
|
IdDt getIdDt();
|
||||||
|
InstantDt getPublished();
|
||||||
|
Long getResourceId();
|
||||||
|
String getResourceType();
|
||||||
|
InstantDt getUpdated();
|
||||||
|
Date getUpdatedDate();
|
||||||
|
long getVersion();
|
||||||
|
boolean isHasTags();
|
||||||
|
}
|
|
@ -0,0 +1,200 @@
|
||||||
|
package ca.uhn.fhir.jpa.entity;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR JPA Server
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2018 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EnumType;
|
||||||
|
import javax.persistence.Enumerated;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Lob;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.Immutable;
|
||||||
|
import org.hibernate.annotations.Subselect;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
|
||||||
|
//@formatter:off
|
||||||
|
@Entity
|
||||||
|
@Immutable
|
||||||
|
@Subselect("SELECT h.pid as pid " +
|
||||||
|
", h.res_id as res_id " +
|
||||||
|
", h.res_type as res_type " +
|
||||||
|
", h.res_version as res_version " + // FHIR version
|
||||||
|
", h.res_ver as res_ver " + // resource version
|
||||||
|
", h.has_tags as has_tags " +
|
||||||
|
", h.res_deleted_at as res_deleted_at " +
|
||||||
|
", h.res_published as res_published " +
|
||||||
|
", h.res_updated as res_updated " +
|
||||||
|
", h.res_text as res_text " +
|
||||||
|
", h.res_encoding as res_encoding " +
|
||||||
|
", f.forced_id as forced_pid " +
|
||||||
|
"FROM HFJ_RES_VER h "
|
||||||
|
+ " LEFT OUTER JOIN HFJ_FORCED_ID f ON f.resource_pid = h.res_id "
|
||||||
|
+ " INNER JOIN HFJ_RESOURCE r ON r.res_id = h.res_id and r.res_ver = h.res_ver")
|
||||||
|
// @formatter:on
|
||||||
|
public class ResourceSearchView implements IBaseResourceEntity, Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name = "PID")
|
||||||
|
private Long myId;
|
||||||
|
|
||||||
|
@Column(name = "RES_ID")
|
||||||
|
private Long myResourceId;
|
||||||
|
|
||||||
|
@Column(name = "RES_TYPE")
|
||||||
|
private String myResourceType;
|
||||||
|
|
||||||
|
@Column(name = "RES_VERSION")
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
private FhirVersionEnum myFhirVersion;
|
||||||
|
|
||||||
|
@Column(name = "RES_VER")
|
||||||
|
private Long myResourceVersion;
|
||||||
|
|
||||||
|
@Column(name = "HAS_TAGS")
|
||||||
|
private boolean myHasTags;
|
||||||
|
|
||||||
|
@Column(name = "RES_DELETED_AT")
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
private Date myDeleted;
|
||||||
|
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
@Column(name = "RES_PUBLISHED")
|
||||||
|
private Date myPublished;
|
||||||
|
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
@Column(name = "RES_UPDATED")
|
||||||
|
private Date myUpdated;
|
||||||
|
|
||||||
|
@Column(name = "RES_TEXT")
|
||||||
|
@Lob()
|
||||||
|
private byte[] myResource;
|
||||||
|
|
||||||
|
@Column(name = "RES_ENCODING")
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
private ResourceEncodingEnum myEncoding;
|
||||||
|
|
||||||
|
@Column(name = "forced_pid")
|
||||||
|
private String myForcedPid;
|
||||||
|
|
||||||
|
public ResourceSearchView() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getDeleted() {
|
||||||
|
return myDeleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeleted(Date theDate) {
|
||||||
|
myDeleted = theDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FhirVersionEnum getFhirVersion() {
|
||||||
|
return myFhirVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFhirVersion(FhirVersionEnum theFhirVersion) {
|
||||||
|
myFhirVersion = theFhirVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getForcedId() {
|
||||||
|
return myForcedPid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getId() {
|
||||||
|
return myResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IdDt getIdDt() {
|
||||||
|
if (myForcedPid == null) {
|
||||||
|
Long id = myResourceId;
|
||||||
|
return new IdDt(myResourceType + '/' + id + '/' + Constants.PARAM_HISTORY + '/' + getVersion());
|
||||||
|
} else {
|
||||||
|
return new IdDt(
|
||||||
|
getResourceType() + '/' + getForcedId() + '/' + Constants.PARAM_HISTORY + '/' + getVersion());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InstantDt getPublished() {
|
||||||
|
if (myPublished != null) {
|
||||||
|
return new InstantDt(myPublished);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublished(Date thePublished) {
|
||||||
|
myPublished = thePublished;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getResourceId() {
|
||||||
|
return myResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getResourceType() {
|
||||||
|
return myResourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InstantDt getUpdated() {
|
||||||
|
return new InstantDt(myUpdated);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getUpdatedDate() {
|
||||||
|
return myUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getVersion() {
|
||||||
|
return myResourceVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isHasTags() {
|
||||||
|
return myHasTags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getResource() {
|
||||||
|
return myResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceEncodingEnum getEncoding() {
|
||||||
|
return myEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue