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(ourLog, "Column {} does not exist on table {} - No action performed", getColumnName(), getTableName()); 059 return; 060 } 061 062 if (getDriverType().equals(DriverTypeEnum.MYSQL_5_7) || getDriverType().equals(DriverTypeEnum.MARIADB_10_1) 063 || getDriverType().equals(DriverTypeEnum.MSSQL_2012)) { 064 // Some DBs such as MYSQL and Maria DB require that foreign keys depending on the column be dropped before the column itself is dropped. 065 logInfo(ourLog, "Dropping any foreign keys on table {} depending on column {}", getTableName(), getColumnName()); 066 Set<String> foreignKeys = JdbcUtils.getForeignKeysForColumn(getConnectionProperties(), getColumnName(), getTableName()); 067 if (foreignKeys != null) { 068 for (String foreignKey : foreignKeys) { 069 List<String> dropFkSqls = DropForeignKeyTask.generateSql(getTableName(), foreignKey, getDriverType()); 070 for (String dropFkSql : dropFkSqls) { 071 executeSql(getTableName(), dropFkSql); 072 } 073 } 074 } 075 } 076 077 String tableName = getTableName(); 078 String columnName = getColumnName(); 079 String sql = createSql(tableName, columnName); 080 logInfo(ourLog, "Dropping column {} on table {}", getColumnName(), getTableName()); 081 executeSql(getTableName(), sql); 082 } 083 084 085}