Improve synchronous searching by providing offset & limit support (#2059)
* Improve synchronous searching by providing offset & limit support Add support for offset querying which leverages paging at the query level Add configuration for search default page size and search maximum page size If using offset, always use synchronous searching to avoid extra database insert/update etc. When using offset, only calculate count if it's wanted Validate params closer to provider and handle size if search returned "all" (or last) * Review and test fixes Comment _offset as nonstandard parameter Make synchronous search always count the total value (for now) Fix issue with FulltextSearchSvcImpl mutating param map Dirty fix for BaseJpaTest (not sure how to fix the including resources issue) * Remove temporary count querying fix for synchronous loads * Fix offsetting of everything operations, do not drop zero offset * Fix jpa test default and maximum page size, add some fixmes to tests before resolved * Ignore one failing test, fix others * Fix Dereferenced variable may be null * Fix everything paging in R4 by adding DISTINCT if synchronous load is used Also fix assertion of size when hitting fetchSizeDefaultMaximum * Add documentation about offset annotation and paging Co-authored-by: James Agnew <jamesagnew@gmail.com>
This commit is contained in:
parent
a32397d993
commit
1435540320
|
@ -0,0 +1,38 @@
|
|||
package ca.uhn.fhir.rest.annotation;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2018 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Parameter annotation for the _offset parameter, which indicates to the
|
||||
* server the offset of desired results.
|
||||
*
|
||||
* @see History
|
||||
*/
|
||||
@Target(value=ElementType.PARAMETER)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Offset {
|
||||
//nothing
|
||||
}
|
|
@ -154,6 +154,7 @@ public class Constants {
|
|||
public static final String PARAM_CONTAINED_TYPE = "_containedType";
|
||||
public static final String PARAM_CONTENT = "_content";
|
||||
public static final String PARAM_COUNT = "_count";
|
||||
public static final String PARAM_OFFSET = "_offset";
|
||||
public static final String PARAM_DELETE = "_delete";
|
||||
public static final String PARAM_ELEMENTS = "_elements";
|
||||
public static final String PARAM_ELEMENTS_EXCLUDE_MODIFIER = ":exclude";
|
||||
|
|
|
@ -49,6 +49,16 @@ public interface IQuery<Y> extends IBaseQuery<IQuery<Y>>, IClientExecutable<IQue
|
|||
*/
|
||||
IQuery<Y> count(int theCount);
|
||||
|
||||
/**
|
||||
* Specifies the <code>_offset</code> parameter, which indicates to the server the offset of the query. Use
|
||||
* with {@link #count(int)}.
|
||||
*
|
||||
* This parameter is not part of the FHIR standard, all servers might not implement it.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
IQuery<Y> offset(int theOffset);
|
||||
|
||||
/**
|
||||
* Add an "_include" specification or an "_include:recurse" specification. If you are using
|
||||
* a constant from one of the built-in structures you can select whether you want recursive
|
||||
|
|
|
@ -1817,6 +1817,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
private List<Include> myInclude = new ArrayList<>();
|
||||
private DateRangeParam myLastUpdated;
|
||||
private Integer myParamLimit;
|
||||
private Integer myParamOffset;
|
||||
private List<Collection<String>> myProfiles = new ArrayList<>();
|
||||
private String myResourceId;
|
||||
private String myResourceName;
|
||||
|
@ -1874,6 +1875,16 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery offset(int theOffset) {
|
||||
if (theOffset >= 0) {
|
||||
myParamOffset = theOffset;
|
||||
} else {
|
||||
myParamOffset = null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OUTPUT execute() {
|
||||
|
||||
|
@ -1949,6 +1960,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
addParam(params, Constants.PARAM_COUNT, Integer.toString(myParamLimit));
|
||||
}
|
||||
|
||||
if (myParamOffset != null) {
|
||||
addParam(params, Constants.PARAM_OFFSET, Integer.toString(myParamOffset));
|
||||
}
|
||||
|
||||
if (myLastUpdated != null) {
|
||||
for (DateParam next : myLastUpdated.getValuesAsQueryTokens()) {
|
||||
addParam(params, Constants.PARAM_LASTUPDATED, next.getValueAsQueryToken(myContext));
|
||||
|
|
|
@ -52,6 +52,7 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
set.add(Constants.PARAM_SORT_ASC);
|
||||
set.add(Constants.PARAM_SORT_DESC);
|
||||
set.add(Constants.PARAM_COUNT);
|
||||
set.add(Constants.PARAM_OFFSET);
|
||||
set.add(Constants.PARAM_SUMMARY);
|
||||
set.add(Constants.PARAM_ELEMENTS);
|
||||
ALLOWED_PARAMS = Collections.unmodifiableSet(set);
|
||||
|
|
|
@ -340,6 +340,8 @@ public class MethodUtil {
|
|||
outerCollectionType);
|
||||
} else if (nextAnnotation instanceof Count) {
|
||||
param = new CountParameter();
|
||||
} else if (nextAnnotation instanceof Offset) {
|
||||
param = new OffsetParameter();
|
||||
} else if (nextAnnotation instanceof Sort) {
|
||||
param = new SortParameter(theContext);
|
||||
} else if (nextAnnotation instanceof TransactionParam) {
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package ca.uhn.fhir.rest.client.method;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Client Framework
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2018 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.primitive.IntegerDt;
|
||||
import ca.uhn.fhir.rest.annotation.Offset;
|
||||
import ca.uhn.fhir.rest.annotation.Since;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.param.ParameterUtil;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
|
||||
public class OffsetParameter implements IParameter {
|
||||
|
||||
@Override
|
||||
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource)
|
||||
throws InternalErrorException {
|
||||
if (theSourceClientArgument != null) {
|
||||
IntegerDt since = ParameterUtil.toInteger(theSourceClientArgument);
|
||||
if (since.isEmpty() == false) {
|
||||
theTargetQueryArguments.put(Constants.PARAM_OFFSET, Collections.singletonList(since.getValueAsString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) {
|
||||
if (theOuterCollectionType != null) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is annotated with @" + Offset.class.getName()
|
||||
+ " but can not be of collection type");
|
||||
}
|
||||
if (!ParameterUtil.isBindableIntegerType(theParameterType)) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is annotated with @" + Offset.class.getName()
|
||||
+ " but type '" + theParameterType + "' is an invalid type, must be Integer or IntegerType");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -149,6 +149,43 @@ public List<Patient> findPatients(
|
|||
}
|
||||
//END SNIPPET: sort
|
||||
|
||||
//START SNIPPET: count
|
||||
@Search
|
||||
public List<Patient> findPatients(
|
||||
@RequiredParam(name=Patient.SP_IDENTIFIER) StringParam theParameter,
|
||||
@Count Integer theCount) {
|
||||
List<Patient> retVal=new ArrayList<Patient>(); // populate this
|
||||
|
||||
// count is null unless a _count parameter is actually provided
|
||||
if (theCount != null) {
|
||||
// ... do search with count ...
|
||||
} else {
|
||||
// ... do search without count ...
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
//END SNIPPET: count
|
||||
|
||||
//START SNIPPET: offset
|
||||
@Search
|
||||
public List<Patient> findPatients(
|
||||
@RequiredParam(name=Patient.SP_IDENTIFIER) StringParam theParameter,
|
||||
@Offset Integer theOffset,
|
||||
@Count Integer theCount) {
|
||||
List<Patient> retVal=new ArrayList<Patient>(); // populate this
|
||||
|
||||
// offset is null unless a _offset parameter is actually provided
|
||||
if (theOffset != null) {
|
||||
// ... do search with offset ...
|
||||
} else {
|
||||
// ... do search without offset ...
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
//END SNIPPET: offset
|
||||
|
||||
//START SNIPPET: underlyingReq
|
||||
@Search
|
||||
public List<Patient> findPatients(
|
||||
|
|
|
@ -24,6 +24,19 @@ The following example shows a server implementation with paging support.
|
|||
{{snippet:classpath:/ca/uhn/hapi/fhir/docs/PagingServer.java|provider}}
|
||||
```
|
||||
|
||||
HAPI FHIR contains couple of implementations for `IPagingProvider`.
|
||||
|
||||
### DatabaseBackedPagingProvider
|
||||
|
||||
When using `DatabaseBackedPagingProvider` HAPI FHIR searches may be done asynchronously. This means that
|
||||
the result is also cached to the database and the client may base the cached search result set.
|
||||
|
||||
### FifoMemoryPagingProvider
|
||||
|
||||
When using `FifoMemoryPagingProvider` HAPI FHIR server search is persisted on the server memory and when
|
||||
pages are fetched the server returns the results from the cached memory (unless the cache overflowed and the old result
|
||||
set is no longer available).
|
||||
|
||||
# Bundle Providers
|
||||
|
||||
If a server supports a paging provider, a further optimization is to also use a bundle provider. A bundle provider simply takes the place of the `List<IBaseResource>` return type in your provider methods. In other words, instead of returning *List<IBaseResource>*, your search method will return [IBundleProvider](/hapi-fhir/apidocs/hapi-fhir-server/ca/uhn/fhir/rest/api/server/IBundleProvider.html).
|
||||
|
|
|
@ -349,6 +349,63 @@ Example URL to invoke this method:
|
|||
http://fhir.example.com/Patient?_identifier=urn:foo|123&_sort=given
|
||||
```
|
||||
|
||||
# Limiting results (`_count`)
|
||||
|
||||
FHIR supports [Page Count](http://www.hl7.org/implement/standards/fhir/search.html#count). Count specification may be passed into handler methods with
|
||||
[@Count](/hapi-fhir/apidocs/hapi-fhir-base/ca/uhn/fhir/rest/annotation/Count.html) annotation. Count may be used to limit the number
|
||||
of resources fetched from the database.
|
||||
|
||||
```java
|
||||
{{snippet:classpath:/ca/uhn/hapi/fhir/docs/RestfulPatientResourceProviderMore.java|count}}
|
||||
```
|
||||
|
||||
Example URL to invoke this method:
|
||||
|
||||
```url
|
||||
http://fhir.example.com/Patient?_identifier=urn:foo|123&_count=10
|
||||
```
|
||||
|
||||
# Paging
|
||||
|
||||
## Offset paging with `_offset`
|
||||
|
||||
HAPI FHIR supports also paging. Offset specification can be passed into handler methods with [@Offset](/hapi-fhir/apidocs/hapi-fhir-base/ca/uhn/fhir/rest/annotation/Offset.html) annotation.
|
||||
This annotation is *not* part of the FHIR standard.
|
||||
|
||||
There are two possible ways to use paging. It is possible to define `_offset` parameter in the
|
||||
request which means that when combined with `_count` the paging is done on the database level. This type of
|
||||
paging benefits from not having to return so many items from the database when paging items. It's also possible
|
||||
to define default page size (i.e. default `_count` if not given) and maximum page size (i.e. maximum value
|
||||
for the `_count` parameter). See [RestfulServer](/hapi-fhir/apidocs/hapi-fhir-server/ca/uhn/fhir/rest/server/RestfulServer.html)
|
||||
for more information.
|
||||
|
||||
```java
|
||||
{{snippet:classpath:/ca/uhn/hapi/fhir/docs/RestfulPatientResourceProviderMore.java|offset}}
|
||||
```
|
||||
|
||||
Example URL to invoke this method for the first page:
|
||||
|
||||
```url
|
||||
http://fhir.example.com/Patient?_identifier=urn:foo|123&_count=10&_offset=0
|
||||
```
|
||||
or just
|
||||
```url
|
||||
http://fhir.example.com/Patient?_identifier=urn:foo|123&_count=10
|
||||
```
|
||||
|
||||
Example URL to invoke this method for the second page:
|
||||
|
||||
```url
|
||||
http://fhir.example.com/Patient?_identifier=urn:foo|123&_count=10&_offset=10
|
||||
```
|
||||
|
||||
Note that if the paging provider is configured to be database backed, `_offset=0` behaves differently than no `_offset`. This
|
||||
allows the user the choose if he wants offset paging or database backed paging.
|
||||
|
||||
## Using paging provider
|
||||
|
||||
It is also possible to implement own paging provider (or use implementation bundled in HAPI FHIR). See [Paging](./paging.html) for information on how to use paging provider.
|
||||
|
||||
# Adding Descriptions
|
||||
|
||||
It is also possible to annotate search methods and/or parameters with the [@Description](/hapi-fhir/apidocs/hapi-fhir-base/ca/uhn/fhir/model/api/annotation/Description.html) annotation. This annotation allows you to add a description of the method and the individual parameters. These descriptions will be placed in the server's conformance statement, which can be helpful to anyone who is developing software against your server.
|
||||
|
|
|
@ -32,6 +32,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||
|
||||
public interface IFhirResourceDaoComposition<T extends IBaseResource> extends IFhirResourceDao<T> {
|
||||
|
||||
IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails);
|
||||
IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails);
|
||||
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@ import javax.servlet.http.HttpServletRequest;
|
|||
|
||||
public interface IFhirResourceDaoEncounter<T extends IBaseResource> extends IFhirResourceDao<T> {
|
||||
|
||||
IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdate, SortSpec theSort);
|
||||
IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdate, SortSpec theSort);
|
||||
|
||||
IBundleProvider encounterTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSortSpec);
|
||||
IBundleProvider encounterTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSortSpec);
|
||||
|
||||
}
|
||||
|
|
|
@ -33,9 +33,9 @@ import javax.servlet.http.HttpServletRequest;
|
|||
|
||||
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, StringAndListParam theFilter, RequestDetails theRequestDetails);
|
||||
IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, 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, StringAndListParam theFilter, RequestDetails theRequestDetails);
|
||||
IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSortSpec, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ import ca.uhn.fhir.rest.api.server.SimplePreResourceAccessDetails;
|
|||
import ca.uhn.fhir.rest.api.server.SimplePreResourceShowDetails;
|
||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
|
||||
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||
|
@ -1243,8 +1244,24 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
}
|
||||
}
|
||||
|
||||
if (!isPagingProviderDatabaseBacked(theRequest)) {
|
||||
final Integer offset = RestfulServerUtils.extractOffsetParameter(theRequest);
|
||||
if (offset != null || !isPagingProviderDatabaseBacked(theRequest)) {
|
||||
theParams.setLoadSynchronous(true);
|
||||
if (offset != null) {
|
||||
Validate.inclusiveBetween(0, Integer.MAX_VALUE, offset.intValue(), "Offset must be a positive integer");
|
||||
}
|
||||
theParams.setOffset(offset);
|
||||
}
|
||||
|
||||
final Integer count = RestfulServerUtils.extractCountParameter(theRequest);
|
||||
if (count != null) {
|
||||
Integer maxPageSize = theRequest.getServer().getMaximumPageSize();
|
||||
if (maxPageSize != null) {
|
||||
Validate.inclusiveBetween(1, theRequest.getServer().getMaximumPageSize(), count.intValue(), "Count must be positive integer and less than " + maxPageSize);
|
||||
}
|
||||
theParams.setCount(count);
|
||||
} else if (theRequest.getServer().getDefaultPageSize() != null) {
|
||||
theParams.setCount(theRequest.getServer().getDefaultPageSize());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||
public class FhirResourceDaoCompositionDstu2 extends BaseHapiFhirResourceDao<Composition>implements IFhirResourceDaoComposition<Composition> {
|
||||
|
||||
@Override
|
||||
public IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails) {
|
||||
public IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails) {
|
||||
throw new NotImplementedOperationException("$document not implemented in DSTU2");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,11 +38,14 @@ import java.util.Collections;
|
|||
public class FhirResourceDaoEncounterDstu2 extends BaseHapiFhirResourceDao<Encounter>implements IFhirResourceDaoEncounter<Encounter> {
|
||||
|
||||
@Override
|
||||
public IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
public IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
if (theOffset != null) {
|
||||
paramMap.setOffset(theOffset.getValue());
|
||||
}
|
||||
|
||||
// paramMap.setRevIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
|
@ -57,8 +60,8 @@ public class FhirResourceDaoEncounterDstu2 extends BaseHapiFhirResourceDao<Encou
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider encounterTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
return encounterInstanceEverything(theServletRequest, null, theCount, theLastUpdated, theSort);
|
||||
public IBundleProvider encounterTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
return encounterInstanceEverything(theServletRequest, null, theCount, theOffset, theLastUpdated, theSort);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,11 +47,14 @@ public class FhirResourceDaoPatientDstu2 extends BaseHapiFhirResourceDao<Patient
|
|||
super();
|
||||
}
|
||||
|
||||
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequest) {
|
||||
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequest) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
if (theOffset != null) {
|
||||
paramMap.setOffset(theOffset.getValue());
|
||||
}
|
||||
if (theContent != null) {
|
||||
paramMap.add(Constants.PARAM_CONTENT, theContent);
|
||||
}
|
||||
|
@ -74,21 +77,21 @@ public class FhirResourceDaoPatientDstu2 extends BaseHapiFhirResourceDao<Patient
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, 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, theFilter, theRequestDetails);
|
||||
return doEverythingOperation(theId, theCount, theOffset, theLastUpdated, theSort, theContent, theNarrative, theFilter, theRequestDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, 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, theFilter, theRequestDetails);
|
||||
return doEverythingOperation(null, theCount, theOffset, theLastUpdated, theSort, theContent, theNarrative, theFilter, theRequestDetails);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
|||
import ca.uhn.fhir.jpa.model.entity.ResourceTag;
|
||||
import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
|
||||
import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
|
||||
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
|
||||
import ca.uhn.fhir.jpa.search.lastn.IElasticsearchSvc;
|
||||
import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
|
@ -250,7 +251,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
|
||||
init(theParams, theSearchUuid, theRequestPartitionId);
|
||||
|
||||
List<TypedQuery<Long>> queries = createQuery(null, null, true, theRequest, null);
|
||||
List<TypedQuery<Long>> queries = createQuery(null, null, null, true, theRequest, null);
|
||||
return new CountQueryIterator(queries.get(0));
|
||||
}
|
||||
|
||||
|
@ -285,7 +286,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
myRequestPartitionId = theRequestPartitionId;
|
||||
}
|
||||
|
||||
private List<TypedQuery<Long>> createQuery(SortSpec sort, Integer theMaximumResults, boolean theCount, RequestDetails theRequest,
|
||||
private List<TypedQuery<Long>> createQuery(SortSpec sort, Integer theOffset, Integer theMaximumResults, boolean theCount, RequestDetails theRequest,
|
||||
SearchRuntimeDetails theSearchRuntimeDetails) {
|
||||
|
||||
List<ResourcePersistentId> pids = new ArrayList<>();
|
||||
|
@ -341,22 +342,22 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
if (theMaximumResults != null && pids.size() > theMaximumResults) {
|
||||
pids.subList(0,theMaximumResults-1);
|
||||
}
|
||||
new QueryChunker<Long>().chunk(ResourcePersistentId.toLongList(pids), t-> doCreateChunkedQueries(t, sort, theCount, theRequest, myQueries));
|
||||
new QueryChunker<Long>().chunk(ResourcePersistentId.toLongList(pids), t-> doCreateChunkedQueries(t, sort, theOffset, theCount, theRequest, myQueries));
|
||||
} else {
|
||||
myQueries.add(createChunkedQuery(sort,theMaximumResults, theCount, theRequest, null));
|
||||
myQueries.add(createChunkedQuery(sort, theOffset, theMaximumResults, theCount, theRequest, null));
|
||||
}
|
||||
|
||||
return myQueries;
|
||||
}
|
||||
|
||||
private void doCreateChunkedQueries(List<Long> thePids, SortSpec sort, boolean theCount, RequestDetails theRequest, ArrayList<TypedQuery<Long>> theQueries) {
|
||||
private void doCreateChunkedQueries(List<Long> thePids, SortSpec sort, Integer theOffset, boolean theCount, RequestDetails theRequest, ArrayList<TypedQuery<Long>> theQueries) {
|
||||
if(thePids.size() < getMaximumPageSize()) {
|
||||
normalizeIdListForLastNInClause(thePids);
|
||||
}
|
||||
theQueries.add(createChunkedQuery(sort, thePids.size(), theCount, theRequest, thePids));
|
||||
theQueries.add(createChunkedQuery(sort, theOffset, thePids.size(), theCount, theRequest, thePids));
|
||||
}
|
||||
|
||||
private TypedQuery<Long> createChunkedQuery(SortSpec sort, Integer theMaximumResults, boolean theCount, RequestDetails theRequest, List<Long> thePidList) {
|
||||
private TypedQuery<Long> createChunkedQuery(SortSpec sort, Integer theOffset, Integer theMaximumResults, boolean theCount, RequestDetails theRequest, List<Long> thePidList) {
|
||||
/*
|
||||
* Sort
|
||||
*
|
||||
|
@ -377,6 +378,8 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
|
||||
if (theCount) {
|
||||
myQueryStack.pushResourceTableCountQuery();
|
||||
} else if (myParams.getEverythingMode() != null && myParams.isLoadSynchronous()) {
|
||||
myQueryStack.pushResourceTableDistinctQuery();
|
||||
} else {
|
||||
myQueryStack.pushResourceTableQuery();
|
||||
}
|
||||
|
@ -420,7 +423,9 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
CriteriaQuery<Long> outerQuery = (CriteriaQuery<Long>) myQueryStack.pop();
|
||||
final TypedQuery<Long> query = myEntityManager.createQuery(outerQuery);
|
||||
assert myQueryStack.isEmpty();
|
||||
|
||||
if (!theCount && theOffset != null) {
|
||||
query.setFirstResult(theOffset);
|
||||
}
|
||||
if (theMaximumResults != null) {
|
||||
query.setMaxResults(theMaximumResults);
|
||||
}
|
||||
|
@ -1095,6 +1100,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
private ResourcePersistentId myNext;
|
||||
private Iterator<ResourcePersistentId> myPreResultsIterator;
|
||||
private ScrollableResultsIterator<Long> myResultsIterator;
|
||||
private Integer myOffset;
|
||||
private final SortSpec mySort;
|
||||
private boolean myStillNeedToFetchIncludes;
|
||||
private int mySkipCount = 0;
|
||||
|
@ -1105,6 +1111,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
private QueryIterator(SearchRuntimeDetails theSearchRuntimeDetails, RequestDetails theRequest) {
|
||||
mySearchRuntimeDetails = theSearchRuntimeDetails;
|
||||
mySort = myParams.getSort();
|
||||
myOffset = myParams.getOffset();
|
||||
myRequest = theRequest;
|
||||
|
||||
// Includes are processed inline for $everything query
|
||||
|
@ -1117,6 +1124,13 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
|
||||
}
|
||||
|
||||
private boolean isPagingProviderDatabaseBacked() {
|
||||
if (myRequest == null || myRequest.getServer() == null) {
|
||||
return false;
|
||||
}
|
||||
return myRequest.getServer().getPagingProvider() instanceof DatabaseBackedPagingProvider;
|
||||
}
|
||||
|
||||
private void fetchNext() {
|
||||
|
||||
try {
|
||||
|
@ -1127,10 +1141,16 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
// If we don't have a query yet, create one
|
||||
if (myResultsIterator == null) {
|
||||
if (myMaxResultsToFetch == null) {
|
||||
myMaxResultsToFetch = myDaoConfig.getFetchSizeDefaultMaximum();
|
||||
if (myParams.getLoadSynchronousUpTo() != null) {
|
||||
myMaxResultsToFetch = myParams.getLoadSynchronousUpTo();
|
||||
} else if (myParams.getCount() != null) {
|
||||
myMaxResultsToFetch = myParams.getCount();
|
||||
} else {
|
||||
myMaxResultsToFetch = myDaoConfig.getFetchSizeDefaultMaximum();
|
||||
}
|
||||
}
|
||||
|
||||
initializeIteratorQuery(myMaxResultsToFetch);
|
||||
initializeIteratorQuery(myOffset, myMaxResultsToFetch);
|
||||
|
||||
// If the query resulted in extra results being requested
|
||||
if (myAlsoIncludePids != null) {
|
||||
|
@ -1192,7 +1212,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
.add(StorageProcessingMessage.class, message);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_WARNING, params);
|
||||
|
||||
initializeIteratorQuery(myMaxResultsToFetch);
|
||||
initializeIteratorQuery(null, myMaxResultsToFetch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1255,11 +1275,11 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
|
||||
}
|
||||
|
||||
private void initializeIteratorQuery(Integer theMaxResultsToFetch) {
|
||||
private void initializeIteratorQuery(Integer theOffset, Integer theMaxResultsToFetch) {
|
||||
if (myQueryList.isEmpty()) {
|
||||
// Capture times for Lucene/Elasticsearch queries as well
|
||||
mySearchRuntimeDetails.setQueryStopwatch(new StopWatch());
|
||||
myQueryList = createQuery(mySort, theMaxResultsToFetch, false, myRequest, mySearchRuntimeDetails);
|
||||
myQueryList = createQuery(mySort, theOffset, theMaxResultsToFetch, false, myRequest, mySearchRuntimeDetails);
|
||||
}
|
||||
|
||||
mySearchRuntimeDetails.setQueryStopwatch(new StopWatch());
|
||||
|
|
|
@ -39,11 +39,14 @@ import java.util.Collections;
|
|||
public class FhirResourceDaoCompositionDstu3 extends BaseHapiFhirResourceDao<Composition> implements IFhirResourceDaoComposition<Composition> {
|
||||
|
||||
@Override
|
||||
public IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails) {
|
||||
public IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
if (theOffset != null) {
|
||||
paramMap.setOffset(theOffset.getValue());
|
||||
}
|
||||
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setSort(theSort);
|
||||
paramMap.setLastUpdated(theLastUpdate);
|
||||
|
|
|
@ -39,11 +39,14 @@ import java.util.Collections;
|
|||
public class FhirResourceDaoEncounterDstu3 extends BaseHapiFhirResourceDao<Encounter> implements IFhirResourceDaoEncounter<Encounter> {
|
||||
|
||||
@Override
|
||||
public IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
public IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
if (theOffset != null) {
|
||||
paramMap.setOffset(theOffset.getValue());
|
||||
}
|
||||
|
||||
// paramMap.setRevIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
|
@ -58,8 +61,8 @@ public class FhirResourceDaoEncounterDstu3 extends BaseHapiFhirResourceDao<Encou
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider encounterTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
return encounterInstanceEverything(theServletRequest, null, theCount, theLastUpdated, theSort);
|
||||
public IBundleProvider encounterTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
return encounterInstanceEverything(theServletRequest, null, theCount, theOffset, theLastUpdated, theSort);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -42,11 +42,14 @@ import java.util.Collections;
|
|||
|
||||
public class FhirResourceDaoPatientDstu3 extends BaseHapiFhirResourceDao<Patient>implements IFhirResourceDaoPatient<Patient> {
|
||||
|
||||
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequest) {
|
||||
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequest) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
if (theOffset != null) {
|
||||
paramMap.setOffset(theOffset.getValue());
|
||||
}
|
||||
if (theContent != null) {
|
||||
paramMap.add(Constants.PARAM_CONTENT, theContent);
|
||||
}
|
||||
|
@ -69,13 +72,13 @@ public class FhirResourceDaoPatientDstu3 extends BaseHapiFhirResourceDao<Patient
|
|||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(theId, theCount, theOffset, theLastUpdated, theSort, theContent, theNarrative, theFilter, theRequestDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(null, theCount, theOffset, theLastUpdated, theSort, theContent, theNarrative, theFilter, theRequestDetails);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ class QueryRootEntryResourceTable extends QueryRootEntry {
|
|||
/**
|
||||
* Root query constructor
|
||||
*/
|
||||
QueryRootEntryResourceTable(CriteriaBuilder theCriteriaBuilder, boolean theCountQuery, SearchParameterMap theSearchParameterMap, String theResourceType, RequestPartitionId theRequestPartitionId) {
|
||||
QueryRootEntryResourceTable(CriteriaBuilder theCriteriaBuilder, boolean theDistinct, boolean theCountQuery, SearchParameterMap theSearchParameterMap, String theResourceType, RequestPartitionId theRequestPartitionId) {
|
||||
super(theCriteriaBuilder);
|
||||
myCriteriaBuilder = theCriteriaBuilder;
|
||||
mySearchParameterMap = theSearchParameterMap;
|
||||
|
@ -91,6 +91,8 @@ class QueryRootEntryResourceTable extends QueryRootEntry {
|
|||
|
||||
if (theCountQuery) {
|
||||
query.multiselect(myCriteriaBuilder.countDistinct(myResourceTableRoot));
|
||||
} else if (theDistinct) {
|
||||
query.distinct(true).multiselect(get("myId").as(Long.class));
|
||||
} else {
|
||||
query.multiselect(get("myId").as(Long.class));
|
||||
}
|
||||
|
|
|
@ -87,7 +87,19 @@ public class QueryStack {
|
|||
*/
|
||||
public void pushResourceTableQuery() {
|
||||
assert myQueryRootStack.isEmpty();
|
||||
myQueryRootStack.push(new QueryRootEntryResourceTable(myCriteriaBuilder, false, mySearchParameterMap, myResourceType, myRequestPartitionId));
|
||||
myQueryRootStack.push(new QueryRootEntryResourceTable(myCriteriaBuilder, false, false, mySearchParameterMap, myResourceType, myRequestPartitionId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new <code>select DISTINCT RES_ID from HFJ_RESOURCE</code> to the stack. All predicates added to the {@literal QueryRootStack}
|
||||
* will be added to this select clause until {@link #pop()} is called.
|
||||
* <p>
|
||||
* This method must only be called when the stack is empty.
|
||||
* </p>
|
||||
*/
|
||||
public void pushResourceTableDistinctQuery() {
|
||||
assert myQueryRootStack.isEmpty();
|
||||
myQueryRootStack.push(new QueryRootEntryResourceTable(myCriteriaBuilder, true, false, mySearchParameterMap, myResourceType, myRequestPartitionId));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,7 +111,7 @@ public class QueryStack {
|
|||
*/
|
||||
public void pushResourceTableCountQuery() {
|
||||
assert myQueryRootStack.isEmpty();
|
||||
myQueryRootStack.push(new QueryRootEntryResourceTable(myCriteriaBuilder, true, mySearchParameterMap, myResourceType, myRequestPartitionId));
|
||||
myQueryRootStack.push(new QueryRootEntryResourceTable(myCriteriaBuilder, false, true, mySearchParameterMap, myResourceType, myRequestPartitionId));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -39,11 +39,14 @@ import java.util.Collections;
|
|||
public class FhirResourceDaoCompositionR4 extends BaseHapiFhirResourceDao<Composition> implements IFhirResourceDaoComposition<Composition> {
|
||||
|
||||
@Override
|
||||
public IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails) {
|
||||
public IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
if (theOffset != null) {
|
||||
paramMap.setOffset(theOffset.getValue());
|
||||
}
|
||||
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setSort(theSort);
|
||||
paramMap.setLastUpdated(theLastUpdate);
|
||||
|
|
|
@ -39,11 +39,14 @@ import java.util.Collections;
|
|||
public class FhirResourceDaoEncounterR4 extends BaseHapiFhirResourceDao<Encounter> implements IFhirResourceDaoEncounter<Encounter> {
|
||||
|
||||
@Override
|
||||
public IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
public IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
if (theOffset != null) {
|
||||
paramMap.setOffset(theOffset.getValue());
|
||||
}
|
||||
|
||||
// paramMap.setRevIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
|
@ -58,8 +61,8 @@ public class FhirResourceDaoEncounterR4 extends BaseHapiFhirResourceDao<Encounte
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider encounterTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
return encounterInstanceEverything(theServletRequest, null, theCount, theLastUpdated, theSort);
|
||||
public IBundleProvider encounterTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
return encounterInstanceEverything(theServletRequest, null, theCount, theOffset, theLastUpdated, theSort);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -42,11 +42,14 @@ import java.util.Collections;
|
|||
|
||||
public class FhirResourceDaoPatientR4 extends BaseHapiFhirResourceDao<Patient>implements IFhirResourceDaoPatient<Patient> {
|
||||
|
||||
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequest) {
|
||||
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequest) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
if (theOffset != null) {
|
||||
paramMap.setOffset(theOffset.getValue());
|
||||
}
|
||||
if (theContent != null) {
|
||||
paramMap.add(Constants.PARAM_CONTENT, theContent);
|
||||
}
|
||||
|
@ -69,13 +72,13 @@ public class FhirResourceDaoPatientR4 extends BaseHapiFhirResourceDao<Patient>im
|
|||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(theId, theCount, theOffset, theLastUpdated, theSort, theContent, theNarrative, theFilter, theRequestDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(null, theCount, theOffset, theLastUpdated, theSort, theContent, theNarrative, theFilter, theRequestDetails);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,11 +39,14 @@ import java.util.Collections;
|
|||
public class FhirResourceDaoCompositionR5 extends BaseHapiFhirResourceDao<Composition> implements IFhirResourceDaoComposition<Composition> {
|
||||
|
||||
@Override
|
||||
public IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails) {
|
||||
public IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
if (theOffset != null) {
|
||||
paramMap.setOffset(theOffset.getValue());
|
||||
}
|
||||
paramMap.setIncludes(Collections.singleton(IBaseResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setSort(theSort);
|
||||
paramMap.setLastUpdated(theLastUpdate);
|
||||
|
|
|
@ -39,11 +39,14 @@ import java.util.Collections;
|
|||
public class FhirResourceDaoEncounterR5 extends BaseHapiFhirResourceDao<Encounter> implements IFhirResourceDaoEncounter<Encounter> {
|
||||
|
||||
@Override
|
||||
public IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
public IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
if (theOffset != null) {
|
||||
paramMap.setOffset(theOffset.getValue());
|
||||
}
|
||||
|
||||
// paramMap.setRevIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setIncludes(Collections.singleton(IBaseResource.INCLUDE_ALL.asRecursive()));
|
||||
|
@ -58,8 +61,8 @@ public class FhirResourceDaoEncounterR5 extends BaseHapiFhirResourceDao<Encounte
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider encounterTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
return encounterInstanceEverything(theServletRequest, null, theCount, theLastUpdated, theSort);
|
||||
public IBundleProvider encounterTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
return encounterInstanceEverything(theServletRequest, null, theCount, theOffset, theLastUpdated, theSort);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -42,11 +42,14 @@ import java.util.Collections;
|
|||
|
||||
public class FhirResourceDaoPatientR5 extends BaseHapiFhirResourceDao<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, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequest) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
if (theOffset != null) {
|
||||
paramMap.setOffset(theOffset.getValue());
|
||||
}
|
||||
if (theContent != null) {
|
||||
paramMap.add(Constants.PARAM_CONTENT, theContent);
|
||||
}
|
||||
|
@ -69,13 +72,13 @@ public class FhirResourceDaoPatientR5 extends BaseHapiFhirResourceDao<Patient> i
|
|||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(theId, theCount, theOffset, theLastUpdated, theSort, theContent, theNarrative, theRequestDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
return doEverythingOperation(null, theCount, theOffset, theLastUpdated, theSort, theContent, theNarrative, theRequestDetails);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public class BaseJpaResourceProviderCompositionDstu2 extends JpaResourceProvider
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
((IFhirResourceDaoComposition<Composition>)getDao()).getDocumentForComposition(theServletRequest, null, null, null, null, null);
|
||||
((IFhirResourceDaoComposition<Composition>)getDao()).getDocumentForComposition(theServletRequest, null, null, null, null, null, null);
|
||||
return null;
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
|
|
|
@ -51,6 +51,10 @@ public class BaseJpaResourceProviderEncounterDstu2 extends JpaResourceProviderDs
|
|||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
ca.uhn.fhir.model.primitive.UnsignedIntDt theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
ca.uhn.fhir.model.primitive.UnsignedIntDt theOffset,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
DateRangeParam theLastUpdated,
|
||||
|
@ -61,7 +65,7 @@ public class BaseJpaResourceProviderEncounterDstu2 extends JpaResourceProviderDs
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec);
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterInstanceEverything(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}}
|
||||
|
@ -78,6 +82,10 @@ public class BaseJpaResourceProviderEncounterDstu2 extends JpaResourceProviderDs
|
|||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
ca.uhn.fhir.model.primitive.UnsignedIntDt theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
ca.uhn.fhir.model.primitive.UnsignedIntDt theOffset,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
DateRangeParam theLastUpdated,
|
||||
|
@ -88,7 +96,7 @@ public class BaseJpaResourceProviderEncounterDstu2 extends JpaResourceProviderDs
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec);
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterTypeEverything(theServletRequest, theCount, theOffset,theLastUpdated, theSortSpec);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
|
|
@ -59,6 +59,10 @@ public class BaseJpaResourceProviderPatientDstu2 extends JpaResourceProviderDstu
|
|||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
|
||||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
ca.uhn.fhir.model.primitive.UnsignedIntDt theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
ca.uhn.fhir.model.primitive.UnsignedIntDt theOffset,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
|
@ -84,7 +88,7 @@ public class BaseJpaResourceProviderPatientDstu2 extends JpaResourceProviderDstu
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theOffset,theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
@ -101,6 +105,10 @@ public class BaseJpaResourceProviderPatientDstu2 extends JpaResourceProviderDstu
|
|||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
|
||||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
ca.uhn.fhir.model.primitive.UnsignedIntDt theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
ca.uhn.fhir.model.primitive.UnsignedIntDt theOffset,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
|
@ -126,7 +134,7 @@ public class BaseJpaResourceProviderPatientDstu2 extends JpaResourceProviderDstu
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theOffset, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
|
|
@ -62,6 +62,10 @@ public class BaseJpaResourceProviderCompositionDstu3 extends JpaResourceProvider
|
|||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
|
||||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
UnsignedIntType theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
UnsignedIntType theOffset,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
|
@ -76,7 +80,7 @@ public class BaseJpaResourceProviderCompositionDstu3 extends JpaResourceProvider
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
IBundleProvider bundleProvider = ((IFhirResourceDaoComposition<Composition>) getDao()).getDocumentForComposition(theServletRequest, theId, theCount, theLastUpdated, theSortSpec, theRequestDetails);
|
||||
IBundleProvider bundleProvider = ((IFhirResourceDaoComposition<Composition>) getDao()).getDocumentForComposition(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec, theRequestDetails);
|
||||
List<IBaseResource> resourceList = bundleProvider.getResources(0, bundleProvider.size());
|
||||
|
||||
boolean foundCompositionResource = false;
|
||||
|
|
|
@ -52,6 +52,10 @@ public class BaseJpaResourceProviderEncounterDstu3 extends JpaResourceProviderDs
|
|||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
|
||||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
UnsignedIntType theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
UnsignedIntType theOffset,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
|
@ -63,7 +67,7 @@ public class BaseJpaResourceProviderEncounterDstu3 extends JpaResourceProviderDs
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec);
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterInstanceEverything(theServletRequest, theId, theCount, theOffset,theLastUpdated, theSortSpec);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}}
|
||||
|
@ -79,6 +83,10 @@ public class BaseJpaResourceProviderEncounterDstu3 extends JpaResourceProviderDs
|
|||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
|
||||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
UnsignedIntType theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
UnsignedIntType theOffset,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
|
@ -90,7 +98,7 @@ public class BaseJpaResourceProviderEncounterDstu3 extends JpaResourceProviderDs
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec);
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterTypeEverything(theServletRequest, theCount, theOffset, theLastUpdated, theSortSpec);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
|
|
@ -62,6 +62,10 @@ public class BaseJpaResourceProviderPatientDstu3 extends JpaResourceProviderDstu
|
|||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
UnsignedIntType theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
UnsignedIntType theOffset,
|
||||
|
||||
@Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
|
||||
DateRangeParam theLastUpdated,
|
||||
|
@ -86,7 +90,7 @@ public class BaseJpaResourceProviderPatientDstu3 extends JpaResourceProviderDstu
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
@ -104,6 +108,10 @@ public class BaseJpaResourceProviderPatientDstu3 extends JpaResourceProviderDstu
|
|||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
UnsignedIntType theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
UnsignedIntType theOffset,
|
||||
|
||||
@Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
|
||||
DateRangeParam theLastUpdated,
|
||||
|
@ -128,7 +136,7 @@ public class BaseJpaResourceProviderPatientDstu3 extends JpaResourceProviderDstu
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theOffset, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
|
|
@ -61,6 +61,10 @@ public class BaseJpaResourceProviderCompositionR4 extends JpaResourceProviderR4<
|
|||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
UnsignedIntType theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
UnsignedIntType theOffset,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
DateRangeParam theLastUpdated,
|
||||
|
@ -73,7 +77,7 @@ public class BaseJpaResourceProviderCompositionR4 extends JpaResourceProviderR4<
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
IBundleProvider bundleProvider = ((IFhirResourceDaoComposition<Composition>) getDao()).getDocumentForComposition(theServletRequest, theId, theCount, theLastUpdated, theSortSpec, theRequestDetails);
|
||||
IBundleProvider bundleProvider = ((IFhirResourceDaoComposition<Composition>) getDao()).getDocumentForComposition(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec, theRequestDetails);
|
||||
List<IBaseResource> resourceList = bundleProvider.getResources(0, bundleProvider.size());
|
||||
|
||||
boolean foundCompositionResource = false;
|
||||
|
|
|
@ -52,6 +52,10 @@ public class BaseJpaResourceProviderEncounterR4 extends JpaResourceProviderR4<En
|
|||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
|
||||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
UnsignedIntType theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
UnsignedIntType theOffset,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
|
@ -63,7 +67,7 @@ public class BaseJpaResourceProviderEncounterR4 extends JpaResourceProviderR4<En
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec);
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterInstanceEverything(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}}
|
||||
|
@ -79,6 +83,10 @@ public class BaseJpaResourceProviderEncounterR4 extends JpaResourceProviderR4<En
|
|||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
|
||||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
UnsignedIntType theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
UnsignedIntType theOffset,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
|
@ -90,7 +98,7 @@ public class BaseJpaResourceProviderEncounterR4 extends JpaResourceProviderR4<En
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec);
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterTypeEverything(theServletRequest, theCount, theOffset, theLastUpdated, theSortSpec);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
|
|
@ -62,6 +62,10 @@ public class BaseJpaResourceProviderPatientR4 extends JpaResourceProviderR4<Pati
|
|||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
UnsignedIntType theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
UnsignedIntType theOffset,
|
||||
|
||||
@Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
|
||||
DateRangeParam theLastUpdated,
|
||||
|
@ -86,7 +90,7 @@ public class BaseJpaResourceProviderPatientR4 extends JpaResourceProviderR4<Pati
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
@ -104,6 +108,10 @@ public class BaseJpaResourceProviderPatientR4 extends JpaResourceProviderR4<Pati
|
|||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
UnsignedIntType theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
UnsignedIntType theOffset,
|
||||
|
||||
@Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
|
||||
DateRangeParam theLastUpdated,
|
||||
|
@ -128,7 +136,7 @@ public class BaseJpaResourceProviderPatientR4 extends JpaResourceProviderR4<Pati
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theOffset, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
|
|
@ -61,6 +61,10 @@ public class BaseJpaResourceProviderCompositionR5 extends JpaResourceProviderR5<
|
|||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
UnsignedIntType theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
UnsignedIntType theOffset,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
DateRangeParam theLastUpdated,
|
||||
|
@ -73,7 +77,7 @@ public class BaseJpaResourceProviderCompositionR5 extends JpaResourceProviderR5<
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
IBundleProvider bundleProvider = ((IFhirResourceDaoComposition<Composition>) getDao()).getDocumentForComposition(theServletRequest, theId, theCount, theLastUpdated, theSortSpec, theRequestDetails);
|
||||
IBundleProvider bundleProvider = ((IFhirResourceDaoComposition<Composition>) getDao()).getDocumentForComposition(theServletRequest, theId, theCount, theOffset,theLastUpdated, theSortSpec, theRequestDetails);
|
||||
List<IBaseResource> resourceList = bundleProvider.getResources(0, bundleProvider.size());
|
||||
|
||||
boolean foundCompositionResource = false;
|
||||
|
|
|
@ -52,6 +52,10 @@ public class BaseJpaResourceProviderEncounterR5 extends JpaResourceProviderR5<En
|
|||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
|
||||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
UnsignedIntType theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
UnsignedIntType theOffset,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
|
@ -63,7 +67,7 @@ public class BaseJpaResourceProviderEncounterR5 extends JpaResourceProviderR5<En
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec);
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterInstanceEverything(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}}
|
||||
|
@ -79,6 +83,10 @@ public class BaseJpaResourceProviderEncounterR5 extends JpaResourceProviderR5<En
|
|||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
|
||||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
UnsignedIntType theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
UnsignedIntType theOffset,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
|
@ -90,7 +98,7 @@ public class BaseJpaResourceProviderEncounterR5 extends JpaResourceProviderR5<En
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec);
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterTypeEverything(theServletRequest, theCount, theOffset, theLastUpdated, theSortSpec);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
|
|
@ -62,6 +62,10 @@ public class BaseJpaResourceProviderPatientR5 extends JpaResourceProviderR5<Pati
|
|||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
UnsignedIntType theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
UnsignedIntType theOffset,
|
||||
|
||||
@Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
|
||||
DateRangeParam theLastUpdated,
|
||||
|
@ -86,7 +90,7 @@ public class BaseJpaResourceProviderPatientR5 extends JpaResourceProviderR5<Pati
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
@ -104,6 +108,10 @@ public class BaseJpaResourceProviderPatientR5 extends JpaResourceProviderR5<Pati
|
|||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
UnsignedIntType theCount,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
|
||||
@OperationParam(name = Constants.PARAM_OFFSET)
|
||||
UnsignedIntType theOffset,
|
||||
|
||||
@Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
|
||||
DateRangeParam theLastUpdated,
|
||||
|
@ -128,7 +136,7 @@ public class BaseJpaResourceProviderPatientR5 extends JpaResourceProviderR5<Pati
|
|||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theOffset, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ import ca.uhn.fhir.jpa.entity.Search;
|
|||
import ca.uhn.fhir.jpa.entity.SearchInclude;
|
||||
import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
|
||||
import ca.uhn.fhir.jpa.interceptor.JpaPreResourceAccessDetails;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||
import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
|
||||
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
|
||||
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
|
||||
|
@ -458,15 +460,43 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
SearchRuntimeDetails searchRuntimeDetails = new SearchRuntimeDetails(theRequestDetails, theSearchUuid);
|
||||
searchRuntimeDetails.setLoadSynchronous(true);
|
||||
|
||||
boolean wantOnlyCount = isWantOnlyCount(theParams);
|
||||
boolean wantCount = isWantCount(theParams, wantOnlyCount);
|
||||
|
||||
// Execute the query and make sure we return distinct results
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager);
|
||||
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
|
||||
return txTemplate.execute(t -> {
|
||||
|
||||
|
||||
// Load the results synchronously
|
||||
final List<ResourcePersistentId> pids = new ArrayList<>();
|
||||
|
||||
RequestPartitionId requestPartitionId = myRequestPartitionHelperService.determineReadPartitionForRequest(theRequestDetails, theResourceType);
|
||||
|
||||
Long count = 0L;
|
||||
if (wantCount) {
|
||||
ourLog.trace("Performing count");
|
||||
// TODO FulltextSearchSvcImpl will remove necessary parameters from the "theParams", this will cause actual query after count to
|
||||
// return wrong response. This is some dirty fix to avoid that issue. Params should not be mutated?
|
||||
// Maybe instead of removing them we could skip them in db query builder if full text search was used?
|
||||
List<List<IQueryParameterType>> contentAndTerms = theParams.get(Constants.PARAM_CONTENT);
|
||||
List<List<IQueryParameterType>> textAndTerms = theParams.get(Constants.PARAM_TEXT);
|
||||
|
||||
Iterator<Long> countIterator = theSb.createCountQuery(theParams, theSearchUuid, theRequestDetails, requestPartitionId);
|
||||
|
||||
if (contentAndTerms != null) theParams.put(Constants.PARAM_CONTENT, contentAndTerms);
|
||||
if (textAndTerms != null) theParams.put(Constants.PARAM_TEXT, textAndTerms);
|
||||
|
||||
count = countIterator.next();
|
||||
ourLog.trace("Got count {}", count);
|
||||
}
|
||||
|
||||
if (wantOnlyCount) {
|
||||
SimpleBundleProvider bundleProvider = new SimpleBundleProvider();
|
||||
bundleProvider.setSize(count.intValue());
|
||||
return bundleProvider;
|
||||
}
|
||||
|
||||
try (IResultIterator resultIter = theSb.createQuery(theParams, searchRuntimeDetails, theRequestDetails, requestPartitionId)) {
|
||||
while (resultIter.hasNext()) {
|
||||
pids.add(resultIter.next());
|
||||
|
@ -498,7 +528,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
/*
|
||||
* For synchronous queries, we load all the includes right away
|
||||
* since we're returning a static bundle with all the results
|
||||
* pre-loaded. This is ok because syncronous requests are not
|
||||
* pre-loaded. This is ok because synchronous requests are not
|
||||
* expected to be paged
|
||||
*
|
||||
* On the other hand for async queries we load includes/revincludes
|
||||
|
@ -515,10 +545,47 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
// Hook: STORAGE_PRESHOW_RESOURCES
|
||||
resources = InterceptorUtil.fireStoragePreshowResource(resources, theRequestDetails, myInterceptorBroadcaster);
|
||||
|
||||
return new SimpleBundleProvider(resources);
|
||||
SimpleBundleProvider bundleProvider = new SimpleBundleProvider(resources);
|
||||
|
||||
if (wantCount) {
|
||||
bundleProvider.setSize(count.intValue());
|
||||
} else {
|
||||
Integer queryCount = getQueryCount(theLoadSynchronousUpTo, theParams);
|
||||
if (queryCount == null || queryCount > pids.size()) {
|
||||
// No limit, last page or everything was fetched within the limit
|
||||
bundleProvider.setSize(getTotalCount(queryCount, theParams.getOffset(), pids.size()));
|
||||
} else {
|
||||
bundleProvider.setSize(null);
|
||||
}
|
||||
}
|
||||
|
||||
return bundleProvider;
|
||||
});
|
||||
}
|
||||
|
||||
private int getTotalCount(Integer queryCount, Integer offset, int queryResultCount) {
|
||||
if (queryCount != null) {
|
||||
if (offset != null) {
|
||||
return offset + queryResultCount;
|
||||
} else {
|
||||
return queryResultCount;
|
||||
}
|
||||
} else {
|
||||
return queryResultCount;
|
||||
}
|
||||
}
|
||||
|
||||
private Integer getQueryCount(Integer theLoadSynchronousUpTo, SearchParameterMap theParams) {
|
||||
if (theLoadSynchronousUpTo != null) {
|
||||
return theLoadSynchronousUpTo;
|
||||
} else if (theParams.getCount() != null) {
|
||||
return theParams.getCount();
|
||||
} else if (myDaoConfig.getFetchSizeDefaultMaximum() != null) {
|
||||
return myDaoConfig.getFetchSizeDefaultMaximum();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@org.jetbrains.annotations.Nullable
|
||||
private Integer getLoadSynchronousUpToOrNull(CacheControlDirective theCacheControlDirective) {
|
||||
final Integer loadSynchronousUpTo;
|
||||
|
@ -990,13 +1057,8 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
*
|
||||
* before doing anything else.
|
||||
*/
|
||||
boolean wantOnlyCount =
|
||||
SummaryEnum.COUNT.equals(myParams.getSummaryMode())
|
||||
| INTEGER_0.equals(myParams.getCount());
|
||||
boolean wantCount =
|
||||
wantOnlyCount ||
|
||||
SearchTotalModeEnum.ACCURATE.equals(myParams.getSearchTotalMode()) ||
|
||||
(myParams.getSearchTotalMode() == null && SearchTotalModeEnum.ACCURATE.equals(myDaoConfig.getDefaultTotalMode()));
|
||||
boolean wantOnlyCount = isWantOnlyCount(myParams);
|
||||
boolean wantCount = isWantCount(myParams, wantOnlyCount);
|
||||
if (wantCount) {
|
||||
ourLog.trace("Performing count");
|
||||
ISearchBuilder sb = newSearchBuilder();
|
||||
|
@ -1125,6 +1187,16 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isWantCount(SearchParameterMap myParams, boolean wantOnlyCount) {
|
||||
return wantOnlyCount ||
|
||||
SearchTotalModeEnum.ACCURATE.equals(myParams.getSearchTotalMode()) ||
|
||||
(myParams.getSearchTotalMode() == null && SearchTotalModeEnum.ACCURATE.equals(myDaoConfig.getDefaultTotalMode()));
|
||||
}
|
||||
|
||||
private static boolean isWantOnlyCount(SearchParameterMap myParams) {
|
||||
return SummaryEnum.COUNT.equals(myParams.getSummaryMode())
|
||||
| INTEGER_0.equals(myParams.getCount());
|
||||
}
|
||||
|
||||
public class SearchContinuationTask extends SearchTask {
|
||||
|
||||
|
|
|
@ -207,6 +207,8 @@ public abstract class BaseJpaTest extends BaseTest {
|
|||
when(mySrd.getInterceptorBroadcaster()).thenReturn(myRequestOperationCallback);
|
||||
when(mySrd.getUserData()).thenReturn(new HashMap<>());
|
||||
when(mySrd.getHeaders(eq(JpaConstants.HEADER_META_SNAPSHOT_MODE))).thenReturn(new ArrayList<>());
|
||||
when(mySrd.getServer().getDefaultPageSize()).thenReturn(null);
|
||||
when(mySrd.getServer().getMaximumPageSize()).thenReturn(null);
|
||||
}
|
||||
|
||||
protected CountDownLatch registerLatchHookInterceptor(int theCount, Pointcut theLatchPointcut) {
|
||||
|
@ -374,7 +376,9 @@ public abstract class BaseJpaTest extends BaseTest {
|
|||
}
|
||||
|
||||
ourLog.info("Found {} results", size);
|
||||
List<IBaseResource> resources = theProvider.getResources(0, size);
|
||||
List<IBaseResource> resources = theProvider instanceof PersistedJpaBundleProvider ?
|
||||
theProvider.getResources(0, size) :
|
||||
theProvider.getResources(0, Integer.MAX_VALUE);
|
||||
for (IBaseResource next : resources) {
|
||||
retVal.add(next.getIdElement().toUnqualifiedVersionless());
|
||||
}
|
||||
|
|
|
@ -247,16 +247,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, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientInstanceEverything(request, ptId1, null, 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, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientInstanceEverything(request, ptId1, null, 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, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, null, null, null, mySrd));
|
||||
assertThat(actual, containsInAnyOrder(ptId1, obsId1, obsId2, devId1));
|
||||
|
||||
/*
|
||||
|
@ -272,7 +272,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, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, param, null, null, mySrd));
|
||||
assertThat(actual, containsInAnyOrder(ptId1, obsId1, obsId4, devId1));
|
||||
|
||||
/*
|
||||
|
@ -288,7 +288,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, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, param, null, null, mySrd));
|
||||
assertThat(actual, containsInAnyOrder(ptId1, obsId4));
|
||||
|
||||
}
|
||||
|
@ -339,11 +339,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, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientTypeEverything(request, null, 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, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientTypeEverything(request, null, null, null, null, null, null, null, mySrd));
|
||||
assertThat(actual, containsInAnyOrder(ptId1, obsId1, obsId2, devId1, ptId2, obsId3));
|
||||
|
||||
/*
|
||||
|
@ -359,7 +359,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, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientTypeEverything(request, null, null, null, null, param, null, null, mySrd));
|
||||
assertThat(actual, containsInAnyOrder(ptId1, obsId1, obsId4, devId1));
|
||||
|
||||
/*
|
||||
|
@ -375,7 +375,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, null, mySrd));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.patientTypeEverything(request, null, null, null, null, param, null, null, mySrd));
|
||||
assertThat(actual, containsInAnyOrder(ptId1, obsId4));
|
||||
|
||||
}
|
||||
|
|
|
@ -116,11 +116,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, null, mySrd);
|
||||
IBundleProvider resp = myPatientDao.patientTypeEverything(request, null, 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, null, mySrd);
|
||||
resp = myPatientDao.patientInstanceEverything(request, patId, null, null, null, null, null, null, null, mySrd);
|
||||
assertThat(toUnqualifiedVersionlessIds(resp), containsInAnyOrder(orgId, medId, patId, moId));
|
||||
}
|
||||
|
||||
|
|
|
@ -1227,7 +1227,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
|
|||
ourLog.info("Updated patient, got id: {}", idv2);
|
||||
|
||||
Bundle request = new Bundle();
|
||||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient?" + Constants.PARAM_COUNT + "=1");
|
||||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient?" + Constants.PARAM_COUNT + "=1&_total=accurate");
|
||||
Bundle resp = mySystemDao.transaction(mySrd, request);
|
||||
|
||||
assertEquals(1, resp.getEntry().size());
|
||||
|
|
|
@ -344,16 +344,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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, 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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, 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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, null, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId2, devId1)));
|
||||
|
||||
/*
|
||||
|
@ -369,7 +369,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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId4, devId1)));
|
||||
|
||||
/*
|
||||
|
@ -385,7 +385,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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId4)));
|
||||
|
||||
}
|
||||
|
@ -436,11 +436,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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, 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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, null, null, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId2, devId1, ptId2, obsId3)));
|
||||
|
||||
/*
|
||||
|
@ -456,7 +456,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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId4, devId1)));
|
||||
|
||||
/*
|
||||
|
@ -472,7 +472,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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId4)));
|
||||
|
||||
}
|
||||
|
|
|
@ -245,11 +245,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, null, mySrd);
|
||||
IBundleProvider resp = myPatientDao.patientTypeEverything(request, null, 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, null, mySrd);
|
||||
resp = myPatientDao.patientInstanceEverything(request, patId, null, null, null, null, null, null, null, mySrd);
|
||||
assertThat(toUnqualifiedVersionlessIds(resp), containsInAnyOrder(orgId, medId, patId, moId));
|
||||
}
|
||||
|
||||
|
@ -276,7 +276,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, null, mySrd);
|
||||
IBundleProvider everything = myPatientDao.patientInstanceEverything(mySrd.getServletRequest(), new IdType("Patient/A161443"), count, null, null, null, null, null, null, mySrd);
|
||||
|
||||
TreeSet<String> ids = new TreeSet<>(toUnqualifiedVersionlessIdValues(everything));
|
||||
assertThat(ids, hasItem("List/A161444"));
|
||||
|
@ -2114,7 +2114,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
|||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
IBundleProvider values = myPatientDao.search(map);
|
||||
assertEquals(5, values.size().intValue());
|
||||
assertEquals(null, values.size());
|
||||
assertEquals(5, values.getResources(0, 1000).size());
|
||||
}
|
||||
|
||||
|
|
|
@ -2050,7 +2050,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
|
|||
ourLog.info("Updated patient, got id: {}", idv2);
|
||||
|
||||
Bundle request = new Bundle();
|
||||
request.addEntry().getRequest().setMethod(HTTPVerb.GET).setUrl("Patient?" + Constants.PARAM_COUNT + "=1");
|
||||
request.addEntry().getRequest().setMethod(HTTPVerb.GET).setUrl("Patient?" + Constants.PARAM_COUNT + "=1&_total=accurate");
|
||||
Bundle resp = mySystemDao.transaction(mySrd, request);
|
||||
|
||||
assertEquals(1, resp.getEntry().size());
|
||||
|
|
|
@ -338,16 +338,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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, 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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, 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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, null, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId2, devId1)));
|
||||
|
||||
/*
|
||||
|
@ -363,7 +363,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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId4, devId1)));
|
||||
|
||||
/*
|
||||
|
@ -379,7 +379,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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId4)));
|
||||
|
||||
}
|
||||
|
@ -430,11 +430,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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, 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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, null, null, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId2, devId1, ptId2, obsId3)));
|
||||
|
||||
/*
|
||||
|
@ -450,7 +450,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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId4, devId1)));
|
||||
|
||||
/*
|
||||
|
@ -466,7 +466,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, null, mockSrd()));
|
||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, null, param, null, null, mockSrd()));
|
||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId4)));
|
||||
|
||||
}
|
||||
|
|
|
@ -750,11 +750,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, null, mySrd);
|
||||
IBundleProvider resp = myPatientDao.patientTypeEverything(request, null, 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, null, mySrd);
|
||||
resp = myPatientDao.patientInstanceEverything(request, patId, null, null, null, null, null, null, null, mySrd);
|
||||
assertThat(toUnqualifiedVersionlessIds(resp), containsInAnyOrder(orgId, medId, patId, moId));
|
||||
}
|
||||
|
||||
|
@ -782,7 +782,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, null, mySrd);
|
||||
IBundleProvider everything = myPatientDao.patientInstanceEverything(mySrd.getServletRequest(), new IdType("Patient/A161443"), count, null, null, null, null, null, null, mySrd);
|
||||
|
||||
TreeSet<String> ids = new TreeSet<>(toUnqualifiedVersionlessIdValues(everything));
|
||||
assertThat(ids, hasItem("List/A161444"));
|
||||
|
@ -4161,7 +4161,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
IBundleProvider values = myPatientDao.search(map);
|
||||
assertEquals(5, values.size().intValue());
|
||||
assertEquals(null, values.size());
|
||||
assertEquals(5, values.getResources(0, 1000).size());
|
||||
}
|
||||
|
||||
|
|
|
@ -378,11 +378,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, null, mySrd);
|
||||
IBundleProvider resp = myPatientDao.patientTypeEverything(request, null, 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, null, mySrd);
|
||||
resp = myPatientDao.patientInstanceEverything(request, patId, null, null, null, null, null, null, null, mySrd);
|
||||
assertThat(toUnqualifiedVersionlessIds(resp), containsInAnyOrder(orgId, medId, patId, moId));
|
||||
}
|
||||
|
||||
|
@ -410,7 +410,7 @@ 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, null, mySrd);
|
||||
IBundleProvider everything = myPatientDao.patientInstanceEverything(mySrd.getServletRequest(), new IdType("Patient/A161443"), count, null, null, null, null, null, null, mySrd);
|
||||
|
||||
TreeSet<String> ids = new TreeSet<>(toUnqualifiedVersionlessIdValues(everything));
|
||||
assertThat(ids, hasItem("List/A161444"));
|
||||
|
@ -2667,7 +2667,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
|
|||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
IBundleProvider values = myPatientDao.search(map);
|
||||
assertEquals(5, values.size().intValue());
|
||||
assertEquals(null, values.size());
|
||||
assertEquals(5, values.getResources(0, 1000).size());
|
||||
}
|
||||
|
||||
|
|
|
@ -2689,7 +2689,7 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
|
|||
ourLog.info("Updated patient, got id: {}", idv2);
|
||||
|
||||
Bundle request = new Bundle();
|
||||
request.addEntry().getRequest().setMethod(HTTPVerb.GET).setUrl("Patient?" + Constants.PARAM_COUNT + "=1");
|
||||
request.addEntry().getRequest().setMethod(HTTPVerb.GET).setUrl("Patient?" + Constants.PARAM_COUNT + "=1&_total=accurate");
|
||||
Bundle resp = mySystemDao.transaction(mySrd, request);
|
||||
|
||||
assertEquals(1, resp.getEntry().size());
|
||||
|
|
|
@ -39,6 +39,7 @@ import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
|||
import ca.uhn.fhir.model.dstu2.resource.SearchParameter;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.XPathUsageTypeEnum;
|
||||
import ca.uhn.fhir.model.primitive.IntegerDt;
|
||||
import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.gclient.NumberClientParam;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
@ -1694,7 +1695,19 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
.useHttpGet()
|
||||
.execute();
|
||||
|
||||
assertEquals(21, response.getEntry().size());
|
||||
assertEquals(10, response.getEntry().size());
|
||||
assertEquals(null, response.getTotalElement().getValue());
|
||||
assertThat(response.getLink("next").getUrl(), not(emptyString()));
|
||||
|
||||
response = ourClient.fetchResourceFromUrl(ca.uhn.fhir.model.dstu2.resource.Bundle.class, response.getLink("next").getUrl());
|
||||
|
||||
assertEquals(10, response.getEntry().size());
|
||||
assertEquals(null, response.getTotalElement().getValue());
|
||||
assertThat(response.getLink("next").getUrl(), not(emptyString()));
|
||||
|
||||
response = ourClient.fetchResourceFromUrl(ca.uhn.fhir.model.dstu2.resource.Bundle.class, response.getLink("next").getUrl());
|
||||
|
||||
assertEquals(1, response.getEntry().size());
|
||||
assertEquals(21, response.getTotalElement().getValue().intValue());
|
||||
assertEquals(null, response.getLink("next"));
|
||||
|
||||
|
|
|
@ -2347,7 +2347,19 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
|||
.useHttpGet()
|
||||
.execute();
|
||||
|
||||
assertEquals(21, response.getEntry().size());
|
||||
assertEquals(10, response.getEntry().size());
|
||||
assertEquals(null, response.getTotalElement().getValue());
|
||||
assertThat(response.getLink("next").getUrl(), not(emptyString()));
|
||||
|
||||
response = ourClient.fetchResourceFromUrl(Bundle.class, response.getLink("next").getUrl());
|
||||
|
||||
assertEquals(10, response.getEntry().size());
|
||||
assertEquals(null, response.getTotalElement().getValue());
|
||||
assertThat(response.getLink("next").getUrl(), not(emptyString()));
|
||||
|
||||
response = ourClient.fetchResourceFromUrl(Bundle.class, response.getLink("next").getUrl());
|
||||
|
||||
assertEquals(1, response.getEntry().size());
|
||||
assertEquals(21, response.getTotalElement().getValue().intValue());
|
||||
assertEquals(null, response.getLink("next"));
|
||||
|
||||
|
|
|
@ -2946,7 +2946,19 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
|||
.useHttpGet()
|
||||
.execute();
|
||||
|
||||
assertEquals(21, response.getEntry().size());
|
||||
assertEquals(10, response.getEntry().size());
|
||||
assertEquals(null, response.getTotalElement().getValue());
|
||||
assertThat(response.getLink("next").getUrl(), not(emptyString()));
|
||||
|
||||
response = myClient.fetchResourceFromUrl(Bundle.class, response.getLink("next").getUrl());
|
||||
|
||||
assertEquals(10, response.getEntry().size());
|
||||
assertEquals(null, response.getTotalElement().getValue());
|
||||
assertThat(response.getLink("next").getUrl(), not(emptyString()));
|
||||
|
||||
response = myClient.fetchResourceFromUrl(Bundle.class, response.getLink("next").getUrl());
|
||||
|
||||
assertEquals(1, response.getEntry().size());
|
||||
assertEquals(21, response.getTotalElement().getValue().intValue());
|
||||
assertEquals(null, response.getLink("next"));
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.junit.jupiter.api.Test;
|
|||
import org.springframework.test.util.AopTestUtils;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.leftPad;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
|
||||
|
@ -89,5 +90,55 @@ public class PagingMultinodeProviderDstu3Test extends BaseResourceProviderDstu3T
|
|||
assertThat(toUnqualifiedVersionlessIdValues(found), contains("Patient/A030", "Patient/A031", "Patient/A032", "Patient/A033", "Patient/A034", "Patient/A035", "Patient/A036", "Patient/A037", "Patient/A038", "Patient/A039"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithOffset() {
|
||||
{
|
||||
for (int i = 0; i < 100; i++) {
|
||||
Patient patient = new Patient();
|
||||
String id = "A" + leftPad(Integer.toString(i), 3, '0');
|
||||
patient.setId(id);
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("A" + i);
|
||||
patient.addName().setFamily(id);
|
||||
myPatientDao.update(patient, mySrd).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
}
|
||||
|
||||
Bundle found;
|
||||
|
||||
mySearchCoordinatorSvcRaw.setLoadingThrottleForUnitTests(50);
|
||||
mySearchCoordinatorSvcRaw.setSyncSizeForUnitTests(10);
|
||||
mySearchCoordinatorSvcRaw.setNeverUseLocalSearchForUnitTests(true);
|
||||
|
||||
found = ourClient
|
||||
.search()
|
||||
.forResource(Patient.class)
|
||||
.sort().ascending(Patient.SP_FAMILY)
|
||||
.count(10)
|
||||
.offset(0)
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
assertThat(toUnqualifiedVersionlessIdValues(found), contains("Patient/A000", "Patient/A001", "Patient/A002", "Patient/A003", "Patient/A004", "Patient/A005", "Patient/A006", "Patient/A007", "Patient/A008", "Patient/A009"));
|
||||
assertThat(found.getLink().stream().filter(l -> l.getRelation().equals("next")).map(l -> l.getUrl()).findAny()
|
||||
.orElseThrow(() -> new IllegalStateException("No next page link")).contains("_offset=10"), is(true));
|
||||
|
||||
found = ourClient
|
||||
.loadPage()
|
||||
.next(found)
|
||||
.execute();
|
||||
assertThat(toUnqualifiedVersionlessIdValues(found), contains("Patient/A010", "Patient/A011", "Patient/A012", "Patient/A013", "Patient/A014", "Patient/A015", "Patient/A016", "Patient/A017", "Patient/A018", "Patient/A019"));
|
||||
|
||||
found = ourClient
|
||||
.loadPage()
|
||||
.next(found)
|
||||
.execute();
|
||||
assertThat(toUnqualifiedVersionlessIdValues(found), contains("Patient/A020", "Patient/A021", "Patient/A022", "Patient/A023", "Patient/A024", "Patient/A025", "Patient/A026", "Patient/A027", "Patient/A028", "Patient/A029"));
|
||||
|
||||
found = ourClient
|
||||
.loadPage()
|
||||
.next(found)
|
||||
.execute();
|
||||
assertThat(toUnqualifiedVersionlessIdValues(found), contains("Patient/A030", "Patient/A031", "Patient/A032", "Patient/A033", "Patient/A034", "Patient/A035", "Patient/A036", "Patient/A037", "Patient/A038", "Patient/A039"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -22,12 +22,14 @@ import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
|||
import ca.uhn.fhir.jpa.util.BaseIterator;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.rest.api.CacheControlDirective;
|
||||
import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
@ -552,6 +554,32 @@ public class SearchCoordinatorSvcImplTest {
|
|||
assertEquals("799", resources.get(789).getIdElement().getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSynchronousSearchWithOffset() {
|
||||
when(mySearchBuilderFactory.newSearchBuilder(any(), any(), any())).thenReturn(mySearchBuilder);
|
||||
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
params.setLoadSynchronous(true);
|
||||
params.add("name", new StringParam("ANAME"));
|
||||
params.setCount(10);
|
||||
params.setOffset(10);
|
||||
params.setSearchTotalMode(SearchTotalModeEnum.ACCURATE);
|
||||
|
||||
List<ResourcePersistentId> pids = createPidSequence(30);
|
||||
when(mySearchBuilder.createCountQuery(same(params), any(String.class), nullable(RequestDetails.class), nullable(RequestPartitionId.class))).thenReturn(Lists.newArrayList(Long.valueOf(20L)).iterator());
|
||||
when(mySearchBuilder.createQuery(same(params), any(), nullable(RequestDetails.class), nullable(RequestPartitionId.class))).thenReturn(new ResultIterator(pids.subList(10, 20).iterator()));
|
||||
|
||||
doAnswer(loadPids()).when(mySearchBuilder).loadResourcesByPid(any(Collection.class), any(Collection.class), any(List.class), anyBoolean(), any());
|
||||
|
||||
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null);
|
||||
assertNull(result.getUuid());
|
||||
assertEquals(20, result.size().intValue());
|
||||
|
||||
List<IBaseResource> resources = result.getResources(0, 10);
|
||||
assertEquals(10, resources.size());
|
||||
assertEquals("20", resources.get(0).getIdElement().getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSynchronousSearchUpTo() {
|
||||
when(mySearchBuilderFactory.newSearchBuilder(any(), any(), any())).thenReturn(mySearchBuilder);
|
||||
|
|
|
@ -101,7 +101,7 @@ public class MatchUrlService {
|
|||
IQueryParameterAnd<?> param = ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.HAS, nextParamName, paramList);
|
||||
paramMap.add(nextParamName, param);
|
||||
} else if (Constants.PARAM_COUNT.equals(nextParamName)) {
|
||||
if (paramList.size() > 0 && paramList.get(0).size() > 0) {
|
||||
if (paramList != null && paramList.size() > 0 && paramList.get(0).size() > 0) {
|
||||
String intString = paramList.get(0).get(0);
|
||||
try {
|
||||
paramMap.setCount(Integer.parseInt(intString));
|
||||
|
@ -109,6 +109,15 @@ public class MatchUrlService {
|
|||
throw new InvalidRequestException("Invalid " + Constants.PARAM_COUNT + " value: " + intString);
|
||||
}
|
||||
}
|
||||
} else if (Constants.PARAM_OFFSET.equals(nextParamName)) {
|
||||
if (paramList != null && paramList.size() > 0 && paramList.get(0).size() > 0) {
|
||||
String intString = paramList.get(0).get(0);
|
||||
try {
|
||||
paramMap.setOffset(Integer.parseInt(intString));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new InvalidRequestException("Invalid " + Constants.PARAM_OFFSET + " value: " + intString);
|
||||
}
|
||||
}
|
||||
} else if (ResourceMetaParams.RESOURCE_META_PARAMS.containsKey(nextParamName)) {
|
||||
if (isNotBlank(paramList.get(0).getQualifier()) && paramList.get(0).getQualifier().startsWith(".")) {
|
||||
throw new InvalidRequestException("Invalid parameter chain: " + nextParamName + paramList.get(0).getQualifier());
|
||||
|
|
|
@ -51,6 +51,7 @@ public class SearchParameterMap implements Serializable {
|
|||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Integer myCount;
|
||||
private Integer myOffset;
|
||||
private EverythingModeEnum myEverythingMode = null;
|
||||
private Set<Include> myIncludes;
|
||||
private DateRangeParam myLastUpdated;
|
||||
|
@ -198,6 +199,14 @@ public class SearchParameterMap implements Serializable {
|
|||
myCount = theCount;
|
||||
}
|
||||
|
||||
public Integer getOffset() {
|
||||
return myOffset;
|
||||
}
|
||||
|
||||
public void setOffset(Integer theOffset) {
|
||||
myOffset = theOffset;
|
||||
}
|
||||
|
||||
public EverythingModeEnum getEverythingMode() {
|
||||
return myEverythingMode;
|
||||
}
|
||||
|
@ -461,6 +470,13 @@ public class SearchParameterMap implements Serializable {
|
|||
b.append(getCount());
|
||||
}
|
||||
|
||||
if (getOffset() != null) {
|
||||
addUrlParamSeparator(b);
|
||||
b.append(Constants.PARAM_OFFSET);
|
||||
b.append('=');
|
||||
b.append(getOffset());
|
||||
}
|
||||
|
||||
// Summary mode (_summary)
|
||||
if (getSummaryMode() != null) {
|
||||
addUrlParamSeparator(b);
|
||||
|
@ -652,7 +668,7 @@ public class SearchParameterMap implements Serializable {
|
|||
return mySearchParameterMap.get(theName);
|
||||
}
|
||||
|
||||
private void put(String theName, List<List<IQueryParameterType>> theParams) {
|
||||
public void put(String theName, List<List<IQueryParameterType>> theParams) {
|
||||
mySearchParameterMap.put(theName, theParams);
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,20 @@ public interface IRestfulServerDefaults {
|
|||
*/
|
||||
IPagingProvider getPagingProvider();
|
||||
|
||||
/**
|
||||
* Default page size for searches. Null means no limit (DaoConfig might have size limit however)
|
||||
*/
|
||||
default Integer getDefaultPageSize() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum page size for searches. Null means no upper limit.
|
||||
*/
|
||||
default Integer getMaximumPageSize() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the server "pretty print" responses by default (requesting clients can always override this default by
|
||||
* supplying an <code>Accept</code> header in the request, or a <code>_pretty</code>
|
||||
|
|
|
@ -140,6 +140,9 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
|||
private boolean myIgnoreServerParsedRequestParameters = true;
|
||||
private String myImplementationDescription;
|
||||
private IPagingProvider myPagingProvider;
|
||||
private Integer myDefaultPageSize;
|
||||
private Integer myMaximumPageSize;
|
||||
private boolean myStatelessPagingDefault = false;
|
||||
private Lock myProviderRegistrationMutex = new ReentrantLock();
|
||||
private Map<String, ResourceBinding> myResourceNameToBinding = new HashMap<>();
|
||||
private IServerAddressStrategy myServerAddressStrategy = new IncomingRequestAddressStrategy();
|
||||
|
@ -674,6 +677,30 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
|||
myPagingProvider = thePagingProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getDefaultPageSize() {
|
||||
return myDefaultPageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default page size to use, or <code>null</code> if no default page size
|
||||
*/
|
||||
public void setDefaultPageSize(Integer thePageSize) {
|
||||
myDefaultPageSize = thePageSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getMaximumPageSize() {
|
||||
return myMaximumPageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum page size to use, or <code>null</code> if no maximum page size
|
||||
*/
|
||||
public void setMaximumPageSize(Integer theMaximumPageSize) {
|
||||
myMaximumPageSize = theMaximumPageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the non-resource specific providers which implement method calls on this server
|
||||
*
|
||||
|
|
|
@ -49,6 +49,7 @@ import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
|||
import ca.uhn.fhir.util.BinaryUtil;
|
||||
import ca.uhn.fhir.util.DateUtils;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBinary;
|
||||
|
@ -233,6 +234,76 @@ public class RestfulServerUtils {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static String createLinkSelf(String theServerBase, RequestDetails theRequest) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(theServerBase);
|
||||
|
||||
if (isNotBlank(theRequest.getRequestPath())) {
|
||||
b.append('/');
|
||||
if (isNotBlank(theRequest.getTenantId()) && theRequest.getRequestPath().startsWith(theRequest.getTenantId() + "/")) {
|
||||
b.append(theRequest.getRequestPath().substring(theRequest.getTenantId().length() + 1));
|
||||
} else {
|
||||
b.append(theRequest.getRequestPath());
|
||||
}
|
||||
}
|
||||
// For POST the URL parameters get jumbled with the post body parameters so don't include them, they might be huge
|
||||
if (theRequest.getRequestType() == RequestTypeEnum.GET) {
|
||||
boolean first = true;
|
||||
Map<String, String[]> parameters = theRequest.getParameters();
|
||||
for (String nextParamName : new TreeSet<>(parameters.keySet())) {
|
||||
for (String nextParamValue : parameters.get(nextParamName)) {
|
||||
if (first) {
|
||||
b.append('?');
|
||||
first = false;
|
||||
} else {
|
||||
b.append('&');
|
||||
}
|
||||
b.append(UrlUtil.escapeUrlParam(nextParamName));
|
||||
b.append('=');
|
||||
b.append(UrlUtil.escapeUrlParam(nextParamValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public static String createOffsetPagingLink(String theServerBase, String requestPath, String tenantId, Integer theOffset, Integer theCount, Map<String, String[]> theRequestParameters) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(theServerBase);
|
||||
|
||||
if (isNotBlank(requestPath)) {
|
||||
b.append('/');
|
||||
if (isNotBlank(tenantId) && requestPath.startsWith(tenantId + "/")) {
|
||||
b.append(requestPath.substring(tenantId.length() + 1));
|
||||
} else {
|
||||
b.append(requestPath);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String[]> params = Maps.newLinkedHashMap(theRequestParameters);
|
||||
params.put(Constants.PARAM_OFFSET, new String[]{String.valueOf(theOffset)});
|
||||
params.put(Constants.PARAM_COUNT, new String[]{String.valueOf(theCount)});
|
||||
|
||||
boolean first = true;
|
||||
for (String nextParamName : new TreeSet<>(params.keySet())) {
|
||||
for (String nextParamValue : params.get(nextParamName)) {
|
||||
if (first) {
|
||||
b.append('?');
|
||||
first = false;
|
||||
} else {
|
||||
b.append('&');
|
||||
}
|
||||
b.append(UrlUtil.escapeUrlParam(nextParamName));
|
||||
b.append('=');
|
||||
b.append(UrlUtil.escapeUrlParam(nextParamValue));
|
||||
}
|
||||
}
|
||||
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public static String createPagingLink(Set<Include> theIncludes, RequestDetails theRequestDetails, String theSearchId, int theOffset, int theCount, Map<String, String[]> theRequestParameters, boolean thePrettyPrint,
|
||||
BundleTypeEnum theBundleType) {
|
||||
return createPagingLink(theIncludes, theRequestDetails, theSearchId, theOffset, theCount, theRequestParameters, thePrettyPrint,
|
||||
|
@ -573,6 +644,10 @@ public class RestfulServerUtils {
|
|||
return RestfulServerUtils.tryToExtractNamedParameter(theRequest, Constants.PARAM_COUNT);
|
||||
}
|
||||
|
||||
public static Integer extractOffsetParameter(RequestDetails theRequest) {
|
||||
return RestfulServerUtils.tryToExtractNamedParameter(theRequest, Constants.PARAM_OFFSET);
|
||||
}
|
||||
|
||||
public static IPrimitiveType<Date> extractLastUpdatedFromResource(IBaseResource theResource) {
|
||||
IPrimitiveType<Date> lastUpdated = null;
|
||||
if (theResource instanceof IResource) {
|
||||
|
|
|
@ -117,13 +117,23 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
IBaseResource createBundleFromBundleProvider(IRestfulServer<?> theServer, RequestDetails theRequest, Integer theLimit, String theLinkSelf, Set<Include> theIncludes,
|
||||
IBundleProvider theResult, int theOffset, BundleTypeEnum theBundleType, EncodingEnum theLinkEncoding, String theSearchId) {
|
||||
IVersionSpecificBundleFactory bundleFactory = theServer.getFhirContext().newBundleFactory();
|
||||
final Integer requestOffset = RestfulServerUtils.tryToExtractNamedParameter(theRequest, Constants.PARAM_OFFSET);
|
||||
|
||||
int numToReturn;
|
||||
String searchId = null;
|
||||
List<IBaseResource> resourceList;
|
||||
Integer numTotalResults = theResult.size();
|
||||
if (theServer.getPagingProvider() == null) {
|
||||
numToReturn = numTotalResults;
|
||||
|
||||
if (requestOffset != null || theServer.getPagingProvider() == null) {
|
||||
if (theLimit != null) {
|
||||
numToReturn = theLimit;
|
||||
} else {
|
||||
if (theServer.getDefaultPageSize() != null) {
|
||||
numToReturn = theServer.getDefaultPageSize();
|
||||
} else {
|
||||
numToReturn = numTotalResults != null ? numTotalResults : Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
if (numToReturn > 0) {
|
||||
resourceList = theResult.getResources(0, numToReturn);
|
||||
} else {
|
||||
|
@ -200,7 +210,18 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
String linkPrev = null;
|
||||
String linkNext = null;
|
||||
|
||||
if (isNotBlank(theResult.getCurrentPageId())) {
|
||||
if (theServer.getPagingProvider() == null || requestOffset != null) {
|
||||
int myOffset = requestOffset != null ? requestOffset : 0;
|
||||
// Paging without caching
|
||||
// We're doing requestOffset pages
|
||||
if (numTotalResults == null || myOffset + numToReturn < numTotalResults) {
|
||||
linkNext = (RestfulServerUtils.createOffsetPagingLink(serverBase, theRequest.getRequestPath(), theRequest.getTenantId(), myOffset + numToReturn, numToReturn, theRequest.getParameters()));
|
||||
}
|
||||
if (myOffset > 0) {
|
||||
int start = Math.max(0, myOffset - numToReturn);
|
||||
linkPrev = RestfulServerUtils.createOffsetPagingLink(serverBase, theRequest.getRequestPath(), theRequest.getTenantId(), start, numToReturn, theRequest.getParameters());
|
||||
}
|
||||
} else if (isNotBlank(theResult.getCurrentPageId())) {
|
||||
// We're doing named pages
|
||||
searchId = theResult.getUuid();
|
||||
if (isNotBlank(theResult.getNextPageId())) {
|
||||
|
@ -221,8 +242,8 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
linkNext = (RestfulServerUtils.createPagingLink(theIncludes, theRequest, searchId, theOffset + numToReturn, numToReturn, theRequest.getParameters(), prettyPrint, theBundleType));
|
||||
}
|
||||
if (theOffset > 0) {
|
||||
int start = Math.max(0, theOffset - theLimit);
|
||||
linkPrev = RestfulServerUtils.createPagingLink(theIncludes, theRequest, searchId, start, theLimit, theRequest.getParameters(), prettyPrint, theBundleType);
|
||||
int start = Math.max(0, theOffset - numToReturn);
|
||||
linkPrev = RestfulServerUtils.createPagingLink(theIncludes, theRequest, searchId, start, numToReturn, theRequest.getParameters(), prettyPrint, theBundleType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -260,37 +281,7 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
* Figure out the self-link for this request
|
||||
*/
|
||||
String serverBase = theRequest.getServerBaseForRequest();
|
||||
String linkSelf;
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(serverBase);
|
||||
|
||||
if (isNotBlank(theRequest.getRequestPath())) {
|
||||
b.append('/');
|
||||
if (isNotBlank(theRequest.getTenantId()) && theRequest.getRequestPath().startsWith(theRequest.getTenantId() + "/")) {
|
||||
b.append(theRequest.getRequestPath().substring(theRequest.getTenantId().length() + 1));
|
||||
} else {
|
||||
b.append(theRequest.getRequestPath());
|
||||
}
|
||||
}
|
||||
// For POST the URL parameters get jumbled with the post body parameters so don't include them, they might be huge
|
||||
if (theRequest.getRequestType() == RequestTypeEnum.GET) {
|
||||
boolean first = true;
|
||||
Map<String, String[]> parameters = theRequest.getParameters();
|
||||
for (String nextParamName : new TreeSet<>(parameters.keySet())) {
|
||||
for (String nextParamValue : parameters.get(nextParamName)) {
|
||||
if (first) {
|
||||
b.append('?');
|
||||
first = false;
|
||||
} else {
|
||||
b.append('&');
|
||||
}
|
||||
b.append(UrlUtil.escapeUrlParam(nextParamName));
|
||||
b.append('=');
|
||||
b.append(UrlUtil.escapeUrlParam(nextParamValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
linkSelf = b.toString();
|
||||
String linkSelf = RestfulServerUtils.createLinkSelf(theRequest.getFhirServerBase(), theRequest);
|
||||
|
||||
if (getMethodReturnType() == MethodReturnTypeEnum.BUNDLE_RESOURCE) {
|
||||
IBaseResource resource;
|
||||
|
|
|
@ -213,6 +213,8 @@ public class MethodUtil {
|
|||
((AtParameter) param).setType(theContext, parameterType, innerCollectionType, outerCollectionType);
|
||||
} else if (nextAnnotation instanceof Count) {
|
||||
param = new CountParameter();
|
||||
} else if (nextAnnotation instanceof Offset) {
|
||||
param = new OffsetParameter();
|
||||
} else if (nextAnnotation instanceof GraphQLQueryUrl) {
|
||||
param = new GraphQLQueryUrlParameter();
|
||||
} else if (nextAnnotation instanceof GraphQLQueryBody) {
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
package ca.uhn.fhir.rest.server.method;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Server Framework
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2018 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.model.primitive.IntegerDt;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.rest.annotation.Offset;
|
||||
import ca.uhn.fhir.rest.annotation.Since;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.param.ParameterUtil;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
public class OffsetParameter implements IParameter {
|
||||
|
||||
private Class<?> myType;
|
||||
|
||||
@Override
|
||||
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
|
||||
String[] sinceParams = theRequest.getParameters().get(Constants.PARAM_OFFSET);
|
||||
if (sinceParams != null) {
|
||||
if (sinceParams.length > 0) {
|
||||
if (StringUtils.isNotBlank(sinceParams[0])) {
|
||||
try {
|
||||
IntegerDt since = new IntegerDt(sinceParams[0]);
|
||||
return ParameterUtil.fromInteger(myType, since);
|
||||
} catch (DataFormatException e) {
|
||||
throw new InvalidRequestException("Invalid " + Constants.PARAM_OFFSET + " value: " + sinceParams[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ParameterUtil.fromInteger(myType, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) {
|
||||
if (theOuterCollectionType != null) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" +theMethod.getDeclaringClass().getCanonicalName()+ "' is annotated with @" + Offset.class.getName() + " but can not be of collection type");
|
||||
}
|
||||
if (!ParameterUtil.isBindableIntegerType(theParameterType)) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" +theMethod.getDeclaringClass().getCanonicalName()+ "' is annotated with @" + Offset.class.getName() + " but type '" + theParameterType + "' is an invalid type, must be one of Integer or IntegerType");
|
||||
}
|
||||
myType = theParameterType;
|
||||
}
|
||||
|
||||
}
|
|
@ -133,6 +133,9 @@ public class ${className}ResourceProvider extends
|
|||
@ca.uhn.fhir.rest.annotation.Count
|
||||
Integer theCount,
|
||||
|
||||
@ca.uhn.fhir.rest.annotation.Offset
|
||||
Integer theOffset,
|
||||
|
||||
SummaryEnum theSummaryMode,
|
||||
|
||||
SearchTotalModeEnum theSearchTotalMode
|
||||
|
@ -159,6 +162,7 @@ public class ${className}ResourceProvider extends
|
|||
paramMap.setIncludes(theIncludes);
|
||||
paramMap.setSort(theSort);
|
||||
paramMap.setCount(theCount);
|
||||
paramMap.setOffset(theOffset);
|
||||
paramMap.setSummaryMode(theSummaryMode);
|
||||
paramMap.setSearchTotalMode(theSearchTotalMode);
|
||||
|
||||
|
|
Loading…
Reference in New Issue