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