cleanup
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / database / update / IndexRenamer.java
1 /**
2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.cdm.database.update;
10
11 import java.sql.SQLException;
12 import java.util.List;
13
14 import org.apache.logging.log4j.LogManager;
15 import org.apache.logging.log4j.Logger;
16
17 import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
18 import eu.etaxonomy.cdm.database.DatabaseTypeEnum;
19 import eu.etaxonomy.cdm.database.ICdmDataSource;
20
21 /**
22 * @author a.mueller
23 * @since 15.06.2017
24 *
25 */
26 public class IndexRenamer extends SchemaUpdaterStepBase {
27
28 private static final Logger logger = LogManager.getLogger();
29
30 private String tableName;
31
32 private String oldIndexName;
33
34 private String newIndexName;
35
36 private String columnName;
37
38 private Integer length;
39
40 // ********************** FACTORY ****************************************/
41
42 public static final IndexRenamer NewStringInstance(List<ISchemaUpdaterStep> stepList, String tableName, String oldIndexName,
43 String newIndexName, String columnName, Integer length){
44 return new IndexRenamer(stepList, tableName, oldIndexName,
45 newIndexName, columnName, length == null ? 255 : length);
46 }
47
48 public static final IndexRenamer NewIntegerInstance(List<ISchemaUpdaterStep> stepList, String tableName, String oldIndexName,
49 String newIndexName, String columnName){
50 return new IndexRenamer(stepList, tableName, oldIndexName, newIndexName, columnName, null);
51 }
52 /**
53 * @param stepName
54 */
55 protected IndexRenamer(List<ISchemaUpdaterStep> stepList, String tableName, String oldIndexName,
56 String newIndexName, String columnName, Integer length) {
57 super(stepList, "Rename index " + oldIndexName + " to " + newIndexName);
58 this.tableName = tableName;
59 this.oldIndexName = oldIndexName;
60 this.newIndexName = newIndexName;
61 this.columnName = columnName;
62 this.length = length;
63 }
64
65 /**
66 * {@inheritDoc}
67 */
68 @Override
69 public void invoke(ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType,
70 SchemaUpdateResult result) throws SQLException {
71 try {
72 String[] updateQuery = getCreateQuery(datasource, caseType, tableName, oldIndexName, newIndexName, columnName, length);
73 try {
74 datasource.executeUpdate(updateQuery[0]);
75 } catch (Exception e) {
76 if (updateQuery.length > 1){
77 datasource.executeUpdate(updateQuery[1]);
78 }else{
79 throw e;
80 }
81 }
82 return;
83 } catch (Exception e) {
84 String message = "Index ("+tableName +"."+oldIndexName+") could not be renamed "
85 + "to ("+newIndexName+") or drop/add was not possible.\n"
86 + "Please ask your admin to rename manually.";
87 logger.warn(message);
88 result.addWarning(message, this, "invoke");
89 return;
90 }
91
92 }
93
94 private String[] getCreateQuery(ICdmDataSource datasource, CaseType caseType, String tableName, String oldIndexName, String newIndexName, String columnName, Integer length) {
95 DatabaseTypeEnum type = datasource.getDatabaseType();
96 // String indexName = "_UniqueKey";
97 String[] updateQueries;
98 if (type.equals(DatabaseTypeEnum.MySQL)){
99 //https://stackoverflow.com/questions/1463363/how-do-i-rename-an-index-in-mysql
100 //in future: https://dev.mysql.com/worklog/task/?id=6555
101 String format = "ALTER TABLE @@%s@@ DROP INDEX %s, ADD INDEX %s (%s%s)";
102 updateQueries = new String[]{String.format(format, tableName, oldIndexName, newIndexName, columnName, length!= null ? "("+length+")": "")};
103 }else if (type.equals(DatabaseTypeEnum.H2) || type.equals(DatabaseTypeEnum.PostgreSQL)){
104 //http://www.h2database.com/html/grammar.html#alter_index_rename
105 //https://www.postgresql.org/docs/9.4/static/sql-alterindex.html (maybe IF EXISTS does not work prior to 9.x)
106 String format = "ALTER INDEX %s %s RENAME TO %s";
107 updateQueries = new String[]{String.format(format, " IF EXISTS ", oldIndexName, newIndexName),
108 String.format(format, "", oldIndexName, newIndexName)};
109
110 }else if (type.equals(DatabaseTypeEnum.SqlServer2005)){
111 //TODO Untested !!!!
112 //https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-rename-transact-sql
113 //https://www.mssqltips.com/sqlservertip/2709/script-to-rename-constraints-and-indexes-to-conform-to-a-sql-server-naming-convention/
114 //https://stackoverflow.com/questions/40865886/rename-sql-server-index-in-ms-sql-server
115 String format = "EXEC sp_rename N'%s.%s', N'%s', N'INDEX'";
116 updateQueries = new String[]{String.format(format, tableName, oldIndexName, newIndexName)};
117 }else{
118 throw new IllegalArgumentException("Datasource type not supported yet: " + type.getName());
119 }
120 // updateQuery = updateQuery.replace("@indexName", indexName);
121 for (int i = 0; i < updateQueries.length ; i++ ){
122 updateQueries[i] = caseType.replaceTableNames(updateQueries[i]);
123 }
124 return updateQueries;
125 }
126
127 }