001package ca.uhn.fhir.jpa.search.builder.predicate;
002
003/*
004 * #%L
005 * HAPI FHIR JPA Server
006 * %%
007 * Copyright (C) 2014 - 2022 Smile CDR, Inc.
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import ca.uhn.fhir.context.FhirContext;
024import ca.uhn.fhir.interceptor.model.RequestPartitionId;
025import ca.uhn.fhir.jpa.dao.predicate.SearchFilterParser;
026import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
027import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamBaseQuantity;
028import ca.uhn.fhir.jpa.search.builder.QueryStack;
029import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryBuilder;
030import ca.uhn.fhir.model.api.IQueryParameterType;
031import ca.uhn.fhir.model.base.composite.BaseQuantityDt;
032import ca.uhn.fhir.rest.param.ParamPrefixEnum;
033import ca.uhn.fhir.rest.param.QuantityParam;
034import com.healthmarketscience.sqlbuilder.BinaryCondition;
035import com.healthmarketscience.sqlbuilder.ComboCondition;
036import com.healthmarketscience.sqlbuilder.Condition;
037import com.healthmarketscience.sqlbuilder.dbspec.basic.DbColumn;
038import com.healthmarketscience.sqlbuilder.dbspec.basic.DbTable;
039import org.springframework.beans.factory.annotation.Autowired;
040
041import javax.persistence.criteria.CriteriaBuilder;
042import java.math.BigDecimal;
043
044import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
045import static org.apache.commons.lang3.StringUtils.isBlank;
046
047
048public abstract class QuantityBasePredicateBuilder extends BaseSearchParamPredicateBuilder {
049
050        protected DbColumn myColumnHashIdentitySystemUnits;
051        protected DbColumn myColumnHashIdentityUnits;
052        protected DbColumn myColumnValue;
053
054        @Autowired
055        private FhirContext myFhirContext;
056
057        /**
058         * Constructor
059         */
060        public QuantityBasePredicateBuilder(SearchQueryBuilder theSearchSqlBuilder, DbTable theTable) {
061                super(theSearchSqlBuilder, theTable);
062        }
063
064        public Condition createPredicateQuantity(QuantityParam theParam, String theResourceName, String theParamName, CriteriaBuilder theBuilder, QuantityBasePredicateBuilder theFrom, SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) {
065
066                String systemValue = theParam.getSystem();
067                String unitsValue = theParam.getUnits();
068                ParamPrefixEnum cmpValue = theParam.getPrefix();
069                BigDecimal valueValue = theParam.getValue();
070
071                Condition hashPredicate;
072                if (!isBlank(systemValue) && !isBlank(unitsValue)) {
073                        long hash = ResourceIndexedSearchParamBaseQuantity.calculateHashSystemAndUnits(getPartitionSettings(), theRequestPartitionId, theResourceName, theParamName, systemValue, unitsValue);
074                        hashPredicate = BinaryCondition.equalTo(myColumnHashIdentitySystemUnits, generatePlaceholder(hash));
075                } else if (!isBlank(unitsValue)) {
076                        long hash = ResourceIndexedSearchParamBaseQuantity.calculateHashUnits(getPartitionSettings(), theRequestPartitionId, theResourceName, theParamName, unitsValue);
077                        hashPredicate = BinaryCondition.equalTo(myColumnHashIdentityUnits, generatePlaceholder(hash));
078                } else {
079                        long hash = BaseResourceIndexedSearchParam.calculateHashIdentity(getPartitionSettings(), theRequestPartitionId, theResourceName, theParamName);
080                        hashPredicate = BinaryCondition.equalTo(getColumnHashIdentity(), generatePlaceholder(hash));
081                }
082
083                SearchFilterParser.CompareOperation operation = theOperation;
084                if (operation == null && cmpValue != null) {
085                        operation = QueryStack.toOperation(cmpValue);
086                }
087                operation = defaultIfNull(operation, SearchFilterParser.CompareOperation.eq);
088                Condition numericPredicate = NumberPredicateBuilder.createPredicateNumeric(this, operation, valueValue, myColumnValue, "invalidQuantityPrefix", myFhirContext, theParam);
089
090                return ComboCondition.and(hashPredicate, numericPredicate);
091        }
092
093        public DbColumn getColumnValue() {
094                return myColumnValue;
095        }
096
097}