]> source.dussan.org Git - sonarqube.git/blob
b041f4f9d4dbc2d1addde618b86faf3392af7bb7
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2024 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonar.server.platform.db.migration.sql;
21
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 import org.apache.commons.lang3.text.StrSubstitutor;
26 import org.junit.Test;
27 import org.sonar.db.dialect.Dialect;
28 import org.sonar.db.dialect.H2;
29 import org.sonar.db.dialect.MsSql;
30 import org.sonar.db.dialect.Oracle;
31 import org.sonar.db.dialect.PostgreSql;
32 import org.sonar.server.platform.db.migration.def.BigIntegerColumnDef;
33 import org.sonar.server.platform.db.migration.def.BlobColumnDef;
34 import org.sonar.server.platform.db.migration.def.BooleanColumnDef;
35 import org.sonar.server.platform.db.migration.def.ClobColumnDef;
36 import org.sonar.server.platform.db.migration.def.ColumnDef;
37 import org.sonar.server.platform.db.migration.def.DecimalColumnDef;
38 import org.sonar.server.platform.db.migration.def.IntegerColumnDef;
39 import org.sonar.server.platform.db.migration.def.TinyIntColumnDef;
40 import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
41
42 import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
43 import static org.assertj.core.api.Assertions.assertThat;
44 import static org.assertj.core.api.Assertions.assertThatThrownBy;
45
46 public class RenameColumnsBuilderTest {
47   private static final String NEW_COLUMN_NAME = "new_" + randomAlphabetic(6).toLowerCase();
48
49   private static final DatabaseAndResult[] DATABASES = {
50     new DatabaseAndResult(new H2(), "ALTER TABLE ${table_name} ALTER COLUMN ${old_column_name} RENAME TO ${new_column_name}"),
51     new DatabaseAndResult(new PostgreSql(), "ALTER TABLE ${table_name} RENAME COLUMN ${old_column_name} TO ${new_column_name}"),
52     new DatabaseAndResult(new MsSql(), "EXEC sp_rename '${table_name}.${old_column_name}', '${new_column_name}', 'COLUMN'"),
53     new DatabaseAndResult(new Oracle(), "ALTER TABLE ${table_name} RENAME COLUMN ${old_column_name} TO ${new_column_name}")
54   };
55
56   public static final ColumnDef[] COLUMN_DEFS = {
57     BigIntegerColumnDef.newBigIntegerColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false).build(),
58     BigIntegerColumnDef.newBigIntegerColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true).build(),
59     BlobColumnDef.newBlobColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false).build(),
60     BlobColumnDef.newBlobColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true).build(),
61     BooleanColumnDef.newBooleanColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false).build(),
62     BooleanColumnDef.newBooleanColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true).build(),
63     ClobColumnDef.newClobColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false).build(),
64     ClobColumnDef.newClobColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true).build(),
65     DecimalColumnDef.newDecimalColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false).build(),
66     DecimalColumnDef.newDecimalColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true).build(),
67     IntegerColumnDef.newIntegerColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false).build(),
68     IntegerColumnDef.newIntegerColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true).build(),
69     TinyIntColumnDef.newTinyIntColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false).build(),
70     TinyIntColumnDef.newTinyIntColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true).build(),
71     VarcharColumnDef.newVarcharColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false).setLimit(10).build(),
72     VarcharColumnDef.newVarcharColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true).setLimit(10).build(),
73   };
74
75   public static final String[] ILLEGAL_COLUMN_NAME = {
76     "",
77     "AA",
78     "A.A",
79     "_A",
80     "1A",
81     "\uD801\uDC8B\uD801\uDC8C\uD801\uDC8D"
82   };
83
84   @Test
85   public void run_checkSQL_results() {
86     for (DatabaseAndResult database : DATABASES) {
87       for (ColumnDef columnDef : COLUMN_DEFS) {
88         checkSQL_results(database, columnDef);
89       }
90     }
91   }
92
93   private void checkSQL_results(
94     DatabaseAndResult database,
95     ColumnDef columnDef) {
96
97     String oldColumnName = "old_" + randomAlphabetic(6).toLowerCase();
98     String tableName = "table_" + randomAlphabetic(6).toLowerCase();
99
100     List<String> result = new RenameColumnsBuilder(database.dialect(), tableName)
101       .renameColumn(oldColumnName, columnDef)
102       .build();
103
104     Map<String, String> parameters = new HashMap<>();
105     parameters.put("table_name", tableName);
106     parameters.put("old_column_name", oldColumnName);
107     parameters.put("new_column_name", NEW_COLUMN_NAME);
108     parameters.put("column_def", columnDef.generateSqlType(database.dialect()));
109     String expectedResult = StrSubstitutor.replace(database.templateSql(), parameters);
110     assertThat(result).containsExactlyInAnyOrder(expectedResult);
111   }
112
113   @Test
114   public void run_when_old_column_is_same_as_new_column_ISA_is_thrown() {
115     for (DatabaseAndResult database : DATABASES) {
116       for (ColumnDef columnDef : COLUMN_DEFS) {
117         when_old_column_is_same_as_new_column_ISA_is_thrown(database, columnDef);
118       }
119     }
120   }
121
122   private void when_old_column_is_same_as_new_column_ISA_is_thrown(
123     DatabaseAndResult database,
124     ColumnDef columnDef) {
125
126     String tableName = "table_" + randomAlphabetic(6).toLowerCase();
127
128     RenameColumnsBuilder renameColumnsBuilder = new RenameColumnsBuilder(database.dialect(), tableName)
129       .renameColumn(NEW_COLUMN_NAME, columnDef);
130     assertThatThrownBy(renameColumnsBuilder::build)
131       .isInstanceOf(IllegalArgumentException.class)
132       .hasMessageContaining("Column names must be different");
133   }
134
135   @Test
136   public void run_when_new_column_contains_illegal_character_ISA_is_thrown() {
137     for (DatabaseAndResult database : DATABASES) {
138       for (ColumnDef columnDef : COLUMN_DEFS) {
139         for (String illegalColumnName : ILLEGAL_COLUMN_NAME) {
140           when_new_column_contains_illegal_character_ISA_is_thrown(database, columnDef, illegalColumnName);
141         }
142       }
143     }
144   }
145
146   private void when_new_column_contains_illegal_character_ISA_is_thrown(
147     DatabaseAndResult database,
148     ColumnDef columnDef,
149     String illegalColumnName) {
150
151     String tableName = "table_" + randomAlphabetic(6).toLowerCase();
152
153     RenameColumnsBuilder renameColumnsBuilder = new RenameColumnsBuilder(database.dialect(), tableName)
154       .renameColumn(illegalColumnName, columnDef);
155
156     assertThatThrownBy(renameColumnsBuilder::build)
157       .isInstanceOf(IllegalArgumentException.class);
158   }
159
160   private record DatabaseAndResult(Dialect dialect, String templateSql) {
161   }
162 }