001/*- 002 * #%L 003 * HAPI FHIR Server - SQL Migration 004 * %% 005 * Copyright (C) 2014 - 2026 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}