diff options
author | Léo Geoffroy <99647462+leo-geoffroy-sonarsource@users.noreply.github.com> | 2022-09-30 11:43:36 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-10-12 20:03:44 +0000 |
commit | d9a12fc4c11a83195e121041390181aab142960a (patch) | |
tree | da04881cd178611193da0053b5724cd5d5acc0ae /server/sonar-db-migration | |
parent | 7ff8cad89d1ff47e74d4046b4830296104552fc2 (diff) | |
download | sonarqube-d9a12fc4c11a83195e121041390181aab142960a.tar.gz sonarqube-d9a12fc4c11a83195e121041390181aab142960a.zip |
SONAR-17352 Refactor component keys to not include branch suffix
Diffstat (limited to 'server/sonar-db-migration')
7 files changed, 394 insertions, 2 deletions
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v97/CreateUniqueIndexForComponentsKeeAndBranchUuid.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v97/CreateUniqueIndexForComponentsKeeAndBranchUuid.java new file mode 100644 index 00000000000..a73007beeb3 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v97/CreateUniqueIndexForComponentsKeeAndBranchUuid.java @@ -0,0 +1,62 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 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.v97; + +import com.google.common.annotations.VisibleForTesting; +import java.sql.Connection; +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.DatabaseUtils; +import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; +import org.sonar.server.platform.db.migration.step.DdlChange; + +public class CreateUniqueIndexForComponentsKeeAndBranchUuid extends DdlChange { + + @VisibleForTesting + static final String COLUMN_NAME_KEE = "kee"; + static final String COLUMN_NAME_BRANCH = "branch_uuid"; + @VisibleForTesting + static final String TABLE = "components"; + @VisibleForTesting + static final String INDEX_NAME = "components_kee_branch_uuid"; + + public CreateUniqueIndexForComponentsKeeAndBranchUuid(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + try (Connection connection = getDatabase().getDataSource().getConnection()) { + createComponentsKeeAndBranchUuidUniqueIndex(context, connection); + } + } + + private static void createComponentsKeeAndBranchUuidUniqueIndex(Context context, Connection connection) { + if (!DatabaseUtils.indexExistsIgnoreCase(TABLE, INDEX_NAME, connection)) { + context.execute(new CreateIndexBuilder() + .setTable(TABLE) + .setName(INDEX_NAME) + .addColumn(COLUMN_NAME_KEE) + .addColumn(COLUMN_NAME_BRANCH) + .setUnique(true) + .build()); + } + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v97/DbVersion97.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v97/DbVersion97.java index 8cfd5e7b247..8de3f411b34 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v97/DbVersion97.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v97/DbVersion97.java @@ -33,8 +33,9 @@ public class DbVersion97 implements DbVersion { .add(6603, "Drop index for 'project_uuid' in 'components'", DropIndexForComponentsProjectUuid.class) .add(6604, "Rename column 'project_uuid' to 'branch_uuid' in 'components'", RenameProjectUuidToBranchUuidInComponents.class) .add(6605, "Create index for 'branch_uuid' in 'components'", CreateIndexForComponentsBranchUuid.class) - + .add(6606, "Drop index for 'kee' in 'components'", DropIndexForComponentsKey.class) - ; + .add(6607, "Remove branch information from 'kee' in 'components'", RemoveBranchInformationFromComponentsKey.class) + .add(6608, "Add unique index on 'kee','branch_uuid' in 'components'", CreateUniqueIndexForComponentsKeeAndBranchUuid.class); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v97/RemoveBranchInformationFromComponentsKey.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v97/RemoveBranchInformationFromComponentsKey.java new file mode 100644 index 00000000000..d07a18a7fe6 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v97/RemoveBranchInformationFromComponentsKey.java @@ -0,0 +1,70 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 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.v97; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.es.MigrationEsClient; +import org.sonar.server.platform.db.migration.step.DataChange; +import org.sonar.server.platform.db.migration.step.MassUpdate; + +public class RemoveBranchInformationFromComponentsKey extends DataChange { + + private static final String BRANCH_IDENTIFIER = ":BRANCH:"; + private static final String PULL_REQUEST_IDENTIFIER = ":PULL_REQUEST:"; + private static final String SELECT_QUERY = "select kee, uuid from components where main_branch_project_uuid is not null"; + private static final String UPDATE_QUERY = "update components set kee = ? where uuid= ?"; + + private final MigrationEsClient migrationEsClient; + + public RemoveBranchInformationFromComponentsKey(Database db, MigrationEsClient migrationEsClient) { + super(db); + this.migrationEsClient = migrationEsClient; + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select(SELECT_QUERY); + massUpdate.update(UPDATE_QUERY); + massUpdate.execute((row, update) -> { + boolean toUpdate = false; + String componentKey = row.getString(1); + String componentUuid = row.getString(2); + + int branchIndex = componentKey.indexOf(BRANCH_IDENTIFIER); + if (branchIndex > -1) { + toUpdate = true; + componentKey = componentKey.substring(0, branchIndex); + + } else { + int pullRequestIndex = componentKey.indexOf(PULL_REQUEST_IDENTIFIER); + if (pullRequestIndex > -1) { + toUpdate = true; + componentKey = componentKey.substring(0, pullRequestIndex); + } + } + update.setString(1, componentKey) + .setString(2, componentUuid); + return toUpdate; + }); + migrationEsClient.deleteIndexes("components"); + } +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v97/CreateUniqueIndexForComponentsKeeAndBranchUuidTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v97/CreateUniqueIndexForComponentsKeeAndBranchUuidTest.java new file mode 100644 index 00000000000..e2d3e9ce017 --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v97/CreateUniqueIndexForComponentsKeeAndBranchUuidTest.java @@ -0,0 +1,59 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 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.v97; + +import java.sql.SQLException; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.db.CoreDbTester; + +import static org.sonar.server.platform.db.migration.version.v97.CreateUniqueIndexForComponentsKeeAndBranchUuid.COLUMN_NAME_BRANCH; +import static org.sonar.server.platform.db.migration.version.v97.CreateUniqueIndexForComponentsKeeAndBranchUuid.COLUMN_NAME_KEE; +import static org.sonar.server.platform.db.migration.version.v97.CreateUniqueIndexForComponentsKeeAndBranchUuid.INDEX_NAME; +import static org.sonar.server.platform.db.migration.version.v97.CreateUniqueIndexForComponentsKeeAndBranchUuid.TABLE; + + +public class CreateUniqueIndexForComponentsKeeAndBranchUuidTest { + + @Rule + public final CoreDbTester db = CoreDbTester.createForSchema(CreateUniqueIndexForComponentsKeeAndBranchUuidTest.class, "schema.sql"); + + private final CreateUniqueIndexForComponentsKeeAndBranchUuid createUniqueIndexForComponentsKeeAndBranchUuid = new CreateUniqueIndexForComponentsKeeAndBranchUuid(db.database()); + + @Test + public void migration_should_create_index() throws SQLException { + db.assertIndexDoesNotExist(TABLE, INDEX_NAME); + + createUniqueIndexForComponentsKeeAndBranchUuid.execute(); + + db.assertUniqueIndex(TABLE, INDEX_NAME, COLUMN_NAME_KEE, COLUMN_NAME_BRANCH); + } + + @Test + public void migration_should_be_reentrant() throws SQLException { + db.assertIndexDoesNotExist(TABLE, INDEX_NAME); + + createUniqueIndexForComponentsKeeAndBranchUuid.execute(); + createUniqueIndexForComponentsKeeAndBranchUuid.execute(); + + db.assertUniqueIndex(TABLE, INDEX_NAME, COLUMN_NAME_KEE, COLUMN_NAME_BRANCH); + } + +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v97/RemoveBranchInformationFromComponentsKeyTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v97/RemoveBranchInformationFromComponentsKeyTest.java new file mode 100644 index 00000000000..5d4ab2b8fcc --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v97/RemoveBranchInformationFromComponentsKeyTest.java @@ -0,0 +1,120 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 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.v97; + +import java.sql.SQLException; +import java.util.Map; +import java.util.stream.Collectors; +import javax.annotation.Nullable; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.db.CoreDbTester; +import org.sonar.server.platform.db.migration.es.MigrationEsClient; +import org.sonar.server.platform.db.migration.step.DataChange; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class RemoveBranchInformationFromComponentsKeyTest { + + private static final String FILE_KEY_PREFIX = "org.sonarsource.sonarqube:sonarqube-private:server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PersistAdHocRulesStepTest.java"; + private static final String DIR_KEY_PREFIX = "org.sonarsource.sonarqube:sonarqube-private:server/sonar-ce-task-projectanalysis/src/test/java/org"; + private static final String PROJ_KEY_PREFIX = "org.sonarsource.sonarqube:sonarqube-private"; + + @Rule + public final CoreDbTester db = CoreDbTester.createForSchema(RemoveBranchInformationFromComponentsKeyTest.class, "schema.sql"); + + private DataChange underTest; + private MigrationEsClient migrationEsClient; + + @Before + public void before() { + migrationEsClient = mock(MigrationEsClient.class); + underTest = new RemoveBranchInformationFromComponentsKey(db.database(), migrationEsClient); + } + + @Test + public void migration_should_update_component_keys_from_branch_or_pull_request() throws SQLException { + insertComponents(db, "uuid1", FILE_KEY_PREFIX, null); + insertComponents(db, "uuid2", FILE_KEY_PREFIX + ":BRANCH:branch-9.4", "main_branch"); + insertComponents(db, "uuid3", FILE_KEY_PREFIX + ":PULL_REQUEST:143", "main_branch"); + + underTest.execute(); + + Map<String, String> componentKeyByUuid = retrieveComponentKeyByUuid(db); + assertThat(componentKeyByUuid) + .containsEntry("uuid1", FILE_KEY_PREFIX) + .containsEntry("uuid2", FILE_KEY_PREFIX) + .containsEntry("uuid3", FILE_KEY_PREFIX); + + verify(migrationEsClient).deleteIndexes("components"); + + } + + @Test + public void migration_should_update_component_keys_from_file_proj_and_dir() throws SQLException { + insertComponents(db, "uuid1", FILE_KEY_PREFIX + ":PULL_REQUEST:6637", "main_branch"); + insertComponents(db, "uuid2", DIR_KEY_PREFIX + ":BRANCH:this:is:a:branch", "main_branch"); + insertComponents(db, "uuid3", PROJ_KEY_PREFIX + ":PULL_REQUEST:143", "main_branch"); + + underTest.execute(); + + Map<String, String> componentKeyByUuid = retrieveComponentKeyByUuid(db); + assertThat(componentKeyByUuid) + .containsEntry("uuid1", FILE_KEY_PREFIX) + .containsEntry("uuid2", DIR_KEY_PREFIX) + .containsEntry("uuid3", PROJ_KEY_PREFIX); + + verify(migrationEsClient).deleteIndexes("components"); + + } + + @Test + public void migration_should_reentrant() throws SQLException { + + insertComponents(db, "uuid1", FILE_KEY_PREFIX + ":BRANCH:branch-9.4", "main_branch"); + + underTest.execute(); + + underTest.execute(); + + Map<String, String> componentKeyByUuid = retrieveComponentKeyByUuid(db); + assertThat(componentKeyByUuid).containsEntry("uuid1", FILE_KEY_PREFIX); + } + + private static Map<String, String> retrieveComponentKeyByUuid(CoreDbTester db) { + return db.select("select uuid, kee from components").stream() + .collect(Collectors.toMap(e -> (String) e.get("UUID"), e -> (String) e.get("KEE"))); + } + + private static void insertComponents(CoreDbTester db, String uuid, String key, @Nullable String mainBranchUuid) { + db.executeInsert("components", + "enabled", true, + "uuid", uuid, + "kee", key, + "branch_uuid", "branch_uuid", + "root_uuid", "root_uuid", + "uuid_path", "uuid_path", + "private", false, + "main_branch_project_uuid", mainBranchUuid); + } +} diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v97/CreateUniqueIndexForComponentsKeeAndBranchUuidTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v97/CreateUniqueIndexForComponentsKeeAndBranchUuidTest/schema.sql new file mode 100644 index 00000000000..f13b9781621 --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v97/CreateUniqueIndexForComponentsKeeAndBranchUuidTest/schema.sql @@ -0,0 +1,40 @@ +CREATE TABLE "COMPONENTS"( + "UUID" CHARACTER VARYING(50) NOT NULL, + "KEE" CHARACTER VARYING(1000), + "DEPRECATED_KEE" CHARACTER VARYING(400), + "NAME" CHARACTER VARYING(2000), + "LONG_NAME" CHARACTER VARYING(2000), + "DESCRIPTION" CHARACTER VARYING(2000), + "ENABLED" BOOLEAN DEFAULT TRUE NOT NULL, + "SCOPE" CHARACTER VARYING(3), + "QUALIFIER" CHARACTER VARYING(10), + "PRIVATE" BOOLEAN NOT NULL, + "ROOT_UUID" CHARACTER VARYING(50) NOT NULL, + "LANGUAGE" CHARACTER VARYING(20), + "COPY_COMPONENT_UUID" CHARACTER VARYING(50), + "PATH" CHARACTER VARYING(2000), + "UUID_PATH" CHARACTER VARYING(1500) NOT NULL, + "BRANCH_UUID" CHARACTER VARYING(50) NOT NULL, + "MODULE_UUID" CHARACTER VARYING(50), + "MODULE_UUID_PATH" CHARACTER VARYING(1500), + "MAIN_BRANCH_PROJECT_UUID" CHARACTER VARYING(50), + "B_CHANGED" BOOLEAN, + "B_NAME" CHARACTER VARYING(500), + "B_LONG_NAME" CHARACTER VARYING(500), + "B_DESCRIPTION" CHARACTER VARYING(2000), + "B_ENABLED" BOOLEAN, + "B_QUALIFIER" CHARACTER VARYING(10), + "B_LANGUAGE" CHARACTER VARYING(20), + "B_COPY_COMPONENT_UUID" CHARACTER VARYING(50), + "B_PATH" CHARACTER VARYING(2000), + "B_UUID_PATH" CHARACTER VARYING(1500), + "B_MODULE_UUID" CHARACTER VARYING(50), + "B_MODULE_UUID_PATH" CHARACTER VARYING(1500), + "CREATED_AT" TIMESTAMP +); +CREATE INDEX "PROJECTS_MODULE_UUID" ON "COMPONENTS"("MODULE_UUID" NULLS FIRST); +CREATE INDEX "PROJECTS_QUALIFIER" ON "COMPONENTS"("QUALIFIER" NULLS FIRST); +CREATE INDEX "PROJECTS_ROOT_UUID" ON "COMPONENTS"("ROOT_UUID" NULLS FIRST); +CREATE INDEX "IDX_MAIN_BRANCH_PRJ_UUID" ON "COMPONENTS"("MAIN_BRANCH_PROJECT_UUID" NULLS FIRST); +CREATE UNIQUE INDEX "COMPONENTS_UUID" ON "COMPONENTS"("UUID" NULLS FIRST); +CREATE INDEX "COMPONENTS_BRANCH_UUID" ON "COMPONENTS"("BRANCH_UUID" NULLS FIRST); diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v97/RemoveBranchInformationFromComponentsKeyTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v97/RemoveBranchInformationFromComponentsKeyTest/schema.sql new file mode 100644 index 00000000000..f13b9781621 --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v97/RemoveBranchInformationFromComponentsKeyTest/schema.sql @@ -0,0 +1,40 @@ +CREATE TABLE "COMPONENTS"( + "UUID" CHARACTER VARYING(50) NOT NULL, + "KEE" CHARACTER VARYING(1000), + "DEPRECATED_KEE" CHARACTER VARYING(400), + "NAME" CHARACTER VARYING(2000), + "LONG_NAME" CHARACTER VARYING(2000), + "DESCRIPTION" CHARACTER VARYING(2000), + "ENABLED" BOOLEAN DEFAULT TRUE NOT NULL, + "SCOPE" CHARACTER VARYING(3), + "QUALIFIER" CHARACTER VARYING(10), + "PRIVATE" BOOLEAN NOT NULL, + "ROOT_UUID" CHARACTER VARYING(50) NOT NULL, + "LANGUAGE" CHARACTER VARYING(20), + "COPY_COMPONENT_UUID" CHARACTER VARYING(50), + "PATH" CHARACTER VARYING(2000), + "UUID_PATH" CHARACTER VARYING(1500) NOT NULL, + "BRANCH_UUID" CHARACTER VARYING(50) NOT NULL, + "MODULE_UUID" CHARACTER VARYING(50), + "MODULE_UUID_PATH" CHARACTER VARYING(1500), + "MAIN_BRANCH_PROJECT_UUID" CHARACTER VARYING(50), + "B_CHANGED" BOOLEAN, + "B_NAME" CHARACTER VARYING(500), + "B_LONG_NAME" CHARACTER VARYING(500), + "B_DESCRIPTION" CHARACTER VARYING(2000), + "B_ENABLED" BOOLEAN, + "B_QUALIFIER" CHARACTER VARYING(10), + "B_LANGUAGE" CHARACTER VARYING(20), + "B_COPY_COMPONENT_UUID" CHARACTER VARYING(50), + "B_PATH" CHARACTER VARYING(2000), + "B_UUID_PATH" CHARACTER VARYING(1500), + "B_MODULE_UUID" CHARACTER VARYING(50), + "B_MODULE_UUID_PATH" CHARACTER VARYING(1500), + "CREATED_AT" TIMESTAMP +); +CREATE INDEX "PROJECTS_MODULE_UUID" ON "COMPONENTS"("MODULE_UUID" NULLS FIRST); +CREATE INDEX "PROJECTS_QUALIFIER" ON "COMPONENTS"("QUALIFIER" NULLS FIRST); +CREATE INDEX "PROJECTS_ROOT_UUID" ON "COMPONENTS"("ROOT_UUID" NULLS FIRST); +CREATE INDEX "IDX_MAIN_BRANCH_PRJ_UUID" ON "COMPONENTS"("MAIN_BRANCH_PROJECT_UUID" NULLS FIRST); +CREATE UNIQUE INDEX "COMPONENTS_UUID" ON "COMPONENTS"("UUID" NULLS FIRST); +CREATE INDEX "COMPONENTS_BRANCH_UUID" ON "COMPONENTS"("BRANCH_UUID" NULLS FIRST); |