* Initial commit of _filter keyword implementation. * - Completed all search parameter types for _filter. - Implemented handling for _has, _id, _security, language, _profile, _security, and _tag. * - Changes to support "ne" matching on resource ID for _filter * Implemented language * Commit/push before creation of pull request * Ongoing merge work * Ongoing merge work * Merge master in * Test fix
This commit is contained in:
parent
f0121ccf9a
commit
301a8f8432
|
@ -138,6 +138,7 @@ public class Constants {
|
|||
* Used in paging links
|
||||
*/
|
||||
public static final String PARAM_BUNDLETYPE = "_bundletype";
|
||||
public static final String PARAM_FILTER = "_filter";
|
||||
public static final String PARAM_CONTENT = "_content";
|
||||
public static final String PARAM_COUNT = "_count";
|
||||
public static final String PARAM_DELETE = "_delete";
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum;
|
||||
import ca.uhn.fhir.jpa.search.warm.WarmCacheEntry;
|
||||
|
@ -149,6 +150,7 @@ public class DaoConfig {
|
|||
* EXPERIMENTAL - Do not use in production! Do not change default of {@code false}!
|
||||
*/
|
||||
private boolean myPreExpandValueSetsExperimental = false;
|
||||
private boolean myFilterParameterEnabled = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -972,7 +974,7 @@ public class DaoConfig {
|
|||
* and other FHIR features may not behave as expected when referential integrity is not
|
||||
* preserved. Use this feature with caution.
|
||||
* </p>
|
||||
* @see ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor
|
||||
* @see CascadingDeleteInterceptor
|
||||
*/
|
||||
public boolean isEnforceReferentialIntegrityOnDelete() {
|
||||
return myEnforceReferentialIntegrityOnDelete;
|
||||
|
@ -986,7 +988,7 @@ public class DaoConfig {
|
|||
* and other FHIR features may not behave as expected when referential integrity is not
|
||||
* preserved. Use this feature with caution.
|
||||
* </p>
|
||||
* @see ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor
|
||||
* @see CascadingDeleteInterceptor
|
||||
*/
|
||||
public void setEnforceReferentialIntegrityOnDelete(boolean theEnforceReferentialIntegrityOnDelete) {
|
||||
myEnforceReferentialIntegrityOnDelete = theEnforceReferentialIntegrityOnDelete;
|
||||
|
@ -1632,6 +1634,28 @@ public class DaoConfig {
|
|||
myPreExpandValueSetsExperimental = thePreExpandValueSetsExperimental;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to <code>true</code> the _filter search parameter will be enabled on this server. Note that _filter
|
||||
* is very powerful, but also potentially dangerous as it can allow a user to create a query for which there
|
||||
* are no indexes or efficient query plans for the database to leverage while performing the query.
|
||||
* As a result, this feature is recommended only for servers where the querying applications are known in advance
|
||||
* and a database administrator can properly tune the database for the resulting queries.
|
||||
*/
|
||||
public boolean isFilterParameterEnabled() {
|
||||
return myFilterParameterEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to <code>true</code> the _filter search parameter will be enabled on this server. Note that _filter
|
||||
* is very powerful, but also potentially dangerous as it can allow a user to create a query for which there
|
||||
* are no indexes or efficient query plans for the database to leverage while performing the query.
|
||||
* As a result, this feature is recommended only for servers where the querying applications are known in advance
|
||||
* and a database administrator can properly tune the database for the resulting queries.
|
||||
*/
|
||||
public void setFilterParameterEnabled(boolean theFilterParameterEnabled) {
|
||||
myFilterParameterEnabled = theFilterParameterEnabled;
|
||||
}
|
||||
|
||||
public enum IndexEnabledEnum {
|
||||
ENABLED,
|
||||
DISABLED
|
||||
|
|
|
@ -43,7 +43,7 @@ public class FhirResourceDaoPatientDstu2 extends FhirResourceDaoDstu2<Patient>im
|
|||
super();
|
||||
}
|
||||
|
||||
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequest) {
|
||||
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequest) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
|
@ -70,21 +70,21 @@ public class FhirResourceDaoPatientDstu2 extends FhirResourceDaoDstu2<Patient>im
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequestDetails) {
|
||||
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
// Notify interceptors
|
||||
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getResourceName(), null);
|
||||
notifyInterceptors(RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE, requestDetails);
|
||||
|
||||
return doEverythingOperation(theId, theCount, theLastUpdated, theSort, theContent, theNarrative, theRequestDetails);
|
||||
return doEverythingOperation(theId, theCount, theLastUpdated, theSort, theContent, theNarrative, theFilter, theRequestDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequestDetails) {
|
||||
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
// Notify interceptors
|
||||
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getResourceName(), null);
|
||||
notifyInterceptors(RestOperationTypeEnum.EXTENDED_OPERATION_TYPE, requestDetails);
|
||||
|
||||
return doEverythingOperation(null, theCount, theLastUpdated, theSort, theContent, theNarrative, theRequestDetails);
|
||||
return doEverythingOperation(null, theCount, theLastUpdated, theSort, theContent, theNarrative, theFilter, theRequestDetails);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.param.StringAndListParam;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/*
|
||||
|
@ -21,19 +30,12 @@ import javax.servlet.http.HttpServletRequest;
|
|||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.param.StringAndListParam;
|
||||
|
||||
public interface IFhirResourceDaoPatient<T extends IBaseResource> extends IFhirResourceDao<T> {
|
||||
|
||||
IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdate, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequestDetails);
|
||||
IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdate, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails);
|
||||
|
||||
IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSortSpec, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequestDetails);
|
||||
IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSortSpec, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -28,12 +28,13 @@ import ca.uhn.fhir.rest.api.server.RequestDetails;
|
|||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
public interface ISearchBuilder {
|
||||
|
||||
IResultIterator createQuery(SearchParameterMap theParams, SearchRuntimeDetails theSearchRuntime, RequestDetails theRequest);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,597 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SearchFilterParser {
|
||||
|
||||
private static final String XML_DATE_PATTERN = "[0-9]{4}(-(0[1-9]|1[0-2])(-(0[0-9]|[1-2][0-9]|3[0-1])(T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\\.[0-9]+)?(Z|([+\\-])((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?)?)?)?";
|
||||
private static final Pattern XML_DATE_MATCHER = Pattern.compile(XML_DATE_PATTERN);
|
||||
private static final List<String> CODES_CompareOperation = Arrays.asList("eq", "ne", "co", "sw", "ew", "gt", "lt", "ge", "le", "pr", "po", "ss", "sb", "in", "re");
|
||||
private static final List<String> CODES_LogicalOperation = Arrays.asList("and", "or", "not");
|
||||
private String original = null;
|
||||
private int cursor;
|
||||
|
||||
private boolean isDate(String s) {
|
||||
Matcher m = XML_DATE_MATCHER.matcher(s);
|
||||
return m.matches();
|
||||
}
|
||||
|
||||
private FilterLexType peek() throws FilterSyntaxException {
|
||||
|
||||
FilterLexType result;
|
||||
while ((cursor < original.length()) && (original.charAt(cursor) == ' ')) {
|
||||
cursor++;
|
||||
}
|
||||
|
||||
if (cursor >= original.length()) {
|
||||
result = FilterLexType.fsltEnded;
|
||||
} else {
|
||||
if (((original.charAt(cursor) >= 'a') && (original.charAt(cursor) <= 'z')) ||
|
||||
((original.charAt(cursor) >= 'A') && (original.charAt(cursor) <= 'Z')) ||
|
||||
(original.charAt(cursor) == '_')) {
|
||||
result = FilterLexType.fsltName;
|
||||
} else if ((original.charAt(cursor) >= '0') && (original.charAt(cursor) <= '9')) {
|
||||
result = FilterLexType.fsltNumber;
|
||||
} else if (original.charAt(cursor) == '"') {
|
||||
result = FilterLexType.fsltString;
|
||||
} else if (original.charAt(cursor) == '.') {
|
||||
result = FilterLexType.fsltDot;
|
||||
} else if (original.charAt(cursor) == '(') {
|
||||
result = FilterLexType.fsltOpen;
|
||||
} else if (original.charAt(cursor) == ')') {
|
||||
result = FilterLexType.fsltClose;
|
||||
} else if (original.charAt(cursor) == '[') {
|
||||
result = FilterLexType.fsltOpenSq;
|
||||
} else if (original.charAt(cursor) == ']') {
|
||||
result = FilterLexType.fsltCloseSq;
|
||||
} else {
|
||||
throw new FilterSyntaxException(String.format("Unknown Character \"%s\" at %d",
|
||||
peekCh(),
|
||||
cursor));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String peekCh() {
|
||||
|
||||
String result;
|
||||
if (cursor > original.length()) {
|
||||
result = "[end!]";
|
||||
} else {
|
||||
result = original.substring(cursor, cursor + 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String consumeName() {
|
||||
|
||||
String result;
|
||||
int i = cursor;
|
||||
do {
|
||||
i++;
|
||||
} while ((i <= original.length() - 1) &&
|
||||
(((original.charAt(i) >= 'a') && (original.charAt(i) <= 'z')) ||
|
||||
((original.charAt(i) >= 'A') && (original.charAt(i) <= 'Z')) ||
|
||||
((original.charAt(i) >= '0') && (original.charAt(i) <= '9')) ||
|
||||
(original.charAt(i) == '-') ||
|
||||
(original.charAt(i) == '_') ||
|
||||
(original.charAt(i) == ':')));
|
||||
|
||||
result = original.substring(cursor,
|
||||
i/* - cursor*/);
|
||||
cursor = i;
|
||||
return result;
|
||||
}
|
||||
|
||||
private String consumeToken() {
|
||||
|
||||
String result;
|
||||
int i = cursor;
|
||||
do {
|
||||
i++;
|
||||
} while ((i <= original.length() - 1) &&
|
||||
(original.charAt(i) > 32) &&
|
||||
(!StringUtils.isWhitespace(original.substring(i, i + 1))) &&
|
||||
(original.charAt(i) != ')') &&
|
||||
(original.charAt(i) != ']'));
|
||||
result = original.substring(cursor,
|
||||
i/* - cursor*/);
|
||||
cursor = i;
|
||||
return result;
|
||||
}
|
||||
|
||||
private String consumeNumberOrDate() {
|
||||
|
||||
String result;
|
||||
int i = cursor;
|
||||
do {
|
||||
i++;
|
||||
} while ((i <= original.length() - 1) &&
|
||||
(((original.charAt(i) >= '0') && (original.charAt(i) <= '9')) ||
|
||||
(original.charAt(i) == '.') ||
|
||||
(original.charAt(i) == '-') ||
|
||||
(original.charAt(i) == ':') ||
|
||||
(original.charAt(i) == '+') ||
|
||||
(original.charAt(i) == 'T')));
|
||||
result = original.substring(cursor,
|
||||
i/* - cursor*/);
|
||||
cursor = i;
|
||||
return result;
|
||||
}
|
||||
|
||||
private String consumeString() throws FilterSyntaxException {
|
||||
|
||||
// int l = 0;
|
||||
cursor++;
|
||||
StringBuilder str = new StringBuilder(original.length());
|
||||
// setLength(result, length(original)); // can't be longer than that
|
||||
while ((cursor <= original.length()) && (original.charAt(cursor) != '"')) {
|
||||
// l++;
|
||||
if (original.charAt(cursor) != '\\') {
|
||||
str.append(original.charAt(cursor));
|
||||
// str.setCharAt(l, original.charAt(cursor));
|
||||
} else {
|
||||
cursor++;
|
||||
if (original.charAt(cursor) == '"') {
|
||||
str.append('"');
|
||||
// str.setCharAt(l, '"');
|
||||
} else if (original.charAt(cursor) == 't') {
|
||||
str.append('\t');
|
||||
// str.setCharAt(l, '\t');
|
||||
} else if (original.charAt(cursor) == 'r') {
|
||||
str.append('\r');
|
||||
// str.setCharAt(l, '\r');
|
||||
} else if (original.charAt(cursor) == 'n') {
|
||||
str.append('\n');
|
||||
// str.setCharAt(l, '\n');
|
||||
} else {
|
||||
throw new FilterSyntaxException(String.format("Unknown escape sequence at %d",
|
||||
cursor));
|
||||
}
|
||||
}
|
||||
cursor++;
|
||||
}
|
||||
// SetLength(result, l);
|
||||
if ((cursor > original.length()) || (original.charAt(cursor) != '"')) {
|
||||
throw new FilterSyntaxException(String.format("Problem with string termination at %d",
|
||||
cursor));
|
||||
}
|
||||
|
||||
if (str.length() == 0) {
|
||||
throw new FilterSyntaxException(String.format("Problem with string at %d cannot be empty",
|
||||
cursor));
|
||||
}
|
||||
|
||||
cursor++;
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
private Filter parse() throws FilterSyntaxException {
|
||||
|
||||
Filter result = parseOpen();
|
||||
if (cursor < original.length()) {
|
||||
throw new FilterSyntaxException(String.format("Expression did not terminate at %d",
|
||||
cursor));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Filter parseOpen() throws FilterSyntaxException {
|
||||
|
||||
Filter result;
|
||||
String s;
|
||||
FilterParameterGroup grp;
|
||||
if (peek() == FilterLexType.fsltOpen) {
|
||||
cursor++;
|
||||
grp = new FilterParameterGroup();
|
||||
grp.setContained(parseOpen());
|
||||
if (peek() != FilterLexType.fsltClose) {
|
||||
throw new FilterSyntaxException(String.format("Expected ')' at %d but found %s",
|
||||
cursor,
|
||||
peekCh()));
|
||||
}
|
||||
cursor++;
|
||||
FilterLexType lexType = peek();
|
||||
if (lexType == FilterLexType.fsltName) {
|
||||
result = parseLogical(grp);
|
||||
} else if ((lexType == FilterLexType.fsltEnded) || (lexType == FilterLexType.fsltClose) || (lexType == FilterLexType.fsltCloseSq)) {
|
||||
result = grp;
|
||||
} else {
|
||||
throw new FilterSyntaxException(String.format("Unexpected Character %s at %d",
|
||||
peekCh(),
|
||||
cursor));
|
||||
}
|
||||
} else {
|
||||
s = consumeName();
|
||||
if (s.compareToIgnoreCase("not") == 0) {
|
||||
result = parseLogical(null);
|
||||
} else {
|
||||
result = parseParameter(s);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Filter parseLogical(Filter filter) throws FilterSyntaxException {
|
||||
|
||||
Filter result = null;
|
||||
String s;
|
||||
FilterLogical logical;
|
||||
if (filter == null) {
|
||||
s = "not";
|
||||
} else {
|
||||
s = consumeName();
|
||||
if ((!s.equals("or")) && (!s.equals("and")) && (!s.equals("not"))) {
|
||||
throw new FilterSyntaxException(String.format("Unexpected Name %s at %d",
|
||||
s,
|
||||
cursor));
|
||||
}
|
||||
|
||||
logical = new FilterLogical();
|
||||
logical.setFilter1(filter);
|
||||
if (s.compareToIgnoreCase("or") == 0) {
|
||||
logical.setOperation(FilterLogicalOperation.or);
|
||||
} else if (s.compareToIgnoreCase("not") == 0) {
|
||||
logical.setOperation(FilterLogicalOperation.not);
|
||||
} else {
|
||||
logical.setOperation(FilterLogicalOperation.and);
|
||||
}
|
||||
|
||||
logical.setFilter2(parseOpen());
|
||||
result = logical;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private FilterParameterPath parsePath(String name) throws FilterSyntaxException {
|
||||
|
||||
FilterParameterPath result = new FilterParameterPath();
|
||||
result.setName(name);
|
||||
if (peek() == FilterLexType.fsltOpenSq) {
|
||||
cursor++;
|
||||
result.setFilter(parseOpen());
|
||||
if (peek() != FilterLexType.fsltCloseSq) {
|
||||
throw new FilterSyntaxException(String.format("Expected ']' at %d but found %c",
|
||||
cursor,
|
||||
peekCh()));
|
||||
}
|
||||
cursor++;
|
||||
}
|
||||
|
||||
if (peek() == FilterLexType.fsltDot) {
|
||||
cursor++;
|
||||
if (peek() != FilterLexType.fsltName) {
|
||||
throw new FilterSyntaxException(String.format("Unexpected Character %c at %d",
|
||||
peekCh(),
|
||||
cursor));
|
||||
}
|
||||
result.setNext(parsePath(consumeName()));
|
||||
} else if (result.getFilter() != null) {
|
||||
throw new FilterSyntaxException(String.format("Expected '.' at %d but found %c",
|
||||
cursor,
|
||||
peekCh()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Filter parseParameter(String name) throws FilterSyntaxException {
|
||||
|
||||
Filter result;
|
||||
String s;
|
||||
FilterParameter filter = new FilterParameter();
|
||||
|
||||
// 1. the path
|
||||
filter.setParamPath(parsePath(name));
|
||||
|
||||
if (peek() != FilterLexType.fsltName) {
|
||||
throw new FilterSyntaxException(String.format("Unexpected Character %s at %d",
|
||||
peekCh(),
|
||||
cursor));
|
||||
}
|
||||
s = consumeName();
|
||||
int index = CODES_CompareOperation.indexOf(s);
|
||||
if (index == -1) {
|
||||
throw new FilterSyntaxException(String.format("Unknown operation %s at %d",
|
||||
s,
|
||||
cursor));
|
||||
}
|
||||
filter.setOperation(CompareOperation.values()[index]);
|
||||
|
||||
FilterLexType lexType = peek();
|
||||
if (lexType == FilterLexType.fsltName) {
|
||||
filter.setValue(consumeToken());
|
||||
filter.setValueType(FilterValueType.token);
|
||||
} else if (lexType == FilterLexType.fsltNumber) {
|
||||
filter.setValue(consumeNumberOrDate());
|
||||
filter.setValueType(FilterValueType.numberOrDate);
|
||||
} else if (lexType == FilterLexType.fsltString) {
|
||||
filter.setValue(consumeString());
|
||||
filter.setValueType(FilterValueType.string);
|
||||
} else {
|
||||
throw new FilterSyntaxException(String.format("Unexpected Character %s at %d",
|
||||
peekCh(),
|
||||
cursor));
|
||||
}
|
||||
|
||||
// check operation / value type results
|
||||
if (filter.getOperation() == CompareOperation.pr) {
|
||||
if ((filter.getValue().compareToIgnoreCase("true") != 0) &&
|
||||
(filter.getValue().compareToIgnoreCase("false") != 0)) {
|
||||
throw new FilterSyntaxException(String.format("Value %s not valid for operation %s at %d",
|
||||
filter.getValue(),
|
||||
CODES_CompareOperation.get(filter.getOperation().ordinal()),
|
||||
cursor));
|
||||
}
|
||||
} else if (filter.getOperation() == CompareOperation.po) {
|
||||
if (!isDate(filter.getValue())) {
|
||||
throw new FilterSyntaxException(String.format("Value %s not valid for operation %s at %d",
|
||||
filter.getValue(),
|
||||
CODES_CompareOperation.get(filter.getOperation().ordinal()),
|
||||
cursor));
|
||||
}
|
||||
}
|
||||
|
||||
lexType = peek();
|
||||
if (lexType == FilterLexType.fsltName) {
|
||||
result = parseLogical(filter);
|
||||
} else if ((lexType == FilterLexType.fsltEnded) || (lexType == FilterLexType.fsltClose) || (lexType == FilterLexType.fsltCloseSq)) {
|
||||
result = filter;
|
||||
} else {
|
||||
throw new FilterSyntaxException(String.format("Unexpected Character %s at %d",
|
||||
peekCh(),
|
||||
cursor));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public enum CompareOperation {
|
||||
eq,
|
||||
ne,
|
||||
co,
|
||||
sw,
|
||||
ew,
|
||||
gt,
|
||||
lt,
|
||||
ge,
|
||||
le,
|
||||
pr,
|
||||
po,
|
||||
ss,
|
||||
sb,
|
||||
in,
|
||||
re
|
||||
}
|
||||
|
||||
public enum FilterLogicalOperation {
|
||||
and,
|
||||
or,
|
||||
not
|
||||
}
|
||||
|
||||
public enum FilterItemType {
|
||||
parameter,
|
||||
logical,
|
||||
parameterGroup
|
||||
}
|
||||
|
||||
public enum FilterValueType {
|
||||
token,
|
||||
string,
|
||||
numberOrDate
|
||||
}
|
||||
|
||||
public enum FilterLexType {
|
||||
fsltEnded,
|
||||
fsltName,
|
||||
fsltString,
|
||||
fsltNumber,
|
||||
fsltDot,
|
||||
fsltOpen,
|
||||
fsltClose,
|
||||
fsltOpenSq,
|
||||
fsltCloseSq
|
||||
}
|
||||
|
||||
abstract public static class Filter {
|
||||
|
||||
private FilterItemType itemType;
|
||||
|
||||
public FilterItemType getFilterItemType() {
|
||||
return itemType;
|
||||
}
|
||||
}
|
||||
|
||||
public static class FilterParameterPath {
|
||||
|
||||
private String FName;
|
||||
private Filter FFilter;
|
||||
private FilterParameterPath FNext;
|
||||
|
||||
public String getName() {
|
||||
|
||||
return FName;
|
||||
}
|
||||
|
||||
public void setName(String value) {
|
||||
|
||||
FName = value;
|
||||
}
|
||||
|
||||
public Filter getFilter() {
|
||||
|
||||
return FFilter;
|
||||
}
|
||||
|
||||
public void setFilter(Filter value) {
|
||||
|
||||
FFilter = value;
|
||||
}
|
||||
|
||||
public FilterParameterPath getNext() {
|
||||
|
||||
return FNext;
|
||||
}
|
||||
|
||||
public void setNext(FilterParameterPath value) {
|
||||
|
||||
FNext = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String result;
|
||||
if (getFilter() != null) {
|
||||
result = getName() + "[" + getFilter().toString() + "]";
|
||||
} else {
|
||||
result = getName();
|
||||
}
|
||||
if (getNext() != null) {
|
||||
result += "." + getNext().toString();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static class FilterParameterGroup extends Filter {
|
||||
|
||||
private Filter FContained;
|
||||
|
||||
public Filter getContained() {
|
||||
|
||||
return FContained;
|
||||
}
|
||||
|
||||
public void setContained(Filter value) {
|
||||
|
||||
FContained = value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
return "(" + FContained.toString() + ")";
|
||||
}
|
||||
}
|
||||
|
||||
public static class FilterParameter extends Filter {
|
||||
|
||||
private FilterParameterPath FParamPath;
|
||||
private CompareOperation FOperation;
|
||||
private String FValue;
|
||||
private FilterValueType FValueType;
|
||||
|
||||
FilterParameterPath getParamPath() {
|
||||
|
||||
return FParamPath;
|
||||
}
|
||||
|
||||
void setParamPath(FilterParameterPath value) {
|
||||
|
||||
FParamPath = value;
|
||||
}
|
||||
|
||||
|
||||
public CompareOperation getOperation() {
|
||||
|
||||
return FOperation;
|
||||
}
|
||||
|
||||
public void setOperation(CompareOperation value) {
|
||||
|
||||
FOperation = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
|
||||
return FValue;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
|
||||
FValue = value;
|
||||
}
|
||||
|
||||
public FilterValueType getValueType() {
|
||||
|
||||
return FValueType;
|
||||
}
|
||||
|
||||
public void setValueType(FilterValueType FValueType) {
|
||||
|
||||
this.FValueType = FValueType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (FValueType == FilterValueType.string) {
|
||||
return getParamPath().toString() + " " + CODES_CompareOperation.get(getOperation().ordinal()) + " \"" + getValue() + "\"";
|
||||
} else {
|
||||
return getParamPath().toString() + " " + CODES_CompareOperation.get(getOperation().ordinal()) + " " + getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class FilterLogical extends Filter {
|
||||
|
||||
private Filter FFilter1;
|
||||
private FilterLogicalOperation FOperation;
|
||||
private Filter FFilter2;
|
||||
|
||||
|
||||
Filter getFilter1() {
|
||||
|
||||
return FFilter1;
|
||||
}
|
||||
|
||||
void setFilter1(Filter FFilter1) {
|
||||
|
||||
this.FFilter1 = FFilter1;
|
||||
}
|
||||
|
||||
public FilterLogicalOperation getOperation() {
|
||||
|
||||
return FOperation;
|
||||
}
|
||||
|
||||
public void setOperation(FilterLogicalOperation FOperation) {
|
||||
|
||||
this.FOperation = FOperation;
|
||||
}
|
||||
|
||||
Filter getFilter2() {
|
||||
|
||||
return FFilter2;
|
||||
}
|
||||
|
||||
void setFilter2(Filter FFilter2) {
|
||||
|
||||
this.FFilter2 = FFilter2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return FFilter1.toString() + " " + CODES_LogicalOperation.get(getOperation().ordinal()) + " " + FFilter2.toString();
|
||||
}
|
||||
}
|
||||
|
||||
static class FilterSyntaxException extends Exception {
|
||||
FilterSyntaxException(String theMessage) {
|
||||
super(theMessage);
|
||||
}
|
||||
}
|
||||
|
||||
static public Filter parse(String expression) throws FilterSyntaxException {
|
||||
SearchFilterParser parser = new SearchFilterParser();
|
||||
parser.original = expression;
|
||||
parser.cursor = 0;
|
||||
return parser.parse();
|
||||
}
|
||||
}
|
|
@ -41,7 +41,7 @@ import ca.uhn.fhir.rest.param.*;
|
|||
|
||||
public class FhirResourceDaoPatientDstu3 extends FhirResourceDaoDstu3<Patient>implements IFhirResourceDaoPatient<Patient> {
|
||||
|
||||
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequest) {
|
||||
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequest) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
|
@ -68,13 +68,13 @@ public class FhirResourceDaoPatientDstu3 extends FhirResourceDaoDstu3<Patient>im
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(theId, theCount, theLastUpdated, theSort, theContent, theNarrative, theRequestDetails);
|
||||
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(theId, theCount, theLastUpdated, theSort, theContent, theNarrative, theFilter, theRequestDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(null, theCount, theLastUpdated, theSort, theContent, theNarrative, theRequestDetails);
|
||||
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(null, theCount, theLastUpdated, theSort, theContent, theNarrative, theFilter, theRequestDetails);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ import ca.uhn.fhir.rest.param.*;
|
|||
|
||||
public class FhirResourceDaoPatientR4 extends FhirResourceDaoR4<Patient>implements IFhirResourceDaoPatient<Patient> {
|
||||
|
||||
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequest) {
|
||||
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequest) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
|
@ -68,13 +68,13 @@ public class FhirResourceDaoPatientR4 extends FhirResourceDaoR4<Patient>implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(theId, theCount, theLastUpdated, theSort, theContent, theNarrative, theRequestDetails);
|
||||
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(theId, theCount, theLastUpdated, theSort, theContent, theNarrative, theFilter, theRequestDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(null, theCount, theLastUpdated, theSort, theContent, theNarrative, theRequestDetails);
|
||||
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(null, theCount, theLastUpdated, theSort, theContent, theNarrative, theFilter, theRequestDetails);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -68,12 +68,12 @@ public class FhirResourceDaoPatientR5 extends FhirResourceDaoR5<Patient> impleme
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequestDetails) {
|
||||
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(theId, theCount, theLastUpdated, theSort, theContent, theNarrative, theRequestDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequestDetails) {
|
||||
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(null, theCount, theLastUpdated, theSort, theContent, theNarrative, theRequestDetails);
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,10 @@ public class BaseJpaResourceProviderPatientDstu2 extends JpaResourceProviderDstu
|
|||
@OperationParam(name = Constants.PARAM_TEXT, min=0, max=OperationParam.MAX_UNLIMITED)
|
||||
List<StringDt> theNarrative,
|
||||
|
||||
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
|
||||
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
|
||||
List<StringDt> theFilter,
|
||||
|
||||
@Sort
|
||||
SortSpec theSortSpec,
|
||||
|
||||
|
@ -74,7 +78,7 @@ public class BaseJpaResourceProviderPatientDstu2 extends JpaResourceProviderDstu
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
@ -104,6 +108,10 @@ public class BaseJpaResourceProviderPatientDstu2 extends JpaResourceProviderDstu
|
|||
@OperationParam(name = Constants.PARAM_TEXT, min=0, max=OperationParam.MAX_UNLIMITED)
|
||||
List<StringDt> theNarrative,
|
||||
|
||||
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
|
||||
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
|
||||
List<StringDt> theFilter,
|
||||
|
||||
@Sort
|
||||
SortSpec theSortSpec,
|
||||
|
||||
|
@ -112,7 +120,7 @@ public class BaseJpaResourceProviderPatientDstu2 extends JpaResourceProviderDstu
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.jpa.provider.dstu3;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoPatient;
|
||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
|
@ -23,8 +25,6 @@ import org.hl7.fhir.dstu3.model.UnsignedIntType;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
|
@ -74,6 +74,10 @@ public class BaseJpaResourceProviderPatientDstu3 extends JpaResourceProviderDstu
|
|||
@OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED)
|
||||
List<StringType> theNarrative,
|
||||
|
||||
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
|
||||
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
|
||||
List<StringType> theFilter,
|
||||
|
||||
@Sort
|
||||
SortSpec theSortSpec,
|
||||
|
||||
|
@ -82,7 +86,7 @@ public class BaseJpaResourceProviderPatientDstu3 extends JpaResourceProviderDstu
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
@ -112,6 +116,10 @@ public class BaseJpaResourceProviderPatientDstu3 extends JpaResourceProviderDstu
|
|||
@OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED)
|
||||
List<StringType> theNarrative,
|
||||
|
||||
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
|
||||
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
|
||||
List<StringType> theFilter,
|
||||
|
||||
@Sort
|
||||
SortSpec theSortSpec,
|
||||
|
||||
|
@ -120,7 +128,7 @@ public class BaseJpaResourceProviderPatientDstu3 extends JpaResourceProviderDstu
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.jpa.provider.r4;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoPatient;
|
||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
|
@ -23,8 +25,6 @@ import org.hl7.fhir.r4.model.UnsignedIntType;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
|
@ -74,6 +74,10 @@ public class BaseJpaResourceProviderPatientR4 extends JpaResourceProviderR4<Pati
|
|||
@OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED)
|
||||
List<StringType> theNarrative,
|
||||
|
||||
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
|
||||
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
|
||||
List<StringType> theFilter,
|
||||
|
||||
@Sort
|
||||
SortSpec theSortSpec,
|
||||
|
||||
|
@ -82,7 +86,7 @@ public class BaseJpaResourceProviderPatientR4 extends JpaResourceProviderR4<Pati
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
@ -112,6 +116,10 @@ public class BaseJpaResourceProviderPatientR4 extends JpaResourceProviderR4<Pati
|
|||
@OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED)
|
||||
List<StringType> theNarrative,
|
||||
|
||||
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
|
||||
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
|
||||
List<StringType> theFilter,
|
||||
|
||||
@Sort
|
||||
SortSpec theSortSpec,
|
||||
|
||||
|
@ -120,7 +128,7 @@ public class BaseJpaResourceProviderPatientR4 extends JpaResourceProviderR4<Pati
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
|
|
@ -74,6 +74,10 @@ public class BaseJpaResourceProviderPatientR5 extends JpaResourceProviderR5<Pati
|
|||
@OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED)
|
||||
List<StringType> theNarrative,
|
||||
|
||||
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
|
||||
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
|
||||
List<StringType> theFilter,
|
||||
|
||||
@Sort
|
||||
SortSpec theSortSpec,
|
||||
|
||||
|
@ -82,7 +86,7 @@ public class BaseJpaResourceProviderPatientR5 extends JpaResourceProviderR5<Pati
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
@ -112,6 +116,10 @@ public class BaseJpaResourceProviderPatientR5 extends JpaResourceProviderR5<Pati
|
|||
@OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED)
|
||||
List<StringType> theNarrative,
|
||||
|
||||
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
|
||||
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
|
||||
List<StringType> theFilter,
|
||||
|
||||
@Sort
|
||||
SortSpec theSortSpec,
|
||||
|
||||
|
@ -120,7 +128,7 @@ public class BaseJpaResourceProviderPatientR5 extends JpaResourceProviderR5<Pati
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SearchFilterSyntaxTest {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchFilterSyntaxTest.class);
|
||||
|
||||
private void testParse(String theExpression) throws SearchFilterParser.FilterSyntaxException {
|
||||
SearchFilterParser.Filter filter = SearchFilterParser.parse(theExpression);
|
||||
ourLog.info("Source: {}", theExpression);
|
||||
ourLog.info("Parsed: {}", filter.toString());
|
||||
Assert.assertNotNull("Parsing failed - returned null",
|
||||
filter);
|
||||
Assert.assertEquals(String.format("Expression mismatch: found %s, expecting %s",
|
||||
filter.toString(),
|
||||
theExpression),
|
||||
theExpression,
|
||||
filter.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testString() throws SearchFilterParser.FilterSyntaxException {
|
||||
testParse("userName eq \"bjensen\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToken() throws SearchFilterParser.FilterSyntaxException {
|
||||
testParse("name eq loinc|1234");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUrl() throws SearchFilterParser.FilterSyntaxException {
|
||||
testParse("name in http://loinc.org/vs/LP234");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDate() throws SearchFilterParser.FilterSyntaxException {
|
||||
testParse("date ge 2010-10-10");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubsumes() throws SearchFilterParser.FilterSyntaxException {
|
||||
testParse("code sb snomed|diabetes");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubsumesId() throws SearchFilterParser.FilterSyntaxException {
|
||||
testParse("code ss snomed|diabetes-NIDDM-stage-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilter() throws SearchFilterParser.FilterSyntaxException {
|
||||
testParse("related[type eq comp].target pr false");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilter2() throws SearchFilterParser.FilterSyntaxException {
|
||||
testParse("related[type eq comp and this lt that].target pr false");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParentheses() throws SearchFilterParser.FilterSyntaxException {
|
||||
testParse("((userName eq \"bjensen\") or (userName eq \"jdoe\")) and (code sb snomed|diabetes)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrecedence() throws SearchFilterParser.FilterSyntaxException {
|
||||
testParse("this eq that and this1 eq that1");
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
}
|
|
@ -251,16 +251,16 @@ public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, null, mySrd));
|
||||
assertThat(actual, containsInAnyOrder(ptId1, obsId1, devId1));
|
||||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obstext1")));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, param, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, param, null, mySrd));
|
||||
assertThat(actual, containsInAnyOrder(ptId1, obsId1, devId1));
|
||||
|
||||
request = mock(HttpServletRequest.class);
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, null, null, mySrd));
|
||||
assertThat(actual, containsInAnyOrder(ptId1, obsId1, obsId2, devId1));
|
||||
|
||||
/*
|
||||
|
@ -276,7 +276,7 @@ public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, null, mySrd));
|
||||
assertThat(actual, containsInAnyOrder(ptId1, obsId1, obsId4, devId1));
|
||||
|
||||
/*
|
||||
|
@ -292,7 +292,7 @@ public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, null, mySrd));
|
||||
assertThat(actual, containsInAnyOrder(ptId1, obsId4));
|
||||
|
||||
}
|
||||
|
@ -343,11 +343,11 @@ public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientTypeEverything(request, null, null, null, param, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientTypeEverything(request, null, null, null, param, null, null, mySrd));
|
||||
assertThat(actual, containsInAnyOrder(ptId1, obsId1, devId1));
|
||||
|
||||
request = mock(HttpServletRequest.class);
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientTypeEverything(request, null, null, null, null, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientTypeEverything(request, null, null, null, null, null, null, mySrd));
|
||||
assertThat(actual, containsInAnyOrder(ptId1, obsId1, obsId2, devId1, ptId2, obsId3));
|
||||
|
||||
/*
|
||||
|
@ -363,7 +363,7 @@ public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientTypeEverything(request, null, null, null, param, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientTypeEverything(request, null, null, null, param, null, null, mySrd));
|
||||
assertThat(actual, containsInAnyOrder(ptId1, obsId1, obsId4, devId1));
|
||||
|
||||
/*
|
||||
|
@ -379,7 +379,7 @@ public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientTypeEverything(request, null, null, null, param, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientTypeEverything(request, null, null, null, param, null, null, mySrd));
|
||||
assertThat(actual, containsInAnyOrder(ptId1, obsId4));
|
||||
|
||||
}
|
||||
|
|
|
@ -92,11 +92,11 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
|
|||
IIdType moId = myMedicationOrderDao.create(mo, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
IBundleProvider resp = myPatientDao.patientTypeEverything(request, null, null, null, null, null, mySrd);
|
||||
IBundleProvider resp = myPatientDao.patientTypeEverything(request, null, null, null, null, null, null, mySrd);
|
||||
assertThat(toUnqualifiedVersionlessIds(resp), containsInAnyOrder(orgId, medId, patId, moId, patId2));
|
||||
|
||||
request = mock(HttpServletRequest.class);
|
||||
resp = myPatientDao.patientInstanceEverything(request, patId, null, null, null, null, null, mySrd);
|
||||
resp = myPatientDao.patientInstanceEverything(request, patId, null, null, null, null, null, null, mySrd);
|
||||
assertThat(toUnqualifiedVersionlessIds(resp), containsInAnyOrder(orgId, medId, patId, moId));
|
||||
}
|
||||
|
||||
|
|
|
@ -334,16 +334,16 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, devId1)));
|
||||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obstext1")));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, param, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, param, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, devId1)));
|
||||
|
||||
request = mock(HttpServletRequest.class);
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId2, devId1)));
|
||||
|
||||
/*
|
||||
|
@ -359,7 +359,7 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId4, devId1)));
|
||||
|
||||
/*
|
||||
|
@ -375,7 +375,7 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId4)));
|
||||
|
||||
}
|
||||
|
@ -426,11 +426,11 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, devId1)));
|
||||
|
||||
request = mock(HttpServletRequest.class);
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, null, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, null, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId2, devId1, ptId2, obsId3)));
|
||||
|
||||
/*
|
||||
|
@ -446,7 +446,7 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId4, devId1)));
|
||||
|
||||
/*
|
||||
|
@ -462,7 +462,7 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId4)));
|
||||
|
||||
}
|
||||
|
|
|
@ -171,11 +171,11 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
|||
IIdType moId = myMedicationRequestDao.create(mo, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
IBundleProvider resp = myPatientDao.patientTypeEverything(request, null, null, null, null, null, mySrd);
|
||||
IBundleProvider resp = myPatientDao.patientTypeEverything(request, null, null, null, null, null, null, mySrd);
|
||||
assertThat(toUnqualifiedVersionlessIds(resp), containsInAnyOrder(orgId, medId, patId, moId, patId2));
|
||||
|
||||
request = mock(HttpServletRequest.class);
|
||||
resp = myPatientDao.patientInstanceEverything(request, patId, null, null, null, null, null, mySrd);
|
||||
resp = myPatientDao.patientInstanceEverything(request, patId, null, null, null, null, null, null, mySrd);
|
||||
assertThat(toUnqualifiedVersionlessIds(resp), containsInAnyOrder(orgId, medId, patId, moId));
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
|||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setEverythingMode(EverythingModeEnum.PATIENT_INSTANCE);
|
||||
IPrimitiveType<Integer> count = new IntegerType(1000);
|
||||
IBundleProvider everything = myPatientDao.patientInstanceEverything(mySrd.getServletRequest(), new IdType("Patient/A161443"), count, null, null, null, null, mySrd);
|
||||
IBundleProvider everything = myPatientDao.patientInstanceEverything(mySrd.getServletRequest(), new IdType("Patient/A161443"), count, null, null, null, null, null, mySrd);
|
||||
|
||||
TreeSet<String> ids = new TreeSet<>(toUnqualifiedVersionlessIdValues(everything));
|
||||
assertThat(ids, hasItem("List/A161444"));
|
||||
|
|
|
@ -464,12 +464,6 @@ public class ConsentEventsDaoR4Test extends BaseJpaR4SystemTest {
|
|||
|
||||
ourLog.info("Allowing IDs: {}", nonBlocked);
|
||||
|
||||
try {
|
||||
throw new Exception();
|
||||
} catch (Exception e) {
|
||||
ourLog.error("Trace", e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
package ca.uhn.fhir.jpa.dao.r4;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.util.TestUtil;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@SuppressWarnings({"Duplicates"})
|
||||
public class FhirResourceDaoR4FilterTest extends BaseJpaR4Test {
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
myDaoConfig.setFilterParameterEnabled(new DaoConfig().isFilterParameterEnabled());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
myDaoConfig.setFilterParameterEnabled(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedFilter() {
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
map.add(Constants.PARAM_FILTER, new StringParam("name eq smith))"));
|
||||
try {
|
||||
myPatientDao.search(map);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals("Error parsing _filter syntax: Expression did not terminate at 13", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChainWithMultipleTypePossibilities() {
|
||||
|
||||
Patient p= new Patient();
|
||||
p.addName().setFamily("Smith").addGiven("John");
|
||||
p.setActive(true);
|
||||
String id1 = myPatientDao.create(p).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
p = new Patient();
|
||||
p.addName().setFamily("Jones").addGiven("Frank");
|
||||
p.setActive(false);
|
||||
String id2 = myPatientDao.create(p).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
SearchParameterMap map;
|
||||
List<String> found;
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
map.add(Constants.PARAM_FILTER, new StringParam("name eq smith"));
|
||||
found = toUnqualifiedVersionlessIdValues(myPatientDao.search(map));
|
||||
assertThat(found, containsInAnyOrder(id1));
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
map.add(Constants.PARAM_FILTER, new StringParam("(name eq smith) or (name eq jones)"));
|
||||
found = toUnqualifiedVersionlessIdValues(myPatientDao.search(map));
|
||||
assertThat(found, containsInAnyOrder(id1,id2));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilterDisabled() {
|
||||
myDaoConfig.setFilterParameterEnabled(false);
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
map.add(Constants.PARAM_FILTER, new StringParam("name eq smith"));
|
||||
try {
|
||||
myPatientDao.search(map);
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals("_filter parameter is disabled on this server", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
}
|
|
@ -345,16 +345,16 @@ public class FhirResourceDaoR4SearchFtTest extends BaseJpaR4Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, devId1)));
|
||||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obstext1")));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, param, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, param, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, devId1)));
|
||||
|
||||
request = mock(HttpServletRequest.class);
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId2, devId1)));
|
||||
|
||||
/*
|
||||
|
@ -370,7 +370,7 @@ public class FhirResourceDaoR4SearchFtTest extends BaseJpaR4Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId4, devId1)));
|
||||
|
||||
/*
|
||||
|
@ -386,7 +386,7 @@ public class FhirResourceDaoR4SearchFtTest extends BaseJpaR4Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId4)));
|
||||
|
||||
}
|
||||
|
@ -437,11 +437,11 @@ public class FhirResourceDaoR4SearchFtTest extends BaseJpaR4Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, devId1)));
|
||||
|
||||
request = mock(HttpServletRequest.class);
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, null, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, null, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId2, devId1, ptId2, obsId3)));
|
||||
|
||||
/*
|
||||
|
@ -457,7 +457,7 @@ public class FhirResourceDaoR4SearchFtTest extends BaseJpaR4Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId4, devId1)));
|
||||
|
||||
/*
|
||||
|
@ -473,7 +473,7 @@ public class FhirResourceDaoR4SearchFtTest extends BaseJpaR4Test {
|
|||
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId4)));
|
||||
|
||||
}
|
||||
|
|
|
@ -470,11 +470,11 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
IIdType moId = myMedicationRequestDao.create(mo, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
IBundleProvider resp = myPatientDao.patientTypeEverything(request, null, null, null, null, null, mySrd);
|
||||
IBundleProvider resp = myPatientDao.patientTypeEverything(request, null, null, null, null, null, null, mySrd);
|
||||
assertThat(toUnqualifiedVersionlessIds(resp), containsInAnyOrder(orgId, medId, patId, moId, patId2));
|
||||
|
||||
request = mock(HttpServletRequest.class);
|
||||
resp = myPatientDao.patientInstanceEverything(request, patId, null, null, null, null, null, mySrd);
|
||||
resp = myPatientDao.patientInstanceEverything(request, patId, null, null, null, null, null, null, mySrd);
|
||||
assertThat(toUnqualifiedVersionlessIds(resp), containsInAnyOrder(orgId, medId, patId, moId));
|
||||
}
|
||||
|
||||
|
@ -502,7 +502,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setEverythingMode(EverythingModeEnum.PATIENT_INSTANCE);
|
||||
IPrimitiveType<Integer> count = new IntegerType(1000);
|
||||
IBundleProvider everything = myPatientDao.patientInstanceEverything(mySrd.getServletRequest(), new IdType("Patient/A161443"), count, null, null, null, null, mySrd);
|
||||
IBundleProvider everything = myPatientDao.patientInstanceEverything(mySrd.getServletRequest(), new IdType("Patient/A161443"), count, null, null, null, null, null, mySrd);
|
||||
|
||||
TreeSet<String> ids = new TreeSet<>(toUnqualifiedVersionlessIdValues(everything));
|
||||
assertThat(ids, hasItem("List/A161444"));
|
||||
|
|
|
@ -292,11 +292,11 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
|
|||
IIdType moId = myMedicationRequestDao.create(mo, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
IBundleProvider resp = myPatientDao.patientTypeEverything(request, null, null, null, null, null, mySrd);
|
||||
IBundleProvider resp = myPatientDao.patientTypeEverything(request, null, null, null, null, null, null, mySrd);
|
||||
assertThat(toUnqualifiedVersionlessIds(resp), containsInAnyOrder(orgId, medId, patId, moId, patId2));
|
||||
|
||||
request = mock(HttpServletRequest.class);
|
||||
resp = myPatientDao.patientInstanceEverything(request, patId, null, null, null, null, null, mySrd);
|
||||
resp = myPatientDao.patientInstanceEverything(request, patId, null, null, null, null, null, null, mySrd);
|
||||
assertThat(toUnqualifiedVersionlessIds(resp), containsInAnyOrder(orgId, medId, patId, moId));
|
||||
}
|
||||
|
||||
|
@ -324,9 +324,9 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
|
|||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setEverythingMode(EverythingModeEnum.PATIENT_INSTANCE);
|
||||
IPrimitiveType<Integer> count = new IntegerType(1000);
|
||||
IBundleProvider everything = myPatientDao.patientInstanceEverything(mySrd.getServletRequest(), new IdType("Patient/A161443"), count, null, null, null, null, mySrd);
|
||||
IBundleProvider everything = myPatientDao.patientInstanceEverything(mySrd.getServletRequest(), new IdType("Patient/A161443"), count, null, null, null, null, null, mySrd);
|
||||
|
||||
TreeSet<String> ids = new TreeSet<String>(toUnqualifiedVersionlessIdValues(everything));
|
||||
TreeSet<String> ids = new TreeSet<>(toUnqualifiedVersionlessIdValues(everything));
|
||||
assertThat(ids, hasItem("List/A161444"));
|
||||
assertThat(ids, hasItem("List/A161468"));
|
||||
assertThat(ids, hasItem("List/A161500"));
|
||||
|
@ -335,7 +335,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
|
|||
ourLog.info("Actual {} - {}", ids.size(), ids);
|
||||
assertEquals(allIds, ids);
|
||||
|
||||
ids = new TreeSet<String>();
|
||||
ids = new TreeSet<>();
|
||||
for (int i = 0; i < everything.size(); i++) {
|
||||
for (IBaseResource next : everything.getResources(i, i + 1)) {
|
||||
ids.add(next.getIdElement().toUnqualifiedVersionless().getValue());
|
||||
|
|
|
@ -141,6 +141,41 @@
|
|||
<artifactId>commons-dbcp2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.2.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bitbucket.b_c</groupId>
|
||||
<artifactId>jose4j</artifactId>
|
||||
<version>0.6.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>20180130</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
<version>2.0.2.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security.oauth</groupId>
|
||||
<artifactId>spring-security-oauth2</artifactId>
|
||||
<version>2.3.3.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-xml</artifactId>
|
||||
<version>2.9.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- This example uses Derby embedded database. If you are using another database such as Mysql or Oracle, you may omit the following dependencies and replace them with an appropriate database client
|
||||
dependency for your database platform. -->
|
||||
<dependency>
|
||||
|
@ -244,8 +279,8 @@
|
|||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
@ -288,8 +323,8 @@
|
|||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
<!-- <goal>integration-test</goal> -->
|
||||
<!-- <goal>verify</goal> -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
|
|
|
@ -127,7 +127,7 @@ public class FhirPathEngineR4Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testConcatenationFunction() throws FHIRException {
|
||||
public void testStringCompare() throws FHIRException {
|
||||
String exp = "element.first().path.startsWith(%resource.type) and element.tail().all(path.startsWith(%resource.type&'.'))";
|
||||
|
||||
StructureDefinition sd = new StructureDefinition();
|
||||
|
@ -138,9 +138,9 @@ public class FhirPathEngineR4Test {
|
|||
|
||||
Patient p = new Patient();
|
||||
p.addName().setFamily("TEST");
|
||||
List<Base> result = ourEngine.evaluate(null, p, diff, exp);
|
||||
List<Base> result = ourEngine.evaluate(null, p, null, diff, exp);
|
||||
ourLog.info(result.toString());
|
||||
// assertEquals("TEST.", result);
|
||||
assertEquals(true, ((BooleanType)result.get(0)).booleanValue());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -42,7 +42,11 @@ public class ${className}ResourceProvider extends
|
|||
javax.servlet.http.HttpServletResponse theServletResponse,
|
||||
|
||||
ca.uhn.fhir.rest.api.server.RequestDetails theRequestDetails,
|
||||
|
||||
|
||||
@Description(shortDefinition="Search the contents of the resource's data using a filter")
|
||||
@OptionalParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_FILTER)
|
||||
StringAndListParam theFtFilter,
|
||||
|
||||
@Description(shortDefinition="Search the contents of the resource's data using a fulltext search")
|
||||
@OptionalParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_CONTENT)
|
||||
StringAndListParam theFtContent,
|
||||
|
@ -142,6 +146,7 @@ public class ${className}ResourceProvider extends
|
|||
startRequest(theServletRequest);
|
||||
try {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_FILTER, theFtFilter);
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_CONTENT, theFtContent);
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_TEXT, theFtText);
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_TAG, theSearchForTag);
|
||||
|
|
|
@ -147,34 +147,6 @@ public class Dstu2ResourceValidatorDstu2Test {
|
|||
assertEquals(1, operationOutcome.getIssue().size());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void testSchemaResourceValidator() throws IOException {
|
||||
String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("patient-example-dicom.json"));
|
||||
Patient p = ourCtx.newJsonParser().parseResource(Patient.class, res);
|
||||
|
||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p));
|
||||
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.setValidateAgainstStandardSchema(true);
|
||||
if (ValidationConstants.SCHEMATRON_ENABLED) {
|
||||
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
|
||||
}
|
||||
|
||||
val.validate(p);
|
||||
|
||||
p.getAnimal().getBreed().setText("The Breed");
|
||||
try {
|
||||
val.validate(p);
|
||||
fail();
|
||||
} catch (ValidationFailureException e) {
|
||||
OperationOutcome operationOutcome = (OperationOutcome) e.getOperationOutcome();
|
||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome));
|
||||
assertEquals(1, operationOutcome.getIssue().size());
|
||||
assertThat(operationOutcome.getIssueFirstRep().getDetailsElement().getValue(), containsString("cvc-complex-type"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that the elements that appear in all resources (meta, language, extension, etc)
|
||||
* all appear in the correct order
|
||||
|
|
Loading…
Reference in New Issue