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.i18n.Msg;
024import ca.uhn.fhir.jpa.migrate.JdbcUtils;
025import org.slf4j.Logger;
026import org.slf4j.LoggerFactory;
027
028import java.sql.SQLException;
029import java.util.Set;
030
031public class AddColumnTask extends BaseTableColumnTypeTask {
032
033        private static final Logger ourLog = LoggerFactory.getLogger(AddColumnTask.class);
034
035        public AddColumnTask(String theProductVersion, String theSchemaVersion) {
036                super(theProductVersion, theSchemaVersion);
037        }
038
039        @Override
040        public void validate() {
041                super.validate();
042                setDescription("Add column " + getColumnName() + " on table " + getTableName());
043        }
044
045        @Override
046        public void doExecute() throws SQLException {
047                Set<String> columnNames = JdbcUtils.getColumnNames(getConnectionProperties(), getTableName());
048                if (columnNames.contains(getColumnName())) {
049                        logInfo(ourLog, "Column {} already exists on table {} - No action performed", getColumnName(), getTableName());
050                        return;
051                }
052
053                String typeStatement = getTypeStatement();
054
055                String sql;
056                switch (getDriverType()) {
057                        case MYSQL_5_7:
058                        case MARIADB_10_1:
059                                // Quote the column name as "SYSTEM" is a reserved word in MySQL
060                                sql = "alter table " + getTableName() + " add column `" + getColumnName() + "` " + typeStatement;
061                                break;
062                        case DERBY_EMBEDDED:
063                        case POSTGRES_9_4:
064                                sql = "alter table " + getTableName() + " add column " + getColumnName() + " " + typeStatement;
065                                break;
066                        case MSSQL_2012:
067                        case ORACLE_12C:
068                        case H2_EMBEDDED:
069                                sql = "alter table " + getTableName() + " add " + getColumnName() + " " + typeStatement;
070                                break;
071                        default:
072                                throw new IllegalStateException(Msg.code(60));
073                }
074
075                logInfo(ourLog, "Adding column {} of type {} to table {}", getColumnName(), getSqlType(), getTableName());
076                executeSql(getTableName(), sql);
077        }
078
079        public String getTypeStatement() {
080                String type = getSqlType();
081                String nullable = getSqlNotNull();
082                if (isNullable()) {
083                        nullable = "";
084                }
085                return type + " " + nullable;
086        }
087
088}