"SHORT_NAME" VARCHAR(64),
"QUALITATIVE" BOOLEAN DEFAULT FALSE NOT NULL,
"VAL_TYPE" VARCHAR(8),
- "USER_MANAGED" BOOLEAN DEFAULT FALSE,
"ENABLED" BOOLEAN DEFAULT TRUE,
"WORST_VALUE" DOUBLE,
"BEST_VALUE" DOUBLE,
import org.sonar.server.platform.db.migration.step.MigrationStepRegistry;
import org.sonar.server.platform.db.migration.version.DbVersion;
-import org.sonar.server.platform.db.migration.version.v90.AddPrimaryKeyOnKeeColumnOfIssuesTable;
-import org.sonar.server.platform.db.migration.version.v90.AddPrimaryKeyOnUuidColumnOfCeActivityTable;
-import org.sonar.server.platform.db.migration.version.v90.AddPrimaryKeyOnUuidColumnOfEventsTable;
-import org.sonar.server.platform.db.migration.version.v90.AddPrimaryKeyOnUuidColumnOfSnapshotsTable;
-import org.sonar.server.platform.db.migration.version.v90.DropAnalysesUuidIndex;
-import org.sonar.server.platform.db.migration.version.v90.DropCeActivityUuidIndex;
-import org.sonar.server.platform.db.migration.version.v90.DropEventsUuidIndex;
-import org.sonar.server.platform.db.migration.version.v90.DropIssuesKeeIndex;
-import org.sonar.server.platform.db.migration.version.v90.DropPrimaryKeyOnKeeColumnOfIssuesTable;
-import org.sonar.server.platform.db.migration.version.v90.DropPrimaryKeyOnUuidColumnOfCeActivityTable;
-import org.sonar.server.platform.db.migration.version.v90.DropPrimaryKeyOnUuidColumnOfEventsTable;
-import org.sonar.server.platform.db.migration.version.v90.DropPrimaryKeyOnUuidColumnOfSnapshotsTable;
public class DbVersion91 implements DbVersion {
@Override
public void addSteps(MigrationStepRegistry registry) {
registry
.add(6001, "Drop 'manual_measures_component_uuid' index", DropManualMeasuresComponentUuidIndex.class)
- .add(6002, "Drop 'manual_measures' table", DropManualMeasuresTable.class);
+ .add(6002, "Drop 'manual_measures' table", DropManualMeasuresTable.class)
+ .add(6003, "Drop custom metrics data from 'live_measures' table", DropCustomMetricsLiveMeasuresData.class)
+ .add(6004, "Drop custom metrics data from 'project_measures' table", DropCustomMetricsProjectMeasuresData.class)
+ .add(6005, "Drop custom metrics data from 'metrics' table", DropUserManagedMetricsData.class)
+ .add(6006, "Drop 'user_managed' column from 'metrics' table", DropUserManagedColumnFromMetricsTable.class);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info 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.server.platform.db.migration.version.v91;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DataChange;
+
+abstract class DropCustomMetricsData extends DataChange {
+
+ DropCustomMetricsData(Database db) {
+ super(db);
+ }
+
+ @Override
+ protected void execute(Context context) throws SQLException {
+ var massUpdate = context.prepareMassUpdate();
+ massUpdate.select(selectQuery()).setBoolean(1, true);
+ massUpdate.update(updateQuery());
+
+ massUpdate.execute((row, update) -> {
+ update.setString(1, row.getString(1));
+ return true;
+ });
+ }
+
+ abstract String selectQuery();
+
+ abstract String updateQuery();
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info 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.server.platform.db.migration.version.v91;
+
+import org.sonar.db.Database;
+
+public class DropCustomMetricsLiveMeasuresData extends DropCustomMetricsData {
+
+ public DropCustomMetricsLiveMeasuresData(Database db) {
+ super(db);
+ }
+
+ @Override
+ String selectQuery() {
+ return "SELECT lm.uuid FROM metrics m join live_measures lm ON m.uuid = lm.metric_uuid WHERE m.user_managed = ?";
+ }
+
+ @Override
+ String updateQuery() {
+ return "DELETE FROM live_measures WHERE uuid = ?";
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info 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.server.platform.db.migration.version.v91;
+
+import org.sonar.db.Database;
+
+public class DropCustomMetricsProjectMeasuresData extends DropCustomMetricsData {
+
+ public DropCustomMetricsProjectMeasuresData(Database db) {
+ super(db);
+ }
+
+ @Override
+ String selectQuery() {
+ return "SELECT pm.uuid FROM metrics m JOIN project_measures pm ON m.uuid = pm.metric_uuid WHERE m.user_managed = ?";
+ }
+
+ @Override
+ String updateQuery() {
+ return "DELETE FROM project_measures WHERE uuid = ?";
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info 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.server.platform.db.migration.version.v91;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.DropMsSQLDefaultConstraintsBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public class DropUserManagedColumnFromMetricsTable extends DdlChange {
+
+ private static final String TABLE_NAME = "metrics";
+ private static final String COLUMN = "user_managed";
+
+ private final Database db;
+
+ public DropUserManagedColumnFromMetricsTable(Database db) {
+ super(db);
+ this.db = db;
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ if (MsSql.ID.equals(db.getDialect().getId())) {
+ context.execute(new DropMsSQLDefaultConstraintsBuilder(db).setTable(TABLE_NAME).setColumns(COLUMN).build());
+ }
+ context.execute(new DropColumnsBuilder(db.getDialect(), TABLE_NAME, COLUMN).build());
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info 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.server.platform.db.migration.version.v91;
+
+import org.sonar.db.Database;
+
+public class DropUserManagedMetricsData extends DropCustomMetricsData {
+
+ public DropUserManagedMetricsData(Database db) {
+ super(db);
+ }
+
+ @Override
+ String selectQuery() {
+ return "SELECT m.uuid FROM metrics m WHERE m.user_managed = ?";
+ }
+
+ @Override
+ String updateQuery() {
+ return "DELETE FROM metrics WHERE uuid = ?";
+ }
+}
@Test
public void verify_migration_count() {
- verifyMigrationCount(underTest, 2);
+ verifyMigrationCount(underTest, 6);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info 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.server.platform.db.migration.version.v91;
+
+import java.sql.SQLException;
+import java.util.stream.Collectors;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.DataChange;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+
+public class DropCustomMetricsLiveMeasuresDataTest {
+ private final UuidFactory uuidFactory = UuidFactoryFast.getInstance();
+
+ @Rule
+ public final CoreDbTester db = CoreDbTester.createForSchema(DropCustomMetricsLiveMeasuresDataTest.class, "schema.sql");
+
+ private final DataChange underTest = new DropCustomMetricsLiveMeasuresData(db.database());
+
+ @Test
+ public void do_not_fail_if_no_rows_to_delete() {
+ assertThatCode(underTest::execute)
+ .doesNotThrowAnyException();
+ }
+
+ @Test
+ public void delete_user_managed_live_measures_when_other_measures_exist() throws SQLException {
+ insertMetric("metric-1", true);
+ insertMetric("metric-2", true);
+ insertMetric("metric-3", false);
+
+ insertLiveMeasure("lm-1", "metric-1");
+ insertLiveMeasure("lm-2", "metric-1");
+ insertLiveMeasure("lm-3", "metric-2");
+ insertLiveMeasure("lm-4", "metric-2");
+ insertLiveMeasure("lm-5", "metric-3");
+ insertLiveMeasure("lm-6", "metric-3");
+
+ underTest.execute();
+
+ // re-entrant
+ underTest.execute();
+
+ assertThat(db.select("select uuid from live_measures").stream().map(row -> row.get("UUID")).collect(Collectors.toList()))
+ .containsExactlyInAnyOrder("lm-5", "lm-6");
+ }
+
+ @Test
+ public void migration_is_reentrant() throws SQLException {
+ insertMetric("metric-1", true);
+ insertMetric("metric-2", true);
+ insertMetric("metric-3", false);
+
+ insertLiveMeasure("lm-1", "metric-1");
+ insertLiveMeasure("lm-2", "metric-1");
+ insertLiveMeasure("lm-3", "metric-2");
+ insertLiveMeasure("lm-4", "metric-2");
+ insertLiveMeasure("lm-5", "metric-3");
+ insertLiveMeasure("lm-6", "metric-3");
+
+ underTest.execute();
+
+ // re-entrant
+ underTest.execute();
+
+ assertThat(db.select("select uuid from live_measures").stream().map(row -> row.get("UUID")).collect(Collectors.toList()))
+ .containsExactlyInAnyOrder("lm-5", "lm-6");
+ }
+
+ @Test
+ public void delete_user_managed_metrics() throws SQLException {
+ insertMetric("metric-1", true);
+ insertMetric("metric-2", true);
+
+ insertLiveMeasure("lm-1", "metric-1");
+ insertLiveMeasure("lm-2", "metric-1");
+ insertLiveMeasure("lm-3", "metric-2");
+ insertLiveMeasure("lm-4", "metric-2");
+
+ underTest.execute();
+
+ // re-entrant
+ underTest.execute();
+
+ assertThat(db.select("select uuid from live_measures").stream().map(row -> row.get("UUID")).collect(Collectors.toList()))
+ .isEmpty();
+ }
+
+ @Test
+ public void do_not_fail_if_no_user_managed_rows_to_delete() throws SQLException {
+ insertMetric("metric-1", false);
+ insertMetric("metric-2", false);
+
+ insertLiveMeasure("lm-1", "metric-1");
+ insertLiveMeasure("lm-2", "metric-1");
+ insertLiveMeasure("lm-3", "metric-2");
+ insertLiveMeasure("lm-4", "metric-2");
+
+ underTest.execute();
+
+ assertThat(db.select("select uuid from live_measures").stream().map(row -> row.get("UUID")).collect(Collectors.toList()))
+ .containsExactlyInAnyOrder("lm-1", "lm-2", "lm-3", "lm-4");
+ }
+
+ private void insertLiveMeasure(String uuid, String metricUuid) {
+ db.executeInsert("live_measures",
+ "UUID", uuid,
+ "PROJECT_UUID", uuidFactory.create(),
+ "COMPONENT_UUID", uuidFactory.create(),
+ "METRIC_UUID", metricUuid,
+ "CREATED_AT", System.currentTimeMillis(),
+ "UPDATED_AT", System.currentTimeMillis());
+ }
+
+ private void insertMetric(String uuid, boolean userManaged) {
+ db.executeInsert("metrics",
+ "UUID", uuid,
+ "NAME", "name-" + uuid,
+ "USER_MANAGED", String.valueOf(userManaged));
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info 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.server.platform.db.migration.version.v91;
+
+import java.sql.SQLException;
+import java.util.stream.Collectors;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.DataChange;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+
+public class DropCustomMetricsProjectMeasuresDataTest {
+ private final UuidFactory uuidFactory = UuidFactoryFast.getInstance();
+
+ @Rule
+ public final CoreDbTester db = CoreDbTester.createForSchema(DropCustomMetricsProjectMeasuresDataTest.class, "schema.sql");
+
+ private final DataChange underTest = new DropCustomMetricsProjectMeasuresData(db.database());
+
+ @Test
+ public void do_not_fail_if_no_rows_to_delete() {
+ assertThatCode(underTest::execute)
+ .doesNotThrowAnyException();
+ }
+
+ @Test
+ public void delete_user_managed_project_measures_when_other_measures_exist() throws SQLException {
+ insertMetric("metric-1", true);
+ insertMetric("metric-2", true);
+ insertMetric("metric-3", false);
+
+ insertProjectMeasure("pm-1", "metric-1");
+ insertProjectMeasure("pm-2", "metric-1");
+ insertProjectMeasure("pm-3", "metric-2");
+ insertProjectMeasure("pm-4", "metric-2");
+ insertProjectMeasure("pm-5", "metric-3");
+ insertProjectMeasure("pm-6", "metric-3");
+
+ underTest.execute();
+
+ // re-entrant
+ underTest.execute();
+
+ assertThat(db.select("select uuid from project_measures").stream().map(row -> row.get("UUID")).collect(Collectors.toList()))
+ .containsExactlyInAnyOrder("pm-5", "pm-6");
+ }
+
+ @Test
+ public void migration_is_reentrant() throws SQLException {
+ insertMetric("metric-1", true);
+ insertMetric("metric-2", true);
+ insertMetric("metric-3", false);
+
+ insertProjectMeasure("pm-1", "metric-1");
+ insertProjectMeasure("pm-2", "metric-1");
+ insertProjectMeasure("pm-3", "metric-2");
+ insertProjectMeasure("pm-4", "metric-2");
+ insertProjectMeasure("pm-5", "metric-3");
+ insertProjectMeasure("pm-6", "metric-3");
+
+ underTest.execute();
+
+ // re-entrant
+ underTest.execute();
+
+ assertThat(db.select("select uuid from project_measures").stream().map(row -> row.get("UUID")).collect(Collectors.toList()))
+ .containsExactlyInAnyOrder("pm-5", "pm-6");
+ }
+
+ @Test
+ public void delete_user_managed_measures() throws SQLException {
+ insertMetric("metric-1", true);
+ insertMetric("metric-2", true);
+
+ insertProjectMeasure("pm-1", "metric-1");
+ insertProjectMeasure("pm-2", "metric-1");
+ insertProjectMeasure("pm-3", "metric-2");
+ insertProjectMeasure("pm-4", "metric-2");
+
+ underTest.execute();
+
+ // re-entrant
+ underTest.execute();
+
+ assertThat(db.select("select uuid from project_measures").stream().map(row -> row.get("UUID")).collect(Collectors.toList()))
+ .isEmpty();
+ }
+
+ @Test
+ public void do_not_fail_if_no_user_managed_rows_to_delete() throws SQLException {
+ insertMetric("metric-1", false);
+ insertMetric("metric-2", false);
+
+ insertProjectMeasure("pm-1", "metric-1");
+ insertProjectMeasure("pm-2", "metric-1");
+ insertProjectMeasure("pm-3", "metric-2");
+ insertProjectMeasure("pm-4", "metric-2");
+
+ underTest.execute();
+
+ assertThat(db.select("select uuid from project_measures").stream().map(row -> row.get("UUID")).collect(Collectors.toList()))
+ .containsExactlyInAnyOrder("pm-1", "pm-2", "pm-3", "pm-4");
+ }
+
+ private void insertProjectMeasure(String uuid, String metricUuid) {
+ db.executeInsert("project_measures",
+ "UUID", uuid,
+ "ANALYSIS_UUID", uuidFactory.create(),
+ "COMPONENT_UUID", uuidFactory.create(),
+ "METRIC_UUID", metricUuid);
+ }
+
+ private void insertMetric(String uuid, boolean userManaged) {
+ db.executeInsert("metrics",
+ "UUID", uuid,
+ "NAME", "name-" + uuid,
+ "USER_MANAGED", String.valueOf(userManaged));
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info 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.server.platform.db.migration.version.v91;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public class DropUserManagedColumnFromMetricsTableTest {
+ private static final String COLUMN_NAME = "user_managed";
+ private static final String TABLE_NAME = "metrics";
+
+ @Rule
+ public final CoreDbTester db = CoreDbTester.createForSchema(DropUserManagedColumnFromMetricsTableTest.class, "schema.sql");
+
+ private final DdlChange underTest = new DropUserManagedColumnFromMetricsTable(db.database());
+
+ @Test
+ public void migration_should_drop_unique_index_on_manual_measures() throws SQLException {
+ db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.BOOLEAN, null, true);
+ underTest.execute();
+ db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info 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.server.platform.db.migration.version.v91;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.DataChange;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+
+public class DropUserManagedMetricsDataTest {
+ private static final String TABLE_NAME = "metrics";
+
+ @Rule
+ public final CoreDbTester db = CoreDbTester.createForSchema(DropUserManagedMetricsDataTest.class, "schema.sql");
+
+ private final DataChange underTest = new DropUserManagedMetricsData(db.database());
+
+ @Test
+ public void do_not_fail_if_no_rows_to_delete() {
+ assertThatCode(underTest::execute)
+ .doesNotThrowAnyException();
+ }
+
+ @Test
+ public void delete_user_managed_metrics_when_other_metrics_exist() throws SQLException {
+ insertMetric("1", false);
+ insertMetric("2", false);
+ insertMetric("3", false);
+
+ insertMetric("4", true);
+ insertMetric("5", true);
+ insertMetric("6", true);
+
+ underTest.execute();
+
+ assertThat(db.countSql("select count(*) from metrics where user_managed = false")).isEqualTo(3);
+ assertThat(db.countSql("select count(*) from metrics where user_managed = true")).isZero();
+ }
+
+ @Test
+ public void migration_is_reentrant() throws SQLException {
+ insertMetric("1", false);
+ insertMetric("2", false);
+ insertMetric("3", false);
+
+ insertMetric("4", true);
+ insertMetric("5", true);
+ insertMetric("6", true);
+
+ underTest.execute();
+
+ // re-entrant
+ underTest.execute();
+
+ assertThat(db.countSql("select count(*) from metrics where user_managed = false")).isEqualTo(3);
+ assertThat(db.countSql("select count(*) from metrics where user_managed = true")).isZero();
+ }
+
+ @Test
+ public void delete_user_managed_metrics() throws SQLException {
+ insertMetric("1", true);
+ insertMetric("2", true);
+ insertMetric("3", true);
+
+ underTest.execute();
+
+ assertThat(db.countRowsOfTable(TABLE_NAME)).isZero();
+ }
+
+ @Test
+ public void do_not_fail_if_no_user_managed_rows_to_delete() throws SQLException {
+ insertMetric("1", false);
+ insertMetric("2", false);
+ insertMetric("3", false);
+
+ underTest.execute();
+
+ assertThat(db.countRowsOfTable(TABLE_NAME)).isEqualTo(3);
+ }
+
+ private void insertMetric(String uuid, boolean userManaged) {
+ db.executeInsert(TABLE_NAME,
+ "UUID", uuid,
+ "NAME", "name-" + uuid,
+ "USER_MANAGED", String.valueOf(userManaged));
+ }
+
+}
--- /dev/null
+CREATE TABLE "METRICS"(
+ "UUID" VARCHAR(40) NOT NULL,
+ "NAME" VARCHAR(64) NOT NULL,
+ "DESCRIPTION" VARCHAR(255),
+ "DIRECTION" INTEGER DEFAULT 0 NOT NULL,
+ "DOMAIN" VARCHAR(64),
+ "SHORT_NAME" VARCHAR(64),
+ "QUALITATIVE" BOOLEAN DEFAULT FALSE NOT NULL,
+ "VAL_TYPE" VARCHAR(8),
+ "USER_MANAGED" BOOLEAN DEFAULT FALSE,
+ "ENABLED" BOOLEAN DEFAULT TRUE,
+ "WORST_VALUE" DOUBLE,
+ "BEST_VALUE" DOUBLE,
+ "OPTIMIZED_BEST_VALUE" BOOLEAN,
+ "HIDDEN" BOOLEAN,
+ "DELETE_HISTORICAL_DATA" BOOLEAN,
+ "DECIMAL_SCALE" INTEGER
+);
+ALTER TABLE "METRICS" ADD CONSTRAINT "PK_METRICS" PRIMARY KEY("UUID");
+CREATE UNIQUE INDEX "METRICS_UNIQUE_NAME" ON "METRICS"("NAME");
+
+CREATE TABLE "LIVE_MEASURES"(
+ "UUID" VARCHAR(40) NOT NULL,
+ "PROJECT_UUID" VARCHAR(50) NOT NULL,
+ "COMPONENT_UUID" VARCHAR(50) NOT NULL,
+ "METRIC_UUID" VARCHAR(40) NOT NULL,
+ "VALUE" DOUBLE,
+ "TEXT_VALUE" VARCHAR(4000),
+ "VARIATION" DOUBLE,
+ "MEASURE_DATA" BLOB,
+ "UPDATE_MARKER" VARCHAR(40),
+ "CREATED_AT" BIGINT NOT NULL,
+ "UPDATED_AT" BIGINT NOT NULL
+);
+ALTER TABLE "LIVE_MEASURES" ADD CONSTRAINT "PK_LIVE_MEASURES" PRIMARY KEY("UUID");
+CREATE INDEX "LIVE_MEASURES_PROJECT" ON "LIVE_MEASURES"("PROJECT_UUID");
+CREATE UNIQUE INDEX "LIVE_MEASURES_COMPONENT" ON "LIVE_MEASURES"("COMPONENT_UUID", "METRIC_UUID");
--- /dev/null
+CREATE TABLE "METRICS"(
+ "UUID" VARCHAR(40) NOT NULL,
+ "NAME" VARCHAR(64) NOT NULL,
+ "DESCRIPTION" VARCHAR(255),
+ "DIRECTION" INTEGER DEFAULT 0 NOT NULL,
+ "DOMAIN" VARCHAR(64),
+ "SHORT_NAME" VARCHAR(64),
+ "QUALITATIVE" BOOLEAN DEFAULT FALSE NOT NULL,
+ "VAL_TYPE" VARCHAR(8),
+ "USER_MANAGED" BOOLEAN DEFAULT FALSE,
+ "ENABLED" BOOLEAN DEFAULT TRUE,
+ "WORST_VALUE" DOUBLE,
+ "BEST_VALUE" DOUBLE,
+ "OPTIMIZED_BEST_VALUE" BOOLEAN,
+ "HIDDEN" BOOLEAN,
+ "DELETE_HISTORICAL_DATA" BOOLEAN,
+ "DECIMAL_SCALE" INTEGER
+);
+ALTER TABLE "METRICS" ADD CONSTRAINT "PK_METRICS" PRIMARY KEY("UUID");
+CREATE UNIQUE INDEX "METRICS_UNIQUE_NAME" ON "METRICS"("NAME");
+
+CREATE TABLE "PROJECT_MEASURES"(
+ "UUID" VARCHAR(40) NOT NULL,
+ "VALUE" DOUBLE,
+ "ANALYSIS_UUID" VARCHAR(50) NOT NULL,
+ "COMPONENT_UUID" VARCHAR(50) NOT NULL,
+ "TEXT_VALUE" VARCHAR(4000),
+ "ALERT_STATUS" VARCHAR(5),
+ "ALERT_TEXT" VARCHAR(4000),
+ "PERSON_ID" INTEGER,
+ "VARIATION_VALUE_1" DOUBLE,
+ "MEASURE_DATA" BLOB,
+ "METRIC_UUID" VARCHAR(40) NOT NULL
+);
+ALTER TABLE "PROJECT_MEASURES" ADD CONSTRAINT "PK_PROJECT_MEASURES" PRIMARY KEY("UUID");
+CREATE INDEX "MEASURES_COMPONENT_UUID" ON "PROJECT_MEASURES"("COMPONENT_UUID");
+CREATE INDEX "MEASURES_ANALYSIS_METRIC" ON "PROJECT_MEASURES"("ANALYSIS_UUID", "METRIC_UUID");
+CREATE INDEX "PROJECT_MEASURES_METRIC" ON "PROJECT_MEASURES"("METRIC_UUID");
--- /dev/null
+CREATE TABLE "METRICS"(
+ "UUID" VARCHAR(40) NOT NULL,
+ "NAME" VARCHAR(64) NOT NULL,
+ "DESCRIPTION" VARCHAR(255),
+ "DIRECTION" INTEGER DEFAULT 0 NOT NULL,
+ "DOMAIN" VARCHAR(64),
+ "SHORT_NAME" VARCHAR(64),
+ "QUALITATIVE" BOOLEAN DEFAULT FALSE NOT NULL,
+ "VAL_TYPE" VARCHAR(8),
+ "USER_MANAGED" BOOLEAN DEFAULT FALSE,
+ "ENABLED" BOOLEAN DEFAULT TRUE,
+ "WORST_VALUE" DOUBLE,
+ "BEST_VALUE" DOUBLE,
+ "OPTIMIZED_BEST_VALUE" BOOLEAN,
+ "HIDDEN" BOOLEAN,
+ "DELETE_HISTORICAL_DATA" BOOLEAN,
+ "DECIMAL_SCALE" INTEGER
+);
+ALTER TABLE "METRICS" ADD CONSTRAINT "PK_METRICS" PRIMARY KEY("UUID");
+CREATE UNIQUE INDEX "METRICS_UNIQUE_NAME" ON "METRICS"("NAME");
--- /dev/null
+CREATE TABLE "METRICS"(
+ "UUID" VARCHAR(40) NOT NULL,
+ "NAME" VARCHAR(64) NOT NULL,
+ "DESCRIPTION" VARCHAR(255),
+ "DIRECTION" INTEGER DEFAULT 0 NOT NULL,
+ "DOMAIN" VARCHAR(64),
+ "SHORT_NAME" VARCHAR(64),
+ "QUALITATIVE" BOOLEAN DEFAULT FALSE NOT NULL,
+ "VAL_TYPE" VARCHAR(8),
+ "USER_MANAGED" BOOLEAN DEFAULT FALSE,
+ "ENABLED" BOOLEAN DEFAULT TRUE,
+ "WORST_VALUE" DOUBLE,
+ "BEST_VALUE" DOUBLE,
+ "OPTIMIZED_BEST_VALUE" BOOLEAN,
+ "HIDDEN" BOOLEAN,
+ "DELETE_HISTORICAL_DATA" BOOLEAN,
+ "DECIMAL_SCALE" INTEGER
+);
+ALTER TABLE "METRICS" ADD CONSTRAINT "PK_METRICS" PRIMARY KEY("UUID");
+CREATE UNIQUE INDEX "METRICS_UNIQUE_NAME" ON "METRICS"("NAME");