Class JDBCQueryBuilder
- java.lang.Object
-
- com.ibm.fhir.persistence.util.AbstractQueryBuilder<SqlQueryData>
-
- com.ibm.fhir.persistence.jdbc.util.JDBCQueryBuilder
-
- All Implemented Interfaces:
QueryBuilder<SqlQueryData>
public class JDBCQueryBuilder extends AbstractQueryBuilder<SqlQueryData>
This is the JDBC implementation of a query builder for the IBM FHIR Server JDBC persistence layer schema. Queries are built in SQL.
For the new R4 schema, the search parameter tables (e.g.<resourceType>_STR_VALUES
) are joined to their corresponding_LOGICAL_RESOURCES tables on LOGICAL_RESOURCE_ID. This is because the search parameters are not versioned, and are associated with the logical resource, not the resource version.
Useful column reference:
------------------------ RESOURCE_TYPE_NAME the formal name of the resource type e.g. 'Patient' RESOURCE_TYPE_ID FK to the RESOURCE_TYPES table LOGICAL_ID the VARCHAR holding the logical-id of the resource. Unique for a given resource type LOGICAL_RESOURCE_ID the database BIGINT CURRENT_RESOURCE_ID the unique BIGINT id of the latest resource version for the logical resource VERSION_ID INT resource version number incrementing by 1 RESOURCE_ID the PK of the version-specific resource. Now only used as the target for CURRENT_RESOURCE_ID
-
-
Constructor Summary
Constructors Constructor Description JDBCQueryBuilder(ParameterDAO parameterDao, ResourceDAO resourceDao, QueryHints queryHints, JDBCIdentityCache identityCache)
Public constructor
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description SqlQueryData
buildCountQuery(Class<?> resourceType, FHIRSearchContext searchContext)
Builds a query that returns the count of the search results that would be found by applying the search parameters contained within the passed search context.SqlQueryData
buildIncludeQuery(Class<?> resourceType, FHIRSearchContext searchContext, InclusionParameter inclusionParm, Set<String> ids, String inclusionType)
Builds a query that returns included resources.protected SqlQueryData
buildLocationQuerySegment(String parmName, List<Bounding> boundingAreas, String paramTableAlias)
Builds a query segment for the passed parameter name using the geospatial data contained with the passed BoundingBoxSqlQueryData
buildQuery(Class<?> resourceType, FHIRSearchContext searchContext)
Build and return query for the passed resource type and search parameters.protected SqlQueryData
buildQueryParm(Class<?> resourceType, QueryParameter queryParm, String paramTableAlias, String logicalRsrcTableAlias, boolean endOfChain)
Builds a query segment for the passed query parameter.protected String
getOperator(QueryParameter queryParm)
protected String
getOperator(QueryParameter queryParm, String defaultOverride)
Map the Modifier in the passed Parameter to a supported query operator.protected SqlQueryData
processChainedReferenceParm(QueryParameter queryParm)
Contains special logic for handling chained reference search parameters.protected SqlQueryData
processCompositeParm(Class<?> resourceType, QueryParameter queryParm)
Creates a query segment for a Composite type parameter.protected SqlQueryData
processDateParm(Class<?> resourceType, QueryParameter queryParm)
Creates a query segment for a Date type parameter.protected SqlQueryData
processInclusionCriteria(QueryParameter queryParm)
This method is the entry point for processing inclusion criteria, which define resources that are part of a compartment-based search.protected SqlQueryData
processNumberParm(Class<?> resourceType, QueryParameter queryParm)
Creates a query segment for a Number type parameter.protected SqlQueryData
processQuantityParm(Class<?> resourceType, QueryParameter queryParm)
Creates a query segment for a Quantity type parameter.protected SqlQueryData
processReferenceParm(Class<?> resourceType, QueryParameter queryParm)
Creates a query segment for a Reference type parameter.protected SqlQueryData
processReverseChainedReferenceParm(Class<?> resourceType, QueryParameter queryParm)
Contains special logic for handling reverse chained reference search parameters.protected SqlQueryData
processStringParm(QueryParameter queryParm)
Creates a query segment for a String type parameter.protected SqlQueryData
processTokenParm(Class<?> resourceType, QueryParameter queryParm)
Creates a query segment for a Token type parameter.protected SqlQueryData
processUriParm(QueryParameter queryParm)
Creates a query segment for a URI type parameter.protected SqlQueryData
processUriParm(QueryParameter queryParm, String tableAlias)
Creates a query segment for a URI type parameter.-
Methods inherited from class com.ibm.fhir.persistence.util.AbstractQueryBuilder
buildQueryParm, extractReferenceFromUrl, isAbsoluteURL, processLocationPosition
-
-
-
-
Constructor Detail
-
JDBCQueryBuilder
public JDBCQueryBuilder(ParameterDAO parameterDao, ResourceDAO resourceDao, QueryHints queryHints, JDBCIdentityCache identityCache)
Public constructor- Parameters:
parameterDao
-resourceDao
-queryHints
-identityCache
-
-
-
Method Detail
-
buildCountQuery
public SqlQueryData buildCountQuery(Class<?> resourceType, FHIRSearchContext searchContext) throws Exception
Builds a query that returns the count of the search results that would be found by applying the search parameters contained within the passed search context.- Parameters:
resourceType
- - The type of resource being searched for.searchContext
- - The search context containing the search parameters.- Returns:
- String - A count query SQL string
- Throws:
Exception
-
buildQuery
public SqlQueryData buildQuery(Class<?> resourceType, FHIRSearchContext searchContext) throws Exception
Description copied from interface:QueryBuilder
Build and return query for the passed resource type and search parameters.- Parameters:
resourceType
- A FHIR Resource subclass.searchContext
- A search context that contains a List of search parameters to be used for constructing the query.- Returns:
- An instance of T representing the constructed query.
- Throws:
FHIRPersistenceException
- thrown for any non-recoverable failure that occurs during query construction.Exception
-
getOperator
protected String getOperator(QueryParameter queryParm)
-
getOperator
protected String getOperator(QueryParameter queryParm, String defaultOverride)
Map the Modifier in the passed Parameter to a supported query operator. If the mapping results in the default operator, override the default operator with the passed operator if the passed operator is not null.- Parameters:
queryParm
- - A valid query Parameter.defaultOverride
- - An operator that should override the default operator.- Returns:
- A supported operator.
-
buildQueryParm
protected SqlQueryData buildQueryParm(Class<?> resourceType, QueryParameter queryParm, String paramTableAlias, String logicalRsrcTableAlias, boolean endOfChain) throws Exception
Builds a query segment for the passed query parameter.- Parameters:
resourceType
- - A valid FHIR Resource typequeryParm
- - A Parameter object describing the name, value and type of search parmparamTableAlias
- - An alias for the parameter table for which this query parameter applieslogicalRsrcTableAlias
- - An alias for the logical resource table for which this query parameter appliesendOfChain
- - true if query parameter is at the end of a chain, otherwise false- Returns:
- SqlQueryData - An object representing the selector query segment for the passed search parm.
- Throws:
Exception
-
processStringParm
protected SqlQueryData processStringParm(QueryParameter queryParm) throws FHIRPersistenceException
Description copied from class:AbstractQueryBuilder
Creates a query segment for a String type parameter.- Specified by:
processStringParm
in classAbstractQueryBuilder<SqlQueryData>
- Parameters:
queryParm
- - The query parameter.- Returns:
- T1 - An object containing query segment.
- Throws:
FHIRPersistenceException
-
processReferenceParm
protected SqlQueryData processReferenceParm(Class<?> resourceType, QueryParameter queryParm) throws Exception
Description copied from class:AbstractQueryBuilder
Creates a query segment for a Reference type parameter.- Specified by:
processReferenceParm
in classAbstractQueryBuilder<SqlQueryData>
- Parameters:
resourceType
- - The resource type.queryParm
- - The query parameter.- Returns:
- T1 - An object containing query segment.
- Throws:
Exception
-
processChainedReferenceParm
protected SqlQueryData processChainedReferenceParm(QueryParameter queryParm) throws Exception
Contains special logic for handling chained reference search parameters.Nested sub-selects are built to realize the chaining logic required. Here is a sample chained query for an Observation given this search parameter:
device:Device.patient.family=Monella
SELECT R.RESOURCE_ID, R.LOGICAL_RESOURCE_ID, R.VERSION_ID, R.LAST_UPDATED, R.IS_DELETED, R.DATA, LR.LOGICAL_ID FROM Observation_LOGICAL_RESOURCES LR JOIN Observation_RESOURCES R ON R.LOGICAL_RESOURCE_ID = LR.LOGICAL_RESOURCE_ID AND R.RESOURCE_ID = LR.CURRENT_RESOURCE_ID AND R.IS_DELETED = 'N' JOIN (SELECT DISTINCT LOGICAL_RESOURCE_ID FROM Observation_STR_VALUES WHERE(P1.PARAMETER_NAME_ID = 107 AND (p1.STR_VALUE IN (SELECT 'Device' || '/' || CLR1.LOGICAL_ID FROM Device_RESOURCES CR1, Device_LOGICAL_RESOURCES CLR1, Device_STR_VALUES CP1 WHERE CR1.RESOURCE_ID = CLR1.CURRENT_RESOURCE_ID AND CR1.IS_DELETED = 'N' AND CP1.RESOURCE_ID = CR1.RESOURCE_ID AND CP1.PARAMETER_NAME_ID = 17 AND CP1.STR_VALUE IN (SELECT 'Patient' || '/' || CLR2.LOGICAL_ID FROM Patient_RESOURCES CR2, Patient_LOGICAL_RESOURCES CLR2, Patient_STR_VALUES CP2 WHERE CR2.RESOURCE_ID = CLR2.CURRENT_RESOURCE_ID AND CR2.IS_DELETED = 'N' AND CP2.RESOURCE_ID = CR2.RESOURCE_ID AND CP2.PARAMETER_NAME_ID = 5 AND CP2.STR_VALUE = 'Monella'))) TMP0 ON TMP0.LOGICAL_RESOURCE_ID = R.LOGICAL_RESOURCE_ID;
- Specified by:
processChainedReferenceParm
in classAbstractQueryBuilder<SqlQueryData>
- Parameters:
queryParm
- - A Parameter representing a chained query.- Returns:
- SqlQueryData - The query segment for a chained parameter reference search.
- Throws:
Exception
FHIRPersistenceException
-
processInclusionCriteria
protected SqlQueryData processInclusionCriteria(QueryParameter queryParm) throws Exception
This method is the entry point for processing inclusion criteria, which define resources that are part of a compartment-based search. Example inclusion criteria for AuditEvent in the Patient compartment: TODO: revisit this method in light of https://jira.hl7.org/browse/FHIR-15906 (removal of chained inclusion criteria) TODO: consider leaving the chained inclusion in light of https://jira.hl7.org/browse/FHIR-17358{ "name": "AuditEvent", "inclusionCriteria": [ "patient", This is a simple attribute inclusion criterion "participant.patient:Device", This is a chained inclusion criterion "participant.patient:RelatedPerson", This is a chained inclusion criterion "reference.patient:*" This is a chained inclusion criterion with wildcard. The wildcard means "any resource type". ] }
Here is a sample generated query for this inclusion criteria:
- PARAMETER_NAME_ID 13 = 'participant'
- PARAMETER_NAME_ID 14 = 'patient'
- PARAMETER_NAME_ID 16 = 'reference'
SELECT COUNT(R.RESOURCE_ID) FROM AuditEvent_RESOURCES R, AuditEvent_LOGICAL_RESOURCES LR , AuditEvent_STR_VALUES P1 WHERE R.RESOURCE_ID = LR.CURRENT_RESOURCE_ID AND R.IS_DELETED = 'N' AND P1.RESOURCE_ID = R.RESOURCE_ID AND ((P1.PARAMETER_NAME_ID=14 AND P1.STR_VALUE = ?) OR ((P1.PARAMETER_NAME_ID=13 AND (P1.STR_VALUE IN (SELECT 'Device' || '/' || CLR1.LOGICAL_ID FROM Device_RESOURCES CR1, Device_LOGICAL_RESOURCES CLR1, Device_STR_VALUES CP1 WHERE CR1.RESOURCE_ID = CLR1.CURRENT_RESOURCE_ID AND CR1.IS_DELETED = 'N' AND CP1.RESOURCE_ID = CR1.RESOURCE_ID AND CP1.PARAMETER_NAME_ID=14 AND CP1.STR_VALUE = ?)))) OR ((P1.PARAMETER_NAME_ID=13 AND (P1.STR_VALUE IN (SELECT 'RelatedPerson' || '/' || CLR1.LOGICAL_ID FROM RelatedPerson_RESOURCES CR1, RelatedPerson_LOGICAL_RESOURCES CLR1, RelatedPerson_STR_VALUES CP1 WHERE CR1.RESOURCE_ID = CLR1.CURRENT_RESOURCE_ID AND CR1.IS_DELETED = 'N' AND CP1.RESOURCE_ID = CR1.RESOURCE_ID AND CP1.PARAMETER_NAME_ID=14 AND CP1.STR_VALUE = ?)))) OR ((P1.PARAMETER_NAME_ID=16 AND (P1.STR_VALUE IN (SELECT 'AuditEvent' || '/' || CLR1.LOGICAL_ID FROM auditevent_RESOURCES CR1, auditevent_LOGICAL_RESOURCES CLR1, auditevent_STR_VALUES CP1 WHERE CR1.RESOURCE_ID = CLR1.CURRENT_RESOURCE_ID AND CR1.IS_DELETED = 'N' AND CP1.RESOURCE_ID = CR1.RESOURCE_ID AND CP1.PARAMETER_NAME_ID=14 AND CP1.STR_VALUE = ? UNION SELECT 'Device' || '/' || CLR1.LOGICAL_ID FROM device_RESOURCES CR1, device_LOGICAL_RESOURCES CLR1, device_STR_VALUES CP1 WHERE CR1.RESOURCE_ID = CLR1.CURRENT_RESOURCE_ID AND CR1.IS_DELETED = 'N' AND CP1.RESOURCE_ID = CR1.RESOURCE_ID AND CP1.PARAMETER_NAME_ID=14 AND CP1.STR_VALUE = ?)))));
- Specified by:
processInclusionCriteria
in classAbstractQueryBuilder<SqlQueryData>
- Parameters:
queryParm
- - The query parameter.- Returns:
- T1 - An object containing a query segment.
- Throws:
Exception
FHIRPersistenceException
- See Also:
for the specificaiton of compartments, resources contained in each compartment, and the criteria for a resource to be included in a compartment.
-
processDateParm
protected SqlQueryData processDateParm(Class<?> resourceType, QueryParameter queryParm) throws Exception
Description copied from class:AbstractQueryBuilder
Creates a query segment for a Date type parameter.- Specified by:
processDateParm
in classAbstractQueryBuilder<SqlQueryData>
- Parameters:
resourceType
- - The resource type.queryParm
- - The query parameter.- Returns:
- T1 - An object containing query segment.
- Throws:
Exception
-
processTokenParm
protected SqlQueryData processTokenParm(Class<?> resourceType, QueryParameter queryParm) throws FHIRPersistenceException
Description copied from class:AbstractQueryBuilder
Creates a query segment for a Token type parameter.- Specified by:
processTokenParm
in classAbstractQueryBuilder<SqlQueryData>
- Parameters:
resourceType
- - The resource type.queryParm
- - The query parameter.- Returns:
- T1 - An object containing query segment.
- Throws:
FHIRPersistenceException
-
processNumberParm
protected SqlQueryData processNumberParm(Class<?> resourceType, QueryParameter queryParm) throws FHIRPersistenceException
Description copied from class:AbstractQueryBuilder
Creates a query segment for a Number type parameter.- Specified by:
processNumberParm
in classAbstractQueryBuilder<SqlQueryData>
- Parameters:
resourceType
- - The resource type.queryParm
- - The query parameter.- Returns:
- T1 - An object containing query segment.
- Throws:
FHIRPersistenceException
-
processQuantityParm
protected SqlQueryData processQuantityParm(Class<?> resourceType, QueryParameter queryParm) throws Exception
Description copied from class:AbstractQueryBuilder
Creates a query segment for a Quantity type parameter.- Specified by:
processQuantityParm
in classAbstractQueryBuilder<SqlQueryData>
- Parameters:
resourceType
- - The resource type.queryParm
- - The query parameter.- Returns:
- T1 - An object containing query segment.
- Throws:
Exception
-
processUriParm
protected SqlQueryData processUriParm(QueryParameter queryParm) throws FHIRPersistenceException
Description copied from class:AbstractQueryBuilder
Creates a query segment for a URI type parameter.- Specified by:
processUriParm
in classAbstractQueryBuilder<SqlQueryData>
- Parameters:
queryParm
- - The query parameter.- Returns:
- T1 - An object containing query segment.
- Throws:
FHIRPersistenceException
-
processUriParm
protected SqlQueryData processUriParm(QueryParameter queryParm, String tableAlias) throws FHIRPersistenceException
Creates a query segment for a URI type parameter.- Parameters:
queryParm
- - The query parametertableAlias
- - An alias for the table to query- Returns:
- SqlQueryData - An object containing query segment
- Throws:
FHIRPersistenceException
-
processCompositeParm
protected SqlQueryData processCompositeParm(Class<?> resourceType, QueryParameter queryParm) throws FHIRPersistenceException
Description copied from class:AbstractQueryBuilder
Creates a query segment for a Composite type parameter.- Specified by:
processCompositeParm
in classAbstractQueryBuilder<SqlQueryData>
- Parameters:
resourceType
- - The resource type.queryParm
- - The query parameter- Returns:
- T1 - An object containing query segment
- Throws:
FHIRPersistenceException
-
buildLocationQuerySegment
protected SqlQueryData buildLocationQuerySegment(String parmName, List<Bounding> boundingAreas, String paramTableAlias) throws FHIRPersistenceException
Description copied from class:AbstractQueryBuilder
Builds a query segment for the passed parameter name using the geospatial data contained with the passed BoundingBox- Specified by:
buildLocationQuerySegment
in classAbstractQueryBuilder<SqlQueryData>
- Parameters:
parmName
- - The name of the search parameterboundingAreas
- - Container for the geospatial data needed to construct the query segment.paramTableAlias
- the alias name of the parameter table- Returns:
- T1 - The query segment necessary for searching locations that are inside the bounding box.
- Throws:
FHIRPersistenceException
-
processReverseChainedReferenceParm
protected SqlQueryData processReverseChainedReferenceParm(Class<?> resourceType, QueryParameter queryParm) throws Exception
Contains special logic for handling reverse chained reference search parameters.A select statement is built to realize the reverse chaining logic required. Here is a sample reverse chained query for a Patient given this search parameter: _has:Observation:patient:code=1234
SELECT CLR0.LOGICAL_ID FROM Patient_LOGICAL_RESOURCES AS CLR0 JOIN Patient_RESOURCES AS CR0 ON CR0.RESOURCE_ID = CLR0.CURRENT_RESOURCE_ID AND CR0.IS_DELETED = 'N' WHERE EXISTS ( SELECT 1 FROM Observation_TOKEN_VALUES_V AS CP1 JOIN Observation_LOGICAL_RESOURCES AS CLR1 ON CLR1.LOGICAL_RESOURCE_ID = CP1.LOGICAL_RESOURCE_ID JOIN Observation_RESOURCES AS CR1 ON CR1.RESOURCE_ID = CLR1.CURRENT_RESOURCE_ID AND CR1.IS_DELETED = 'N' JOIN Observation_TOKEN_VALUES_V AS CP2 ON CP2.LOGICAL_RESOURCE_ID = CLR1.LOGICAL_RESOURCE_ID AND ( CP2.PARAMETER_NAME_ID = 1073 AND ((CP2.TOKEN_VALUE = ?)) ) WHERE COALESCE(CP1.REF_VERSION_ID, CR0.VERSION_ID) = CR0.VERSION_ID AND CP1.TOKEN_VALUE = CLR0.LOGICAL_ID AND CP1.PARAMETER_NAME_ID = 1274 AND CP1.CODE_SYSTEM_ID = 20004 )
- Specified by:
processReverseChainedReferenceParm
in classAbstractQueryBuilder<SqlQueryData>
- Parameters:
resourceType
- - The resource type being searched.queryParm
- - A Parameter representing a reverse chained query.- Returns:
- SqlQueryData - The query segment for a reverse chained parameter reference search.
- Throws:
Exception
FHIRPersistenceException
-
buildIncludeQuery
public SqlQueryData buildIncludeQuery(Class<?> resourceType, FHIRSearchContext searchContext, InclusionParameter inclusionParm, Set<String> ids, String inclusionType) throws Exception
Builds a query that returns included resources.- Parameters:
resourceType
- - the type of resource being searched for.searchContext
- - the search context containing the search parameters.inclusionParm
- - the inclusion parameter for which the query is being built.ids
- - the set of logical resource IDs the query will run against.inclusionType
- - either INCLUDE or REVINCLUDE.- Returns:
- SqlQueryData the populated inclusion query
- Throws:
Exception
-
-