diff options
4 files changed, 217 insertions, 0 deletions
diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202501/RenameOldSonarWayToLegacyIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202501/RenameOldSonarWayToLegacyIT.java new file mode 100644 index 00000000000..0c691a22132 --- /dev/null +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202501/RenameOldSonarWayToLegacyIT.java @@ -0,0 +1,105 @@ +/* + * 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.v202501; + +import java.sql.SQLException; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.sonar.api.testfixtures.log.LogTesterJUnit5; +import org.sonar.db.MigrationDbTester; +import org.sonar.server.platform.db.migration.step.DataChange; + +import static org.assertj.core.api.Assertions.assertThat; + +class RenameOldSonarWayToLegacyIT { + @RegisterExtension + final LogTesterJUnit5 logger = new LogTesterJUnit5(); + + @RegisterExtension + final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RenameOldSonarWayToLegacy.class); + + private final DataChange underTest = new RenameOldSonarWayToLegacy(db.database()); + + @BeforeEach + void before() { + logger.clear(); + } + + @Test + void migration_when_empty_sonar_way_exists() throws SQLException { + db.executeInsert("quality_gates", "name", "Sonar way", "is_built_in", true, "uuid", "quality_gate_uuid"); + + underTest.execute(); + + assertThat(db.select("select * from quality_gates where name='Sonar way'")).isNotEmpty(); + assertThat(db.select("select * from quality_gates where name='Sonar way (legacy)'")).isEmpty(); + } + + @Test + void migration_when_old_sonar_way_exists() throws SQLException { + insertOldSonarWay(); + + underTest.execute(); + + assertThat(db.select("select * from quality_gates where name='Sonar way'")).isEmpty(); + Map<String, Object> legacy = db.selectFirst("select * from quality_gates where name='Sonar way (legacy)'"); + assertThat(legacy).isNotEmpty().contains(Map.entry("is_built_in", false)); + } + + @Test + void migration_when_new_sonar_way_exists() throws SQLException { + insertNewSonarWay(); + + underTest.execute(); + + assertThat(db.select("select * from quality_gates where name='Sonar way'")).isNotEmpty(); + assertThat(db.select("select * from quality_gates where name='Sonar way (legacy)'")).isEmpty(); + } + + @Test + void migration_when_old_sonar_way_exists_is_reentrant() throws SQLException { + insertOldSonarWay(); + + underTest.execute(); + underTest.execute(); + + assertThat(db.select("select * from quality_gates where name='Sonar way'")).isEmpty(); + Map<String, Object> legacy = db.selectFirst("select * from quality_gates where name='Sonar way (legacy)'"); + assertThat(legacy).isNotEmpty().contains(Map.entry("is_built_in", false)); + } + + private void insertOldSonarWay() { + insertSonarWay("some_metric"); + } + + private void insertSonarWay(String metric) { + db.executeInsert("quality_gates", "name", "Sonar way", "is_built_in", true, "uuid", "quality_gate_uuid"); + db.executeInsert("METRICS", "name", metric, "uuid", "metric_uuid"); + db.executeInsert("quality_gate_conditions", "metric_uuid", "metric_uuid", "qgate_uuid", "quality_gate_uuid", "value_error", "0", + "operator", "GT", "uuid", "condition_uuid"); + } + + private void insertNewSonarWay() { + insertSonarWay("new_violations"); + } + +} diff --git a/server/sonar-db-migration/src/it/resources/org/sonar/server/platform/db/migration/version/v202501/RenameOldSonarWayToLegacyIT/schema.sql b/server/sonar-db-migration/src/it/resources/org/sonar/server/platform/db/migration/version/v202501/RenameOldSonarWayToLegacyIT/schema.sql new file mode 100644 index 00000000000..8c754918639 --- /dev/null +++ b/server/sonar-db-migration/src/it/resources/org/sonar/server/platform/db/migration/version/v202501/RenameOldSonarWayToLegacyIT/schema.sql @@ -0,0 +1,40 @@ +CREATE TABLE "QUALITY_GATE_CONDITIONS"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "OPERATOR" CHARACTER VARYING(3), + "VALUE_ERROR" CHARACTER VARYING(64), + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP, + "METRIC_UUID" CHARACTER VARYING(40) NOT NULL, + "QGATE_UUID" CHARACTER VARYING(40) NOT NULL +); +ALTER TABLE "QUALITY_GATE_CONDITIONS" ADD CONSTRAINT "PK_QUALITY_GATE_CONDITIONS" PRIMARY KEY("UUID"); + +CREATE TABLE "QUALITY_GATES"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "NAME" CHARACTER VARYING(100) NOT NULL, + "IS_BUILT_IN" BOOLEAN NOT NULL, + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP, + "AI_CODE_SUPPORTED" BOOLEAN DEFAULT FALSE NOT NULL +); +ALTER TABLE "QUALITY_GATES" ADD CONSTRAINT "PK_QUALITY_GATES" PRIMARY KEY("UUID"); + +CREATE TABLE "METRICS"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "NAME" CHARACTER VARYING(64) NOT NULL, + "DESCRIPTION" CHARACTER VARYING(255), + "DIRECTION" INTEGER DEFAULT 0 NOT NULL, + "DOMAIN" CHARACTER VARYING(64), + "SHORT_NAME" CHARACTER VARYING(64), + "QUALITATIVE" BOOLEAN DEFAULT FALSE NOT NULL, + "VAL_TYPE" CHARACTER VARYING(8), + "ENABLED" BOOLEAN DEFAULT TRUE, + "WORST_VALUE" DOUBLE PRECISION, + "BEST_VALUE" DOUBLE PRECISION, + "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 NULLS NOT DISTINCT INDEX "METRICS_UNIQUE_NAME" ON "METRICS"("NAME" NULLS FIRST); diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/DbVersion202501.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/DbVersion202501.java index b2d1d16893d..0ecc76cac19 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/DbVersion202501.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/DbVersion202501.java @@ -41,6 +41,7 @@ public class DbVersion202501 implements DbVersion { .add(2025_01_001, "Delete removed complexity measures from 'project_measures' table", DeleteRemovedComplexityMeasuresFromProjectMeasures.class) .add(2025_01_002, "Delete removed complexity metrics from 'metrics' table", DeleteRemovedComplexityMetrics.class) .add(2025_01_003, "Create index on 'rule_tags' table", CreateIndexOnRuleTagsTable.class) + .add(2025_01_004, "Rename 'Sonar Way' without 0 new issues condition to 'Sonar Way(legacy)'", RenameOldSonarWayToLegacy.class) ; } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/RenameOldSonarWayToLegacy.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/RenameOldSonarWayToLegacy.java new file mode 100644 index 00000000000..5b2b4289bd0 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/RenameOldSonarWayToLegacy.java @@ -0,0 +1,71 @@ +/* + * 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.v202501; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.step.DataChange; + +public class RenameOldSonarWayToLegacy extends DataChange { + + private static final String SELECT_SONAR_WAY = "select uuid from quality_gates where name = 'Sonar way'"; + private static final String SELECT_SONAR_WAY_CONDITIONS = "select * from quality_gate_conditions where qgate_uuid = ?"; + private static final String SELECT_0_NEW_ISSUES_CONDITION = """ + select * from quality_gate_conditions where qgate_uuid = ? + and metric_uuid = (select uuid from metrics where name = 'new_violations') + and value_error = '0' and operator = 'GT' + """; + private static final String UPDATE_SONAR_WAY_NAME = """ + update quality_gates set name = ?, is_built_in=? where uuid = ? + """; + + public RenameOldSonarWayToLegacy(Database db) { + super(db); + } + + @Override + protected void execute(Context context) throws SQLException { + String sonarWayUuid = context.prepareSelect(SELECT_SONAR_WAY).get(row -> row.getString(1)); + if (sonarWayUuid == null) { + //Sonar way has been already renamed, and the new one hasn't been created yet + return; + } + String sonarWayConditions = context.prepareSelect(SELECT_SONAR_WAY_CONDITIONS) + .setString(1, sonarWayUuid) + .get(row -> row.getString(1)); + if (sonarWayConditions == null) { + //Fresh instance, Sonar way created, but the conditions weren't populated yet + return; + } + String sonarWayWith0NewIssues = context.prepareSelect(SELECT_0_NEW_ISSUES_CONDITION) + .setString(1, sonarWayUuid) + .get(row -> row.getString(1)); + if (sonarWayWith0NewIssues != null) { + //Migrating from version 10.3 or newer, Sonar way with 0 new issues condition exists + return; + } + context.prepareUpsert(UPDATE_SONAR_WAY_NAME) + .setString(1, "Sonar way (legacy)") + .setBoolean(2, false) + .setString(3, sonarWayUuid) + .execute() + .commit(); + } +} |