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.apache.commons.lang3.Validate; 026import org.apache.commons.lang3.builder.EqualsBuilder; 027import org.apache.commons.lang3.builder.HashCodeBuilder; 028import org.intellij.lang.annotations.Language; 029import org.slf4j.Logger; 030import org.slf4j.LoggerFactory; 031 032import java.sql.SQLException; 033import java.util.ArrayList; 034import java.util.Collections; 035import java.util.List; 036import java.util.Set; 037 038public class RenameIndexTask extends BaseTableTask { 039 private static final Logger ourLog = LoggerFactory.getLogger(RenameIndexTask.class); 040 private String myOldIndexName; 041 private String myNewIndexName; 042 043 public RenameIndexTask(String theProductVersion, String theSchemaVersion) { 044 super(theProductVersion, theSchemaVersion); 045 } 046 047 static List<String> createRenameIndexSql(DriverTypeEnum.ConnectionProperties theConnectionProperties, String theTableName, String theOldIndexName, String theNewIndexName, DriverTypeEnum theDriverType) throws SQLException { 048 Validate.notBlank(theOldIndexName, "theOldIndexName must not be blank"); 049 Validate.notBlank(theNewIndexName, "theNewIndexName must not be blank"); 050 Validate.notBlank(theTableName, "theTableName must not be blank"); 051 052 if (!JdbcUtils.getIndexNames(theConnectionProperties, theTableName).contains(theOldIndexName)) { 053 return Collections.emptyList(); 054 } 055 056 List<String> sql = new ArrayList<>(); 057 058 // Drop constraint 059 switch (theDriverType) { 060 case MYSQL_5_7: 061 case MARIADB_10_1: 062 // Quote the index names as "PRIMARY" is a reserved word in MySQL 063 sql.add("rename index `" + theOldIndexName + "` to `" + theNewIndexName + "`"); 064 break; 065 case DERBY_EMBEDDED: 066 sql.add("rename index " + theOldIndexName + " to " + theNewIndexName); 067 break; 068 case H2_EMBEDDED: 069 case POSTGRES_9_4: 070 case ORACLE_12C: 071 sql.add("alter index " + theOldIndexName + " rename to " + theNewIndexName); 072 break; 073 case MSSQL_2012: 074 sql.add("EXEC sp_rename '" + theTableName + "." + theOldIndexName + "', '" + theNewIndexName + "'"); 075 break; 076 } 077 return sql; 078 } 079 080 @Override 081 public void validate() { 082 super.validate(); 083 Validate.notBlank(myOldIndexName, "The old index name must not be blank"); 084 Validate.notBlank(myNewIndexName, "The new index name must not be blank"); 085 086 setDescription("Rename index from " + myOldIndexName + " to " + myNewIndexName + " on table " + getTableName()); 087 } 088 089 @Override 090 public void doExecute() throws SQLException { 091 Set<String> indexNames = JdbcUtils.getIndexNames(getConnectionProperties(), getTableName()); 092 093 if (!indexNames.contains(myOldIndexName)) { 094 logInfo(ourLog, "Index {} does not exist on table {} - No action needed", myOldIndexName, getTableName()); 095 return; 096 } 097 098 List<String> sqls = createRenameIndexSql(getConnectionProperties(), getTableName(), myOldIndexName, myNewIndexName, getDriverType()); 099 if (!sqls.isEmpty()) { 100 logInfo(ourLog, "Renaming index from {} to {} on table {}", myOldIndexName, myNewIndexName, getTableName()); 101 } 102 for (@Language("SQL") String sql : sqls) { 103 executeSql(getTableName(), sql); 104 } 105 } 106 107 public RenameIndexTask setNewIndexName(String theNewIndexName) { 108 myNewIndexName = theNewIndexName; 109 return this; 110 } 111 112 public RenameIndexTask setOldIndexName(String theOldIndexName) { 113 myOldIndexName = theOldIndexName; 114 return this; 115 } 116 117 @Override 118 protected void generateEquals(EqualsBuilder theBuilder, BaseTask theOtherObject) { 119 RenameIndexTask otherObject = (RenameIndexTask) theOtherObject; 120 super.generateEquals(theBuilder, otherObject); 121 theBuilder.append(myOldIndexName, otherObject.myOldIndexName); 122 theBuilder.append(myNewIndexName, otherObject.myNewIndexName); 123 } 124 125 @Override 126 protected void generateHashCode(HashCodeBuilder theBuilder) { 127 super.generateHashCode(theBuilder); 128 theBuilder.append(myOldIndexName); 129 theBuilder.append(myNewIndexName); 130 } 131}