001/*-
002 * #%L
003 * HAPI FHIR Server - SQL Migration
004 * %%
005 * Copyright (C) 2014 - 2023 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.jpa.migrate.DriverTypeEnum;
023import ca.uhn.fhir.jpa.migrate.JdbcUtils;
024import org.intellij.lang.annotations.Language;
025import org.slf4j.Logger;
026import org.slf4j.LoggerFactory;
027
028import java.sql.SQLException;
029import java.util.List;
030import java.util.Set;
031
032public class DropColumnTask extends BaseTableColumnTask {
033
034        private static final Logger ourLog = LoggerFactory.getLogger(DropColumnTask.class);
035
036        /**
037         * Constructor
038         */
039        public DropColumnTask(String theProductVersion, String theSchemaVersion) {
040                super(theProductVersion, theSchemaVersion);
041        }
042
043        @Language("SQL")
044        static String createSql(String theTableName, String theColumnName) {
045                return "alter table " + theTableName + " drop column " + theColumnName;
046        }
047
048        @Override
049        public void validate() {
050                super.validate();
051                setDescription("Drop column " + getColumnName() + " from table " + getTableName());
052        }
053
054        @Override
055        public void doExecute() throws SQLException {
056                Set<String> columnNames = JdbcUtils.getColumnNames(getConnectionProperties(), getTableName());
057                if (!columnNames.contains(getColumnName())) {
058                        logInfo(
059                                        ourLog,
060                                        "Column {} does not exist on table {} - No action performed",
061                                        getColumnName(),
062                                        getTableName());
063                        return;
064                }
065
066                if (getDriverType().equals(DriverTypeEnum.MYSQL_5_7)
067                                || getDriverType().equals(DriverTypeEnum.MARIADB_10_1)
068                                || getDriverType().equals(DriverTypeEnum.MSSQL_2012)) {
069                        // Some DBs such as MYSQL and Maria DB require that foreign keys depending on the column be dropped before
070                        // the column itself is dropped.
071                        logInfo(
072                                        ourLog,
073                                        "Dropping any foreign keys on table {} depending on column {}",
074                                        getTableName(),
075                                        getColumnName());
076                        Set<String> foreignKeys =
077                                        JdbcUtils.getForeignKeysForColumn(getConnectionProperties(), getColumnName(), getTableName());
078                        if (foreignKeys != null) {
079                                for (String foreignKey : foreignKeys) {
080                                        List<String> dropFkSqls =
081                                                        DropForeignKeyTask.generateSql(getTableName(), foreignKey, getDriverType());
082                                        for (String dropFkSql : dropFkSqls) {
083                                                executeSql(getTableName(), dropFkSql);
084                                        }
085                                }
086                        }
087                }
088
089                String tableName = getTableName();
090                String columnName = getColumnName();
091                String sql = createSql(tableName, columnName);
092                logInfo(ourLog, "Dropping column {} on table {}", getColumnName(), getTableName());
093                executeSql(getTableName(), sql);
094        }
095}