To provide the target resource partitionId and partitionDate in the resourceLinlk (#6149)
* initial POC. * addressing comments from first code review * Adding tests * adding changelog and spotless * fixing tests * spotless --------- Co-authored-by: peartree <etienne.poirier@smilecdr.com>
This commit is contained in:
parent
d32433e68b
commit
8384325d78
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
type: add
|
||||
issue: 6148
|
||||
jira: SMILE-8613
|
||||
title: "Added the target resource partitionId and partitionDate to the resourceLink table."
|
|
@ -135,7 +135,8 @@ public interface IResourceTableDao
|
|||
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
||||
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.
|
||||
*/
|
||||
@Query("SELECT t.myResourceType, t.myId, t.myDeleted FROM ResourceTable t WHERE t.myId IN (:pid)")
|
||||
@Query(
|
||||
"SELECT t.myResourceType, t.myId, t.myDeleted, t.myPartitionIdValue, t.myPartitionDateValue FROM ResourceTable t WHERE t.myId IN (:pid)")
|
||||
Collection<Object[]> findLookupFieldsByResourcePid(@Param("pid") List<Long> thePids);
|
||||
|
||||
/**
|
||||
|
@ -143,7 +144,7 @@ public interface IResourceTableDao
|
|||
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.
|
||||
*/
|
||||
@Query(
|
||||
"SELECT t.myResourceType, t.myId, t.myDeleted FROM ResourceTable t WHERE t.myId IN (:pid) AND t.myPartitionIdValue IN :partition_id")
|
||||
"SELECT t.myResourceType, t.myId, t.myDeleted, t.myPartitionIdValue, t.myPartitionDateValue FROM ResourceTable t WHERE t.myId IN (:pid) AND t.myPartitionIdValue IN :partition_id")
|
||||
Collection<Object[]> findLookupFieldsByResourcePidInPartitionIds(
|
||||
@Param("pid") List<Long> thePids, @Param("partition_id") Collection<Integer> thePartitionId);
|
||||
|
||||
|
@ -152,7 +153,7 @@ public interface IResourceTableDao
|
|||
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.
|
||||
*/
|
||||
@Query(
|
||||
"SELECT t.myResourceType, t.myId, t.myDeleted FROM ResourceTable t WHERE t.myId IN (:pid) AND (t.myPartitionIdValue IS NULL OR t.myPartitionIdValue IN :partition_id)")
|
||||
"SELECT t.myResourceType, t.myId, t.myDeleted, t.myPartitionIdValue, t.myPartitionDateValue FROM ResourceTable t WHERE t.myId IN (:pid) AND (t.myPartitionIdValue IS NULL OR t.myPartitionIdValue IN :partition_id)")
|
||||
Collection<Object[]> findLookupFieldsByResourcePidInPartitionIdsOrNullPartition(
|
||||
@Param("pid") List<Long> thePids, @Param("partition_id") Collection<Integer> thePartitionId);
|
||||
|
||||
|
@ -161,7 +162,7 @@ public interface IResourceTableDao
|
|||
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.
|
||||
*/
|
||||
@Query(
|
||||
"SELECT t.myResourceType, t.myId, t.myDeleted FROM ResourceTable t WHERE t.myId IN (:pid) AND t.myPartitionIdValue IS NULL")
|
||||
"SELECT t.myResourceType, t.myId, t.myDeleted, t.myPartitionIdValue, t.myPartitionDateValue FROM ResourceTable t WHERE t.myId IN (:pid) AND t.myPartitionIdValue IS NULL")
|
||||
Collection<Object[]> findLookupFieldsByResourcePidInPartitionNull(@Param("pid") List<Long> thePids);
|
||||
|
||||
@Query("SELECT t.myVersion FROM ResourceTable t WHERE t.myId = :pid")
|
||||
|
|
|
@ -56,9 +56,10 @@ public class IResourceTableDaoImpl implements IForcedIdQueries {
|
|||
@Override
|
||||
public Collection<Object[]> findAndResolveByForcedIdWithNoType(
|
||||
String theResourceType, Collection<String> theForcedIds, boolean theExcludeDeleted) {
|
||||
String query = "SELECT t.myResourceType, t.myId, t.myFhirId, t.myDeleted "
|
||||
+ "FROM ResourceTable t "
|
||||
+ "WHERE t.myResourceType = :resource_type AND t.myFhirId IN ( :forced_id )";
|
||||
String query =
|
||||
"SELECT t.myResourceType, t.myId, t.myFhirId, t.myDeleted, t.myPartitionIdValue, t.myPartitionDateValue "
|
||||
+ "FROM ResourceTable t "
|
||||
+ "WHERE t.myResourceType = :resource_type AND t.myFhirId IN ( :forced_id )";
|
||||
|
||||
if (theExcludeDeleted) {
|
||||
query += " AND t.myDeleted IS NULL";
|
||||
|
@ -82,9 +83,10 @@ public class IResourceTableDaoImpl implements IForcedIdQueries {
|
|||
Collection<String> theForcedIds,
|
||||
Collection<Integer> thePartitionId,
|
||||
boolean theExcludeDeleted) {
|
||||
String query = "SELECT t.myResourceType, t.myId, t.myFhirId, t.myDeleted "
|
||||
+ "FROM ResourceTable t "
|
||||
+ "WHERE t.myResourceType = :resource_type AND t.myFhirId IN ( :forced_id ) AND t.myPartitionIdValue IN ( :partition_id )";
|
||||
String query =
|
||||
"SELECT t.myResourceType, t.myId, t.myFhirId, t.myDeleted, t.myPartitionIdValue, t.myPartitionDateValue "
|
||||
+ "FROM ResourceTable t "
|
||||
+ "WHERE t.myResourceType = :resource_type AND t.myFhirId IN ( :forced_id ) AND t.myPartitionIdValue IN ( :partition_id )";
|
||||
|
||||
if (theExcludeDeleted) {
|
||||
query += " AND t.myDeleted IS NULL";
|
||||
|
@ -106,9 +108,11 @@ public class IResourceTableDaoImpl implements IForcedIdQueries {
|
|||
@Override
|
||||
public Collection<Object[]> findAndResolveByForcedIdWithNoTypeInPartitionNull(
|
||||
String theResourceType, Collection<String> theForcedIds, boolean theExcludeDeleted) {
|
||||
String query = "SELECT t.myResourceType, t.myId, t.myFhirId, t.myDeleted "
|
||||
+ "FROM ResourceTable t "
|
||||
+ "WHERE t.myResourceType = :resource_type AND t.myFhirId IN ( :forced_id ) AND t.myPartitionIdValue IS NULL";
|
||||
// we fetch myPartitionIdValue and myPartitionDateValue for resultSet processing consistency
|
||||
String query =
|
||||
"SELECT t.myResourceType, t.myId, t.myFhirId, t.myDeleted, t.myPartitionIdValue, t.myPartitionDateValue "
|
||||
+ "FROM ResourceTable t "
|
||||
+ "WHERE t.myResourceType = :resource_type AND t.myFhirId IN ( :forced_id ) AND t.myPartitionIdValue IS NULL";
|
||||
|
||||
if (theExcludeDeleted) {
|
||||
query += " AND t.myDeleted IS NULL";
|
||||
|
@ -132,9 +136,10 @@ public class IResourceTableDaoImpl implements IForcedIdQueries {
|
|||
Collection<String> theForcedIds,
|
||||
List<Integer> thePartitionIdsWithoutDefault,
|
||||
boolean theExcludeDeleted) {
|
||||
String query = "SELECT t.myResourceType, t.myId, t.myFhirId, t.myDeleted "
|
||||
+ "FROM ResourceTable t "
|
||||
+ "WHERE t.myResourceType = :resource_type AND t.myFhirId IN ( :forced_id ) AND (t.myPartitionIdValue IS NULL OR t.myPartitionIdValue IN ( :partition_id ))";
|
||||
String query =
|
||||
"SELECT t.myResourceType, t.myId, t.myFhirId, t.myDeleted, t.myPartitionIdValue, t.myPartitionDateValue "
|
||||
+ "FROM ResourceTable t "
|
||||
+ "WHERE t.myResourceType = :resource_type AND t.myFhirId IN ( :forced_id ) AND (t.myPartitionIdValue IS NULL OR t.myPartitionIdValue IN ( :partition_id ))";
|
||||
|
||||
if (theExcludeDeleted) {
|
||||
query += " AND t.myDeleted IS NULL";
|
||||
|
|
|
@ -30,6 +30,7 @@ import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
|||
import ca.uhn.fhir.jpa.model.cross.IResourceLookup;
|
||||
import ca.uhn.fhir.jpa.model.cross.JpaResourceLookup;
|
||||
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
||||
import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.search.builder.SearchBuilder;
|
||||
import ca.uhn.fhir.jpa.util.MemoryCacheService;
|
||||
|
@ -59,12 +60,11 @@ import org.hl7.fhir.instance.model.api.IAnyResource;
|
|||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.r4.model.IdType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -100,7 +100,6 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|||
*/
|
||||
@Service
|
||||
public class IdHelperService implements IIdHelperService<JpaPid> {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(IdHelperService.class);
|
||||
public static final Predicate[] EMPTY_PREDICATE_ARRAY = new Predicate[0];
|
||||
public static final String RESOURCE_PID = "RESOURCE_PID";
|
||||
|
||||
|
@ -523,7 +522,7 @@ public class IdHelperService implements IIdHelperService<JpaPid> {
|
|||
if (myStorageSettings.getResourceClientIdStrategy() != JpaStorageSettings.ClientIdStrategyEnum.ANY) {
|
||||
List<Long> pids = theId.stream()
|
||||
.filter(t -> isValidPid(t))
|
||||
.map(t -> t.getIdPartAsLong())
|
||||
.map(IIdType::getIdPartAsLong)
|
||||
.collect(Collectors.toList());
|
||||
if (!pids.isEmpty()) {
|
||||
resolvePids(requestPartitionId, pids, retVal);
|
||||
|
@ -578,8 +577,14 @@ public class IdHelperService implements IIdHelperService<JpaPid> {
|
|||
Long resourcePid = (Long) next[1];
|
||||
String forcedId = (String) next[2];
|
||||
Date deletedAt = (Date) next[3];
|
||||
Integer partitionId = (Integer) next[4];
|
||||
LocalDate partitionDate = (LocalDate) next[5];
|
||||
|
||||
JpaResourceLookup lookup = new JpaResourceLookup(resourceType, resourcePid, deletedAt);
|
||||
JpaResourceLookup lookup = new JpaResourceLookup(
|
||||
resourceType,
|
||||
resourcePid,
|
||||
deletedAt,
|
||||
PartitionablePartitionId.with(partitionId, partitionDate));
|
||||
retVal.computeIfAbsent(forcedId, id -> new ArrayList<>()).add(lookup);
|
||||
|
||||
if (!myStorageSettings.isDeleteEnabled()) {
|
||||
|
@ -638,7 +643,11 @@ public class IdHelperService implements IIdHelperService<JpaPid> {
|
|||
}
|
||||
}
|
||||
lookup.stream()
|
||||
.map(t -> new JpaResourceLookup((String) t[0], (Long) t[1], (Date) t[2]))
|
||||
.map(t -> new JpaResourceLookup(
|
||||
(String) t[0],
|
||||
(Long) t[1],
|
||||
(Date) t[2],
|
||||
PartitionablePartitionId.with((Integer) t[3], (LocalDate) t[4])))
|
||||
.forEach(t -> {
|
||||
String id = t.getPersistentId().toString();
|
||||
if (!theTargets.containsKey(id)) {
|
||||
|
@ -683,9 +692,8 @@ public class IdHelperService implements IIdHelperService<JpaPid> {
|
|||
MemoryCacheService.CacheEnum.PID_TO_FORCED_ID, nextResourcePid, Optional.empty());
|
||||
}
|
||||
Map<JpaPid, Optional<String>> convertRetVal = new HashMap<>();
|
||||
retVal.forEach((k, v) -> {
|
||||
convertRetVal.put(JpaPid.fromId(k), v);
|
||||
});
|
||||
retVal.forEach((k, v) -> convertRetVal.put(JpaPid.fromId(k), v));
|
||||
|
||||
return new PersistentIdToForcedIdMap<>(convertRetVal);
|
||||
}
|
||||
|
||||
|
@ -716,7 +724,8 @@ public class IdHelperService implements IIdHelperService<JpaPid> {
|
|||
}
|
||||
|
||||
if (!myStorageSettings.isDeleteEnabled()) {
|
||||
JpaResourceLookup lookup = new JpaResourceLookup(theResourceType, theJpaPid.getId(), theDeletedAt);
|
||||
JpaResourceLookup lookup = new JpaResourceLookup(
|
||||
theResourceType, theJpaPid.getId(), theDeletedAt, theJpaPid.getPartitionablePartitionId());
|
||||
String nextKey = theJpaPid.toString();
|
||||
myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.RESOURCE_LOOKUP, nextKey, lookup);
|
||||
}
|
||||
|
@ -744,8 +753,7 @@ public class IdHelperService implements IIdHelperService<JpaPid> {
|
|||
@Nonnull
|
||||
public List<JpaPid> getPidsOrThrowException(
|
||||
@Nonnull RequestPartitionId theRequestPartitionId, List<IIdType> theIds) {
|
||||
List<JpaPid> resourcePersistentIds = resolveResourcePersistentIdsWithCache(theRequestPartitionId, theIds);
|
||||
return resourcePersistentIds;
|
||||
return resolveResourcePersistentIdsWithCache(theRequestPartitionId, theIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -471,10 +471,26 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
|
|||
}
|
||||
}
|
||||
|
||||
version.onTable(Search.HFJ_SEARCH)
|
||||
.modifyColumn("20240722.1", Search.SEARCH_UUID)
|
||||
.nonNullable()
|
||||
.withType(ColumnTypeEnum.STRING, 48);
|
||||
{
|
||||
// Add target resource partition id/date columns to resource link
|
||||
Builder.BuilderWithTableName resourceLinkTable = version.onTable("HFJ_RES_LINK");
|
||||
|
||||
resourceLinkTable
|
||||
.addColumn("20240718.10", "TARGET_RES_PARTITION_ID")
|
||||
.nullable()
|
||||
.type(ColumnTypeEnum.INT);
|
||||
resourceLinkTable
|
||||
.addColumn("20240718.20", "TARGET_RES_PARTITION_DATE")
|
||||
.nullable()
|
||||
.type(ColumnTypeEnum.DATE_ONLY);
|
||||
}
|
||||
|
||||
{
|
||||
version.onTable(Search.HFJ_SEARCH)
|
||||
.modifyColumn("20240722.1", Search.SEARCH_UUID)
|
||||
.nonNullable()
|
||||
.withType(ColumnTypeEnum.STRING, 48);
|
||||
}
|
||||
|
||||
{
|
||||
final Builder.BuilderWithTableName hfjResource = version.onTable("HFJ_RESOURCE");
|
||||
|
|
|
@ -20,18 +20,26 @@
|
|||
package ca.uhn.fhir.jpa.model.cross;
|
||||
|
||||
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
||||
import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class JpaResourceLookup implements IResourceLookup<JpaPid> {
|
||||
|
||||
private final String myResourceType;
|
||||
private final Long myResourcePid;
|
||||
private final Date myDeletedAt;
|
||||
private final PartitionablePartitionId myPartitionablePartitionId;
|
||||
|
||||
public JpaResourceLookup(String theResourceType, Long theResourcePid, Date theDeletedAt) {
|
||||
public JpaResourceLookup(
|
||||
String theResourceType,
|
||||
Long theResourcePid,
|
||||
Date theDeletedAt,
|
||||
PartitionablePartitionId thePartitionablePartitionId) {
|
||||
myResourceType = theResourceType;
|
||||
myResourcePid = theResourcePid;
|
||||
myDeletedAt = theDeletedAt;
|
||||
myPartitionablePartitionId = thePartitionablePartitionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -46,6 +54,9 @@ public class JpaResourceLookup implements IResourceLookup<JpaPid> {
|
|||
|
||||
@Override
|
||||
public JpaPid getPersistentId() {
|
||||
return JpaPid.fromId(myResourcePid);
|
||||
JpaPid jpaPid = JpaPid.fromId(myResourcePid);
|
||||
jpaPid.setPartitionablePartitionId(myPartitionablePartitionId);
|
||||
|
||||
return jpaPid;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
package ca.uhn.fhir.jpa.model.dao;
|
||||
|
||||
import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId;
|
||||
import ca.uhn.fhir.rest.api.server.storage.BaseResourcePersistentId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -34,6 +35,7 @@ import java.util.Set;
|
|||
*/
|
||||
public class JpaPid extends BaseResourcePersistentId<Long> {
|
||||
private final Long myId;
|
||||
private PartitionablePartitionId myPartitionablePartitionId;
|
||||
|
||||
private JpaPid(Long theId) {
|
||||
super(null);
|
||||
|
@ -55,6 +57,15 @@ public class JpaPid extends BaseResourcePersistentId<Long> {
|
|||
myId = theId;
|
||||
}
|
||||
|
||||
public PartitionablePartitionId getPartitionablePartitionId() {
|
||||
return myPartitionablePartitionId;
|
||||
}
|
||||
|
||||
public JpaPid setPartitionablePartitionId(PartitionablePartitionId thePartitionablePartitionId) {
|
||||
myPartitionablePartitionId = thePartitionablePartitionId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static List<Long> toLongList(Collection<JpaPid> thePids) {
|
||||
List<Long> retVal = new ArrayList<>(thePids.size());
|
||||
for (JpaPid next : thePids) {
|
||||
|
|
|
@ -25,6 +25,7 @@ import jakarta.persistence.Embedded;
|
|||
import jakarta.persistence.MappedSuperclass;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* This is the base class for entities with partitioning that does NOT include Hibernate Envers logging.
|
||||
|
@ -44,6 +45,13 @@ public abstract class BasePartitionable implements Serializable {
|
|||
@Column(name = PartitionablePartitionId.PARTITION_ID, insertable = false, updatable = false, nullable = true)
|
||||
private Integer myPartitionIdValue;
|
||||
|
||||
/**
|
||||
* This is here to support queries only, do not set this field directly
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = PartitionablePartitionId.PARTITION_DATE, insertable = false, updatable = false, nullable = true)
|
||||
private LocalDate myPartitionDateValue;
|
||||
|
||||
@Nullable
|
||||
public PartitionablePartitionId getPartitionId() {
|
||||
return myPartitionId;
|
||||
|
@ -57,6 +65,7 @@ public abstract class BasePartitionable implements Serializable {
|
|||
public String toString() {
|
||||
return "BasePartitionable{" + "myPartitionId="
|
||||
+ myPartitionId + ", myPartitionIdValue="
|
||||
+ myPartitionIdValue + '}';
|
||||
+ myPartitionIdValue + ", myPartitionDateValue="
|
||||
+ myPartitionDateValue + '}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import java.time.LocalDate;
|
|||
public class PartitionablePartitionId implements Cloneable {
|
||||
|
||||
static final String PARTITION_ID = "PARTITION_ID";
|
||||
static final String PARTITION_DATE = "PARTITION_DATE";
|
||||
|
||||
@Column(name = PARTITION_ID, nullable = true, insertable = true, updatable = false)
|
||||
private Integer myPartitionId;
|
||||
|
@ -132,4 +133,9 @@ public class PartitionablePartitionId implements Cloneable {
|
|||
}
|
||||
return new PartitionablePartitionId(partitionId, theRequestPartitionId.getPartitionDate());
|
||||
}
|
||||
|
||||
public static PartitionablePartitionId with(
|
||||
@Nullable Integer thePartitionId, @Nullable LocalDate thePartitionDate) {
|
||||
return new PartitionablePartitionId(thePartitionId, thePartitionDate);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,9 @@
|
|||
*/
|
||||
package ca.uhn.fhir.jpa.model.entity;
|
||||
|
||||
import jakarta.annotation.Nullable;
|
||||
import jakarta.persistence.AttributeOverride;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Embedded;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.ForeignKey;
|
||||
|
@ -119,6 +120,11 @@ public class ResourceLink extends BaseResourceIndex {
|
|||
@Transient
|
||||
private transient String myTargetResourceId;
|
||||
|
||||
@Embedded
|
||||
@AttributeOverride(name = "myPartitionId", column = @Column(name = "TARGET_RES_PARTITION_ID"))
|
||||
@AttributeOverride(name = "myPartitionDate", column = @Column(name = "TARGET_RES_PARTITION_DATE"))
|
||||
private PartitionablePartitionId myTargetResourcePartitionId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
@ -188,6 +194,7 @@ public class ResourceLink extends BaseResourceIndex {
|
|||
myTargetResourceType = source.getTargetResourceType();
|
||||
myTargetResourceVersion = source.getTargetResourceVersion();
|
||||
myTargetResourceUrl = source.getTargetResourceUrl();
|
||||
myTargetResourcePartitionId = source.getTargetResourcePartitionId();
|
||||
}
|
||||
|
||||
public String getSourcePath() {
|
||||
|
@ -270,6 +277,15 @@ public class ResourceLink extends BaseResourceIndex {
|
|||
myId = theId;
|
||||
}
|
||||
|
||||
public PartitionablePartitionId getTargetResourcePartitionId() {
|
||||
return myTargetResourcePartitionId;
|
||||
}
|
||||
|
||||
public ResourceLink setTargetResourcePartitionId(PartitionablePartitionId theTargetResourcePartitionId) {
|
||||
myTargetResourcePartitionId = theTargetResourcePartitionId;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearHashes() {
|
||||
// nothing right now
|
||||
|
@ -363,23 +379,113 @@ public class ResourceLink extends BaseResourceIndex {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param theTargetResourceVersion This should only be populated if the reference actually had a version
|
||||
*/
|
||||
public static ResourceLink forLocalReference(
|
||||
String theSourcePath,
|
||||
ResourceTable theSourceResource,
|
||||
String theTargetResourceType,
|
||||
Long theTargetResourcePid,
|
||||
String theTargetResourceId,
|
||||
Date theUpdated,
|
||||
@Nullable Long theTargetResourceVersion) {
|
||||
ResourceLinkForLocalReferenceParams theResourceLinkForLocalReferenceParams) {
|
||||
|
||||
ResourceLink retVal = new ResourceLink();
|
||||
retVal.setSourcePath(theSourcePath);
|
||||
retVal.setSourceResource(theSourceResource);
|
||||
retVal.setTargetResource(theTargetResourceType, theTargetResourcePid, theTargetResourceId);
|
||||
retVal.setTargetResourceVersion(theTargetResourceVersion);
|
||||
retVal.setUpdated(theUpdated);
|
||||
retVal.setSourcePath(theResourceLinkForLocalReferenceParams.getSourcePath());
|
||||
retVal.setSourceResource(theResourceLinkForLocalReferenceParams.getSourceResource());
|
||||
retVal.setTargetResource(
|
||||
theResourceLinkForLocalReferenceParams.getTargetResourceType(),
|
||||
theResourceLinkForLocalReferenceParams.getTargetResourcePid(),
|
||||
theResourceLinkForLocalReferenceParams.getTargetResourceId());
|
||||
|
||||
retVal.setTargetResourcePartitionId(
|
||||
theResourceLinkForLocalReferenceParams.getTargetResourcePartitionablePartitionId());
|
||||
retVal.setTargetResourceVersion(theResourceLinkForLocalReferenceParams.getTargetResourceVersion());
|
||||
retVal.setUpdated(theResourceLinkForLocalReferenceParams.getUpdated());
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static class ResourceLinkForLocalReferenceParams {
|
||||
private String mySourcePath;
|
||||
private ResourceTable mySourceResource;
|
||||
private String myTargetResourceType;
|
||||
private Long myTargetResourcePid;
|
||||
private String myTargetResourceId;
|
||||
private Date myUpdated;
|
||||
private Long myTargetResourceVersion;
|
||||
private PartitionablePartitionId myTargetResourcePartitionablePartitionId;
|
||||
|
||||
public static ResourceLinkForLocalReferenceParams instance() {
|
||||
return new ResourceLinkForLocalReferenceParams();
|
||||
}
|
||||
|
||||
public String getSourcePath() {
|
||||
return mySourcePath;
|
||||
}
|
||||
|
||||
public ResourceLinkForLocalReferenceParams setSourcePath(String theSourcePath) {
|
||||
mySourcePath = theSourcePath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ResourceTable getSourceResource() {
|
||||
return mySourceResource;
|
||||
}
|
||||
|
||||
public ResourceLinkForLocalReferenceParams setSourceResource(ResourceTable theSourceResource) {
|
||||
mySourceResource = theSourceResource;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getTargetResourceType() {
|
||||
return myTargetResourceType;
|
||||
}
|
||||
|
||||
public ResourceLinkForLocalReferenceParams setTargetResourceType(String theTargetResourceType) {
|
||||
myTargetResourceType = theTargetResourceType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Long getTargetResourcePid() {
|
||||
return myTargetResourcePid;
|
||||
}
|
||||
|
||||
public ResourceLinkForLocalReferenceParams setTargetResourcePid(Long theTargetResourcePid) {
|
||||
myTargetResourcePid = theTargetResourcePid;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getTargetResourceId() {
|
||||
return myTargetResourceId;
|
||||
}
|
||||
|
||||
public ResourceLinkForLocalReferenceParams setTargetResourceId(String theTargetResourceId) {
|
||||
myTargetResourceId = theTargetResourceId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Date getUpdated() {
|
||||
return myUpdated;
|
||||
}
|
||||
|
||||
public ResourceLinkForLocalReferenceParams setUpdated(Date theUpdated) {
|
||||
myUpdated = theUpdated;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Long getTargetResourceVersion() {
|
||||
return myTargetResourceVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param theTargetResourceVersion This should only be populated if the reference actually had a version
|
||||
*/
|
||||
public ResourceLinkForLocalReferenceParams setTargetResourceVersion(Long theTargetResourceVersion) {
|
||||
myTargetResourceVersion = theTargetResourceVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PartitionablePartitionId getTargetResourcePartitionablePartitionId() {
|
||||
return myTargetResourcePartitionablePartitionId;
|
||||
}
|
||||
|
||||
public ResourceLinkForLocalReferenceParams setTargetResourcePartitionablePartitionId(
|
||||
PartitionablePartitionId theTargetResourcePartitionablePartitionId) {
|
||||
myTargetResourcePartitionablePartitionId = theTargetResourcePartitionablePartitionId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceIndexedComboStringUnique;
|
|||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedComboTokenNonUnique;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceLink;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceLink.ResourceLinkForLocalReferenceParams;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.model.entity.SearchParamPresentEntity;
|
||||
import ca.uhn.fhir.jpa.model.entity.StorageSettings;
|
||||
|
@ -71,6 +72,8 @@ import java.util.Optional;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static ca.uhn.fhir.jpa.model.config.PartitionSettings.CrossPartitionReferenceMode.ALLOWED_UNQUALIFIED;
|
||||
import static ca.uhn.fhir.jpa.model.entity.ResourceLink.forLocalReference;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
|
@ -105,26 +108,6 @@ public class SearchParamExtractorService {
|
|||
mySearchParamExtractor = theSearchParamExtractor;
|
||||
}
|
||||
|
||||
public void extractFromResource(
|
||||
RequestPartitionId theRequestPartitionId,
|
||||
RequestDetails theRequestDetails,
|
||||
ResourceIndexedSearchParams theParams,
|
||||
ResourceTable theEntity,
|
||||
IBaseResource theResource,
|
||||
TransactionDetails theTransactionDetails,
|
||||
boolean theFailOnInvalidReference) {
|
||||
extractFromResource(
|
||||
theRequestPartitionId,
|
||||
theRequestDetails,
|
||||
theParams,
|
||||
ResourceIndexedSearchParams.withSets(),
|
||||
theEntity,
|
||||
theResource,
|
||||
theTransactionDetails,
|
||||
theFailOnInvalidReference,
|
||||
ISearchParamExtractor.ALL_PARAMS);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is responsible for scanning a resource for all of the search parameter instances.
|
||||
* I.e. for all search parameters defined for
|
||||
|
@ -702,14 +685,18 @@ public class SearchParamExtractorService {
|
|||
* need to resolve it again
|
||||
*/
|
||||
myResourceLinkResolver.validateTypeOrThrowException(type);
|
||||
resourceLink = ResourceLink.forLocalReference(
|
||||
thePathAndRef.getPath(),
|
||||
theEntity,
|
||||
typeString,
|
||||
resolvedTargetId.getId(),
|
||||
targetId,
|
||||
transactionDate,
|
||||
targetVersionId);
|
||||
|
||||
ResourceLinkForLocalReferenceParams params = ResourceLinkForLocalReferenceParams.instance()
|
||||
.setSourcePath(thePathAndRef.getPath())
|
||||
.setSourceResource(theEntity)
|
||||
.setTargetResourceType(typeString)
|
||||
.setTargetResourcePid(resolvedTargetId.getId())
|
||||
.setTargetResourceId(targetId)
|
||||
.setUpdated(transactionDate)
|
||||
.setTargetResourceVersion(targetVersionId)
|
||||
.setTargetResourcePartitionablePartitionId(resolvedTargetId.getPartitionablePartitionId());
|
||||
|
||||
resourceLink = forLocalReference(params);
|
||||
|
||||
} else if (theFailOnInvalidReference) {
|
||||
|
||||
|
@ -748,6 +735,7 @@ public class SearchParamExtractorService {
|
|||
} else {
|
||||
// Cache the outcome in the current transaction in case there are more references
|
||||
JpaPid persistentId = JpaPid.fromId(resourceLink.getTargetResourcePid());
|
||||
persistentId.setPartitionablePartitionId(resourceLink.getTargetResourcePartitionId());
|
||||
theTransactionDetails.addResolvedResourceId(referenceElement, persistentId);
|
||||
}
|
||||
|
||||
|
@ -757,11 +745,15 @@ public class SearchParamExtractorService {
|
|||
* Just assume the reference is valid. This is used for in-memory matching since there
|
||||
* is no expectation of a database in this situation
|
||||
*/
|
||||
ResourceTable target;
|
||||
target = new ResourceTable();
|
||||
target.setResourceType(typeString);
|
||||
resourceLink = ResourceLink.forLocalReference(
|
||||
thePathAndRef.getPath(), theEntity, typeString, null, targetId, transactionDate, targetVersionId);
|
||||
ResourceLinkForLocalReferenceParams params = ResourceLinkForLocalReferenceParams.instance()
|
||||
.setSourcePath(thePathAndRef.getPath())
|
||||
.setSourceResource(theEntity)
|
||||
.setTargetResourceType(typeString)
|
||||
.setTargetResourceId(targetId)
|
||||
.setUpdated(transactionDate)
|
||||
.setTargetResourceVersion(targetVersionId);
|
||||
|
||||
resourceLink = forLocalReference(params);
|
||||
}
|
||||
|
||||
theNewParams.myLinks.add(resourceLink);
|
||||
|
@ -912,19 +904,24 @@ public class SearchParamExtractorService {
|
|||
RequestDetails theRequest,
|
||||
TransactionDetails theTransactionDetails) {
|
||||
JpaPid resolvedResourceId = (JpaPid) theTransactionDetails.getResolvedResourceId(theNextId);
|
||||
|
||||
if (resolvedResourceId != null) {
|
||||
String targetResourceType = theNextId.getResourceType();
|
||||
Long targetResourcePid = resolvedResourceId.getId();
|
||||
String targetResourceIdPart = theNextId.getIdPart();
|
||||
Long targetVersion = theNextId.getVersionIdPartAsLong();
|
||||
return ResourceLink.forLocalReference(
|
||||
thePathAndRef.getPath(),
|
||||
theEntity,
|
||||
targetResourceType,
|
||||
targetResourcePid,
|
||||
targetResourceIdPart,
|
||||
theUpdateTime,
|
||||
targetVersion);
|
||||
|
||||
ResourceLinkForLocalReferenceParams params = ResourceLinkForLocalReferenceParams.instance()
|
||||
.setSourcePath(thePathAndRef.getPath())
|
||||
.setSourceResource(theEntity)
|
||||
.setTargetResourceType(targetResourceType)
|
||||
.setTargetResourcePid(targetResourcePid)
|
||||
.setTargetResourceId(targetResourceIdPart)
|
||||
.setUpdated(theUpdateTime)
|
||||
.setTargetResourceVersion(targetVersion)
|
||||
.setTargetResourcePartitionablePartitionId(resolvedResourceId.getPartitionablePartitionId());
|
||||
|
||||
return ResourceLink.forLocalReference(params);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -936,8 +933,7 @@ public class SearchParamExtractorService {
|
|||
|
||||
IResourceLookup<JpaPid> targetResource;
|
||||
if (myPartitionSettings.isPartitioningEnabled()) {
|
||||
if (myPartitionSettings.getAllowReferencesAcrossPartitions()
|
||||
== PartitionSettings.CrossPartitionReferenceMode.ALLOWED_UNQUALIFIED) {
|
||||
if (myPartitionSettings.getAllowReferencesAcrossPartitions() == ALLOWED_UNQUALIFIED) {
|
||||
|
||||
// Interceptor: Pointcut.JPA_CROSS_PARTITION_REFERENCE_DETECTED
|
||||
if (CompositeInterceptorBroadcaster.hasHooks(
|
||||
|
@ -981,21 +977,25 @@ public class SearchParamExtractorService {
|
|||
Long targetResourcePid = targetResource.getPersistentId().getId();
|
||||
String targetResourceIdPart = theNextId.getIdPart();
|
||||
Long targetVersion = theNextId.getVersionIdPartAsLong();
|
||||
return ResourceLink.forLocalReference(
|
||||
thePathAndRef.getPath(),
|
||||
theEntity,
|
||||
targetResourceType,
|
||||
targetResourcePid,
|
||||
targetResourceIdPart,
|
||||
theUpdateTime,
|
||||
targetVersion);
|
||||
|
||||
ResourceLinkForLocalReferenceParams params = ResourceLinkForLocalReferenceParams.instance()
|
||||
.setSourcePath(thePathAndRef.getPath())
|
||||
.setSourceResource(theEntity)
|
||||
.setTargetResourceType(targetResourceType)
|
||||
.setTargetResourcePid(targetResourcePid)
|
||||
.setTargetResourceId(targetResourceIdPart)
|
||||
.setUpdated(theUpdateTime)
|
||||
.setTargetResourceVersion(targetVersion)
|
||||
.setTargetResourcePartitionablePartitionId(
|
||||
targetResource.getPersistentId().getPartitionablePartitionId());
|
||||
|
||||
return forLocalReference(params);
|
||||
}
|
||||
|
||||
private RequestPartitionId determineResolverPartitionId(@Nonnull RequestPartitionId theRequestPartitionId) {
|
||||
RequestPartitionId targetRequestPartitionId = theRequestPartitionId;
|
||||
if (myPartitionSettings.isPartitioningEnabled()
|
||||
&& myPartitionSettings.getAllowReferencesAcrossPartitions()
|
||||
== PartitionSettings.CrossPartitionReferenceMode.ALLOWED_UNQUALIFIED) {
|
||||
&& myPartitionSettings.getAllowReferencesAcrossPartitions() == ALLOWED_UNQUALIFIED) {
|
||||
targetRequestPartitionId = RequestPartitionId.allPartitions();
|
||||
}
|
||||
return targetRequestPartitionId;
|
||||
|
|
|
@ -37,7 +37,7 @@ public class ResourceIndexedSearchParamsTest {
|
|||
|
||||
@Test
|
||||
public void matchResourceLinksStringCompareToLong() {
|
||||
ResourceLink link = ResourceLink.forLocalReference("organization", mySource, "Organization", 123L, LONG_ID, new Date(), null);
|
||||
ResourceLink link = getResourceLinkForLocalReference(LONG_ID);
|
||||
myParams.getResourceLinks().add(link);
|
||||
|
||||
ReferenceParam referenceParam = getReferenceParam(STRING_ID);
|
||||
|
@ -47,7 +47,7 @@ public class ResourceIndexedSearchParamsTest {
|
|||
|
||||
@Test
|
||||
public void matchResourceLinksStringCompareToString() {
|
||||
ResourceLink link = ResourceLink.forLocalReference("organization", mySource, "Organization", 123L, STRING_ID, new Date(), null);
|
||||
ResourceLink link = getResourceLinkForLocalReference(STRING_ID);
|
||||
myParams.getResourceLinks().add(link);
|
||||
|
||||
ReferenceParam referenceParam = getReferenceParam(STRING_ID);
|
||||
|
@ -57,7 +57,7 @@ public class ResourceIndexedSearchParamsTest {
|
|||
|
||||
@Test
|
||||
public void matchResourceLinksLongCompareToString() {
|
||||
ResourceLink link = ResourceLink.forLocalReference("organization", mySource, "Organization", 123L, STRING_ID, new Date(), null);
|
||||
ResourceLink link = getResourceLinkForLocalReference(STRING_ID);
|
||||
myParams.getResourceLinks().add(link);
|
||||
|
||||
ReferenceParam referenceParam = getReferenceParam(LONG_ID);
|
||||
|
@ -67,7 +67,7 @@ public class ResourceIndexedSearchParamsTest {
|
|||
|
||||
@Test
|
||||
public void matchResourceLinksLongCompareToLong() {
|
||||
ResourceLink link = ResourceLink.forLocalReference("organization", mySource, "Organization", 123L, LONG_ID, new Date(), null);
|
||||
ResourceLink link = getResourceLinkForLocalReference(LONG_ID);
|
||||
myParams.getResourceLinks().add(link);
|
||||
|
||||
ReferenceParam referenceParam = getReferenceParam(LONG_ID);
|
||||
|
@ -75,6 +75,21 @@ public class ResourceIndexedSearchParamsTest {
|
|||
assertTrue(result);
|
||||
}
|
||||
|
||||
private ResourceLink getResourceLinkForLocalReference(String theTargetResourceId){
|
||||
|
||||
ResourceLink.ResourceLinkForLocalReferenceParams params = ResourceLink.ResourceLinkForLocalReferenceParams
|
||||
.instance()
|
||||
.setSourcePath("organization")
|
||||
.setSourceResource(mySource)
|
||||
.setTargetResourceType("Organization")
|
||||
.setTargetResourcePid(123L)
|
||||
.setTargetResourceId(theTargetResourceId)
|
||||
.setUpdated(new Date());
|
||||
|
||||
return ResourceLink.forLocalReference(params);
|
||||
|
||||
}
|
||||
|
||||
private ReferenceParam getReferenceParam(String theId) {
|
||||
ReferenceParam retVal = new ReferenceParam();
|
||||
retVal.setValue(theId);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package ca.uhn.fhir.jpa.dao.index;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
||||
|
@ -29,6 +27,8 @@ import java.util.function.Function;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
@ -87,13 +87,17 @@ public class IdHelperServiceTest {
|
|||
"Patient",
|
||||
123l,
|
||||
"RED",
|
||||
new Date()
|
||||
new Date(),
|
||||
null,
|
||||
null
|
||||
};
|
||||
Object[] blueView = new Object[] {
|
||||
"Patient",
|
||||
456l,
|
||||
"BLUE",
|
||||
new Date()
|
||||
new Date(),
|
||||
null,
|
||||
null
|
||||
};
|
||||
|
||||
// when
|
||||
|
@ -155,11 +159,13 @@ public class IdHelperServiceTest {
|
|||
String resourceType = "Patient";
|
||||
String resourceForcedId = "AAA";
|
||||
|
||||
Object[] forcedIdView = new Object[4];
|
||||
Object[] forcedIdView = new Object[6];
|
||||
forcedIdView[0] = resourceType;
|
||||
forcedIdView[1] = 1L;
|
||||
forcedIdView[2] = resourceForcedId;
|
||||
forcedIdView[3] = null;
|
||||
forcedIdView[4] = null;
|
||||
forcedIdView[5] = null;
|
||||
|
||||
Collection<Object[]> testForcedIdViews = new ArrayList<>();
|
||||
testForcedIdViews.add(forcedIdView);
|
||||
|
|
|
@ -90,13 +90,11 @@ import java.util.stream.Collectors;
|
|||
import static ca.uhn.fhir.util.TestUtil.sleepAtLeast;
|
||||
import static org.apache.commons.lang3.StringUtils.countMatches;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
|
@ -173,7 +171,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
|||
// Look up the referenced subject/patient
|
||||
String sql = selectQueries.get(0).getSql(true, false).toLowerCase();
|
||||
assertThat(sql).contains(" from hfj_resource ");
|
||||
assertEquals(0, StringUtils.countMatches(selectQueries.get(0).getSql(true, false).toLowerCase(), "partition"));
|
||||
assertEquals(2, StringUtils.countMatches(selectQueries.get(0).getSql(true, false).toLowerCase(), "partition"));
|
||||
|
||||
runInTransaction(() -> {
|
||||
List<ResourceLink> resLinks = myResourceLinkDao.findAll();
|
||||
|
@ -181,6 +179,8 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
|||
assertEquals(2, resLinks.size());
|
||||
assertEquals(obsId.getIdPartAsLong(), resLinks.get(0).getSourceResourcePid());
|
||||
assertEquals(patientId.getIdPartAsLong(), resLinks.get(0).getTargetResourcePid());
|
||||
assertEquals(myPartitionId, resLinks.get(0).getTargetResourcePartitionId().getPartitionId());
|
||||
assertLocalDateFromDbMatches(myPartitionDate, resLinks.get(0).getTargetResourcePartitionId().getPartitionDate());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -465,6 +465,8 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
|||
assertEquals(1, resourceLinks.size());
|
||||
assertEquals(myPartitionId, resourceLinks.get(0).getPartitionId().getPartitionId().intValue());
|
||||
assertLocalDateFromDbMatches(myPartitionDate, resourceLinks.get(0).getPartitionId().getPartitionDate());
|
||||
assertEquals(myPartitionId, resourceLinks.get(0).getTargetResourcePartitionId().getPartitionId().intValue());
|
||||
assertLocalDateFromDbMatches(myPartitionDate, resourceLinks.get(0).getTargetResourcePartitionId().getPartitionDate());
|
||||
|
||||
// HFJ_RES_PARAM_PRESENT
|
||||
List<SearchParamPresentEntity> presents = mySearchParamPresentDao.findAllForResource(resourceTable);
|
||||
|
@ -1375,7 +1377,8 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
|||
|
||||
// Only the read columns should be used, no criteria use partition
|
||||
assertThat(searchSql).as(searchSql).contains("PARTITION_ID IN ('1')");
|
||||
assertThat(StringUtils.countMatches(searchSql, "PARTITION_ID")).as(searchSql).isEqualTo(1);
|
||||
assertThat(StringUtils.countMatches(searchSql, "PARTITION_ID,")).as(searchSql).isEqualTo(1);
|
||||
assertThat(StringUtils.countMatches(searchSql, "PARTITION_DATE")).as(searchSql).isEqualTo(1);
|
||||
}
|
||||
|
||||
// Read in null Partition
|
||||
|
@ -1428,7 +1431,8 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
|||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, false).toUpperCase();
|
||||
ourLog.info("Search SQL:\n{}", searchSql);
|
||||
assertThat(searchSql).as(searchSql).contains("PARTITION_ID IN ('1')");
|
||||
assertThat(StringUtils.countMatches(searchSql, "PARTITION_ID")).as(searchSql).isEqualTo(1);
|
||||
assertThat(StringUtils.countMatches(searchSql, "PARTITION_ID,")).as(searchSql).isEqualTo(1);
|
||||
assertThat(StringUtils.countMatches(searchSql, "PARTITION_DATE")).as(searchSql).isEqualTo(1);
|
||||
|
||||
// Second SQL performs the search
|
||||
searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(1).getSql(true, false).toUpperCase();
|
||||
|
@ -2086,9 +2090,11 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
|||
myCaptureQueriesListener.logSelectQueriesForCurrentThread(1);
|
||||
assertThat(outcome.getResources(0, 1)).hasSize(1);
|
||||
|
||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, false);
|
||||
ourLog.info("Search SQL:\n{}", searchSql);
|
||||
assertThat(StringUtils.countMatches(searchSql, "PARTITION_ID")).as(searchSql).isEqualTo(1);
|
||||
assertThat(searchSql).as(searchSql).contains("PARTITION_ID in ('1')");
|
||||
assertThat(StringUtils.countMatches(searchSql, "PARTITION_ID,")).as(searchSql).isEqualTo(1);
|
||||
assertThat(StringUtils.countMatches(searchSql, "PARTITION_DATE")).as(searchSql).isEqualTo(1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package ca.uhn.fhir.jpa.search.reindex;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
|
@ -17,22 +16,22 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
|||
import ca.uhn.fhir.jpa.model.entity.SearchParamPresentEntity;
|
||||
import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams;
|
||||
import ca.uhn.fhir.test.utilities.HtmlUtil;
|
||||
import org.htmlunit.html.HtmlPage;
|
||||
import org.htmlunit.html.HtmlTable;
|
||||
import jakarta.annotation.Nonnull;
|
||||
import org.hl7.fhir.r4.model.IdType;
|
||||
import org.hl7.fhir.r4.model.Parameters;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
import org.htmlunit.html.HtmlPage;
|
||||
import org.htmlunit.html.HtmlTable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* Tests the narrative generation in {@link InstanceReindexServiceImpl}. This is a separate test
|
||||
|
@ -135,7 +134,7 @@ public class InstanceReindexServiceImplNarrativeR5Test {
|
|||
public void testIndexResourceLink() throws IOException {
|
||||
// Setup
|
||||
ResourceIndexedSearchParams newParams = newParams();
|
||||
newParams.myLinks.add(ResourceLink.forLocalReference("Observation.subject", myEntity, "Patient", 123L, "123", new Date(), 555L));
|
||||
newParams.myLinks.add(getResourceLinkForLocalReference());
|
||||
|
||||
// Test
|
||||
Parameters outcome = mySvc.buildIndexResponse(newParams(), newParams, true, Collections.emptyList());
|
||||
|
@ -311,4 +310,19 @@ public class InstanceReindexServiceImplNarrativeR5Test {
|
|||
return ResourceIndexedSearchParams.withSets();
|
||||
}
|
||||
|
||||
private ResourceLink getResourceLinkForLocalReference(){
|
||||
|
||||
ResourceLink.ResourceLinkForLocalReferenceParams params = ResourceLink.ResourceLinkForLocalReferenceParams
|
||||
.instance()
|
||||
.setSourcePath("Observation.subject")
|
||||
.setSourceResource(myEntity)
|
||||
.setTargetResourceType("Patient")
|
||||
.setTargetResourcePid(123L)
|
||||
.setTargetResourceId("123")
|
||||
.setUpdated(new Date())
|
||||
.setTargetResourceVersion(555L);
|
||||
|
||||
return ResourceLink.forLocalReference(params);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue