FIx up tests

This commit is contained in:
jamesagnew 2018-01-08 08:18:34 -05:00
parent abf76a778f
commit 7e2459fbdc
5 changed files with 595 additions and 616 deletions

View File

@ -1,6 +1,24 @@
package ca.uhn.fhir.model.primitive;
import static org.apache.commons.lang3.StringUtils.defaultString;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
import ca.uhn.fhir.model.api.annotation.SimpleSetter;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.util.UrlUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.HashCodeBuilder;
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 java.math.BigDecimal;
import java.util.UUID;
import static org.apache.commons.lang3.StringUtils.*;
/*
* #%L
* HAPI FHIR - Core Library
@ -10,9 +28,9 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
* 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.
@ -20,26 +38,10 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
* limitations under the License.
* #L%
*/
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.math.BigDecimal;
import java.util.UUID;
import org.apache.commons.lang3.*;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.hl7.fhir.instance.model.api.*;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
import ca.uhn.fhir.model.api.annotation.SimpleSetter;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.util.UrlUtil;
/**
* Represents the FHIR ID type. This is the actual resource ID, meaning the ID that will be used in RESTful URLs, Resource References, etc. to represent a specific instance of a resource.
*
* <p>
* <p>
* <b>Description</b>: A whole number in the range 0 to 2^64-1 (optionally represented in hex), a uuid, an oid, or any other combination of lowercase letters, numerals, "-" and ".", with a length
* limit of 36 characters.
@ -84,7 +86,7 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
/**
* Create a new ID using a string. This String may contain a simple ID (e.g. "1234") or it may contain a complete URL (http://example.com/fhir/Patient/1234).
*
* <p>
* <p>
* <b>Description</b>: A whole number in the range 0 to 2^64-1 (optionally represented in hex), a uuid, an oid, or any other combination of lowercase letters, numerals, "-" and ".", with a length
* limit of 36 characters.
@ -100,11 +102,9 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
/**
* Constructor
*
* @param theResourceType
* The resource type (e.g. "Patient")
* @param theIdPart
* The ID (e.g. "123")
*
* @param theResourceType The resource type (e.g. "Patient")
* @param theIdPart The ID (e.g. "123")
*/
public IdDt(String theResourceType, BigDecimal theIdPart) {
this(theResourceType, toPlainStringWithNpeThrowIfNeeded(theIdPart));
@ -112,11 +112,9 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
/**
* Constructor
*
* @param theResourceType
* The resource type (e.g. "Patient")
* @param theIdPart
* The ID (e.g. "123")
*
* @param theResourceType The resource type (e.g. "Patient")
* @param theIdPart The ID (e.g. "123")
*/
public IdDt(String theResourceType, Long theIdPart) {
this(theResourceType, toPlainStringWithNpeThrowIfNeeded(theIdPart));
@ -125,10 +123,8 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
/**
* Constructor
*
* @param theResourceType
* The resource type (e.g. "Patient")
* @param theId
* The ID (e.g. "123")
* @param theResourceType The resource type (e.g. "Patient")
* @param theId The ID (e.g. "123")
*/
public IdDt(String theResourceType, String theId) {
this(theResourceType, theId, null);
@ -136,13 +132,10 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
/**
* Constructor
*
* @param theResourceType
* The resource type (e.g. "Patient")
* @param theId
* The ID (e.g. "123")
* @param theVersionId
* The version ID ("e.g. "456")
*
* @param theResourceType The resource type (e.g. "Patient")
* @param theId The ID (e.g. "123")
* @param theVersionId The version ID ("e.g. "456")
*/
public IdDt(String theResourceType, String theId, String theVersionId) {
this(null, theResourceType, theId, theVersionId);
@ -150,15 +143,11 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
/**
* Constructor
*
* @param theBaseUrl
* The server base URL (e.g. "http://example.com/fhir")
* @param theResourceType
* The resource type (e.g. "Patient")
* @param theId
* The ID (e.g. "123")
* @param theVersionId
* The version ID ("e.g. "456")
*
* @param theBaseUrl The server base URL (e.g. "http://example.com/fhir")
* @param theResourceType The resource type (e.g. "Patient")
* @param theId The ID (e.g. "123")
* @param theVersionId The version ID ("e.g. "456")
*/
public IdDt(String theBaseUrl, String theResourceType, String theId, String theVersionId) {
myBaseUrl = theBaseUrl;
@ -244,9 +233,8 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
/**
* Returns the unqualified portion of this ID as a big decimal, or <code>null</code> if the value is null
*
* @throws NumberFormatException
* If the value is not a valid BigDecimal
*
* @throws NumberFormatException If the value is not a valid BigDecimal
*/
public BigDecimal getIdPartAsBigDecimal() {
String val = getIdPart();
@ -258,9 +246,8 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
/**
* Returns the unqualified portion of this ID as a {@link Long}, or <code>null</code> if the value is null
*
* @throws NumberFormatException
* If the value is not a valid Long
*
* @throws NumberFormatException If the value is not a valid Long
*/
@Override
public Long getIdPartAsLong() {
@ -278,7 +265,7 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
/**
* Returns the value of this ID. Note that this value may be a fully qualified URL, a relative/partial URL, or a simple ID. Use {@link #getIdPart()} to get just the ID portion.
*
*
* @see #getIdPart()
*/
@Override
@ -323,157 +310,9 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
return super.getValue();
}
@Override
public String getValueAsString() {
return getValue();
}
@Override
public String getVersionIdPart() {
return myUnqualifiedVersionId;
}
@Override
public Long getVersionIdPartAsLong() {
if (!hasVersionIdPart()) {
return null;
}
return Long.parseLong(getVersionIdPart());
}
/**
* Returns true if this ID has a base url
*
* @see #getBaseUrl()
*/
@Override
public boolean hasBaseUrl() {
return isNotBlank(myBaseUrl);
}
@Override
public int hashCode() {
HashCodeBuilder b = new HashCodeBuilder();
b.append(getValueAsString());
return b.toHashCode();
}
@Override
public boolean hasIdPart() {
return isNotBlank(getIdPart());
}
@Override
public boolean hasResourceType() {
return isNotBlank(myResourceType);
}
@Override
public boolean hasVersionIdPart() {
return isNotBlank(getVersionIdPart());
}
/**
* Returns <code>true</code> if this ID contains an absolute URL (in other words, a URL starting with "http://" or "https://"
*/
@Override
public boolean isAbsolute() {
if (StringUtils.isBlank(getValue())) {
return false;
}
return UrlUtil.isAbsolute(getValue());
}
@Override
public boolean isEmpty() {
return super.isBaseEmpty() && isBlank(getValue());
}
@Override
public boolean isIdPartValid() {
String id = getIdPart();
if (StringUtils.isBlank(id)) {
return false;
}
if (id.length() > 64) {
return false;
}
for (int i = 0; i < id.length(); i++) {
char nextChar = id.charAt(i);
if (nextChar >= 'a' && nextChar <= 'z') {
continue;
}
if (nextChar >= 'A' && nextChar <= 'Z') {
continue;
}
if (nextChar >= '0' && nextChar <= '9') {
continue;
}
if (nextChar == '-' || nextChar == '.') {
continue;
}
return false;
}
return true;
}
@Override
public boolean isIdPartValidLong() {
return isValidLong(getIdPart());
}
/**
* Returns <code>true</code> if the ID is a local reference (in other words,
* it begins with the '#' character)
*/
@Override
public boolean isLocal() {
return defaultString(myUnqualifiedId).startsWith("#");
}
private boolean isUrn() {
return defaultString(myUnqualifiedId).startsWith("urn:");
}
@Override
public boolean isVersionIdPartValidLong() {
return isValidLong(getVersionIdPart());
}
/**
* Copies the value from the given IdDt to <code>this</code> IdDt. It is generally not neccesary to use this method but it is provided for consistency with the rest of the API.
* @deprecated
*/
@Deprecated //override deprecated method
@Override
public void setId(IdDt theId) {
setValue(theId.getValue());
}
@Override
public IIdType setParts(String theBaseUrl, String theResourceType, String theIdPart, String theVersionIdPart) {
if (isNotBlank(theVersionIdPart)) {
Validate.notBlank(theResourceType, "If theVersionIdPart is populated, theResourceType and theIdPart must be populated");
Validate.notBlank(theIdPart, "If theVersionIdPart is populated, theResourceType and theIdPart must be populated");
}
if (isNotBlank(theBaseUrl) && isNotBlank(theIdPart)) {
Validate.notBlank(theResourceType, "If theBaseUrl is populated and theIdPart is populated, theResourceType must be populated");
}
setValue(null);
myBaseUrl = theBaseUrl;
myResourceType = theResourceType;
myUnqualifiedId = theIdPart;
myUnqualifiedVersionId = StringUtils.defaultIfBlank(theVersionIdPart, null);
myHaveComponentParts = true;
return this;
}
/**
* Set the value
*
* <p>
* <p>
* <b>Description</b>: A whole number in the range 0 to 2^64-1 (optionally represented in hex), a uuid, an oid, or any other combination of lowercase letters, numerals, "-" and ".", with a length
* limit of 36 characters.
@ -555,9 +394,14 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
return this;
}
@Override
public String getValueAsString() {
return getValue();
}
/**
* Set the value
*
* <p>
* <p>
* <b>Description</b>: A whole number in the range 0 to 2^64-1 (optionally represented in hex), a uuid, an oid, or any other combination of lowercase letters, numerals, "-" and ".", with a length
* limit of 36 characters.
@ -571,6 +415,150 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
setValue(theValue);
}
@Override
public String getVersionIdPart() {
return myUnqualifiedVersionId;
}
@Override
public Long getVersionIdPartAsLong() {
if (!hasVersionIdPart()) {
return null;
}
return Long.parseLong(getVersionIdPart());
}
/**
* Returns true if this ID has a base url
*
* @see #getBaseUrl()
*/
@Override
public boolean hasBaseUrl() {
return isNotBlank(myBaseUrl);
}
@Override
public boolean hasIdPart() {
return isNotBlank(getIdPart());
}
@Override
public boolean hasResourceType() {
return isNotBlank(myResourceType);
}
@Override
public boolean hasVersionIdPart() {
return isNotBlank(getVersionIdPart());
}
@Override
public int hashCode() {
HashCodeBuilder b = new HashCodeBuilder();
b.append(getValueAsString());
return b.toHashCode();
}
/**
* Returns <code>true</code> if this ID contains an absolute URL (in other words, a URL starting with "http://" or "https://"
*/
@Override
public boolean isAbsolute() {
if (StringUtils.isBlank(getValue())) {
return false;
}
return UrlUtil.isAbsolute(getValue());
}
@Override
public boolean isEmpty() {
return super.isBaseEmpty() && isBlank(getValue());
}
@Override
public boolean isIdPartValid() {
String id = getIdPart();
if (StringUtils.isBlank(id)) {
return false;
}
if (id.length() > 64) {
return false;
}
for (int i = 0; i < id.length(); i++) {
char nextChar = id.charAt(i);
if (nextChar >= 'a' && nextChar <= 'z') {
continue;
}
if (nextChar >= 'A' && nextChar <= 'Z') {
continue;
}
if (nextChar >= '0' && nextChar <= '9') {
continue;
}
if (nextChar == '-' || nextChar == '.') {
continue;
}
return false;
}
return true;
}
@Override
public boolean isIdPartValidLong() {
return isValidLong(getIdPart());
}
/**
* Returns <code>true</code> if the ID is a local reference (in other words,
* it begins with the '#' character)
*/
@Override
public boolean isLocal() {
return defaultString(myUnqualifiedId).startsWith("#");
}
private boolean isUrn() {
return defaultString(myUnqualifiedId).startsWith("urn:");
}
@Override
public boolean isVersionIdPartValidLong() {
return isValidLong(getVersionIdPart());
}
/**
* Copies the value from the given IdDt to <code>this</code> IdDt. It is generally not neccesary to use this method but it is provided for consistency with the rest of the API.
*
* @deprecated
*/
@Deprecated //override deprecated method
@Override
public void setId(IdDt theId) {
setValue(theId.getValue());
}
@Override
public IIdType setParts(String theBaseUrl, String theResourceType, String theIdPart, String theVersionIdPart) {
if (isNotBlank(theVersionIdPart)) {
Validate.notBlank(theResourceType, "If theVersionIdPart is populated, theResourceType and theIdPart must be populated");
Validate.notBlank(theIdPart, "If theVersionIdPart is populated, theResourceType and theIdPart must be populated");
}
if (isNotBlank(theBaseUrl) && isNotBlank(theIdPart)) {
Validate.notBlank(theResourceType, "If theBaseUrl is populated and theIdPart is populated, theResourceType must be populated");
}
setValue(null);
myBaseUrl = theBaseUrl;
myResourceType = theResourceType;
myUnqualifiedId = theIdPart;
myUnqualifiedVersionId = StringUtils.defaultIfBlank(theVersionIdPart, null);
myHaveComponentParts = true;
return this;
}
@Override
public String toString() {
return getValue();
@ -615,11 +603,9 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
/**
* Returns a view of this ID as a fully qualified URL, given a server base and resource name (which will only be used if the ID does not already contain those respective parts). Essentially,
* because IdDt can contain either a complete URL or a partial one (or even jut a simple ID), this method may be used to translate into a complete URL.
*
* @param theServerBase
* The server base (e.g. "http://example.com/fhir")
* @param theResourceType
* The resource name (e.g. "Patient")
*
* @param theServerBase The server base (e.g. "http://example.com/fhir")
* @param theResourceType The resource name (e.g. "Patient")
* @return A fully qualified URL for this ID (e.g. "http://example.com/fhir/Patient/1")
*/
@Override
@ -632,9 +618,8 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
/**
* Creates a new instance of this ID which is identical, but refers to the specific version of this resource ID noted by theVersion.
*
* @param theVersion
* The actual version string, e.g. "1"
*
* @param theVersion The actual version string, e.g. "1"
* @return A new instance of IdDt which is identical, but refers to the specific version of this resource ID noted by theVersion.
*/
@Override

View File

@ -1534,7 +1534,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
theEntity.setParamsUriPopulated(uriParams.isEmpty() == false);
theEntity.setParamsCoords(coordsParams);
theEntity.setParamsCoordsPopulated(coordsParams.isEmpty() == false);
// theEntity.setParamsCompositeStringUnique(compositeStringUniques);
theEntity.setParamsCompositeStringUniquePresent(compositeStringUniques.isEmpty() == false);
theEntity.setResourceLinks(links);
theEntity.setHasLinks(links.isEmpty() == false);
@ -1697,7 +1696,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
if (getConfig().isUniqueIndexesEnabled()) {
for (ResourceIndexedCompositeStringUnique next : existingCompositeStringUniques) {
if (!compositeStringUniques.contains(next)) {
ourLog.info("Removing unique index: {}", next);
ourLog.debug("Removing unique index: {}", next);
myEntityManager.remove(next);
}
}
@ -1709,7 +1708,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
throw new PreconditionFailedException("Can not create resource of type " + theEntity.getResourceType() + " as it would create a duplicate index matching query: " + next.getIndexString() + " (existing index belongs to " + existing.getResource().getIdDt().toUnqualifiedVersionless().getValue() + ")");
}
}
ourLog.info("Persisting unique index: {}", next);
ourLog.debug("Persisting unique index: {}", next);
myEntityManager.persist(next);
}
}

View File

@ -68,7 +68,6 @@ public class ResourceIndexedCompositeStringUnique implements Comparable<Resource
@Override
public int compareTo(ResourceIndexedCompositeStringUnique theO) {
CompareToBuilder b = new CompareToBuilder();
b.append(myResource, theO.getResource());
b.append(myIndexString, theO.getIndexString());
return b.toComparison();
}

View File

@ -6,6 +6,7 @@ import ca.uhn.fhir.jpa.subscription.email.IEmailSender;
import ca.uhn.fhir.jpa.subscription.email.JavaMailEmailSender;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
import ca.uhn.fhir.validation.ResultSeverityEnum;
import net.ttddyy.dsproxy.listener.logging.SLF4JLogLevel;
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
import org.apache.commons.dbcp2.BasicDataSource;
import org.hibernate.jpa.HibernatePersistenceProvider;
@ -116,7 +117,7 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
DataSource dataSource = ProxyDataSourceBuilder
.create(basicDataSource())
// .logQueryBySlf4j(SLF4JLogLevel.INFO, "SQL")
// .logQueryBySlf4j(SLF4JLogLevel.INFO, "SQL")
.logSlowQueryBySlf4j(1000, TimeUnit.MILLISECONDS)
.countQuery()
.build();

View File

@ -1,7 +1,6 @@
package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.DaoMethodOutcome;
import ca.uhn.fhir.jpa.dao.SearchBuilder;
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.jpa.entity.ResourceIndexedCompositeStringUnique;
@ -48,32 +47,6 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
myDaoConfig.setDefaultSearchParamsCanBeOverridden(true);
}
@Test
public void testNonTransaction() {
createUniqueBirthdateAndGenderSps();
Patient p = new Patient();
p.setGender(Enumerations.AdministrativeGender.MALE);
p.setBirthDateElement(new DateType("2001-01-01"));
Bundle input = new Bundle();
input.setType(Bundle.BundleType.TRANSACTION);
input.addEntry()
.setResource(p)
.setFullUrl("Patient")
.getRequest()
.setMethod(Bundle.HTTPVerb.POST)
.setUrl("/Patient")
.setIfNoneExist("Patient?gender=http%3A%2F%2Fhl7.org%2Ffhir%2Fadministrative-gender%7Cmale&birthdate=2001-01-01");
Bundle output0 = mySystemDao.transaction(mySrd, input);
Bundle output1 = mySystemDao.transaction(mySrd, input);
assertEquals(output1.getEntry().get(0).getFullUrl(), output0.getEntry().get(0).getFullUrl());
Bundle output2 = mySystemDao.transaction(mySrd, input);
assertEquals(output2.getEntry().get(0).getFullUrl(), output0.getEntry().get(0).getFullUrl());
}
private void createUniqueBirthdateAndGenderSps() {
SearchParameter sp = new SearchParameter();
sp.setId("SearchParameter/patient-gender");
@ -112,6 +85,129 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
mySearchParamRegsitry.forceRefresh();
}
private void createUniqueIndexCoverageBeneficiary() {
SearchParameter sp = new SearchParameter();
sp.setId("SearchParameter/coverage-beneficiary");
sp.setCode("beneficiary");
sp.setExpression("Coverage.beneficiary");
sp.setType(Enumerations.SearchParamType.REFERENCE);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Coverage");
mySearchParameterDao.update(sp);
sp = new SearchParameter();
sp.setId("SearchParameter/coverage-identifier");
sp.setCode("identifier");
sp.setExpression("Coverage.identifier");
sp.setType(Enumerations.SearchParamType.TOKEN);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Coverage");
mySearchParameterDao.update(sp);
sp = new SearchParameter();
sp.setId("SearchParameter/coverage-beneficiary-identifier");
sp.setCode("coverage-beneficiary-identifier");
sp.setExpression("Coverage.beneficiary");
sp.setType(Enumerations.SearchParamType.COMPOSITE);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Coverage");
sp.addComponent()
.setExpression("Coverage")
.setDefinition(new Reference("/SearchParameter/coverage-beneficiary"));
sp.addComponent()
.setExpression("Coverage")
.setDefinition(new Reference("/SearchParameter/coverage-identifier"));
sp.addExtension()
.setUrl(JpaConstants.EXT_SP_UNIQUE)
.setValue(new BooleanType(true));
mySearchParameterDao.update(sp);
mySearchParamRegsitry.forceRefresh();
}
private void createUniqueIndexObservationSubject() {
SearchParameter sp = new SearchParameter();
sp.setId("SearchParameter/observation-subject");
sp.setCode("observation-subject");
sp.setExpression("Observation.subject");
sp.setType(Enumerations.SearchParamType.REFERENCE);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Observation");
mySearchParameterDao.update(sp);
sp = new SearchParameter();
sp.setId("SearchParameter/observation-uniq-subject");
sp.setCode("observation-uniq-subject");
sp.setExpression("Observation.subject");
sp.setType(Enumerations.SearchParamType.COMPOSITE);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Observation");
sp.addComponent()
.setExpression("Observation")
.setDefinition(new Reference("/SearchParameter/observation-subject"));
sp.addExtension()
.setUrl(JpaConstants.EXT_SP_UNIQUE)
.setValue(new BooleanType(true));
mySearchParameterDao.update(sp);
mySearchParamRegsitry.forceRefresh();
}
private void createUniqueIndexPatientIdentifier() {
SearchParameter sp = new SearchParameter();
sp.setId("SearchParameter/patient-identifier");
sp.setCode("identifier");
sp.setExpression("Patient.identifier");
sp.setType(Enumerations.SearchParamType.TOKEN);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Patient");
mySearchParameterDao.update(sp);
sp = new SearchParameter();
sp.setId("SearchParameter/patient-uniq-identifier");
sp.setCode("patient-uniq-identifier");
sp.setExpression("Patient.identifier");
sp.setType(Enumerations.SearchParamType.COMPOSITE);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Patient");
sp.addComponent()
.setExpression("Patient")
.setDefinition(new Reference("/SearchParameter/patient-identifier"));
sp.addExtension()
.setUrl(JpaConstants.EXT_SP_UNIQUE)
.setValue(new BooleanType(true));
mySearchParameterDao.update(sp);
mySearchParamRegsitry.forceRefresh();
}
private void createUniqueIndexPatientIdentifierCount1() {
SearchParameter sp = new SearchParameter();
sp.setId("SearchParameter/patient-identifier");
sp.setCode("first-identifier");
sp.setExpression("Patient.identifier.first()");
sp.setType(Enumerations.SearchParamType.TOKEN);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Patient");
mySearchParameterDao.update(sp);
sp = new SearchParameter();
sp.setId("SearchParameter/patient-uniq-identifier");
sp.setCode("patient-uniq-identifier");
sp.setExpression("Patient.identifier");
sp.setType(Enumerations.SearchParamType.COMPOSITE);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Patient");
sp.addComponent()
.setExpression("Patient")
.setDefinition(new Reference("/SearchParameter/patient-identifier"));
sp.addExtension()
.setUrl(JpaConstants.EXT_SP_UNIQUE)
.setValue(new BooleanType(true));
mySearchParameterDao.update(sp);
mySearchParamRegsitry.forceRefresh();
}
private void createUniqueNameAndManagingOrganizationSps() {
SearchParameter sp = new SearchParameter();
sp.setId("SearchParameter/patient-name");
@ -215,6 +311,98 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
assertEquals("gender", params.get(0).getCompositeOf().get(1).getName());
}
@Test
public void testDoubleMatching() {
createUniqueIndexPatientIdentifier();
Patient pt = new Patient();
pt.addIdentifier().setSystem("urn").setValue("111");
pt.addIdentifier().setSystem("urn").setValue("222");
Bundle input = new Bundle();
input.setType(Bundle.BundleType.TRANSACTION);
input.addEntry()
.setResource(pt)
.setFullUrl("Patient")
.getRequest()
.setMethod(Bundle.HTTPVerb.POST)
.setUrl("/Patient")
.setIfNoneExist("/Patient?identifier=urn|111,urn|222");
mySystemDao.transaction(mySrd, input);
myEntityManager.clear();
pt = new Patient();
pt.setActive(true);
pt.addIdentifier().setSystem("urn").setValue("111");
pt.addIdentifier().setSystem("urn").setValue("222");
input = new Bundle();
input.setType(Bundle.BundleType.TRANSACTION);
input.addEntry()
.setResource(pt)
.setFullUrl("Patient")
.getRequest()
.setMethod(Bundle.HTTPVerb.POST)
.setUrl("/Patient")
.setIfNoneExist("/Patient?identifier=urn|111,urn|222");
mySystemDao.transaction(mySrd, input);
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
List<ResourceIndexedCompositeStringUnique> all = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(2, all.size());
}
});
}
@Test
public void testDoubleMatchingPut() {
createUniqueIndexPatientIdentifier();
Patient pt = new Patient();
pt.addIdentifier().setSystem("urn").setValue("111");
pt.addIdentifier().setSystem("urn").setValue("222");
Bundle input = new Bundle();
input.setType(Bundle.BundleType.TRANSACTION);
input.addEntry()
.setResource(pt)
.setFullUrl("Patient")
.getRequest()
.setMethod(Bundle.HTTPVerb.PUT)
.setUrl("/Patient?identifier=urn|111,urn|222");
mySystemDao.transaction(mySrd, input);
myEntityManager.clear();
pt = new Patient();
pt.setActive(true);
pt.addIdentifier().setSystem("urn").setValue("111");
pt.addIdentifier().setSystem("urn").setValue("222");
input = new Bundle();
input.setType(Bundle.BundleType.TRANSACTION);
input.addEntry()
.setResource(pt)
.setFullUrl("Patient")
.getRequest()
.setMethod(Bundle.HTTPVerb.PUT)
.setUrl("/Patient?identifier=urn|111,urn|222");
mySystemDao.transaction(mySrd, input);
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
List<ResourceIndexedCompositeStringUnique> all = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(2, all.size());
}
});
}
@Test
public void testDuplicateUniqueValuesAreReIndexed() {
@ -302,305 +490,6 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
}
}
@Test
public void testSearchSynchronousUsingUniqueComposite() {
createUniqueBirthdateAndGenderSps();
Patient pt1 = new Patient();
pt1.setGender(Enumerations.AdministrativeGender.MALE);
pt1.setBirthDateElement(new DateType("2011-01-01"));
IIdType id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
Patient pt2 = new Patient();
pt2.setGender(Enumerations.AdministrativeGender.MALE);
pt2.setBirthDateElement(new DateType("2011-01-02"));
IIdType id2 = myPatientDao.create(pt2).getId().toUnqualifiedVersionless();
SearchBuilder.resetLastHandlerMechanismForUnitTest();
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(100);
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
params.add("birthdate", new DateParam("2011-01-01"));
IBundleProvider results = myPatientDao.search(params);
assertThat(toUnqualifiedVersionlessIdValues(results), containsInAnyOrder(id1.getValue()));
assertEquals(SearchBuilder.HandlerTypeEnum.UNIQUE_INDEX, SearchBuilder.getLastHandlerMechanismForUnitTest());
}
@Test
public void testSearchUsingUniqueComposite() {
createUniqueBirthdateAndGenderSps();
Patient pt1 = new Patient();
pt1.setGender(Enumerations.AdministrativeGender.MALE);
pt1.setBirthDateElement(new DateType("2011-01-01"));
String id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless().getValue();
Patient pt2 = new Patient();
pt2.setGender(Enumerations.AdministrativeGender.MALE);
pt2.setBirthDateElement(new DateType("2011-01-02"));
IIdType id2 = myPatientDao.create(pt2).getId().toUnqualifiedVersionless();
SearchBuilder.resetLastHandlerMechanismForUnitTest();
SearchParameterMap params = new SearchParameterMap();
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
params.add("birthdate", new DateParam("2011-01-01"));
IBundleProvider results = myPatientDao.search(params);
String searchId = results.getUuid();
assertThat(toUnqualifiedVersionlessIdValues(results), containsInAnyOrder(id1));
assertEquals(SearchBuilder.HandlerTypeEnum.UNIQUE_INDEX, SearchBuilder.getLastHandlerMechanismForUnitTest());
// Other order
SearchBuilder.resetLastHandlerMechanismForUnitTest();
params = new SearchParameterMap();
params.add("birthdate", new DateParam("2011-01-01"));
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
results = myPatientDao.search(params);
assertEquals(searchId, results.getUuid());
assertThat(toUnqualifiedVersionlessIdValues(results), containsInAnyOrder(id1));
// Null because we just reuse the last search
assertEquals(null, SearchBuilder.getLastHandlerMechanismForUnitTest());
SearchBuilder.resetLastHandlerMechanismForUnitTest();
params = new SearchParameterMap();
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
params.add("birthdate", new DateParam("2011-01-03"));
results = myPatientDao.search(params);
assertThat(toUnqualifiedVersionlessIdValues(results), empty());
assertEquals(SearchBuilder.HandlerTypeEnum.UNIQUE_INDEX, SearchBuilder.getLastHandlerMechanismForUnitTest());
SearchBuilder.resetLastHandlerMechanismForUnitTest();
params = new SearchParameterMap();
params.add("birthdate", new DateParam("2011-01-03"));
results = myPatientDao.search(params);
assertThat(toUnqualifiedVersionlessIdValues(results), empty());
assertEquals(SearchBuilder.HandlerTypeEnum.STANDARD_QUERY, SearchBuilder.getLastHandlerMechanismForUnitTest());
}
private void createUniqueIndexCoverageBeneficiary() {
SearchParameter sp = new SearchParameter();
sp.setId("SearchParameter/coverage-beneficiary");
sp.setCode("beneficiary");
sp.setExpression("Coverage.beneficiary");
sp.setType(Enumerations.SearchParamType.REFERENCE);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Coverage");
mySearchParameterDao.update(sp);
sp = new SearchParameter();
sp.setId("SearchParameter/coverage-identifier");
sp.setCode("identifier");
sp.setExpression("Coverage.identifier");
sp.setType(Enumerations.SearchParamType.TOKEN);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Coverage");
mySearchParameterDao.update(sp);
sp = new SearchParameter();
sp.setId("SearchParameter/coverage-beneficiary-identifier");
sp.setCode("coverage-beneficiary-identifier");
sp.setExpression("Coverage.beneficiary");
sp.setType(Enumerations.SearchParamType.COMPOSITE);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Coverage");
sp.addComponent()
.setExpression("Coverage")
.setDefinition(new Reference("/SearchParameter/coverage-beneficiary"));
sp.addComponent()
.setExpression("Coverage")
.setDefinition(new Reference("/SearchParameter/coverage-identifier"));
sp.addExtension()
.setUrl(JpaConstants.EXT_SP_UNIQUE)
.setValue(new BooleanType(true));
mySearchParameterDao.update(sp);
mySearchParamRegsitry.forceRefresh();
}
private void createUniqueIndexPatientIdentifier() {
SearchParameter sp = new SearchParameter();
sp.setId("SearchParameter/patient-identifier");
sp.setCode("identifier");
sp.setExpression("Patient.identifier");
sp.setType(Enumerations.SearchParamType.TOKEN);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Patient");
mySearchParameterDao.update(sp);
sp = new SearchParameter();
sp.setId("SearchParameter/patient-uniq-identifier");
sp.setCode("patient-uniq-identifier");
sp.setExpression("Patient.identifier");
sp.setType(Enumerations.SearchParamType.COMPOSITE);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Patient");
sp.addComponent()
.setExpression("Patient")
.setDefinition(new Reference("/SearchParameter/patient-identifier"));
sp.addExtension()
.setUrl(JpaConstants.EXT_SP_UNIQUE)
.setValue(new BooleanType(true));
mySearchParameterDao.update(sp);
mySearchParamRegsitry.forceRefresh();
}
private void createUniqueIndexPatientIdentifierCount1() {
SearchParameter sp = new SearchParameter();
sp.setId("SearchParameter/patient-identifier");
sp.setCode("first-identifier");
sp.setExpression("Patient.identifier.first()");
sp.setType(Enumerations.SearchParamType.TOKEN);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Patient");
mySearchParameterDao.update(sp);
sp = new SearchParameter();
sp.setId("SearchParameter/patient-uniq-identifier");
sp.setCode("patient-uniq-identifier");
sp.setExpression("Patient.identifier");
sp.setType(Enumerations.SearchParamType.COMPOSITE);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Patient");
sp.addComponent()
.setExpression("Patient")
.setDefinition(new Reference("/SearchParameter/patient-identifier"));
sp.addExtension()
.setUrl(JpaConstants.EXT_SP_UNIQUE)
.setValue(new BooleanType(true));
mySearchParameterDao.update(sp);
mySearchParamRegsitry.forceRefresh();
}
private void createUniqueIndexObservationSubject() {
SearchParameter sp = new SearchParameter();
sp.setId("SearchParameter/observation-subject");
sp.setCode("observation-subject");
sp.setExpression("Observation.subject");
sp.setType(Enumerations.SearchParamType.REFERENCE);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Observation");
mySearchParameterDao.update(sp);
sp = new SearchParameter();
sp.setId("SearchParameter/observation-uniq-subject");
sp.setCode("observation-uniq-subject");
sp.setExpression("Observation.subject");
sp.setType(Enumerations.SearchParamType.COMPOSITE);
sp.setStatus(PublicationStatus.ACTIVE);
sp.addBase("Observation");
sp.addComponent()
.setExpression("Observation")
.setDefinition(new Reference("/SearchParameter/observation-subject"));
sp.addExtension()
.setUrl(JpaConstants.EXT_SP_UNIQUE)
.setValue(new BooleanType(true));
mySearchParameterDao.update(sp);
mySearchParamRegsitry.forceRefresh();
}
@Test
public void testIndexTransactionWithMatchUrl() {
Patient pt2 = new Patient();
pt2.setGender(Enumerations.AdministrativeGender.MALE);
pt2.setBirthDateElement(new DateType("2011-01-02"));
IIdType id2 = myPatientDao.create(pt2).getId().toUnqualifiedVersionless();
Coverage cov = new Coverage();
cov.getBeneficiary().setReference(id2.getValue());
cov.addIdentifier().setSystem("urn:foo:bar").setValue("123");
IIdType id3 = myCoverageDao.create(cov).getId().toUnqualifiedVersionless();
createUniqueIndexCoverageBeneficiary();
mySystemDao.markAllResourcesForReindexing();
mySystemDao.performReindexingPass(1000);
List<ResourceIndexedCompositeStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(uniques.toString(), 1, uniques.size());
assertEquals("Coverage/" + id3.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Coverage?beneficiary=Patient%2F" + id2.getIdPart() + "&identifier=urn%3Afoo%3Abar%7C123", uniques.get(0).getIndexString());
}
@Test
public void testDoubleMatching() {
createUniqueIndexPatientIdentifier();
Patient pt = new Patient();
pt.addIdentifier().setSystem("urn").setValue("111");
pt.addIdentifier().setSystem("urn").setValue("222");
Bundle input = new Bundle();
input.setType(Bundle.BundleType.TRANSACTION);
input.addEntry()
.setResource(pt)
.setFullUrl("Patient")
.getRequest()
.setMethod(Bundle.HTTPVerb.POST)
.setUrl("/Patient")
.setIfNoneExist("/Patient?identifier=urn|111,urn|222");
mySystemDao.transaction(mySrd, input);
myEntityManager.clear();
pt = new Patient();
pt.setActive(true);
pt.addIdentifier().setSystem("urn").setValue("111");
pt.addIdentifier().setSystem("urn").setValue("222");
input = new Bundle();
input.setType(Bundle.BundleType.TRANSACTION);
input.addEntry()
.setResource(pt)
.setFullUrl("Patient")
.getRequest()
.setMethod(Bundle.HTTPVerb.POST)
.setUrl("/Patient")
.setIfNoneExist("/Patient?identifier=urn|111,urn|222");
mySystemDao.transaction(mySrd, input);
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
List<ResourceIndexedCompositeStringUnique> all = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(2, all.size());
}
});
}
@Test
public void testObservationSubject() {
createUniqueIndexObservationSubject();
Patient pt = new Patient();
pt.addIdentifier().setSystem("urn").setValue("111");
pt.addIdentifier().setSystem("urn").setValue("222");
IIdType ptid = myPatientDao.create(pt).getId().toUnqualifiedVersionless();
Encounter enc = new Encounter();
enc.setSubject(new Reference(ptid));
IIdType encid = myEncounterDao.create(enc).getId().toUnqualifiedVersionless();
Observation obs = new Observation();
obs.setSubject(new Reference(ptid));
obs.setContext(new Reference(encid));
myObservationDao.create(obs);
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
List<ResourceIndexedCompositeStringUnique> all = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(all.toString(), 1, all.size());
}
});
}er
@Test
public void testIndexFirstMatchOnly() {
createUniqueIndexPatientIdentifierCount1();
@ -635,49 +524,28 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
}
@Test
public void testDoubleMatchingPut() {
createUniqueIndexPatientIdentifier();
public void testIndexTransactionWithMatchUrl() {
Patient pt2 = new Patient();
pt2.setGender(Enumerations.AdministrativeGender.MALE);
pt2.setBirthDateElement(new DateType("2011-01-02"));
IIdType id2 = myPatientDao.create(pt2).getId().toUnqualifiedVersionless();
Patient pt = new Patient();
pt.addIdentifier().setSystem("urn").setValue("111");
pt.addIdentifier().setSystem("urn").setValue("222");
Coverage cov = new Coverage();
cov.getBeneficiary().setReference(id2.getValue());
cov.addIdentifier().setSystem("urn:foo:bar").setValue("123");
IIdType id3 = myCoverageDao.create(cov).getId().toUnqualifiedVersionless();
Bundle input = new Bundle();
input.setType(Bundle.BundleType.TRANSACTION);
input.addEntry()
.setResource(pt)
.setFullUrl("Patient")
.getRequest()
.setMethod(Bundle.HTTPVerb.PUT)
.setUrl("/Patient?identifier=urn|111,urn|222");
mySystemDao.transaction(mySrd, input);
createUniqueIndexCoverageBeneficiary();
myEntityManager.clear();
mySystemDao.markAllResourcesForReindexing();
mySystemDao.performReindexingPass(1000);
pt = new Patient();
pt.setActive(true);
pt.addIdentifier().setSystem("urn").setValue("111");
pt.addIdentifier().setSystem("urn").setValue("222");
List<ResourceIndexedCompositeStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(uniques.toString(), 1, uniques.size());
assertEquals("Coverage/" + id3.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Coverage?beneficiary=Patient%2F" + id2.getIdPart() + "&identifier=urn%3Afoo%3Abar%7C123", uniques.get(0).getIndexString());
input = new Bundle();
input.setType(Bundle.BundleType.TRANSACTION);
input.addEntry()
.setResource(pt)
.setFullUrl("Patient")
.getRequest()
.setMethod(Bundle.HTTPVerb.PUT)
.setUrl("/Patient?identifier=urn|111,urn|222");
mySystemDao.transaction(mySrd, input);
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
List<ResourceIndexedCompositeStringUnique> all = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(2, all.size());
}
});
}
@ -791,6 +659,134 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
}
@Test
public void testNonTransaction() {
createUniqueBirthdateAndGenderSps();
Patient p = new Patient();
p.setGender(Enumerations.AdministrativeGender.MALE);
p.setBirthDateElement(new DateType("2001-01-01"));
Bundle input = new Bundle();
input.setType(Bundle.BundleType.TRANSACTION);
input.addEntry()
.setResource(p)
.setFullUrl("Patient")
.getRequest()
.setMethod(Bundle.HTTPVerb.POST)
.setUrl("/Patient")
.setIfNoneExist("Patient?gender=http%3A%2F%2Fhl7.org%2Ffhir%2Fadministrative-gender%7Cmale&birthdate=2001-01-01");
Bundle output0 = mySystemDao.transaction(mySrd, input);
Bundle output1 = mySystemDao.transaction(mySrd, input);
assertEquals(output1.getEntry().get(0).getFullUrl(), output0.getEntry().get(0).getFullUrl());
Bundle output2 = mySystemDao.transaction(mySrd, input);
assertEquals(output2.getEntry().get(0).getFullUrl(), output0.getEntry().get(0).getFullUrl());
}
@Test
public void testObservationSubject() {
createUniqueIndexObservationSubject();
Patient pt = new Patient();
pt.addIdentifier().setSystem("urn").setValue("111");
pt.addIdentifier().setSystem("urn").setValue("222");
IIdType ptid = myPatientDao.create(pt).getId().toUnqualifiedVersionless();
Encounter enc = new Encounter();
enc.setSubject(new Reference(ptid));
IIdType encid = myEncounterDao.create(enc).getId().toUnqualifiedVersionless();
Observation obs = new Observation();
obs.setSubject(new Reference(ptid));
obs.setContext(new Reference(encid));
myObservationDao.create(obs);
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
List<ResourceIndexedCompositeStringUnique> all = myResourceIndexedCompositeStringUniqueDao.findAll();
assertEquals(all.toString(), 1, all.size());
}
});
}
@Test
public void testSearchSynchronousUsingUniqueComposite() {
createUniqueBirthdateAndGenderSps();
Patient pt1 = new Patient();
pt1.setGender(Enumerations.AdministrativeGender.MALE);
pt1.setBirthDateElement(new DateType("2011-01-01"));
IIdType id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
Patient pt2 = new Patient();
pt2.setGender(Enumerations.AdministrativeGender.MALE);
pt2.setBirthDateElement(new DateType("2011-01-02"));
IIdType id2 = myPatientDao.create(pt2).getId().toUnqualifiedVersionless();
SearchBuilder.resetLastHandlerMechanismForUnitTest();
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(100);
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
params.add("birthdate", new DateParam("2011-01-01"));
IBundleProvider results = myPatientDao.search(params);
assertThat(toUnqualifiedVersionlessIdValues(results), containsInAnyOrder(id1.getValue()));
assertEquals(SearchBuilder.HandlerTypeEnum.UNIQUE_INDEX, SearchBuilder.getLastHandlerMechanismForUnitTest());
}
@Test
public void testSearchUsingUniqueComposite() {
createUniqueBirthdateAndGenderSps();
Patient pt1 = new Patient();
pt1.setGender(Enumerations.AdministrativeGender.MALE);
pt1.setBirthDateElement(new DateType("2011-01-01"));
String id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless().getValue();
Patient pt2 = new Patient();
pt2.setGender(Enumerations.AdministrativeGender.MALE);
pt2.setBirthDateElement(new DateType("2011-01-02"));
IIdType id2 = myPatientDao.create(pt2).getId().toUnqualifiedVersionless();
SearchBuilder.resetLastHandlerMechanismForUnitTest();
SearchParameterMap params = new SearchParameterMap();
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
params.add("birthdate", new DateParam("2011-01-01"));
IBundleProvider results = myPatientDao.search(params);
String searchId = results.getUuid();
assertThat(toUnqualifiedVersionlessIdValues(results), containsInAnyOrder(id1));
assertEquals(SearchBuilder.HandlerTypeEnum.UNIQUE_INDEX, SearchBuilder.getLastHandlerMechanismForUnitTest());
// Other order
SearchBuilder.resetLastHandlerMechanismForUnitTest();
params = new SearchParameterMap();
params.add("birthdate", new DateParam("2011-01-01"));
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
results = myPatientDao.search(params);
assertEquals(searchId, results.getUuid());
assertThat(toUnqualifiedVersionlessIdValues(results), containsInAnyOrder(id1));
// Null because we just reuse the last search
assertEquals(null, SearchBuilder.getLastHandlerMechanismForUnitTest());
SearchBuilder.resetLastHandlerMechanismForUnitTest();
params = new SearchParameterMap();
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
params.add("birthdate", new DateParam("2011-01-03"));
results = myPatientDao.search(params);
assertThat(toUnqualifiedVersionlessIdValues(results), empty());
assertEquals(SearchBuilder.HandlerTypeEnum.UNIQUE_INDEX, SearchBuilder.getLastHandlerMechanismForUnitTest());
SearchBuilder.resetLastHandlerMechanismForUnitTest();
params = new SearchParameterMap();
params.add("birthdate", new DateParam("2011-01-03"));
results = myPatientDao.search(params);
assertThat(toUnqualifiedVersionlessIdValues(results), empty());
assertEquals(SearchBuilder.HandlerTypeEnum.STANDARD_QUERY, SearchBuilder.getLastHandlerMechanismForUnitTest());
}
@Test
public void testUniqueValuesAreIndexed_DateAndToken() {
@ -837,38 +833,6 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString());
}
@Test
public void testUniqueValuesAreIndexed_StringAndReference() {
createUniqueNameAndManagingOrganizationSps();
Organization org = new Organization();
org.setId("Organization/ORG");
org.setName("ORG");
myOrganizationDao.update(org);
Patient pt1 = new Patient();
pt1.addName()
.setFamily("FAMILY1")
.addGiven("GIVEN1")
.addGiven("GIVEN2")
.addGiven("GIVEN2"); // GIVEN2 happens twice
pt1.setManagingOrganization(new Reference("Organization/ORG"));
IIdType id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
List<ResourceIndexedCompositeStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
Collections.sort(uniques);
assertEquals(3, uniques.size());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(1).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=GIVEN1&organization=Organization%2FORG", uniques.get(1).getIndexString());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(2).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=GIVEN2&organization=Organization%2FORG", uniques.get(2).getIndexString());
}
@Test
public void testUniqueValuesAreIndexed_Reference_UsingModifierSyntax() {
createUniqueNameAndManagingOrganizationSps();
@ -907,6 +871,37 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
}
@Test
public void testUniqueValuesAreIndexed_StringAndReference() {
createUniqueNameAndManagingOrganizationSps();
Organization org = new Organization();
org.setId("Organization/ORG");
org.setName("ORG");
myOrganizationDao.update(org);
Patient pt1 = new Patient();
pt1.addName()
.setFamily("FAMILY1")
.addGiven("GIVEN1")
.addGiven("GIVEN2")
.addGiven("GIVEN2"); // GIVEN2 happens twice
pt1.setManagingOrganization(new Reference("Organization/ORG"));
IIdType id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
List<ResourceIndexedCompositeStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
Collections.sort(uniques);
assertEquals(3, uniques.size());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(1).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=GIVEN1&organization=Organization%2FORG", uniques.get(1).getIndexString());
assertEquals("Patient/" + id1.getIdPart(), uniques.get(2).getResource().getIdDt().toUnqualifiedVersionless().getValue());
assertEquals("Patient?name=GIVEN2&organization=Organization%2FORG", uniques.get(2).getIndexString());
}
@Test
public void testUniqueValuesAreIndexed_StringAndReference_UsingConditional() {