]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10762 Drop custom metrics and measures data from tables: `metrics`, 'project_me...
authorJacek <jacek.poreda@sonarsource.com>
Fri, 2 Jul 2021 11:49:34 +0000 (13:49 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 7 Jul 2021 20:03:25 +0000 (20:03 +0000)
16 files changed:
server/sonar-db-dao/src/schema/schema-sq.ddl
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DbVersion91.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsData.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsLiveMeasuresData.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsProjectMeasuresData.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedColumnFromMetricsTable.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedMetricsData.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v91/DbVersion91Test.java
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsLiveMeasuresDataTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsProjectMeasuresDataTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedColumnFromMetricsTableTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedMetricsDataTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsLiveMeasuresDataTest/schema.sql [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsProjectMeasuresDataTest/schema.sql [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v91/DropUserManagedColumnFromMetricsTableTest/schema.sql [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v91/DropUserManagedMetricsDataTest/schema.sql [new file with mode: 0644]

index d191de19b5ad88edf5c71fe08e09866026facd6c..03dd4fd18ceaf5b7994221388fbca6a46c4dd694 100644 (file)
@@ -451,7 +451,6 @@ CREATE TABLE "METRICS"(
     "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,
index fa8e898ffe8f87d158cd5aedba19dbd0f12341e8..00be71d3e325fa8d5090ced9d5b4351b4ebc5e82 100644 (file)
@@ -21,24 +21,16 @@ package org.sonar.server.platform.db.migration.version.v91;
 
 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);
   }
 }
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsData.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsData.java
new file mode 100644 (file)
index 0000000..c1036f8
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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();
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsLiveMeasuresData.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsLiveMeasuresData.java
new file mode 100644 (file)
index 0000000..662a613
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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 = ?";
+  }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsProjectMeasuresData.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsProjectMeasuresData.java
new file mode 100644 (file)
index 0000000..3e905f7
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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 = ?";
+  }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedColumnFromMetricsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedColumnFromMetricsTable.java
new file mode 100644 (file)
index 0000000..db4c4b8
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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());
+  }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedMetricsData.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedMetricsData.java
new file mode 100644 (file)
index 0000000..6e21f46
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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 = ?";
+  }
+}
index 562ff4bbff5795241750034983a1ac30f6b60b69..bab346ea2b5c00d2c068d9613174cb18e5ceb483 100644 (file)
@@ -41,7 +41,7 @@ public class DbVersion91Test {
 
   @Test
   public void verify_migration_count() {
-    verifyMigrationCount(underTest, 2);
+    verifyMigrationCount(underTest, 6);
   }
 
 }
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsLiveMeasuresDataTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsLiveMeasuresDataTest.java
new file mode 100644 (file)
index 0000000..1eb208c
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * 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));
+  }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsProjectMeasuresDataTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsProjectMeasuresDataTest.java
new file mode 100644 (file)
index 0000000..9bf44f0
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * 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));
+  }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedColumnFromMetricsTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedColumnFromMetricsTableTest.java
new file mode 100644 (file)
index 0000000..5c734fe
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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);
+  }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedMetricsDataTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedMetricsDataTest.java
new file mode 100644 (file)
index 0000000..98ffe2a
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * 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));
+  }
+
+}
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsLiveMeasuresDataTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsLiveMeasuresDataTest/schema.sql
new file mode 100644 (file)
index 0000000..25be598
--- /dev/null
@@ -0,0 +1,37 @@
+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");
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsProjectMeasuresDataTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v91/DropCustomMetricsProjectMeasuresDataTest/schema.sql
new file mode 100644 (file)
index 0000000..5f973af
--- /dev/null
@@ -0,0 +1,38 @@
+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");
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v91/DropUserManagedColumnFromMetricsTableTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v91/DropUserManagedColumnFromMetricsTableTest/schema.sql
new file mode 100644 (file)
index 0000000..99756bf
--- /dev/null
@@ -0,0 +1,20 @@
+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");
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v91/DropUserManagedMetricsDataTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v91/DropUserManagedMetricsDataTest/schema.sql
new file mode 100644 (file)
index 0000000..99756bf
--- /dev/null
@@ -0,0 +1,20 @@
+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");