From c1cd38a648edbd56f5ca928ea7e9a2a97ff1de8a Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Mon, 7 Nov 2016 16:47:19 +0100 Subject: [PATCH] SONAR-8354 Drop tables "active_dashboards", "dashboards", "widgets", "widget_properties" --- .../1420_drop_related_dashboard_tables.rb | 29 ++++++ .../main/java/org/sonar/db/DatabaseUtils.java | 24 +++++ .../org/sonar/db/version/DatabaseVersion.java | 14 +-- .../sonar/db/version/DropTableBuilder.java | 80 +++++++++++++++ .../sonar/db/version/MigrationStepModule.java | 4 +- .../v62/DropRelatedDashboardTables.java | 65 +++++++++++++ .../org/sonar/db/version/rows-h2.sql | 1 + .../org/sonar/db/version/schema-h2.ddl | 47 --------- .../src/test/java/org/sonar/db/DbTester.java | 9 ++ .../db/version/DropTableBuilderTest.java | 97 +++++++++++++++++++ .../db/version/MigrationStepModuleTest.java | 2 +- .../v62/DropRelatedDashboardTablesTest.java | 56 +++++++++++ .../DropRelatedDashboardTablesTest/schema.sql | 47 +++++++++ 13 files changed, 419 insertions(+), 56 deletions(-) create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1420_drop_related_dashboard_tables.rb create mode 100644 sonar-db/src/main/java/org/sonar/db/version/DropTableBuilder.java create mode 100644 sonar-db/src/main/java/org/sonar/db/version/v62/DropRelatedDashboardTables.java create mode 100644 sonar-db/src/test/java/org/sonar/db/version/DropTableBuilderTest.java create mode 100644 sonar-db/src/test/java/org/sonar/db/version/v62/DropRelatedDashboardTablesTest.java create mode 100644 sonar-db/src/test/resources/org/sonar/db/version/v62/DropRelatedDashboardTablesTest/schema.sql diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1420_drop_related_dashboard_tables.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1420_drop_related_dashboard_tables.rb new file mode 100644 index 00000000000..2aa2c3d81ec --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1420_drop_related_dashboard_tables.rb @@ -0,0 +1,29 @@ +# +# SonarQube, open source software quality management tool. +# Copyright (C) 2008-2014 SonarSource +# mailto:contact AT sonarsource DOT com +# +# SonarQube 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. +# +# SonarQube 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. +# + +# +# SonarQube 6.2 +# +class DropRelatedDashboardTables < ActiveRecord::Migration + + def self.up + execute_java_migration('org.sonar.db.version.v62.DropRelatedDashboardTables') + end +end diff --git a/sonar-db/src/main/java/org/sonar/db/DatabaseUtils.java b/sonar-db/src/main/java/org/sonar/db/DatabaseUtils.java index aa76ec2849d..3b837ed6321 100644 --- a/sonar-db/src/main/java/org/sonar/db/DatabaseUtils.java +++ b/sonar-db/src/main/java/org/sonar/db/DatabaseUtils.java @@ -43,6 +43,7 @@ import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import static com.google.common.collect.Lists.newArrayList; +import static java.lang.String.format; public class DatabaseUtils { @@ -293,4 +294,27 @@ public class DatabaseUtils { Timestamp t = rs.getTimestamp(columnIndex); return rs.wasNull() ? null : new Date(t.getTime()); } + + /** + * @param table case-insensitive name of table + * @return true if a table exists with this name, otherwise false + * @throws SQLException + */ + public static boolean tableExists(String table, Connection connection) { + try (ResultSet rs = connection.getMetaData().getTables(null, null, null, null)) { + while (rs.next()) { + String name = rs.getString("TABLE_NAME"); + if (table.equalsIgnoreCase(name)) { + return true; + } + } + return false; + } catch (SQLException e) { + throw wrapSqlException(e, "Can not check that table %s exists", table); + } + } + + public static IllegalStateException wrapSqlException(SQLException e, String message, Object... messageArgs) { + return new IllegalStateException(format(message, messageArgs), e); + } } diff --git a/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java b/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java index 86bd8c05b1b..3dc598bce86 100644 --- a/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java +++ b/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java @@ -30,7 +30,7 @@ import org.sonar.db.MyBatis; public class DatabaseVersion { - public static final int LAST_VERSION = 1_419; + public static final int LAST_VERSION = 1_420; /** * The minimum supported version which can be upgraded. Lower @@ -47,7 +47,11 @@ public class DatabaseVersion { * @see org.sonar.db.charset.ColumnDef#isInSonarQubeTable() */ public static final Set OLD_DROPPED_TABLES = ImmutableSet.of( - "activities"); + "active_dashboards", + "activities", + "dashboards", + "widgets", + "widget_properties"); /** * List of all the tables. @@ -55,7 +59,6 @@ public class DatabaseVersion { * for all the supported databases, particularly due to Oracle results. */ public static final Set TABLES = ImmutableSet.of( - "active_dashboards", "active_rules", "active_rule_parameters", "authors", @@ -63,7 +66,6 @@ public class DatabaseVersion { "ce_queue", "ce_task_input", "ce_scanner_context", - "dashboards", "duplications_index", "events", "file_sources", @@ -103,9 +105,7 @@ public class DatabaseVersion { "snapshots", "users", "user_roles", - "user_tokens", - "widgets", - "widget_properties"); + "user_tokens"); private MyBatis mybatis; diff --git a/sonar-db/src/main/java/org/sonar/db/version/DropTableBuilder.java b/sonar-db/src/main/java/org/sonar/db/version/DropTableBuilder.java new file mode 100644 index 00000000000..de573851f44 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/DropTableBuilder.java @@ -0,0 +1,80 @@ +/* + * 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.Oracle; + +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static java.util.Objects.requireNonNull; +import static org.sonar.db.version.Validations.TABLE_NAME_MAX_SIZE; +import static org.sonar.db.version.Validations.checkDbIdentifier; + +public class DropTableBuilder { + + private final Dialect dialect; + private final String tableName; + + public DropTableBuilder(Dialect dialect, String tableName) { + this.dialect = requireNonNull(dialect, "dialect can't be null"); + this.tableName = checkDbIdentifier(tableName, "Table name", TABLE_NAME_MAX_SIZE); + } + + public List build() { + if (Oracle.ID.equals(dialect.getId())) { + return dropOracleSequenceAndTriggerAndTableStatements(); + } + return singletonList(dropTableStatement()); + } + + private String dropTableStatement() { + return "DROP TABLE " + tableName; + } + + private List dropOracleSequenceAndTriggerAndTableStatements() { + return asList(dropSequenceFor(tableName), dropTriggerFor(tableName), dropTableStatement()); + } + + private static String dropSequenceFor(String tableName) { + return "BEGIN\n" + + " EXECUTE IMMEDIATE 'DROP SEQUENCE " + tableName + "_seq';\n" + + "EXCEPTION\n" + + " WHEN OTHERS THEN\n" + + " IF SQLCODE != -2289 THEN\n" + + " RAISE;\n" + + " END IF;\n" + + "END;"; + } + + private static String dropTriggerFor(String tableName) { + return "BEGIN\n" + + " EXECUTE IMMEDIATE 'DROP TRIGGER " + tableName + "_idt';\n" + + "EXCEPTION\n" + + " WHEN OTHERS THEN\n" + + " IF SQLCODE != -4080 THEN\n" + + " RAISE;\n" + + " END IF;\n" + + "END;"; + + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java b/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java index adf927f7a26..5e4014e7c0c 100644 --- a/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java +++ b/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java @@ -167,6 +167,7 @@ import org.sonar.db.version.v62.AddOrganizationUuidToUserRoles; import org.sonar.db.version.v62.CreateDefaultOrganization; import org.sonar.db.version.v62.CreateTableOrganizations; import org.sonar.db.version.v62.DeletePermissionShareDashboard; +import org.sonar.db.version.v62.DropRelatedDashboardTables; import org.sonar.db.version.v62.MakeOrganizationUuidNotNullOnGroupRoles; import org.sonar.db.version.v62.MakeOrganizationUuidNotNullOnGroups; import org.sonar.db.version.v62.MakeOrganizationUuidNotNullOnPermissionTemplates; @@ -376,6 +377,7 @@ public class MigrationStepModule extends Module { AddOrganizationUuidToGroupRoles.class, PopulateOrganizationUuidOfGroupRoles.class, MakeOrganizationUuidNotNullOnGroupRoles.class, - UpdateQualityGateConditionsOnCoverage.class); + UpdateQualityGateConditionsOnCoverage.class, + DropRelatedDashboardTables.class); } } diff --git a/sonar-db/src/main/java/org/sonar/db/version/v62/DropRelatedDashboardTables.java b/sonar-db/src/main/java/org/sonar/db/version/v62/DropRelatedDashboardTables.java new file mode 100644 index 00000000000..5d41a2fe848 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v62/DropRelatedDashboardTables.java @@ -0,0 +1,65 @@ +/* + * 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.v62; + +import com.google.common.collect.ImmutableList; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.List; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonar.db.Database; +import org.sonar.db.DatabaseUtils; +import org.sonar.db.version.DdlChange; +import org.sonar.db.version.DropTableBuilder; + +import static org.sonar.core.util.stream.Collectors.toList; + +public class DropRelatedDashboardTables extends DdlChange { + + private static final Logger LOGGER = Loggers.get(DropRelatedDashboardTables.class); + + private static final List TABLES_TO_DROP = ImmutableList.of("widget_properties", "widgets", "active_dashboards", "dashboards"); + + private final Database db; + + public DropRelatedDashboardTables(Database db) { + super(db); + this.db = db; + } + + @Override + public void execute(Context context) throws SQLException { + List tablesToDrop = getEffectiveTablesToDrop(); + LOGGER.info("Removing tables {}", tablesToDrop); + context.execute(tablesToDrop + .stream() + .flatMap(table -> new DropTableBuilder(db.getDialect(), table).build().stream()) + .collect(toList())); + } + + private List getEffectiveTablesToDrop() throws SQLException { + try (Connection connection = db.getDataSource().getConnection()) { + return TABLES_TO_DROP.stream() + .filter(table -> DatabaseUtils.tableExists(table, connection)) + .collect(toList()); + } + } +} diff --git a/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql b/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql index 4863aba48cd..31346602831 100644 --- a/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql +++ b/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql @@ -508,6 +508,7 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1416'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1417'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1418'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1419'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1420'); INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, EXTERNAL_IDENTITY, EXTERNAL_IDENTITY_PROVIDER, USER_LOCAL, CRYPTED_PASSWORD, SALT, IS_ROOT, CREATED_AT, UPDATED_AT) VALUES (1, 'admin', 'Administrator', '', 'admin', 'sonarqube', true, 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', true, '1418215735482', '1418215735482'); ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2; diff --git a/sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl b/sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl index e1c7c789984..a98df497e24 100644 --- a/sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl +++ b/sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl @@ -56,22 +56,6 @@ CREATE TABLE "PROJECT_QPROFILES" ( CREATE UNIQUE INDEX "UNIQ_PROJECT_QPROFILES" ON "PROJECT_QPROFILES" ("PROJECT_UUID", "PROFILE_KEY"); -CREATE TABLE "WIDGETS" ( - "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), - "DASHBOARD_ID" INTEGER NOT NULL, - "WIDGET_KEY" VARCHAR(256) NOT NULL, - "NAME" VARCHAR(256), - "DESCRIPTION" VARCHAR(1000), - "COLUMN_INDEX" INTEGER, - "ROW_INDEX" INTEGER, - "CONFIGURED" BOOLEAN, - "CREATED_AT" TIMESTAMP, - "UPDATED_AT" TIMESTAMP, - "RESOURCE_ID" INTEGER -); -CREATE INDEX "WIDGETS_WIDGETKEY" ON "WIDGETS" ("WIDGET_KEY"); -CREATE INDEX "WIDGETS_DASHBOARDS" ON "WIDGETS" ("DASHBOARD_ID"); - CREATE TABLE "GROUPS" ( "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), @@ -171,15 +155,6 @@ CREATE TABLE "RULES" ( CREATE UNIQUE INDEX "RULES_REPO_KEY" ON "RULES" ("PLUGIN_NAME", "PLUGIN_RULE_KEY"); -CREATE TABLE "WIDGET_PROPERTIES" ( - "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), - "WIDGET_ID" INTEGER NOT NULL, - "KEE" VARCHAR(100), - "TEXT_VALUE" VARCHAR(4000) -); -CREATE INDEX "WIDGET_PROPERTIES_WIDGETS" ON "WIDGET_PROPERTIES" ("WIDGET_ID"); - - CREATE TABLE "EVENTS" ( "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), "NAME" VARCHAR(400), @@ -371,16 +346,6 @@ CREATE INDEX "USER_ROLES_RESOURCE" ON "USER_ROLES" ("RESOURCE_ID"); CREATE INDEX "USER_ROLES_USER" ON "USER_ROLES" ("USER_ID"); -CREATE TABLE "ACTIVE_DASHBOARDS" ( - "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), - "DASHBOARD_ID" INTEGER NOT NULL, - "USER_ID" INTEGER, - "ORDER_INDEX" INTEGER -); -CREATE INDEX "ACTIVE_DASHBOARDS_DASHBOARDID" ON "ACTIVE_DASHBOARDS" ("DASHBOARD_ID"); -CREATE INDEX "ACTIVE_DASHBOARDS_USERID" ON "ACTIVE_DASHBOARDS" ("USER_ID"); - - CREATE TABLE "ACTIVE_RULE_PARAMETERS" ( "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), "ACTIVE_RULE_ID" INTEGER NOT NULL, @@ -410,18 +375,6 @@ CREATE UNIQUE INDEX "USERS_LOGIN" ON "USERS" ("LOGIN"); CREATE INDEX "USERS_UPDATED_AT" ON "USERS" ("UPDATED_AT"); -CREATE TABLE "DASHBOARDS" ( - "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), - "USER_ID" INTEGER, - "NAME" VARCHAR(256), - "DESCRIPTION" VARCHAR(1000), - "COLUMN_LAYOUT" VARCHAR(20), - "SHARED" BOOLEAN, - "CREATED_AT" TIMESTAMP, - "UPDATED_AT" TIMESTAMP -); - - CREATE TABLE "METRICS" ( "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), "NAME" VARCHAR(64) NOT NULL, 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 8a475b5de57..2f0e95ec461 100644 --- a/sonar-db/src/test/java/org/sonar/db/DbTester.java +++ b/sonar-db/src/test/java/org/sonar/db/DbTester.java @@ -510,6 +510,15 @@ public class DbTester extends ExternalResource { } } + public void assertTableDoesNotExist(String table) { + try (Connection connection = getConnection()) { + boolean tableExists = DatabaseUtils.tableExists(table, connection); + assertThat(tableExists).isFalse(); + } catch (Exception e) { + throw new IllegalStateException("Fail to check if table exists", 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/DropTableBuilderTest.java b/sonar-db/src/test/java/org/sonar/db/version/DropTableBuilderTest.java new file mode 100644 index 00000000000..918dcbd28fa --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/DropTableBuilderTest.java @@ -0,0 +1,97 @@ +/* + * 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 org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +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 DropTableBuilderTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void drop_tables_on_mysql() { + assertThat(new DropTableBuilder(new MySql(), "issues") + .build()).containsOnly("DROP TABLE issues"); + } + + @Test + public void drop_tables_on_postgresql() { + assertThat(new DropTableBuilder(new PostgreSql(), "issues") + .build()).containsOnly("DROP TABLE issues"); + } + + @Test + public void drop_tables_on_mssql() { + assertThat(new DropTableBuilder(new MsSql(), "issues") + .build()).containsOnly("DROP TABLE issues"); + } + + @Test + public void drop_tables_on_h2() { + assertThat(new DropTableBuilder(new H2(), "issues") + .build()).containsOnly("DROP TABLE issues"); + } + + @Test + public void drop_columns_on_oracle() { + assertThat(new DropTableBuilder(new Oracle(), "issues") + .build()).containsExactly( + "BEGIN\n" + + " EXECUTE IMMEDIATE 'DROP SEQUENCE issues_seq';\n" + + "EXCEPTION\n" + + " WHEN OTHERS THEN\n" + + " IF SQLCODE != -2289 THEN\n" + + " RAISE;\n" + + " END IF;\n" + + "END;", + "BEGIN\n" + + " EXECUTE IMMEDIATE 'DROP TRIGGER issues_idt';\n" + + "EXCEPTION\n" + + " WHEN OTHERS THEN\n" + + " IF SQLCODE != -4080 THEN\n" + + " RAISE;\n" + + " END IF;\n" + + "END;", + "DROP TABLE issues"); + } + + @Test + public void fail_when_dialect_is_null() throws Exception { + expectedException.expect(NullPointerException.class); + new DropTableBuilder(null, "issues"); + } + + @Test + public void fail_when_table_is_null() throws Exception { + expectedException.expect(NullPointerException.class); + new DropTableBuilder(new PostgreSql(), null); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java b/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java index 70eaab00ab7..700344fb7a7 100644 --- a/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java +++ b/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java @@ -29,6 +29,6 @@ public class MigrationStepModuleTest { public void verify_count_of_added_MigrationStep_types() { ComponentContainer container = new ComponentContainer(); new MigrationStepModule().configure(container); - assertThat(container.size()).isEqualTo(160); + assertThat(container.size()).isEqualTo(161); } } diff --git a/sonar-db/src/test/java/org/sonar/db/version/v62/DropRelatedDashboardTablesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v62/DropRelatedDashboardTablesTest.java new file mode 100644 index 00000000000..7d8fd690e85 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v62/DropRelatedDashboardTablesTest.java @@ -0,0 +1,56 @@ +/* + * 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.v62; + +import java.sql.SQLException; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; + +public class DropRelatedDashboardTablesTest { + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, DropRelatedDashboardTablesTest.class, "schema.sql"); + + private DropRelatedDashboardTables underTest = new DropRelatedDashboardTables(db.database()); + + @Test + public void delete_tables() throws SQLException { + underTest.execute(); + + db.assertTableDoesNotExist("widget_properties"); + db.assertTableDoesNotExist("widgets"); + db.assertTableDoesNotExist("active_dashboards"); + db.assertTableDoesNotExist("dashboards"); + } + + @Test + public void migration_is_re_entrant() throws Exception { + underTest.execute(); + underTest.execute(); + + db.assertTableDoesNotExist("widget_properties"); + db.assertTableDoesNotExist("widgets"); + db.assertTableDoesNotExist("active_dashboards"); + db.assertTableDoesNotExist("dashboards"); + } +} diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v62/DropRelatedDashboardTablesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v62/DropRelatedDashboardTablesTest/schema.sql new file mode 100644 index 00000000000..6456acc22fd --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v62/DropRelatedDashboardTablesTest/schema.sql @@ -0,0 +1,47 @@ +CREATE TABLE "ACTIVE_DASHBOARDS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "DASHBOARD_ID" INTEGER NOT NULL, + "USER_ID" INTEGER, + "ORDER_INDEX" INTEGER +); +CREATE INDEX "ACTIVE_DASHBOARDS_DASHBOARDID" ON "ACTIVE_DASHBOARDS" ("DASHBOARD_ID"); +CREATE INDEX "ACTIVE_DASHBOARDS_USERID" ON "ACTIVE_DASHBOARDS" ("USER_ID"); + + +CREATE TABLE "DASHBOARDS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "USER_ID" INTEGER, + "NAME" VARCHAR(256), + "DESCRIPTION" VARCHAR(1000), + "COLUMN_LAYOUT" VARCHAR(20), + "SHARED" BOOLEAN, + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP +); + +CREATE TABLE "WIDGETS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "DASHBOARD_ID" INTEGER NOT NULL, + "WIDGET_KEY" VARCHAR(256) NOT NULL, + "NAME" VARCHAR(256), + "DESCRIPTION" VARCHAR(1000), + "COLUMN_INDEX" INTEGER, + "ROW_INDEX" INTEGER, + "CONFIGURED" BOOLEAN, + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP, + "RESOURCE_ID" INTEGER +); +CREATE INDEX "WIDGETS_WIDGETKEY" ON "WIDGETS" ("WIDGET_KEY"); +CREATE INDEX "WIDGETS_DASHBOARDS" ON "WIDGETS" ("DASHBOARD_ID"); + + +CREATE TABLE "WIDGET_PROPERTIES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "WIDGET_ID" INTEGER NOT NULL, + "KEE" VARCHAR(100), + "TEXT_VALUE" VARCHAR(4000) +); +CREATE INDEX "WIDGET_PROPERTIES_WIDGETS" ON "WIDGET_PROPERTIES" ("WIDGET_ID"); + + -- 2.39.5