From: Simon Brandhof Date: Tue, 6 Dec 2016 20:00:39 +0000 (+0100) Subject: SONAR-5471 add DropIndexBuilder X-Git-Tag: 6.3-RC1~807 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=1b16981bab6f9309b80fa08dde67aef9a2b3dc1d;p=sonarqube.git SONAR-5471 add DropIndexBuilder --- diff --git a/sonar-db/src/main/java/org/sonar/db/version/DropIndexBuilder.java b/sonar-db/src/main/java/org/sonar/db/version/DropIndexBuilder.java new file mode 100644 index 00000000000..091a5085532 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/DropIndexBuilder.java @@ -0,0 +1,75 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.version; + +import java.util.List; +import org.sonar.db.dialect.Dialect; +import org.sonar.db.dialect.H2; +import org.sonar.db.dialect.MsSql; +import org.sonar.db.dialect.MySql; +import org.sonar.db.dialect.Oracle; +import org.sonar.db.dialect.PostgreSql; + +import static java.util.Collections.singletonList; +import static org.sonar.db.version.Validations.validateIndexName; +import static org.sonar.db.version.Validations.validateTableName; + +public class DropIndexBuilder { + + private final Dialect dialect; + private String tableName; + private String indexName; + + public DropIndexBuilder(Dialect dialect) { + this.dialect = dialect; + } + + public DropIndexBuilder setTable(String s) { + this.tableName = s; + return this; + } + + public DropIndexBuilder setName(String s) { + this.indexName = s; + return this; + } + + public List build() { + validateTableName(tableName); + validateIndexName(indexName); + return singletonList(createSqlStatement()); + } + + private String createSqlStatement() { + switch (dialect.getId()) { + case MsSql.ID: + case MySql.ID: + return "DROP INDEX " + indexName + " ON " + tableName; + case Oracle.ID: + return "DROP INDEX " + indexName; + case H2.ID: + case PostgreSql.ID: + return "DROP INDEX IF EXISTS " + indexName; + default: + throw new IllegalStateException("Unsupported dialect for drop of index: " + dialect); + } + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/DbTester.java b/sonar-db/src/test/java/org/sonar/db/DbTester.java index bbd076c3d06..deb8b1674fd 100644 --- a/sonar-db/src/test/java/org/sonar/db/DbTester.java +++ b/sonar-db/src/test/java/org/sonar/db/DbTester.java @@ -549,7 +549,7 @@ public class DbTester extends ExternalResource { private void assertIndexImpl(String tableName, String indexName, boolean expectedUnique, String expectedColumn, String... expectedSecondaryColumns) { try (Connection connection = getConnection(); - ResultSet rs = connection.getMetaData().getIndexInfo(null, null, tableName.toUpperCase(Locale.ENGLISH), false, true)) { + ResultSet rs = connection.getMetaData().getIndexInfo(null, null, tableName.toUpperCase(Locale.ENGLISH), false, false)) { List onColumns = new ArrayList<>(); while (rs.next()) { if (indexName.equalsIgnoreCase(rs.getString("INDEX_NAME"))) { @@ -564,6 +564,22 @@ public class DbTester extends ExternalResource { } } + /** + * Verify that index with name {@code indexName} does not exist on the table {@code tableName} + */ + public void assertIndexDoesNotExist(String tableName, String indexName) { + try (Connection connection = getConnection(); + ResultSet rs = connection.getMetaData().getIndexInfo(null, null, tableName.toUpperCase(Locale.ENGLISH), false, false)) { + List indices = new ArrayList<>(); + while (rs.next()) { + indices.add(rs.getString("INDEX_NAME").toLowerCase(Locale.ENGLISH)); + } + assertThat(indices).doesNotContain(indexName); + } catch (SQLException e) { + throw new IllegalStateException("Fail to check existence of index", e); + } + } + public void assertPrimaryKey(String tableName, @Nullable String expectedPkName, String columnName, String... otherColumnNames) { try (Connection connection = getConnection()) { PK pk = pkOf(connection, tableName.toUpperCase(Locale.ENGLISH)); diff --git a/sonar-db/src/test/java/org/sonar/db/version/DropIndexBuilderTest.java b/sonar-db/src/test/java/org/sonar/db/version/DropIndexBuilderTest.java new file mode 100644 index 00000000000..7792248ce1c --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/DropIndexBuilderTest.java @@ -0,0 +1,98 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.version; + +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.db.dialect.Dialect; +import org.sonar.db.dialect.H2; +import org.sonar.db.dialect.MsSql; +import org.sonar.db.dialect.MySql; +import org.sonar.db.dialect.Oracle; +import org.sonar.db.dialect.PostgreSql; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DropIndexBuilderTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void drop_index_in_table() { + verifySql(new H2(), "DROP INDEX IF EXISTS issues_key"); + verifySql(new MsSql(), "DROP INDEX issues_key ON issues"); + verifySql(new MySql(), "DROP INDEX issues_key ON issues"); + verifySql(new Oracle(), "DROP INDEX issues_key"); + verifySql(new PostgreSql(), "DROP INDEX IF EXISTS issues_key"); + } + + private static void verifySql(Dialect dialect, String expectedSql) { + List actual = new DropIndexBuilder(dialect) + .setTable("issues") + .setName("issues_key") + .build(); + assertThat(actual).containsExactly(expectedSql); + } + + @Test + public void throw_NPE_if_table_name_is_missing() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("Table name cannot be null"); + + new DropIndexBuilder(new H2()) + .setName("issues_key") + .build(); + } + + @Test + public void throw_IAE_if_table_name_is_not_valid() { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Table name must be lower case and contain only alphanumeric chars or '_', got '(not valid)'"); + + new DropIndexBuilder(new H2()) + .setTable("(not valid)") + .setName("issues_key") + .build(); + } + + @Test + public void throw_NPE_if_index_name_is_missing() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("Index name cannot be null"); + + new DropIndexBuilder(new H2()) + .setTable("issues") + .build(); + } + + @Test + public void throw_IAE_if_index_name_is_not_valid() { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Index name must be lower case and contain only alphanumeric chars or '_', got '(not valid)'"); + + new DropIndexBuilder(new H2()) + .setTable("issues") + .setName("(not valid)") + .build(); + } +}