001/*-
002 * #%L
003 * HAPI FHIR Server - SQL Migration
004 * %%
005 * Copyright (C) 2014 - 2025 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.jpa.migrate.taskdef;
021
022import ca.uhn.fhir.i18n.Msg;
023import jakarta.annotation.Nonnull;
024import org.apache.commons.lang3.Validate;
025import org.apache.commons.lang3.builder.EqualsBuilder;
026import org.apache.commons.lang3.builder.HashCodeBuilder;
027import org.slf4j.Logger;
028import org.slf4j.LoggerFactory;
029
030import java.util.ArrayList;
031import java.util.Collections;
032import java.util.List;
033import java.util.Objects;
034import java.util.Set;
035import java.util.stream.Collectors;
036
037public abstract class BaseTableTask extends BaseTask {
038        private static final Logger ourLog = LoggerFactory.getLogger(BaseTableTask.class);
039        private String myTableName;
040
041        private final List<ColumnDriverMappingOverride> myColumnDriverMappingOverrides;
042
043        public BaseTableTask(String theProductVersion, String theSchemaVersion) {
044                this(theProductVersion, theSchemaVersion, Collections.emptySet());
045        }
046
047        public BaseTableTask(
048                        String theProductVersion,
049                        String theSchemaVersion,
050                        Set<ColumnDriverMappingOverride> theColumnDriverMappingOverrides) {
051                super(theProductVersion, theSchemaVersion);
052                myColumnDriverMappingOverrides = new ArrayList<>(theColumnDriverMappingOverrides);
053        }
054
055        public String getTableName() {
056                return myTableName;
057        }
058
059        public BaseTableTask setTableName(String theTableName) {
060                Validate.notBlank(theTableName);
061                myTableName = theTableName;
062                return this;
063        }
064
065        @Override
066        public void validate() {
067                Validate.notBlank(myTableName);
068        }
069
070        @Override
071        protected void generateEquals(EqualsBuilder theBuilder, BaseTask theOtherObject) {
072                BaseTableTask otherObject = (BaseTableTask) theOtherObject;
073                theBuilder.append(myTableName, otherObject.myTableName);
074        }
075
076        protected String getSqlType(ColumnTypeEnum theColumnType, Long theColumnLength) {
077                final String retVal = getColumnSqlWithToken(theColumnType);
078
079                Objects.requireNonNull(retVal);
080
081                if (theColumnType == ColumnTypeEnum.STRING) {
082                        return retVal.replace("?", Long.toString(theColumnLength));
083                }
084
085                return retVal;
086        }
087
088        @Override
089        protected void generateHashCode(HashCodeBuilder theBuilder) {
090                theBuilder.append(myTableName);
091        }
092
093        @Nonnull
094        private String getColumnSqlWithToken(ColumnTypeEnum theColumnType) {
095                final List<ColumnDriverMappingOverride> eligibleOverrides = myColumnDriverMappingOverrides.stream()
096                                .filter(override -> override.getColumnType() == theColumnType)
097                                .filter(override -> override.getDriverType() == getDriverType())
098                                .collect(Collectors.toUnmodifiableList());
099
100                if (eligibleOverrides.size() > 1) {
101                        ourLog.info("There is more than one eligible override: {}.  Picking the first one", eligibleOverrides);
102                }
103
104                if (eligibleOverrides.size() == 1) {
105                        return eligibleOverrides.get(0).getColumnTypeSql();
106                }
107
108                if (!ColumnTypeToDriverTypeToSqlType.getColumnTypeToDriverTypeToSqlType()
109                                .containsKey(theColumnType)) {
110                        throw new IllegalArgumentException(Msg.code(2449) + "Column type does not exist: " + theColumnType);
111                }
112
113                return ColumnTypeToDriverTypeToSqlType.getColumnTypeToDriverTypeToSqlType()
114                                .get(theColumnType)
115                                .get(getDriverType());
116        }
117}