--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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.v108;
+
+import java.sql.SQLException;
+import java.util.Map;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.sonar.core.util.UuidFactoryImpl;
+import org.sonar.db.MigrationDbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+
+class CreateNewSoftwareQualityMetricsIT {
+ @RegisterExtension
+ public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateNewSoftwareQualityMetrics.class);
+ private final CreateNewSoftwareQualityMetrics underTest = new CreateNewSoftwareQualityMetrics(db.database(), UuidFactoryImpl.INSTANCE);
+
+ @Test
+ void execute_shouldCreateMetrics() throws SQLException {
+ assertThat(db.select("select name,direction,qualitative,enabled,best_value,optimized_best_value,delete_historical_data from metrics"))
+ .isEmpty();
+ underTest.execute();
+ assertThat(db.select("select name,direction,qualitative,enabled,best_value,optimized_best_value,delete_historical_data from metrics"))
+ .hasSize(6)
+ .extracting(s -> s.get("name"), s -> s.get("direction"), s -> s.get("qualitative"), s -> s.get("enabled"), s -> s.get("best_value"), s -> s.get("optimized_best_value"),
+ s -> s.get("delete_historical_data"))
+ .containsExactlyInAnyOrder(
+ tuple("software_quality_reliability_issues", -1L, false, true, 0.0, true, false),
+ tuple("software_quality_security_issues", -1L, false, true, 0.0, true, false),
+ tuple("new_software_quality_reliability_issues", -1L, true, true, 0.0, true, true),
+ tuple("new_software_quality_security_issues", -1L, true, true, 0.0, true, true),
+ tuple("new_software_quality_maintainability_issues", -1L, true, true, 0.0, true, true),
+ tuple("software_quality_maintainability_issues", -1L, false, true, 0.0, true, false));
+ }
+
+ @Test
+ void execute_shouldBeReentrant() throws SQLException {
+ underTest.execute();
+ underTest.execute();
+ assertThat(db.select("select name,direction,qualitative,enabled,best_value,optimized_best_value,delete_historical_data from metrics"))
+ .hasSize(6);
+ }
+
+ @Test
+ void execute_whenOnlyOneMetricExists_shouldCreateOtherOnes() throws SQLException {
+ String existingMetricUuid = insertMetric("software_quality_security_issues");
+ underTest.execute();
+
+ assertThat(db.select("select uuid from metrics"))
+ .hasSize(6)
+ .extracting(e -> e.get("uuid"))
+ .contains(existingMetricUuid);
+ }
+
+ private String insertMetric(String key) {
+ String uuid = UuidFactoryImpl.INSTANCE.create();
+ Map<String, Object> map = Map.ofEntries(
+ Map.entry("UUID", uuid),
+ Map.entry("NAME", key));
+ db.executeInsert("metrics", map);
+ return uuid;
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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.v108;
+
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.sonar.core.util.UuidFactoryImpl;
+import org.sonar.db.MigrationDbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.api.measures.CoreMetrics.MAINTAINABILITY_ISSUES_KEY;
+import static org.sonar.api.measures.CoreMetrics.NEW_MAINTAINABILITY_ISSUES_KEY;
+import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_ISSUES_KEY;
+import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_ISSUES_KEY;
+import static org.sonar.api.measures.CoreMetrics.RELIABILITY_ISSUES_KEY;
+import static org.sonar.api.measures.CoreMetrics.SECURITY_ISSUES_KEY;
+import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY;
+import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY;
+import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_ISSUES_KEY;
+import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY;
+import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY;
+import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_ISSUES_KEY;
+import static org.sonar.server.platform.db.migration.version.v108.MeasureMigration.MIGRATION_MAP;
+
+class MigrateProjectMeasuresDeprecatedMetricsTest {
+ private static final String ANALYSIS_UUID_1 = UuidFactoryImpl.INSTANCE.create();
+ private static final String ANALYSIS_UUID_2 = UuidFactoryImpl.INSTANCE.create();
+ @RegisterExtension
+ private final MigrationDbTester db = MigrationDbTester.createForMigrationStep(MigrateProjectMeasuresDeprecatedMetrics.class);
+ private final MigrateProjectMeasuresDeprecatedMetrics underTest = new MigrateProjectMeasuresDeprecatedMetrics(db.database(),
+ UuidFactoryImpl.INSTANCE);
+ private Map<String, String> metricsToMigrate;
+ private Map<String, String> replacementMetrics;
+
+ @BeforeEach
+ void init() {
+ metricsToMigrate = insertMetricsToMigrate();
+ replacementMetrics = insertReplacementMetrics();
+ }
+
+ @Test
+ void execute_shouldCreateNewMetrics() throws SQLException {
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "1");
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(RELIABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "3");
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(SECURITY_ISSUES_KEY), ANALYSIS_UUID_1, "5");
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "11");
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_RELIABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "13");
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_SECURITY_ISSUES_KEY), ANALYSIS_UUID_1, "15");
+ underTest.execute();
+
+ assertThat(db.select("select metric_uuid, value from project_measures where metric_uuid in (%s)"
+ .formatted(replacementMetrics.values().stream().map(s -> "'" + s + "'").collect(Collectors.joining(",")))))
+ .hasSize(6)
+ .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), "value", 1.0)))
+ .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY), "value", 3.0)))
+ .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_SECURITY_ISSUES_KEY), "value", 5.0)))
+ .contains((Map.of("metric_uuid", replacementMetrics.get(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), "value", 11.0)))
+ .contains((Map.of("metric_uuid", replacementMetrics.get(NEW_SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY), "value", 13.0)))
+ .contains((Map.of("metric_uuid", replacementMetrics.get(NEW_SOFTWARE_QUALITY_SECURITY_ISSUES_KEY), "value", 15.0)));
+ }
+
+ @Test
+ void execute_shouldBeReentrant() throws SQLException {
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "1");
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(RELIABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "3");
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(SECURITY_ISSUES_KEY), ANALYSIS_UUID_1, "5");
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "11");
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_RELIABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "13");
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_SECURITY_ISSUES_KEY), ANALYSIS_UUID_1, "15");
+ underTest.execute();
+ underTest.execute();
+ assertThat(db.select("select * from project_measures"))
+ .hasSize(MIGRATION_MAP.size() * 2);
+ }
+
+ @Test
+ void execute_whenValueCannotBeConverted_shouldCreateOtherNewMetrics() throws SQLException {
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "1");
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(RELIABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "NOT_VALID_NUMBER");
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(SECURITY_ISSUES_KEY), ANALYSIS_UUID_1, "5");
+ underTest.execute();
+
+ assertThat(db.select("select metric_uuid, value from project_measures where metric_uuid in (%s)"
+ .formatted(replacementMetrics.values().stream().map(s -> "'" + s + "'").collect(Collectors.joining(",")))))
+ .hasSize(2)
+ .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), "value", 1.0)))
+ .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_SECURITY_ISSUES_KEY), "value", 5.0)));
+ }
+
+ @Test
+ void execute_whenWasPartiallyMigrated_shouldContinueWithOtherAnalysis() throws SQLException {
+
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "1");
+ createProjectMeasureForNewMetric(replacementMetrics.get(SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, 1);
+
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_2, "4");
+ createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(SECURITY_ISSUES_KEY), ANALYSIS_UUID_2, "5");
+ underTest.execute();
+
+ assertThat(db.select("select metric_uuid, value, analysis_uuid from project_measures where metric_uuid in (%s)"
+ .formatted(replacementMetrics.values().stream().map(s -> "'" + s + "'").collect(Collectors.joining(",")))))
+ .hasSize(3)
+ .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), "value", 1.0, "analysis_uuid"
+ , ANALYSIS_UUID_1)))
+ .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), "value", 4.0, "analysis_uuid"
+ , ANALYSIS_UUID_2)))
+ .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_SECURITY_ISSUES_KEY), "value", 5.0, "analysis_uuid",
+ ANALYSIS_UUID_2)));
+ }
+
+ private void createProjectMeasureForDeprecatedMetric(String metricUuid, String analysisUuid, String totalIssues) {
+ String uuid = UuidFactoryImpl.INSTANCE.create();
+ Map<String, Object> map = Map.ofEntries(
+ Map.entry("UUID", uuid),
+ Map.entry("TEXT_VALUE", "{\"LOW\":X,\"MEDIUM\":Y,\"HIGH\":Z,\"total\":" + totalIssues + "}"),
+ Map.entry("ANALYSIS_UUID", analysisUuid),
+ Map.entry("METRIC_UUID", metricUuid),
+ Map.entry("COMPONENT_UUID", UuidFactoryImpl.INSTANCE.create()));
+ db.executeInsert("project_measures", map);
+ }
+
+ private void createProjectMeasureForNewMetric(String metricUuid, String analysisUuid, int totalIssues) {
+ String uuid = UuidFactoryImpl.INSTANCE.create();
+ Map<String, Object> map = Map.ofEntries(
+ Map.entry("UUID", uuid),
+ Map.entry("VALUE", totalIssues),
+ Map.entry("ANALYSIS_UUID", analysisUuid),
+ Map.entry("METRIC_UUID", metricUuid),
+ Map.entry("COMPONENT_UUID", UuidFactoryImpl.INSTANCE.create()));
+ db.executeInsert("project_measures", map);
+ }
+
+ private Map<String, String> insertMetricsToMigrate() {
+ Map<String, String> createdMetrics = new HashMap<>();
+ MIGRATION_MAP.keySet().forEach(metricKey -> createdMetrics.put(metricKey, insertMetric(metricKey)));
+ return createdMetrics;
+ }
+
+ private Map<String, String> insertReplacementMetrics() {
+ Map<String, String> createdMetrics = new HashMap<>();
+ MIGRATION_MAP.values().forEach(metricKey -> createdMetrics.put(metricKey, insertMetric(metricKey)));
+ return createdMetrics;
+ }
+
+ private String insertMetric(String key) {
+ String uuid = UuidFactoryImpl.INSTANCE.create();
+ Map<String, Object> map = Map.ofEntries(
+ Map.entry("UUID", uuid),
+ Map.entry("NAME", key));
+ db.executeInsert("metrics", map);
+ return uuid;
+ }
+}
String migratedMetricKey = MeasureMigration.getMigrationMetricKey(metricName);
if (migratedMetricKey != null) {
try {
- Object migratedValue = MeasureMigration.migrate(metricValue);
+ Long migratedValue = MeasureMigration.migrate(metricValue);
if (migratedValue != null) {
measureValues.put(migratedMetricKey, migratedValue);
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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.v108;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DataChange;
+import org.sonar.server.platform.db.migration.step.Upsert;
+import org.sonar.server.platform.db.migration.version.v00.PopulateInitialSchema;
+
+public class CreateNewSoftwareQualityMetrics extends DataChange {
+ private final UuidFactory uuidFactory;
+
+ public CreateNewSoftwareQualityMetrics(Database db, UuidFactory uuidFactory) {
+ super(db);
+ this.uuidFactory = uuidFactory;
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ try (Connection connection = getDatabase().getDataSource().getConnection()) {
+ for (String metric : MeasureMigration.MIGRATION_MAP.values()) {
+ if (!metricExists(connection, metric)) {
+ Upsert upsert = context.prepareUpsert(PopulateInitialSchema.createInsertStatement("metrics",
+ "name",
+ "direction",
+ "qualitative",
+ "enabled",
+ "best_value",
+ "optimized_best_value",
+ "delete_historical_data",
+ "uuid"
+ ));
+ upsert
+ .setString(1, metric)
+ .setInt(2, -1)
+ .setBoolean(3, metric.startsWith("new_"))
+ .setBoolean(4, true)
+ .setDouble(5, 0.0)
+ .setBoolean(6, true)
+ .setBoolean(7, metric.startsWith("new_"))
+ .setString(8, uuidFactory.create());
+ upsert.execute().commit();
+ }
+ }
+ }
+ }
+
+ private static boolean metricExists(Connection connection, String metric) throws SQLException {
+ String sql = "SELECT count(1) FROM metrics WHERE name = ?";
+ try (PreparedStatement statement = connection.prepareStatement(sql)) {
+ statement.setString(1, metric);
+ ResultSet result = statement.executeQuery();
+ return result.next() && result.getInt(1) > 0;
+ }
+ }
+}
.add(10_8_016, "Create 'project_dependencies' table", CreateProjectDependenciesTable.class)
.add(10_8_017, "Enable specific MQR mode", EnableSpecificMqrMode.class)
.add(10_8_018, "Make columns 'published_at' and 'last_modified_at' nullable on the 'cves' table", AlterCveColumnsToNullable.class)
- .add(10_8_019, "Delete Software Quality ratings from project_measures", DeleteSoftwareQualityRatingFromProjectMeasures.class);
+ .add(10_8_019, "Delete Software Quality ratings from project_measures", DeleteSoftwareQualityRatingFromProjectMeasures.class)
+ .add(10_8_020, "Create new software quality metrics", CreateNewSoftwareQualityMetrics.class)
+ .add(10_8_021, "Migrate deprecated project_measures to replacement metrics", MigrateProjectMeasuresDeprecatedMetrics.class);
}
}
}
@CheckForNull
- public static Object migrate(Object value) {
+ public static Long migrate(Object value) {
Matcher matcher = VALUE_EXTRACTION_PATTERN.matcher(value.toString());
if (matcher.find()) {
return Long.valueOf(matcher.group(1));
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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.v108;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DataChange;
+import org.sonar.server.platform.db.migration.step.MassUpdate;
+
+public class MigrateProjectMeasuresDeprecatedMetrics extends DataChange {
+
+ private static final String SELECT_QUERY = """
+ select m.name, pm.component_uuid , pm.analysis_uuid, pm.text_value
+ from project_measures pm
+ join metrics m
+ on pm.metric_uuid = m.uuid
+ and m.name in (%s)
+ and not exists (
+ select 1
+ from project_measures pm2
+ join metrics m2
+ on pm2.metric_uuid = m2.uuid
+ and pm.analysis_uuid = pm2.analysis_uuid
+ and m2.name in ('software_quality_maintainability_issues')
+ )
+ order by pm.analysis_uuid
+ """.formatted(MeasureMigration.MIGRATION_MAP.keySet().stream().map(s -> "'" + s + "'").collect(Collectors.joining(",")));
+
+ private static final String SELECT_NEW_METRICS_UUID = """
+ select m.name, m.uuid
+ from metrics m
+ where m.name in (%s)
+ """.formatted(MeasureMigration.MIGRATION_MAP.values().stream().map(s -> "'" + s + "'").collect(Collectors.joining(",")));
+
+ private final UuidFactory uuidFactory;
+
+ public MigrateProjectMeasuresDeprecatedMetrics(Database db, UuidFactory uuidFactory) {
+ super(db);
+ this.uuidFactory = uuidFactory;
+ }
+
+ @Override
+ protected void execute(Context context) throws SQLException {
+
+ Map<String, String> newMetricsUuid = getNewMetricsUuid();
+
+ MassUpdate massUpdate = context.prepareMassUpdate();
+ massUpdate.select(SELECT_QUERY);
+ massUpdate.update("INSERT INTO project_measures (value, component_uuid, analysis_uuid, uuid, metric_uuid) VALUES (?, ?, ?, ?, ?)");
+
+ massUpdate.execute((row, update, index) -> {
+ String metricName = row.getString(1);
+ String componentUuid = row.getString(2);
+ String analysisUuid = row.getString(3);
+ String textValue = row.getString(4);
+
+ Long migratedValue = MeasureMigration.migrate(textValue);
+ if (migratedValue != null) {
+ update.setDouble(1, migratedValue.doubleValue());
+ update.setString(2, componentUuid);
+ update.setString(3, analysisUuid);
+ update.setString(4, uuidFactory.create());
+ String newMetricName = MeasureMigration.MIGRATION_MAP.get(metricName);
+ update.setString(5, newMetricsUuid.get(newMetricName));
+ return true;
+ } else {
+ return false;
+ }
+ });
+ }
+
+ private Map<String, String> getNewMetricsUuid() throws SQLException{
+ Map<String, String> map = new HashMap<>();
+ try (Connection connection = getDatabase().getDataSource().getConnection()) {
+ try (PreparedStatement statement = connection.prepareStatement(SELECT_NEW_METRICS_UUID)) {
+ ResultSet result = statement.executeQuery();
+ while (result.next()) {
+ map.put(result.getString(1), result.getString(2));
+ }
+ return map;
+ }
+ }
+ }
+}