+ * Should searches use the integer field {@code SP_VALUE_LOW_DATE_ORDINAL} and {@code SP_VALUE_HIGH_DATE_ORDINAL} in
+ * {@link ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate} when resolving searches where all predicates are using
+ * precision of {@link ca.uhn.fhir.model.api.TemporalPrecisionEnum#DAY}.
+ *
+ * For example, if enabled, the search of {@code Observation?date=2020-02-25} will cause the date to be collapsed down to an
+ * integer representing the ordinal date {@code 20200225}. It would then be compared against {@link ResourceIndexedSearchParamDate#getValueLowDateOrdinal()}
+ * and {@link ResourceIndexedSearchParamDate#getValueHighDateOrdinal()}
+ *
+ * Default is {@literal true} beginning in HAPI FHIR 4.3.
+ *
+ *
+ * @since 4.3
+ */
+ public boolean getUseOrdinalDatesForDayPrecisionSearches() {
+ return myUseOrdinalDatesForDayPrecisionSearches;
+ }
+
public enum StoreMetaSourceInformationEnum {
NONE(false, false),
SOURCE_URI(true, false),
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
index eebf0f2987f..fc182a9162b 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
@@ -140,7 +140,9 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
DateParam lowerBound = theRange.getLowerBound();
DateParam upperBound = theRange.getUpperBound();
- boolean isOrdinalComparison = isNullOrDayPrecision(lowerBound) && isNullOrDayPrecision(upperBound);
+ Integer lowerBoundAsOrdinal = theRange.getLowerBoundAsDateInteger();
+ Integer upperBoundAsOrdinal = theRange.getUpperBoundAsDateInteger();
+ boolean isOrdinalComparison = isNullOrDayPrecision(lowerBound) && isNullOrDayPrecision(upperBound) && myDaoConfig.getUseOrdinalDatesForDayPrecisionSearches();
Predicate lt = null;
Predicate gt = null;
Predicate lb = null;
@@ -152,7 +154,7 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
}
//im like 80% sure this should be ub and not lb, as it is an UPPER bound.
if (isOrdinalComparison) {
- lb = theBuilder.lessThan(theFrom.get("myValueLowDateOrdinal"), theRange.getLowerBoundAsDateInteger());
+ lb = theBuilder.lessThan(theFrom.get("myValueLowDateOrdinal"), lowerBoundAsOrdinal);
} else {
lb = theBuilder.lessThan(theFrom.get("myValueLow"), lowerBoundInstant);
}
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java
index 6ea71e54b73..98778c257f2 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java
@@ -64,10 +64,11 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks {
version.onTable("HFJ_RES_VER").modifyColumn("20200220.1", "RES_ID").nonNullable().failureAllowed().withType(BaseTableColumnTypeTask.ColumnTypeEnum.LONG);
//
- // Add support for integer comparisons during day-granularity date search.
+ // Add support for integer comparisons during day-precision date search.
Builder.BuilderWithTableName spidxDate = version.onTable("HFJ_SPIDX_DATE");
spidxDate.addColumn("20200225.1", "SP_VALUE_LOW_DATE_ORDINAL").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.INT);
spidxDate.addColumn("20200225.2", "SP_VALUE_HIGH_DATE_ORDINAL").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.INT);
+
spidxDate.addTask(new CalculateOrdinalDatesTask(VersionEnum.V4_3_0, "20200225.3")
.setColumnName("SP_VALUE_LOW_DATE_ORDINAL") //It doesn't matter which of the two we choose as they will both be null.
.addCalculator("SP_VALUE_LOW_DATE_ORDINAL", t -> ResourceIndexedSearchParamDate.calculateOrdinalValue(t.getDate("SP_VALUE_LOW")))
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
index c5ffe82375a..17d011d4e0c 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
@@ -111,6 +111,14 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
this.myValueLowDateOrdinal = generateOrdinalDateInteger(theLow);
}
+ public Integer getValueLowDateOrdinal() {
+ return myValueLowDateOrdinal;
+ }
+
+ public Integer getValueHighDateOrdinal() {
+ return myValueHighDateOrdinal;
+ }
+
@Override
@PrePersist
public void calculateHashes() {
From a1b6e37395746b006594ef144e2b33fab754feaf Mon Sep 17 00:00:00 2001
From: Gary Graham
Date: Tue, 25 Feb 2020 17:03:50 -0500
Subject: [PATCH 11/27] Fix bug with Period bounds not counting as first value
---
.../jpa/model/entity/ResourceIndexedSearchParamDate.java | 8 +++++---
.../searchparam/extractor/BaseSearchParamExtractor.java | 4 ++++
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
index 17d011d4e0c..d38f4dfe440 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
@@ -102,9 +102,11 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
this.myValueHighDateOrdinal = generateOrdinalDateInteger(theHigh);
}
private int generateOrdinalDateInteger(String theDateString){
- String t = theDateString.substring(0, theDateString.indexOf("T"));
- t = t.replace("-", "");
- return Integer.valueOf(t);
+ if (theDateString.contains("T")) {
+ theDateString = theDateString.substring(0, theDateString.indexOf("T"));
+ }
+ theDateString = theDateString.replace("-", "");
+ return Integer.valueOf(theDateString);
}
private void computeValueLowDateOrdinal(String theLow) {
diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java
index d3b42491c51..eb44a8a0a7a 100644
--- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java
+++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java
@@ -642,6 +642,10 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
String endString = extractValueAsString(myPeriodEndValueChild, bounds.get());
dates.add(start);
dates.add(end);
+ //TODO Check if this logic is valid. Does the start of the first period indicate a lower bound??
+ if (firstValue == null) {
+ firstValue = extractValueAsString(myPeriodStartValueChild, bounds.get());
+ }
finalValue = endString;
}
}
From 1e833af5f046c464414821011f66921ceb5460cf Mon Sep 17 00:00:00 2001
From: Gary Graham
Date: Tue, 25 Feb 2020 17:06:38 -0500
Subject: [PATCH 12/27] Variable reuse
---
.../dao/predicate/PredicateBuilderDate.java | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
index fc182a9162b..ae0e3df79ec 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
@@ -164,7 +164,7 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
}
//im like 80% sure this should be ub and not lb, as it is an UPPER bound.
if (isOrdinalComparison) {
- lb = theBuilder.lessThanOrEqualTo(theFrom.get("myValueHighDateOrdinal"), theRange.getUpperBoundAsDateInteger());
+ lb = theBuilder.lessThanOrEqualTo(theFrom.get("myValueHighDateOrdinal"), upperBoundAsOrdinal);
} else {
lb = theBuilder.lessThanOrEqualTo(theFrom.get("myValueHigh"), upperBoundInstant);
}
@@ -173,7 +173,7 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
throw new InvalidRequestException("upperBound value not correctly specified for compare operation");
}
if (isOrdinalComparison) {
- lb = theBuilder.greaterThan(theFrom.get("myValueHighDateOrdinal"), theRange.getUpperBoundAsDateInteger());
+ lb = theBuilder.greaterThan(theFrom.get("myValueHighDateOrdinal"), upperBoundAsOrdinal);
} else {
lb = theBuilder.greaterThan(theFrom.get("myValueHigh"), upperBoundInstant);
}
@@ -182,7 +182,7 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
throw new InvalidRequestException("lowerBound value not correctly specified for compare operation");
}
if (isOrdinalComparison) {
- lb = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueLowDateOrdinal"), theRange.getLowerBoundAsDateInteger());
+ lb = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueLowDateOrdinal"), lowerBoundAsOrdinal);
} else {
lb = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueLow"), lowerBoundInstant);
}
@@ -192,8 +192,8 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
throw new InvalidRequestException("lowerBound and/or upperBound value not correctly specified for compare operation");
}
if (isOrdinalComparison){
- lt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueLowDateOrdinal"), theRange.getLowerBoundAsDateInteger());
- gt = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueHighDateOrdinal"), theRange.getUpperBoundAsDateInteger());
+ lt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueLowDateOrdinal"), lowerBoundAsOrdinal);
+ gt = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueHighDateOrdinal"), upperBoundAsOrdinal);
} else {
lt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueLow"), lowerBoundInstant);
gt = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueHigh"), upperBoundInstant);
@@ -203,8 +203,8 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
} else if ((operation == SearchFilterParser.CompareOperation.eq) || (operation == null)) {
if (lowerBoundInstant != null) {
if (isOrdinalComparison) {
- gt = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueLowDateOrdinal"), theRange.getLowerBoundAsDateInteger());
- lt = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueHighDateOrdinal"), theRange.getLowerBoundAsDateInteger());
+ gt = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueLowDateOrdinal"), lowerBoundAsOrdinal);
+ lt = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueHighDateOrdinal"), lowerBoundAsOrdinal);
//also try a strict equality here.
}
else {
@@ -220,8 +220,8 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
if (upperBoundInstant != null) {
if (isOrdinalComparison) {
- gt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueLowDateOrdinal"), theRange.getUpperBoundAsDateInteger());
- lt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueHighDateOrdinal"), theRange.getUpperBoundAsDateInteger());
+ gt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueLowDateOrdinal"), upperBoundAsOrdinal);
+ lt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueHighDateOrdinal"), upperBoundAsOrdinal);
} else {
gt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueLow"), upperBoundInstant);
lt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueHigh"), upperBoundInstant);
@@ -238,7 +238,7 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
operation.name()));
}
if (isOrdinalComparison) {
- ourLog.trace("Ordinal date range is {} - {} ", theRange.getLowerBoundAsDateInteger(), theRange.getUpperBoundAsDateInteger());
+ ourLog.trace("Ordinal date range is {} - {} ", lowerBoundAsOrdinal, upperBoundAsOrdinal);
}
ourLog.trace("Date range is {} - {}", lowerBoundInstant, upperBoundInstant);
From 2204fbeabd84a75ffd9171daa6c3a7251bd3ee11 Mon Sep 17 00:00:00 2001
From: Gary Graham
Date: Tue, 25 Feb 2020 17:08:11 -0500
Subject: [PATCH 13/27] Adding some comments
---
.../uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
index ae0e3df79ec..a2e0aad60cc 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
@@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.dao.predicate;
* #L%
*/
+import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.SearchBuilder;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
@@ -142,7 +143,13 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
DateParam upperBound = theRange.getUpperBound();
Integer lowerBoundAsOrdinal = theRange.getLowerBoundAsDateInteger();
Integer upperBoundAsOrdinal = theRange.getUpperBoundAsDateInteger();
+
+ /**
+ * If all present search parameters are of DAY precision, and {@link DaoConfig#getUseOrdinalDatesForDayPrecisionSearches()} is true,
+ * then we attempt to use the ordinal field for date comparisons instead of the date field.
+ */
boolean isOrdinalComparison = isNullOrDayPrecision(lowerBound) && isNullOrDayPrecision(upperBound) && myDaoConfig.getUseOrdinalDatesForDayPrecisionSearches();
+
Predicate lt = null;
Predicate gt = null;
Predicate lb = null;
From 165f5fd808a4d6cf5907bf5d8d915629e7e11224 Mon Sep 17 00:00:00 2001
From: Gary Graham
Date: Wed, 26 Feb 2020 09:32:20 -0500
Subject: [PATCH 14/27] fix bugs in calculating ordinal date
---
.../main/java/ca/uhn/fhir/util/DateUtils.java | 8 ++++--
.../ResourceIndexedSearchParamDate.java | 16 +++++++++--
.../ResourceIndexedSearchParamDateTest.java | 27 ++++++++++---------
3 files changed, 34 insertions(+), 17 deletions(-)
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/DateUtils.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/DateUtils.java
index f34a0ee12e5..d208e3fe599 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/DateUtils.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/DateUtils.java
@@ -171,15 +171,19 @@ public final class DateUtils {
return cal.getTime();
}
-
public static int convertDatetoDayInteger(final Date theDateValue) {
notNull(theDateValue, "Date value");
- Calendar cal = org.apache.commons.lang3.time.DateUtils.toCalendar(theDateValue);
SimpleDateFormat format = new SimpleDateFormat(PATTERN_INTEGER_DATE);
String theDateString = format.format(theDateValue);
return Integer.parseInt(theDateString);
}
+ public static String convertDateToIso8601String(final Date theDateValue){
+ notNull(theDateValue, "Date value");
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
+ return format.format(theDateValue);
+ }
+
/**
* Formats the given date according to the RFC 1123 pattern.
*
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
index d38f4dfe440..6a16c59b61e 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
@@ -26,6 +26,7 @@ import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.util.DateUtils;
+import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -34,6 +35,7 @@ import org.hibernate.search.annotations.Field;
import org.hl7.fhir.r4.model.DateTimeType;
import javax.persistence.*;
+import java.text.SimpleDateFormat;
import java.util.Date;
@Embeddable
@@ -93,13 +95,21 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
setParamName(theParamName);
setValueLow(theLow);
setValueHigh(theHigh);
+ if (theHigh != null && theHighString == null) {
+ theHighString = DateUtils.convertDateToIso8601String(theHigh);
+ }
+ if (theLow != null && theLowString == null) {
+ theLowString = DateUtils.convertDateToIso8601String(theLow);
+ }
computeValueHighDateOrdinal(theHighString);
computeValueLowDateOrdinal(theLowString);
myOriginalValue = theOriginalValue;
}
private void computeValueHighDateOrdinal(String theHigh) {
- this.myValueHighDateOrdinal = generateOrdinalDateInteger(theHigh);
+ if (!StringUtils.isBlank(theHigh)) {
+ this.myValueHighDateOrdinal = generateOrdinalDateInteger(theHigh);
+ }
}
private int generateOrdinalDateInteger(String theDateString){
if (theDateString.contains("T")) {
@@ -110,7 +120,9 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
}
private void computeValueLowDateOrdinal(String theLow) {
- this.myValueLowDateOrdinal = generateOrdinalDateInteger(theLow);
+ if (StringUtils.isNotBlank(theLow)) {
+ this.myValueLowDateOrdinal = generateOrdinalDateInteger(theLow);
+ }
}
public Integer getValueLowDateOrdinal() {
diff --git a/hapi-fhir-jpaserver-model/src/test/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDateTest.java b/hapi-fhir-jpaserver-model/src/test/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDateTest.java
index 407d05163f5..4ba8d5517e5 100644
--- a/hapi-fhir-jpaserver-model/src/test/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDateTest.java
+++ b/hapi-fhir-jpaserver-model/src/test/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDateTest.java
@@ -4,6 +4,7 @@ import org.junit.Before;
import org.junit.Test;
import java.sql.Timestamp;
+import java.time.Instant;
import java.util.Calendar;
import java.util.Date;
@@ -45,8 +46,8 @@ public class ResourceIndexedSearchParamDateTest {
@Test
public void equalsIsTrueForMatchingDates() {
- ResourceIndexedSearchParamDate param = new ResourceIndexedSearchParamDate("Patient", "SomeResource", date1A, date1A.toString(), date2A, date2A.toString(), "SomeValue");
- ResourceIndexedSearchParamDate param2 = new ResourceIndexedSearchParamDate("Patient", "SomeResource", date1B, date1B.toString(), date2B, date2B.toString(), "SomeValue");
+ ResourceIndexedSearchParamDate param = new ResourceIndexedSearchParamDate("Patient", "SomeResource", date1A, null, date2A, null, "SomeValue");
+ ResourceIndexedSearchParamDate param2 = new ResourceIndexedSearchParamDate("Patient", "SomeResource", date1B, null, date2B, null, "SomeValue");
assertTrue(param.equals(param2));
assertTrue(param2.equals(param));
@@ -55,8 +56,8 @@ public class ResourceIndexedSearchParamDateTest {
@Test
public void equalsIsTrueForMatchingTimeStampsThatMatch() {
- ResourceIndexedSearchParamDate param = new ResourceIndexedSearchParamDate("Patient", "SomeResource", timestamp1A, timestamp1A.toString(), timestamp2A, timestamp2A.toString(), "SomeValue");
- ResourceIndexedSearchParamDate param2 = new ResourceIndexedSearchParamDate("Patient", "SomeResource", timestamp1B, timestamp1B.toString(), timestamp2B, timestamp2B.toString(), "SomeValue");
+ ResourceIndexedSearchParamDate param = new ResourceIndexedSearchParamDate("Patient", "SomeResource", timestamp1A, null, timestamp2A, null, "SomeValue");
+ ResourceIndexedSearchParamDate param2 = new ResourceIndexedSearchParamDate("Patient", "SomeResource", timestamp1B, null, timestamp2B, null, "SomeValue");
assertTrue(param.equals(param2));
assertTrue(param2.equals(param));
@@ -67,8 +68,8 @@ public class ResourceIndexedSearchParamDateTest {
// other will be equivalent but will be a java.sql.Timestamp. Equals should work in both directions.
@Test
public void equalsIsTrueForMixedTimestampsAndDates() {
- ResourceIndexedSearchParamDate param = new ResourceIndexedSearchParamDate("Patient", "SomeResource", date1A, date1A.toString(), date2A, date2A.toString(), "SomeValue");
- ResourceIndexedSearchParamDate param2 = new ResourceIndexedSearchParamDate("Patient", "SomeResource", timestamp1A, timestamp1A.toString(), timestamp2A, timestamp2A.toString(), "SomeValue");
+ ResourceIndexedSearchParamDate param = new ResourceIndexedSearchParamDate("Patient", "SomeResource", date1A, null, date2A, null, "SomeValue");
+ ResourceIndexedSearchParamDate param2 = new ResourceIndexedSearchParamDate("Patient", "SomeResource", timestamp1A, null, timestamp2A, null, "SomeValue");
assertTrue(param.equals(param2));
assertTrue(param2.equals(param));
@@ -77,8 +78,8 @@ public class ResourceIndexedSearchParamDateTest {
@Test
public void equalsIsFalseForNonMatchingDates() {
- ResourceIndexedSearchParamDate param = new ResourceIndexedSearchParamDate("Patient", "SomeResource", date1A, date1A.toString(), date2A, date2A.toString(), "SomeValue");
- ResourceIndexedSearchParamDate param2 = new ResourceIndexedSearchParamDate("Patient", "SomeResource", date2A, date2A.toString(), date1A, date1A.toString(), "SomeValue");
+ ResourceIndexedSearchParamDate param = new ResourceIndexedSearchParamDate("Patient", "SomeResource", date1A, null, date2A, null, "SomeValue");
+ ResourceIndexedSearchParamDate param2 = new ResourceIndexedSearchParamDate("Patient", "SomeResource", date2A, null, date1A, null, "SomeValue");
assertFalse(param.equals(param2));
assertFalse(param2.equals(param));
@@ -87,7 +88,7 @@ public class ResourceIndexedSearchParamDateTest {
@Test
public void equalsIsFalseForNonMatchingDatesNullCase() {
- ResourceIndexedSearchParamDate param = new ResourceIndexedSearchParamDate("Patient", "SomeResource", date1A, date1A.toString(), date2A, date2A.toString(), "SomeValue");
+ ResourceIndexedSearchParamDate param = new ResourceIndexedSearchParamDate("Patient", "SomeResource", date1A, null, date2A, null, "SomeValue");
ResourceIndexedSearchParamDate param2 = new ResourceIndexedSearchParamDate("Patient", "SomeResource", null, null, null, null, "SomeValue");
assertFalse(param.equals(param2));
@@ -97,8 +98,8 @@ public class ResourceIndexedSearchParamDateTest {
@Test
public void equalsIsFalseForNonMatchingTimeStamps() {
- ResourceIndexedSearchParamDate param = new ResourceIndexedSearchParamDate("Patient", "SomeResource", timestamp1A, timestamp1A.toString(), timestamp2A, timestamp2A.toString(), "SomeValue");
- ResourceIndexedSearchParamDate param2 = new ResourceIndexedSearchParamDate("Patient", "SomeResource", timestamp2A, timestamp2A.toString(), timestamp1A, timestamp1A.toString(), "SomeValue");
+ ResourceIndexedSearchParamDate param = new ResourceIndexedSearchParamDate("Patient", "SomeResource", timestamp1A, null, timestamp2A, null, "SomeValue");
+ ResourceIndexedSearchParamDate param2 = new ResourceIndexedSearchParamDate("Patient", "SomeResource", timestamp2A, null, timestamp1A, null, "SomeValue");
assertFalse(param.equals(param2));
assertFalse(param2.equals(param));
@@ -107,8 +108,8 @@ public class ResourceIndexedSearchParamDateTest {
@Test
public void equalsIsFalseForMixedTimestampsAndDatesThatDoNotMatch() {
- ResourceIndexedSearchParamDate param = new ResourceIndexedSearchParamDate("Patient", "SomeResource", date1A, date1A.toString(), date2A, date2A.toString(), "SomeValue");
- ResourceIndexedSearchParamDate param2 = new ResourceIndexedSearchParamDate("Patient", "SomeResource", timestamp2A, timestamp2A.toString(), timestamp1A, timestamp1A.toString(), "SomeValue");
+ ResourceIndexedSearchParamDate param = new ResourceIndexedSearchParamDate("Patient", "SomeResource", date1A, null, date2A, null, "SomeValue");
+ ResourceIndexedSearchParamDate param2 = new ResourceIndexedSearchParamDate("Patient", "SomeResource", timestamp2A, null, timestamp1A, null, "SomeValue");
assertFalse(param.equals(param2));
assertFalse(param2.equals(param));
From a97443b1ed075845b501a7f42354a1a941ec1e35 Mon Sep 17 00:00:00 2001
From: Gary Graham
Date: Wed, 26 Feb 2020 11:12:27 -0500
Subject: [PATCH 15/27] Fix test failures. One caused by invalid test. One
caused by granularity need LT not LTE
---
.../ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java | 4 ++--
.../fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java | 1 -
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
index 586e9692c95..dade7a7fbbe 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
@@ -222,8 +222,8 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
throw new InvalidRequestException("lowerBound and/or upperBound value not correctly specified for compare operation");
}
if (isOrdinalComparison){
- lt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueLowDateOrdinal"), lowerBoundAsOrdinal);
- gt = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueHighDateOrdinal"), upperBoundAsOrdinal);
+ lt = theBuilder.lessThan(theFrom.get("myValueLowDateOrdinal"), lowerBoundAsOrdinal);
+ gt = theBuilder.greaterThan(theFrom.get("myValueHighDateOrdinal"), upperBoundAsOrdinal);
} else {
lt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueLow"), lowerBoundInstant);
gt = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueHigh"), upperBoundInstant);
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java
index 9d1bbe51f52..143459c3f9b 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java
@@ -3282,7 +3282,6 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
public void testDateSearchParametersShouldBeTimezoneIndependent() {
createObservationWithEffective("NO1", "2011-01-02T23:00:00-11:30");
- createObservationWithEffective("NO2", "2011-01-03T00:00:00+01:00");
createObservationWithEffective("YES01", "2011-01-02T00:00:00-11:30");
createObservationWithEffective("YES02", "2011-01-02T00:00:00-10:00");
From 077f9df814640d37be47af9acfa5b9afbd846ccc Mon Sep 17 00:00:00 2001
From: Gary Graham
Date: Wed, 26 Feb 2020 12:04:33 -0500
Subject: [PATCH 16/27] I keep finding more tests
---
.../fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java | 3 ++-
.../module/matcher/InMemorySubscriptionMatcherR4Test.java | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java
index 143459c3f9b..3e0d4d144d2 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java
@@ -3281,7 +3281,8 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
@Test
public void testDateSearchParametersShouldBeTimezoneIndependent() {
- createObservationWithEffective("NO1", "2011-01-02T23:00:00-11:30");
+ createObservationWithEffective("NO1", "2011-01-01T23:00:00-11:30");
+ createObservationWithEffective("NO2", "2011-01-03T23:00:00+01:30");
createObservationWithEffective("YES01", "2011-01-02T00:00:00-11:30");
createObservationWithEffective("YES02", "2011-01-02T00:00:00-10:00");
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/module/matcher/InMemorySubscriptionMatcherR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/module/matcher/InMemorySubscriptionMatcherR4Test.java
index ee88580d9d6..77e2044500e 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/module/matcher/InMemorySubscriptionMatcherR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/module/matcher/InMemorySubscriptionMatcherR4Test.java
@@ -884,10 +884,10 @@ public class InMemorySubscriptionMatcherR4Test {
public void testDateSearchParametersShouldBeTimezoneIndependent() {
List nlist = new ArrayList<>();
- nlist.add(createObservationWithEffective("NO1", "2011-01-02T23:00:00-11:30"));
- nlist.add(createObservationWithEffective("NO2", "2011-01-03T00:00:00+01:00"));
+ nlist.add(createObservationWithEffective("NO1", "2011-01-03T00:00:00+01:00"));
List ylist = new ArrayList<>();
+ ylist.add(createObservationWithEffective("YES00", "2011-01-02T23:00:00-11:30"));
ylist.add(createObservationWithEffective("YES01", "2011-01-02T00:00:00-11:30"));
ylist.add(createObservationWithEffective("YES02", "2011-01-02T00:00:00-10:00"));
ylist.add(createObservationWithEffective("YES03", "2011-01-02T00:00:00-09:00"));
From 2dc94de6bb13962c715e626f0b95c8ac41805b59 Mon Sep 17 00:00:00 2001
From: Gary Graham
Date: Wed, 26 Feb 2020 14:31:35 -0500
Subject: [PATCH 17/27] roll back change to inmemory matcher test
---
.../module/matcher/InMemorySubscriptionMatcherR4Test.java | 4 ++--
.../jpa/model/entity/ResourceIndexedSearchParamDate.java | 5 +++--
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/module/matcher/InMemorySubscriptionMatcherR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/module/matcher/InMemorySubscriptionMatcherR4Test.java
index 77e2044500e..ee88580d9d6 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/module/matcher/InMemorySubscriptionMatcherR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/module/matcher/InMemorySubscriptionMatcherR4Test.java
@@ -884,10 +884,10 @@ public class InMemorySubscriptionMatcherR4Test {
public void testDateSearchParametersShouldBeTimezoneIndependent() {
List nlist = new ArrayList<>();
- nlist.add(createObservationWithEffective("NO1", "2011-01-03T00:00:00+01:00"));
+ nlist.add(createObservationWithEffective("NO1", "2011-01-02T23:00:00-11:30"));
+ nlist.add(createObservationWithEffective("NO2", "2011-01-03T00:00:00+01:00"));
List ylist = new ArrayList<>();
- ylist.add(createObservationWithEffective("YES00", "2011-01-02T23:00:00-11:30"));
ylist.add(createObservationWithEffective("YES01", "2011-01-02T00:00:00-11:30"));
ylist.add(createObservationWithEffective("YES02", "2011-01-02T00:00:00-10:00"));
ylist.add(createObservationWithEffective("YES03", "2011-01-02T00:00:00-09:00"));
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
index 6a16c59b61e..abb132d093d 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
@@ -242,8 +242,9 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
if (!(theParam instanceof DateParam)) {
return false;
}
- DateParam date = (DateParam) theParam;
- DateRangeParam range = new DateRangeParam(date);
+ DateParam dateParam = (DateParam) theParam;
+ DateRangeParam range = new DateRangeParam(dateParam);
+
Date lowerBound = range.getLowerBoundAsInstant();
Date upperBound = range.getUpperBoundAsInstant();
From f86a4c9fa1cad9b1c3e2dd39ac400812ef3568f6 Mon Sep 17 00:00:00 2001
From: Gary Graham
Date: Wed, 26 Feb 2020 17:05:23 -0500
Subject: [PATCH 18/27] Add date ordinals to subscription matching checker
---
.../java/ca/uhn/fhir/jpa/dao/DaoConfig.java | 40 -----------------
.../dao/predicate/BasePredicateBuilder.java | 1 +
.../dao/predicate/PredicateBuilderDate.java | 2 +-
.../InMemorySubscriptionMatcherR4Test.java | 2 +-
.../BaseResourceIndexedSearchParam.java | 2 +-
.../fhir/jpa/model/entity/ModelConfig.java | 45 +++++++++++++++++--
.../ResourceIndexedSearchParamDate.java | 40 ++++++++++++++---
.../ResourceIndexedSearchParamNumber.java | 2 +-
.../ResourceIndexedSearchParamQuantity.java | 2 +-
.../ResourceIndexedSearchParamString.java | 2 +-
.../ResourceIndexedSearchParamToken.java | 2 +-
.../entity/ResourceIndexedSearchParamUri.java | 2 +-
.../ResourceIndexedSearchParams.java | 4 +-
.../matcher/InMemoryResourceMatcher.java | 6 +--
14 files changed, 91 insertions(+), 61 deletions(-)
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java
index 8d75b767a37..6d6262c1f1c 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java
@@ -100,10 +100,6 @@ public class DaoConfig {
*/
private boolean myAllowInlineMatchUrlReferences = true;
private boolean myAllowMultipleDelete;
- /**
- * Update setter javadoc if default changes.
- */
- private boolean myUseOrdinalDatesForDayPrecisionSearches = true;
/**
* update setter javadoc if default changes
*/
@@ -1912,43 +1908,7 @@ public class DaoConfig {
setPreExpandValueSetsDefaultCount(Math.min(getPreExpandValueSetsDefaultCount(), getPreExpandValueSetsMaxCount()));
}
- /**
- *
- * Should searches use the integer field {@code SP_VALUE_LOW_DATE_ORDINAL} and {@code SP_VALUE_HIGH_DATE_ORDINAL} in
- * {@link ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate} when resolving searches where all predicates are using
- * precision of {@link ca.uhn.fhir.model.api.TemporalPrecisionEnum#DAY}.
- *
- * For example, if enabled, the search of {@code Observation?date=2020-02-25} will cause the date to be collapsed down to an
- * ordinal {@code 20200225}. It would then be compared against {@link ResourceIndexedSearchParamDate#getValueLowDateOrdinal()}
- * and {@link ResourceIndexedSearchParamDate#getValueHighDateOrdinal()}
- *
- * Should searches use the integer field {@code SP_VALUE_LOW_DATE_ORDINAL} and {@code SP_VALUE_HIGH_DATE_ORDINAL} in
- * {@link ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate} when resolving searches where all predicates are using
- * precision of {@link ca.uhn.fhir.model.api.TemporalPrecisionEnum#DAY}.
- *
- * For example, if enabled, the search of {@code Observation?date=2020-02-25} will cause the date to be collapsed down to an
- * integer representing the ordinal date {@code 20200225}. It would then be compared against {@link ResourceIndexedSearchParamDate#getValueLowDateOrdinal()}
- * and {@link ResourceIndexedSearchParamDate#getValueHighDateOrdinal()}
- *
- * Default is {@literal true} beginning in HAPI FHIR 4.3.
- *
- *
- * @since 4.3
- */
- public boolean getUseOrdinalDatesForDayPrecisionSearches() {
- return myUseOrdinalDatesForDayPrecisionSearches;
- }
public enum StoreMetaSourceInformationEnum {
NONE(false, false),
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/BasePredicateBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/BasePredicateBuilder.java
index f5c6c0480ba..6c613e684bb 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/BasePredicateBuilder.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/BasePredicateBuilder.java
@@ -50,6 +50,7 @@ abstract class BasePredicateBuilder {
@Autowired
DaoConfig myDaoConfig;
+
boolean myDontUseHashesForSearch;
final IDao myCallingDao;
final CriteriaBuilder myBuilder;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
index dade7a7fbbe..d8bfb3a7876 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
@@ -171,7 +171,7 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
* If all present search parameters are of DAY precision, and {@link DaoConfig#getUseOrdinalDatesForDayPrecisionSearches()} is true,
* then we attempt to use the ordinal field for date comparisons instead of the date field.
*/
- boolean isOrdinalComparison = isNullOrDayPrecision(lowerBound) && isNullOrDayPrecision(upperBound) && myDaoConfig.getUseOrdinalDatesForDayPrecisionSearches();
+ boolean isOrdinalComparison = isNullOrDayPrecision(lowerBound) && isNullOrDayPrecision(upperBound) && myDaoConfig.getModelConfig().getUseOrdinalDatesForDayPrecisionSearches();
Predicate lt = null;
Predicate gt = null;
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/module/matcher/InMemorySubscriptionMatcherR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/module/matcher/InMemorySubscriptionMatcherR4Test.java
index ee88580d9d6..bb98b5de8d9 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/module/matcher/InMemorySubscriptionMatcherR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/module/matcher/InMemorySubscriptionMatcherR4Test.java
@@ -884,10 +884,10 @@ public class InMemorySubscriptionMatcherR4Test {
public void testDateSearchParametersShouldBeTimezoneIndependent() {
List nlist = new ArrayList<>();
- nlist.add(createObservationWithEffective("NO1", "2011-01-02T23:00:00-11:30"));
nlist.add(createObservationWithEffective("NO2", "2011-01-03T00:00:00+01:00"));
List ylist = new ArrayList<>();
+ nlist.add(createObservationWithEffective("YES00", "2011-01-02T23:00:00-11:30"));
ylist.add(createObservationWithEffective("YES01", "2011-01-02T00:00:00-11:30"));
ylist.add(createObservationWithEffective("YES02", "2011-01-02T00:00:00-10:00"));
ylist.add(createObservationWithEffective("YES03", "2011-01-02T00:00:00-09:00"));
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/BaseResourceIndexedSearchParam.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/BaseResourceIndexedSearchParam.java
index b891a3889b2..4393d0a5a29 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/BaseResourceIndexedSearchParam.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/BaseResourceIndexedSearchParam.java
@@ -133,7 +133,7 @@ public abstract class BaseResourceIndexedSearchParam extends BaseResourceIndex {
public abstract IQueryParameterType toQueryParameterType();
- public boolean matches(IQueryParameterType theParam) {
+ public boolean matches(IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
throw new UnsupportedOperationException("No parameter matcher for " + theParam);
}
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ModelConfig.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ModelConfig.java
index 171c6d31866..1938f069ef6 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ModelConfig.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ModelConfig.java
@@ -60,6 +60,10 @@ public class ModelConfig {
private String myEmailFromAddress = "noreply@unknown.com";
private boolean mySubscriptionMatchingEnabled = true;
private String myWebsocketContextPath = DEFAULT_WEBSOCKET_CONTEXT_PATH;
+ /**
+ * Update setter javadoc if default changes.
+ */
+ private boolean myUseOrdinalDatesForDayPrecisionSearches = true;
/**
* Constructor
@@ -257,7 +261,6 @@ public class ModelConfig {
myTreatReferencesAsLogical = new HashSet<>();
}
myTreatReferencesAsLogical.add(theTreatReferencesAsLogical);
-
}
/**
@@ -340,13 +343,12 @@ public class ModelConfig {
return mySubscriptionMatchingEnabled;
}
+
/**
* If set to true (default is true) the server will match incoming resources against active subscriptions
* and send them to the subscription channel. If set to false no matching or sending occurs.
* @since 3.7.0
*/
-
-
public void setSubscriptionMatchingEnabled(boolean theSubscriptionMatchingEnabled) {
mySubscriptionMatchingEnabled = theSubscriptionMatchingEnabled;
}
@@ -388,6 +390,43 @@ public class ModelConfig {
myWebsocketContextPath = theWebsocketContextPath;
}
+ /**
+ *
+ * Should searches use the integer field {@code SP_VALUE_LOW_DATE_ORDINAL} and {@code SP_VALUE_HIGH_DATE_ORDINAL} in
+ * {@link ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate} when resolving searches where all predicates are using
+ * precision of {@link ca.uhn.fhir.model.api.TemporalPrecisionEnum#DAY}.
+ *
+ * For example, if enabled, the search of {@code Observation?date=2020-02-25} will cause the date to be collapsed down to an
+ * ordinal {@code 20200225}. It would then be compared against {@link ResourceIndexedSearchParamDate#getValueLowDateOrdinal()}
+ * and {@link ResourceIndexedSearchParamDate#getValueHighDateOrdinal()}
+ *
+ * Should searches use the integer field {@code SP_VALUE_LOW_DATE_ORDINAL} and {@code SP_VALUE_HIGH_DATE_ORDINAL} in
+ * {@link ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate} when resolving searches where all predicates are using
+ * precision of {@link ca.uhn.fhir.model.api.TemporalPrecisionEnum#DAY}.
+ *
+ * For example, if enabled, the search of {@code Observation?date=2020-02-25} will cause the date to be collapsed down to an
+ * integer representing the ordinal date {@code 20200225}. It would then be compared against {@link ResourceIndexedSearchParamDate#getValueLowDateOrdinal()}
+ * and {@link ResourceIndexedSearchParamDate#getValueHighDateOrdinal()}
+ *
+ * Default is {@literal true} beginning in HAPI FHIR 4.3.
+ *
+ *
+ * @since 4.3
+ */
+ public boolean getUseOrdinalDatesForDayPrecisionSearches() {
+ return myUseOrdinalDatesForDayPrecisionSearches;
+ }
private static void validateTreatBaseUrlsAsLocal(String theUrl) {
Validate.notBlank(theUrl, "Base URL must not be null or empty");
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
index abb132d093d..9b2b4c93129 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
@@ -35,7 +35,6 @@ import org.hibernate.search.annotations.Field;
import org.hl7.fhir.r4.model.DateTimeType;
import javax.persistence.*;
-import java.text.SimpleDateFormat;
import java.util.Date;
@Embeddable
@@ -238,21 +237,33 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
}
@Override
- public boolean matches(IQueryParameterType theParam) {
+ public boolean matches(IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
if (!(theParam instanceof DateParam)) {
return false;
}
DateParam dateParam = (DateParam) theParam;
DateRangeParam range = new DateRangeParam(dateParam);
+
+
+
+ boolean result;
+ if (theUseOrdinalDatesForDayComparison) {
+ result = matchesOrdinalDateBounds(range);
+ } else {
+ result = matchesDateBounds(range);
+ }
+
+ return result;
+ }
+
+ private boolean matchesDateBounds(DateRangeParam range) {
Date lowerBound = range.getLowerBoundAsInstant();
Date upperBound = range.getUpperBoundAsInstant();
-
if (lowerBound == null && upperBound == null) {
// should never happen
return false;
}
-
boolean result = true;
if (lowerBound != null) {
result &= (myValueLow.after(lowerBound) || myValueLow.equals(lowerBound));
@@ -265,8 +276,27 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
return result;
}
+ private boolean matchesOrdinalDateBounds(DateRangeParam range) {
+ boolean result = true;
+ Integer lowerBoundAsDateInteger = range.getLowerBoundAsDateInteger();
+ Integer upperBoundAsDateInteger = range.getUpperBoundAsDateInteger();
+ if (upperBoundAsDateInteger == null && lowerBoundAsDateInteger == null) {
+ return false;
+ }
+ if (lowerBoundAsDateInteger != null) {
+ result &= (myValueLowDateOrdinal.equals(lowerBoundAsDateInteger) || myValueLowDateOrdinal > lowerBoundAsDateInteger);
+ result &= (myValueHighDateOrdinal.equals(lowerBoundAsDateInteger) || myValueHighDateOrdinal > lowerBoundAsDateInteger);
+ }
+ if (upperBoundAsDateInteger != null) {
+ result &= (myValueHighDateOrdinal.equals(upperBoundAsDateInteger) || myValueHighDateOrdinal < upperBoundAsDateInteger);
+ result &= (myValueLowDateOrdinal.equals(upperBoundAsDateInteger) || myValueLowDateOrdinal < upperBoundAsDateInteger);
+ }
+ return result;
+ }
+
+
public static Long calculateOrdinalValue(Date theDate) {
return (long) DateUtils.convertDatetoDayInteger(theDate);
- };
+ }
}
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamNumber.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamNumber.java
index f88e357ccd7..bb686e6cc5f 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamNumber.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamNumber.java
@@ -158,7 +158,7 @@ public class ResourceIndexedSearchParamNumber extends BaseResourceIndexedSearchP
}
@Override
- public boolean matches(IQueryParameterType theParam) {
+ public boolean matches(IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
if (!(theParam instanceof NumberParam)) {
return false;
}
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamQuantity.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamQuantity.java
index 6107df7884d..8b9787a63db 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamQuantity.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamQuantity.java
@@ -237,7 +237,7 @@ public class ResourceIndexedSearchParamQuantity extends BaseResourceIndexedSearc
}
@Override
- public boolean matches(IQueryParameterType theParam) {
+ public boolean matches(IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
if (!(theParam instanceof QuantityParam)) {
return false;
}
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamString.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamString.java
index 155bf7a8da3..714c2cd6f98 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamString.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamString.java
@@ -314,7 +314,7 @@ public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchP
}
@Override
- public boolean matches(IQueryParameterType theParam) {
+ public boolean matches(IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
if (!(theParam instanceof StringParam)) {
return false;
}
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamToken.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamToken.java
index 44a14bf41ee..f18c2d53157 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamToken.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamToken.java
@@ -239,7 +239,7 @@ public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchPa
}
@Override
- public boolean matches(IQueryParameterType theParam) {
+ public boolean matches(IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
if (!(theParam instanceof TokenParam)) {
return false;
}
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamUri.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamUri.java
index c827890d54b..6247dc668d1 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamUri.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamUri.java
@@ -188,7 +188,7 @@ public class ResourceIndexedSearchParamUri extends BaseResourceIndexedSearchPara
}
@Override
- public boolean matches(IQueryParameterType theParam) {
+ public boolean matches(IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
if (!(theParam instanceof UriParam)) {
return false;
}
diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/ResourceIndexedSearchParams.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/ResourceIndexedSearchParams.java
index 73f0df466c1..9dff7395b62 100644
--- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/ResourceIndexedSearchParams.java
+++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/ResourceIndexedSearchParams.java
@@ -217,7 +217,7 @@ public final class ResourceIndexedSearchParams {
return myPopulatedResourceLinkParameters;
}
- public boolean matchParam(String theResourceName, String theParamName, RuntimeSearchParam theParamDef, IQueryParameterType theParam) {
+ public boolean matchParam(String theResourceName, String theParamName, RuntimeSearchParam theParamDef, IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
if (theParamDef == null) {
return false;
}
@@ -254,7 +254,7 @@ public final class ResourceIndexedSearchParams {
}
Predicate namedParamPredicate = param ->
param.getParamName().equalsIgnoreCase(theParamName) &&
- param.matches(theParam);
+ param.matches(theParam, theUseOrdinalDatesForDayComparison);
return resourceParams.stream().anyMatch(namedParamPredicate);
}
diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java
index d83eb5048c9..2b52d347e91 100644
--- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java
+++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java
@@ -202,7 +202,7 @@ public class InMemoryResourceMatcher {
if (theSearchParams == null) {
return InMemoryMatchResult.successfulMatch();
} else {
- return InMemoryMatchResult.fromBoolean(theAndOrParams.stream().anyMatch(nextAnd -> matchParams(theResourceName, theParamName, theParamDef, nextAnd, theSearchParams)));
+ return InMemoryMatchResult.fromBoolean(theAndOrParams.stream().anyMatch(nextAnd -> matchParams(theResourceName, theParamName, theParamDef, nextAnd, theSearchParams, myModelConfig.getUseOrdinalDatesForDayPrecisionSearches())));
}
case COMPOSITE:
case HAS:
@@ -219,11 +219,11 @@ public class InMemoryResourceMatcher {
}
}
- private boolean matchParams(String theResourceName, String theParamName, RuntimeSearchParam paramDef, List extends IQueryParameterType> theNextAnd, ResourceIndexedSearchParams theSearchParams) {
+ private boolean matchParams(String theResourceName, String theParamName, RuntimeSearchParam paramDef, List extends IQueryParameterType> theNextAnd, ResourceIndexedSearchParams theSearchParams, boolean theUseOrdinalDatesForDayComparison) {
if (paramDef.getParamType() == RestSearchParameterTypeEnum.REFERENCE) {
stripBaseUrlsFromReferenceParams(theNextAnd);
}
- return theNextAnd.stream().anyMatch(token -> theSearchParams.matchParam(theResourceName, theParamName, paramDef, token));
+ return theNextAnd.stream().anyMatch(token -> theSearchParams.matchParam(theResourceName, theParamName, paramDef, token, theUseOrdinalDatesForDayComparison));
}
private void stripBaseUrlsFromReferenceParams(List extends IQueryParameterType> theNextAnd) {
From b1d7072c42d20e15d319675a923c51961b30e6c3 Mon Sep 17 00:00:00 2001
From: Gary Graham
Date: Wed, 26 Feb 2020 22:22:42 -0500
Subject: [PATCH 19/27] Add precision checker for ordinal date returning on
DateRangeParam
---
.../uhn/fhir/rest/param/DateRangeParam.java | 42 ++++++++++++++++++-
.../ResourceIndexedSearchParamDate.java | 2 +
.../InMemoryResourceMatcherR5Test.java | 4 +-
3 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java
index d5f491a0f07..a948c247b97 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java
@@ -272,7 +272,27 @@ public class DateRangeParam implements IQueryParameterAnd {
if (myLowerBound == null || myLowerBound.getValue() == null) {
return null;
}
- return DateUtils.convertDatetoDayInteger(myLowerBound.getValue());
+ //TODO LOOK AT THE DATE VERSION, WHERE PRECISION OCCASIONALLY CHANGES THE STUPID THING. ESSENTIALLY ADD A SWITCH
+ int retVal = DateUtils.convertDatetoDayInteger(myLowerBound.getValue());
+
+ if (myLowerBound.getPrefix() != null) {
+ switch (myLowerBound.getPrefix()) {
+ case GREATERTHAN:
+ case STARTS_AFTER:
+ retVal += 1;
+ break;
+ case EQUAL:
+ case GREATERTHAN_OR_EQUALS:
+ break;
+ case LESSTHAN:
+ case APPROXIMATE:
+ case LESSTHAN_OR_EQUALS:
+ case ENDS_BEFORE:
+ case NOT_EQUAL:
+ throw new IllegalStateException("Invalid lower bound comparator: " + myLowerBound.getPrefix());
+ }
+ }
+ return retVal;
}
/**
@@ -284,7 +304,25 @@ public class DateRangeParam implements IQueryParameterAnd {
if (myUpperBound == null || myUpperBound.getValue() == null) {
return null;
}
- return DateUtils.convertDatetoDayInteger(myUpperBound.getValue());
+ int retVal = DateUtils.convertDatetoDayInteger(myUpperBound.getValue());
+ if (myUpperBound.getPrefix() != null) {
+ switch (myUpperBound.getPrefix()) {
+ case LESSTHAN:
+ case ENDS_BEFORE:
+ retVal -= 1;
+ break;
+ case EQUAL:
+ case LESSTHAN_OR_EQUALS:
+ break;
+ case GREATERTHAN_OR_EQUALS:
+ case GREATERTHAN:
+ case APPROXIMATE:
+ case NOT_EQUAL:
+ case STARTS_AFTER:
+ throw new IllegalStateException("Invalid upper bound comparator: " + myUpperBound.getPrefix());
+ }
+ }
+ return retVal;
}
public Date getLowerBoundAsInstant() {
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
index 9b2b4c93129..93e90200079 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
@@ -250,6 +250,7 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
boolean result;
if (theUseOrdinalDatesForDayComparison) {
result = matchesOrdinalDateBounds(range);
+ result = matchesDateBounds(range);
} else {
result = matchesDateBounds(range);
}
@@ -284,6 +285,7 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
return false;
}
if (lowerBoundAsDateInteger != null) {
+ //TODO as we run into equality issues
result &= (myValueLowDateOrdinal.equals(lowerBoundAsDateInteger) || myValueLowDateOrdinal > lowerBoundAsDateInteger);
result &= (myValueHighDateOrdinal.equals(lowerBoundAsDateInteger) || myValueHighDateOrdinal > lowerBoundAsDateInteger);
}
diff --git a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java
index bb111f87e86..daf4215ed68 100644
--- a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java
+++ b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java
@@ -148,8 +148,8 @@ public class InMemoryResourceMatcherR5Test {
@Test
public void testDateSupportedOps() {
- testDateSupportedOp(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, true, true, false);
testDateSupportedOp(ParamPrefixEnum.GREATERTHAN, true, false, false);
+ testDateSupportedOp(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, true, true, false);
testDateSupportedOp(ParamPrefixEnum.EQUAL, false, true, false);
testDateSupportedOp(ParamPrefixEnum.LESSTHAN_OR_EQUALS, false, true, true);
testDateSupportedOp(ParamPrefixEnum.LESSTHAN, false, false, true);
@@ -165,7 +165,7 @@ public class InMemoryResourceMatcherR5Test {
{
InMemoryMatchResult result = myInMemoryResourceMatcher.match(equation + OBSERVATION_DATE, myObservation, mySearchParams);
assertTrue(result.getUnsupportedReason(), result.supported());
- assertEquals(result.matched(), theSame);
+ assertEquals(theSame, result.matched());
}
{
InMemoryMatchResult result = myInMemoryResourceMatcher.match(equation + LATE_DATE, myObservation, mySearchParams);
From 6123e4b189e450952043cf29c705ccda0ad1a12e Mon Sep 17 00:00:00 2001
From: Gary Graham
Date: Fri, 28 Feb 2020 16:31:16 -0500
Subject: [PATCH 20/27] rework based on PR comments
---
.../dao/predicate/PredicateBuilderDate.java | 71 +++++++------------
1 file changed, 27 insertions(+), 44 deletions(-)
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
index d8bfb3a7876..fc509b95aa8 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
@@ -166,7 +166,8 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
DateParam upperBound = theRange.getUpperBound();
Integer lowerBoundAsOrdinal = theRange.getLowerBoundAsDateInteger();
Integer upperBoundAsOrdinal = theRange.getUpperBoundAsDateInteger();
-
+ Comparable genericLowerBound;
+ Comparable genericUpperBound;
/**
* If all present search parameters are of DAY precision, and {@link DaoConfig#getUseOrdinalDatesForDayPrecisionSearches()} is true,
* then we attempt to use the ordinal field for date comparisons instead of the date field.
@@ -177,70 +178,56 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
Predicate gt = null;
Predicate lb = null;
Predicate ub = null;
+ String lowValueField;
+ String highValueField;
+
+ if (isOrdinalComparison) {
+ lowValueField = "myValueLowDateOrdinal";
+ highValueField = "myValueHighDateOrdinal";
+ genericLowerBound = lowerBoundAsOrdinal;
+ genericUpperBound = upperBoundAsOrdinal;
+ } else {
+ lowValueField = "myValueLow";
+ highValueField = "myValueHigh";
+ genericLowerBound = lowerBoundInstant;
+ genericUpperBound = upperBoundInstant;
+ }
if (operation == SearchFilterParser.CompareOperation.lt) {
if (lowerBoundInstant == null) {
throw new InvalidRequestException("lowerBound value not correctly specified for compare operation");
}
//im like 80% sure this should be ub and not lb, as it is an UPPER bound.
- if (isOrdinalComparison) {
- lb = theBuilder.lessThan(theFrom.get("myValueLowDateOrdinal"), lowerBoundAsOrdinal);
- } else {
- lb = theBuilder.lessThan(theFrom.get("myValueLow"), lowerBoundInstant);
- }
+ lb = theBuilder.lessThan(theFrom.get(lowValueField), genericLowerBound);
} else if (operation == SearchFilterParser.CompareOperation.le) {
if (upperBoundInstant == null) {
throw new InvalidRequestException("upperBound value not correctly specified for compare operation");
}
//im like 80% sure this should be ub and not lb, as it is an UPPER bound.
- if (isOrdinalComparison) {
- lb = theBuilder.lessThanOrEqualTo(theFrom.get("myValueHighDateOrdinal"), upperBoundAsOrdinal);
- } else {
- lb = theBuilder.lessThanOrEqualTo(theFrom.get("myValueHigh"), upperBoundInstant);
- }
+ lb = theBuilder.lessThanOrEqualTo(theFrom.get(highValueField), genericUpperBound);
} else if (operation == SearchFilterParser.CompareOperation.gt) {
if (upperBoundInstant == null) {
throw new InvalidRequestException("upperBound value not correctly specified for compare operation");
}
- if (isOrdinalComparison) {
- lb = theBuilder.greaterThan(theFrom.get("myValueHighDateOrdinal"), upperBoundAsOrdinal);
- } else {
- lb = theBuilder.greaterThan(theFrom.get("myValueHigh"), upperBoundInstant);
- }
+ lb = theBuilder.greaterThan(theFrom.get(highValueField), genericUpperBound);
} else if (operation == SearchFilterParser.CompareOperation.ge) {
if (lowerBoundInstant == null) {
throw new InvalidRequestException("lowerBound value not correctly specified for compare operation");
}
- if (isOrdinalComparison) {
- lb = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueLowDateOrdinal"), lowerBoundAsOrdinal);
- } else {
- lb = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueLow"), lowerBoundInstant);
- }
+ lb = theBuilder.greaterThanOrEqualTo(theFrom.get(lowValueField), genericLowerBound);
} else if (operation == SearchFilterParser.CompareOperation.ne) {
if ((lowerBoundInstant == null) ||
(upperBoundInstant == null)) {
throw new InvalidRequestException("lowerBound and/or upperBound value not correctly specified for compare operation");
}
- if (isOrdinalComparison){
- lt = theBuilder.lessThan(theFrom.get("myValueLowDateOrdinal"), lowerBoundAsOrdinal);
- gt = theBuilder.greaterThan(theFrom.get("myValueHighDateOrdinal"), upperBoundAsOrdinal);
- } else {
- lt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueLow"), lowerBoundInstant);
- gt = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueHigh"), upperBoundInstant);
- }
+ lt = theBuilder.lessThan(theFrom.get(lowValueField), genericLowerBound);
+ gt = theBuilder.greaterThan(theFrom.get(highValueField), genericUpperBound);
lb = theBuilder.or(lt,
gt);
} else if ((operation == SearchFilterParser.CompareOperation.eq) || (operation == null)) {
if (lowerBoundInstant != null) {
- if (isOrdinalComparison) {
- gt = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueLowDateOrdinal"), lowerBoundAsOrdinal);
- lt = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueHighDateOrdinal"), lowerBoundAsOrdinal);
- //also try a strict equality here.
- }
- else {
- gt = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueLow"), lowerBoundInstant);
- lt = theBuilder.greaterThanOrEqualTo(theFrom.get("myValueHigh"), lowerBoundInstant);
- }
+ gt = theBuilder.greaterThanOrEqualTo(theFrom.get(lowValueField), genericLowerBound);
+ lt = theBuilder.greaterThanOrEqualTo(theFrom.get(highValueField), genericLowerBound);
if (lowerBound.getPrefix() == ParamPrefixEnum.STARTS_AFTER || lowerBound.getPrefix() == ParamPrefixEnum.EQUAL) {
lb = gt;
} else {
@@ -249,13 +236,9 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
}
if (upperBoundInstant != null) {
- if (isOrdinalComparison) {
- gt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueLowDateOrdinal"), upperBoundAsOrdinal);
- lt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueHighDateOrdinal"), upperBoundAsOrdinal);
- } else {
- gt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueLow"), upperBoundInstant);
- lt = theBuilder.lessThanOrEqualTo(theFrom.get("myValueHigh"), upperBoundInstant);
- }
+ gt = theBuilder.lessThanOrEqualTo(theFrom.get(lowValueField), genericUpperBound);
+ lt = theBuilder.lessThanOrEqualTo(theFrom.get(highValueField), genericUpperBound);
+
if (theRange.getUpperBound().getPrefix() == ParamPrefixEnum.ENDS_BEFORE || theRange.getUpperBound().getPrefix() == ParamPrefixEnum.EQUAL) {
ub = lt;
From df7a9916c39d66422eb8a67f7d3fa4ebf4accaf3 Mon Sep 17 00:00:00 2001
From: Tadgh
Date: Tue, 3 Mar 2020 14:01:12 -0800
Subject: [PATCH 21/27] Swap from trace to info logging
---
hapi-fhir-jpaserver-base/src/test/resources/logback-test.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hapi-fhir-jpaserver-base/src/test/resources/logback-test.xml b/hapi-fhir-jpaserver-base/src/test/resources/logback-test.xml
index c8a33e5568b..6818eb0a0f3 100644
--- a/hapi-fhir-jpaserver-base/src/test/resources/logback-test.xml
+++ b/hapi-fhir-jpaserver-base/src/test/resources/logback-test.xml
@@ -27,7 +27,7 @@
-
+
From a5105439339d6cb94ed22308c97822932d20ad0e Mon Sep 17 00:00:00 2001
From: Tadgh
Date: Tue, 3 Mar 2020 14:03:55 -0800
Subject: [PATCH 22/27] Fix log conditional
---
.../ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
index fc509b95aa8..cb80ed64a5e 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderDate.java
@@ -252,8 +252,9 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
}
if (isOrdinalComparison) {
ourLog.trace("Ordinal date range is {} - {} ", lowerBoundAsOrdinal, upperBoundAsOrdinal);
+ } else {
+ ourLog.trace("Date range is {} - {}", lowerBoundInstant, upperBoundInstant);
}
- ourLog.trace("Date range is {} - {}", lowerBoundInstant, upperBoundInstant);
if (lb != null && ub != null) {
return (theBuilder.and(lb, ub));
From 8b223a1fd9d7a34f22fdb688472ae59db524e93e Mon Sep 17 00:00:00 2001
From: Tadgh
Date: Tue, 3 Mar 2020 16:07:25 -0800
Subject: [PATCH 23/27] Rework selection generation of calculator. Add null
check for empty dates
---
.../migrate/taskdef/BaseColumnCalculatorTask.java | 6 +++---
.../jpa/migrate/taskdef/BaseTableColumnTask.java | 14 +++++++++++++-
.../fhir/jpa/migrate/taskdef/BaseTableTask.java | 3 ++-
.../migrate/taskdef/CalculateOrdinalDatesTask.java | 4 +++-
.../entity/ResourceIndexedSearchParamDate.java | 3 +++
5 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseColumnCalculatorTask.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseColumnCalculatorTask.java
index ddd5300bfcb..909d830bec3 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseColumnCalculatorTask.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseColumnCalculatorTask.java
@@ -20,7 +20,6 @@ package ca.uhn.fhir.jpa.migrate.taskdef;
* #L%
*/
-import ca.uhn.fhir.jpa.migrate.JdbcUtils;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.VersionEnum;
import com.google.common.collect.ForwardingMap;
@@ -77,8 +76,9 @@ public abstract class BaseColumnCalculatorTask extends BaseTableColumnTask {
JdbcTemplate jdbcTemplate = newJdbcTemplate();
jdbcTemplate.setMaxRows(100000);
- String sql = "SELECT * FROM " + getTableName() + " WHERE " + getColumnName() + " IS NULL";
- logInfo(ourLog, "Finding up to {} rows in {} that requires calculations", myBatchSize, getTableName());
+
+ String sql = "SELECT * FROM " + getTableName() + " WHERE " + getWhereClause();
+ logInfo(ourLog, "Finding up to {} rows in {} that requires calculations, using query: {}", myBatchSize, getTableName(), sql);
jdbcTemplate.query(sql, rch);
rch.done();
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTask.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTask.java
index e4e024ed1e1..dc38d081ad4 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTask.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTask.java
@@ -30,6 +30,8 @@ import java.util.Locale;
public abstract class BaseTableColumnTask> extends BaseTableTask {
private String myColumnName;
+ //If a concrete class decides to, they can define a custom WHERE clause for the task.
+ private String myWhereClause;
public BaseTableColumnTask(String theProductVersion, String theSchemaVersion) {
super(theProductVersion, theSchemaVersion);
@@ -41,11 +43,21 @@ public abstract class BaseTableColumnTask> extends Ba
return (T) this;
}
-
public String getColumnName() {
return myColumnName;
}
+ protected void setWhereClause(String theWhereClause) {
+ this.myWhereClause = theWhereClause;
+ }
+ protected String getWhereClause() {
+ if (myWhereClause == null) {
+ return getColumnName() + " IS NULL";
+ } else {
+ return myWhereClause;
+ }
+ }
+
@Override
public void validate() {
super.validate();
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableTask.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableTask.java
index 3fce1b54fa3..73def6f5bc0 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableTask.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableTask.java
@@ -27,6 +27,8 @@ import org.apache.commons.lang3.builder.HashCodeBuilder;
public abstract class BaseTableTask> extends BaseTask {
private String myTableName;
+
+
public BaseTableTask(String theProductVersion, String theSchemaVersion) {
super(theProductVersion, theSchemaVersion);
}
@@ -34,7 +36,6 @@ public abstract class BaseTableTask> extends BaseTask
public String getTableName() {
return myTableName;
}
-
public T setTableName(String theTableName) {
Validate.notBlank(theTableName);
myTableName = theTableName;
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java
index d0d16c1e8d4..29371cc1c6d 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java
@@ -26,8 +26,10 @@ public class CalculateOrdinalDatesTask extends BaseColumnCalculatorTask {
public CalculateOrdinalDatesTask(VersionEnum theRelease, String theVersion) {
super(theRelease, theVersion);
- setDescription("Calculate SP_LOW_VALUE_DATE and SP_HIGH_VALUE_DATE based on existing SP_LOW and SP_HIGH date values in Date Search Params");
+ setDescription("Calculate SP_LOW_VALUE_DATE_ORDINAL and SP_HIGH_VALUE_DATE_ORDINAL based on existing SP_VALUE_LOW and SP_VALUE_HIGH date values in Date Search Params");
+ setWhereClause("SP_VALUE_LOW_DATE_ORDINAL IS NULL AND SP_VALUE_LOW IS NOT NULL) OR (SP_VALUE_HIGH_DATE_ORDINAL IS NULL AND SP_VALUE_HIGH IS NOT NULL");
}
+
@Override
protected boolean shouldSkipTask() {
return false; // TODO Is there a case where we should just not do this?
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
index 93e90200079..8ef1d524fe2 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamDate.java
@@ -298,6 +298,9 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
public static Long calculateOrdinalValue(Date theDate) {
+ if (theDate == null) {
+ return null;
+ }
return (long) DateUtils.convertDatetoDayInteger(theDate);
}
From 14f671ec0bfc158a4dd3b5909983733dd15b744c Mon Sep 17 00:00:00 2001
From: Tadgh
Date: Tue, 3 Mar 2020 22:31:37 -0800
Subject: [PATCH 24/27] Fix SQL Typo
---
.../uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java
index 29371cc1c6d..22e1c0ec206 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java
@@ -27,7 +27,7 @@ public class CalculateOrdinalDatesTask extends BaseColumnCalculatorTask {
public CalculateOrdinalDatesTask(VersionEnum theRelease, String theVersion) {
super(theRelease, theVersion);
setDescription("Calculate SP_LOW_VALUE_DATE_ORDINAL and SP_HIGH_VALUE_DATE_ORDINAL based on existing SP_VALUE_LOW and SP_VALUE_HIGH date values in Date Search Params");
- setWhereClause("SP_VALUE_LOW_DATE_ORDINAL IS NULL AND SP_VALUE_LOW IS NOT NULL) OR (SP_VALUE_HIGH_DATE_ORDINAL IS NULL AND SP_VALUE_HIGH IS NOT NULL");
+ setWhereClause("SP_VALUE_LOW_DATE_ORDINAL IS NULL AND SP_VALUE_LOW IS NOT NULL) OR (SP_VALUE_HIGH_DATE_ORDINAL IS NULL AND SP_VALUE_HIGH IS NOT NULL)");
}
@Override
From 598bf56e871604eec1cdcf841de19990e4706c1e Mon Sep 17 00:00:00 2001
From: Tadgh
Date: Wed, 4 Mar 2020 08:56:03 -0800
Subject: [PATCH 25/27] Broken SQL Statement
---
.../uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java
index 22e1c0ec206..78cbfda2474 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java
@@ -27,7 +27,7 @@ public class CalculateOrdinalDatesTask extends BaseColumnCalculatorTask {
public CalculateOrdinalDatesTask(VersionEnum theRelease, String theVersion) {
super(theRelease, theVersion);
setDescription("Calculate SP_LOW_VALUE_DATE_ORDINAL and SP_HIGH_VALUE_DATE_ORDINAL based on existing SP_VALUE_LOW and SP_VALUE_HIGH date values in Date Search Params");
- setWhereClause("SP_VALUE_LOW_DATE_ORDINAL IS NULL AND SP_VALUE_LOW IS NOT NULL) OR (SP_VALUE_HIGH_DATE_ORDINAL IS NULL AND SP_VALUE_HIGH IS NOT NULL)");
+ setWhereClause("(SP_VALUE_LOW_DATE_ORDINAL IS NULL AND SP_VALUE_LOW IS NOT NULL) OR (SP_VALUE_HIGH_DATE_ORDINAL IS NULL AND SP_VALUE_HIGH IS NOT NULL)");
}
@Override
From 828ddd51854164d18b0f276af45cff0ac78330aa Mon Sep 17 00:00:00 2001
From: Tadgh
Date: Wed, 4 Mar 2020 12:14:55 -0800
Subject: [PATCH 26/27] Update docs
---
.../src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java | 1 -
.../main/resources/ca/uhn/hapi/fhir/docs/server_jpa/search.md | 4 ----
2 files changed, 5 deletions(-)
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java
index a948c247b97..609a49ebd06 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java
@@ -272,7 +272,6 @@ public class DateRangeParam implements IQueryParameterAnd {
if (myLowerBound == null || myLowerBound.getValue() == null) {
return null;
}
- //TODO LOOK AT THE DATE VERSION, WHERE PRECISION OCCASIONALLY CHANGES THE STUPID THING. ESSENTIALLY ADD A SWITCH
int retVal = DateUtils.convertDatetoDayInteger(myLowerBound.getValue());
if (myLowerBound.getPrefix() != null) {
diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/search.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/search.md
index 26fe08dc30c..44f8fc19b8f 100644
--- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/search.md
+++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/search.md
@@ -2,10 +2,6 @@
The HAPI FHIR JPA Server fully implements most [FHIR search](https://www.hl7.org/fhir/search.html) operations for most versions of FHIR. However, there are some known limitations of the current implementation. Here is a partial list of search functionality that is not currently supported in HAPI FHIR:
-### Date searches without timestamp
-
-Searching by date with no timestamp currently doesn't match all records it should. See [Issue 1499](https://github.com/jamesagnew/hapi-fhir/issues/1499).
-
### Chains within _has
Chains within _has are not currently supported for performance reasons. For example, this search is not currently supported
From a5e1b3d159b545f5806913cca21ba69a1784afa7 Mon Sep 17 00:00:00 2001
From: Tadgh
Date: Wed, 29 Apr 2020 16:18:02 -0700
Subject: [PATCH 27/27] Minor changes for merge conflicts
---
.../migrate/taskdef/BaseColumnCalculatorTask.java | 9 +--------
.../jpa/migrate/taskdef/BaseTableColumnTask.java | 14 ++++++++++++--
.../migrate/tasks/HapiFhirJpaMigrationTasks.java | 10 +++++-----
3 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseColumnCalculatorTask.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseColumnCalculatorTask.java
index 909d830bec3..447a95df39c 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseColumnCalculatorTask.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseColumnCalculatorTask.java
@@ -37,11 +37,10 @@ import java.util.*;
import java.util.concurrent.*;
import java.util.function.Function;
-public abstract class BaseColumnCalculatorTask extends BaseTableColumnTask {
+public abstract class BaseColumnCalculatorTask extends BaseTableColumnTask {
protected static final Logger ourLog = LoggerFactory.getLogger(BaseColumnCalculatorTask.class);
private int myBatchSize = 10000;
- private Map, Object>> myCalculators = new HashMap<>();
private ThreadPoolExecutor myExecutor;
public void setBatchSize(int theBatchSize) {
@@ -191,12 +190,6 @@ public abstract class BaseColumnCalculatorTask extends BaseTableColumnTask, Object> theConsumer) {
- Validate.isTrue(myCalculators.containsKey(theColumnName) == false);
- myCalculators.put(theColumnName, theConsumer);
- return this;
- }
-
private class MyRowCallbackHandler implements RowCallbackHandler {
private List> myRows = new ArrayList<>();
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTask.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTask.java
index 567ebf7e052..703e64c510b 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTask.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTask.java
@@ -25,13 +25,17 @@ import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.thymeleaf.util.StringUtils;
+import java.util.HashMap;
import java.util.Locale;
+import java.util.Map;
+import java.util.function.Function;
public abstract class BaseTableColumnTask extends BaseTableTask {
- private String myColumnName;
+ protected Map, Object>> myCalculators = new HashMap<>();
+ protected String myColumnName;
//If a concrete class decides to, they can define a custom WHERE clause for the task.
- private String myWhereClause;
+ protected String myWhereClause;
public BaseTableColumnTask(String theProductVersion, String theSchemaVersion) {
super(theProductVersion, theSchemaVersion);
@@ -75,4 +79,10 @@ public abstract class BaseTableColumnTask extends BaseTableTask {
super.generateHashCode(theBuilder);
theBuilder.append(myColumnName);
}
+
+ public BaseTableColumnTask addCalculator(String theColumnName, Function, Object> theConsumer) {
+ Validate.isTrue(myCalculators.containsKey(theColumnName) == false);
+ myCalculators.put(theColumnName, theConsumer);
+ return this;
+ }
}
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java
index 7b8fdb0c097..7220bf0ced6 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java
@@ -78,9 +78,9 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks {
spidxDate.addColumn("20200225.2", "SP_VALUE_HIGH_DATE_ORDINAL").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.INT);
spidxDate.addTask(new CalculateOrdinalDatesTask(VersionEnum.V4_3_0, "20200225.3")
- .setColumnName("SP_VALUE_LOW_DATE_ORDINAL") //It doesn't matter which of the two we choose as they will both be null.
.addCalculator("SP_VALUE_LOW_DATE_ORDINAL", t -> ResourceIndexedSearchParamDate.calculateOrdinalValue(t.getDate("SP_VALUE_LOW")))
.addCalculator("SP_VALUE_HIGH_DATE_ORDINAL", t -> ResourceIndexedSearchParamDate.calculateOrdinalValue(t.getDate("SP_VALUE_HIGH")))
+ .setColumnName("SP_VALUE_LOW_DATE_ORDINAL") //It doesn't matter which of the two we choose as they will both be null.
);
//
@@ -541,8 +541,8 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks {
.withColumns("HASH_IDENTITY", "SP_LATITUDE", "SP_LONGITUDE");
spidxCoords
.addTask(new CalculateHashesTask(VersionEnum.V3_5_0, "20180903.5")
- .setColumnName("HASH_IDENTITY")
.addCalculator("HASH_IDENTITY", t -> BaseResourceIndexedSearchParam.calculateHashIdentity(new PartitionSettings(), null, t.getResourceType(), t.getString("SP_NAME")))
+ .setColumnName("HASH_IDENTITY")
);
}
@@ -564,8 +564,8 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks {
.dropIndex("20180903.9", "IDX_SP_DATE");
spidxDate
.addTask(new CalculateHashesTask(VersionEnum.V3_5_0, "20180903.10")
- .setColumnName("HASH_IDENTITY")
.addCalculator("HASH_IDENTITY", t -> BaseResourceIndexedSearchParam.calculateHashIdentity(new PartitionSettings(), null, t.getResourceType(), t.getString("SP_NAME")))
+ .setColumnName("HASH_IDENTITY")
);
}
@@ -585,8 +585,8 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks {
.withColumns("HASH_IDENTITY", "SP_VALUE");
spidxNumber
.addTask(new CalculateHashesTask(VersionEnum.V3_5_0, "20180903.14")
- .setColumnName("HASH_IDENTITY")
.addCalculator("HASH_IDENTITY", t -> BaseResourceIndexedSearchParam.calculateHashIdentity(new PartitionSettings(), null, t.getResourceType(), t.getString("SP_NAME")))
+ .setColumnName("HASH_IDENTITY")
);
}
@@ -622,10 +622,10 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks {
.withColumns("HASH_IDENTITY_SYS_UNITS", "SP_VALUE");
spidxQuantity
.addTask(new CalculateHashesTask(VersionEnum.V3_5_0, "20180903.22")
- .setColumnName("HASH_IDENTITY")
.addCalculator("HASH_IDENTITY", t -> BaseResourceIndexedSearchParam.calculateHashIdentity(new PartitionSettings(), null, t.getResourceType(), t.getString("SP_NAME")))
.addCalculator("HASH_IDENTITY_AND_UNITS", t -> ResourceIndexedSearchParamQuantity.calculateHashUnits(new PartitionSettings(), null, t.getResourceType(), t.getString("SP_NAME"), t.getString("SP_UNITS")))
.addCalculator("HASH_IDENTITY_SYS_UNITS", t -> ResourceIndexedSearchParamQuantity.calculateHashSystemAndUnits(new PartitionSettings(), null, t.getResourceType(), t.getString("SP_NAME"), t.getString("SP_SYSTEM"), t.getString("SP_UNITS")))
+ .setColumnName("HASH_IDENTITY")
);
}