From 1cc993f6dae7a22df577faa7101d06dc6c594974 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Fri, 1 Jul 2016 15:07:23 +0200 Subject: [PATCH] SONAR-7780 Fix migration of PROJECTS.UUID_PATH --- .../1255_fix_project_uuid_of_developers.rb | 29 +++++ ... 1256_add_uuid_path_column_to_projects.rb} | 0 ..._populate_uuid_path_column_on_projects.rb} | 0 ..._uuid_path_column_not_null_on_projects.rb} | 0 ...9_remove_users_password_when_not_local.rb} | 0 ... => 1260_add_profile_key_to_activities.rb} | 0 ...261_populate_profile_key_of_activities.rb} | 0 ...ake_profile_key_not_null_on_activities.rb} | 0 ..._add_user_updated_at_to_rules_profiles.rb} | 0 ...late_user_updated_at_of_rules_profiles.rb} | 0 ...5_add_analysis_uuid_column_to_measures.rb} | 0 ...266_populate_analysis_uuid_on_measures.rb} | 0 ...clean_measures_with_null_analysis_uuid.rb} | 0 ...ake_analysis_uuid_not_null_on_measures.rb} | 0 .../org/sonar/db/version/DatabaseVersion.java | 2 +- .../sonar/db/version/MigrationStepModule.java | 2 + .../v60/FixProjectUuidOfDevelopers.java | 50 ++++++++ .../v60/PopulateUuidPathColumnOnProjects.java | 6 +- .../org/sonar/db/version/rows-h2.sql | 1 + .../db/version/MigrationStepModuleTest.java | 2 +- .../v60/FixProjectUuidOfDevelopersTest.java | 108 ++++++++++++++++++ .../PopulateUuidPathColumnOnProjectsTest.java | 58 ++++++---- .../in_progress_projects.sql | 22 ++++ 23 files changed, 251 insertions(+), 29 deletions(-) create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1255_fix_project_uuid_of_developers.rb rename server/sonar-web/src/main/webapp/WEB-INF/db/migrate/{1255_add_uuid_path_column_to_projects.rb => 1256_add_uuid_path_column_to_projects.rb} (100%) rename server/sonar-web/src/main/webapp/WEB-INF/db/migrate/{1256_populate_uuid_path_column_on_projects.rb => 1257_populate_uuid_path_column_on_projects.rb} (100%) rename server/sonar-web/src/main/webapp/WEB-INF/db/migrate/{1257_make_uuid_path_column_not_null_on_projects.rb => 1258_make_uuid_path_column_not_null_on_projects.rb} (100%) rename server/sonar-web/src/main/webapp/WEB-INF/db/migrate/{1258_remove_users_password_when_not_local.rb => 1259_remove_users_password_when_not_local.rb} (100%) rename server/sonar-web/src/main/webapp/WEB-INF/db/migrate/{1259_add_profile_key_to_activities.rb => 1260_add_profile_key_to_activities.rb} (100%) rename server/sonar-web/src/main/webapp/WEB-INF/db/migrate/{1260_populate_profile_key_of_activities.rb => 1261_populate_profile_key_of_activities.rb} (100%) rename server/sonar-web/src/main/webapp/WEB-INF/db/migrate/{1261_make_profile_key_not_null_on_activities.rb => 1262_make_profile_key_not_null_on_activities.rb} (100%) rename server/sonar-web/src/main/webapp/WEB-INF/db/migrate/{1262_add_user_updated_at_to_rules_profiles.rb => 1263_add_user_updated_at_to_rules_profiles.rb} (100%) rename server/sonar-web/src/main/webapp/WEB-INF/db/migrate/{1263_populate_user_updated_at_of_rules_profiles.rb => 1264_populate_user_updated_at_of_rules_profiles.rb} (100%) rename server/sonar-web/src/main/webapp/WEB-INF/db/migrate/{1264_add_analysis_uuid_column_to_measures.rb => 1265_add_analysis_uuid_column_to_measures.rb} (100%) rename server/sonar-web/src/main/webapp/WEB-INF/db/migrate/{1265_populate_analysis_uuid_on_measures.rb => 1266_populate_analysis_uuid_on_measures.rb} (100%) rename server/sonar-web/src/main/webapp/WEB-INF/db/migrate/{1266_clean_measures_with_null_analysis_uuid.rb => 1267_clean_measures_with_null_analysis_uuid.rb} (100%) rename server/sonar-web/src/main/webapp/WEB-INF/db/migrate/{1267_make_analysis_uuid_not_null_on_measures.rb => 1268_make_analysis_uuid_not_null_on_measures.rb} (100%) create mode 100644 sonar-db/src/main/java/org/sonar/db/version/v60/FixProjectUuidOfDevelopers.java create mode 100644 sonar-db/src/test/java/org/sonar/db/version/v60/FixProjectUuidOfDevelopersTest.java create mode 100644 sonar-db/src/test/resources/org/sonar/db/version/v60/FixProjectUuidOfDevelopersTest/in_progress_projects.sql diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1255_fix_project_uuid_of_developers.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1255_fix_project_uuid_of_developers.rb new file mode 100644 index 00000000000..568fa301801 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1255_fix_project_uuid_of_developers.rb @@ -0,0 +1,29 @@ +# +# SonarQube, open source software quality management tool. +# Copyright (C) 2008-2014 SonarSource +# mailto:contact AT sonarsource DOT com +# +# SonarQube 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. +# +# SonarQube 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. +# + +# +# SonarQube 6.0 +# +class FixProjectUuidOfDevelopers < ActiveRecord::Migration + + def self.up + execute_java_migration('org.sonar.db.version.v60.FixProjectUuidOfDevelopers') + end +end diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1255_add_uuid_path_column_to_projects.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1256_add_uuid_path_column_to_projects.rb similarity index 100% rename from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1255_add_uuid_path_column_to_projects.rb rename to server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1256_add_uuid_path_column_to_projects.rb diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1256_populate_uuid_path_column_on_projects.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1257_populate_uuid_path_column_on_projects.rb similarity index 100% rename from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1256_populate_uuid_path_column_on_projects.rb rename to server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1257_populate_uuid_path_column_on_projects.rb diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1257_make_uuid_path_column_not_null_on_projects.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1258_make_uuid_path_column_not_null_on_projects.rb similarity index 100% rename from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1257_make_uuid_path_column_not_null_on_projects.rb rename to server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1258_make_uuid_path_column_not_null_on_projects.rb diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1258_remove_users_password_when_not_local.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1259_remove_users_password_when_not_local.rb similarity index 100% rename from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1258_remove_users_password_when_not_local.rb rename to server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1259_remove_users_password_when_not_local.rb diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1259_add_profile_key_to_activities.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1260_add_profile_key_to_activities.rb similarity index 100% rename from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1259_add_profile_key_to_activities.rb rename to server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1260_add_profile_key_to_activities.rb diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1260_populate_profile_key_of_activities.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1261_populate_profile_key_of_activities.rb similarity index 100% rename from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1260_populate_profile_key_of_activities.rb rename to server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1261_populate_profile_key_of_activities.rb diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1261_make_profile_key_not_null_on_activities.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1262_make_profile_key_not_null_on_activities.rb similarity index 100% rename from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1261_make_profile_key_not_null_on_activities.rb rename to server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1262_make_profile_key_not_null_on_activities.rb diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1262_add_user_updated_at_to_rules_profiles.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1263_add_user_updated_at_to_rules_profiles.rb similarity index 100% rename from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1262_add_user_updated_at_to_rules_profiles.rb rename to server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1263_add_user_updated_at_to_rules_profiles.rb diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1263_populate_user_updated_at_of_rules_profiles.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1264_populate_user_updated_at_of_rules_profiles.rb similarity index 100% rename from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1263_populate_user_updated_at_of_rules_profiles.rb rename to server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1264_populate_user_updated_at_of_rules_profiles.rb diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1264_add_analysis_uuid_column_to_measures.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1265_add_analysis_uuid_column_to_measures.rb similarity index 100% rename from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1264_add_analysis_uuid_column_to_measures.rb rename to server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1265_add_analysis_uuid_column_to_measures.rb diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1265_populate_analysis_uuid_on_measures.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1266_populate_analysis_uuid_on_measures.rb similarity index 100% rename from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1265_populate_analysis_uuid_on_measures.rb rename to server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1266_populate_analysis_uuid_on_measures.rb diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1266_clean_measures_with_null_analysis_uuid.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1267_clean_measures_with_null_analysis_uuid.rb similarity index 100% rename from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1266_clean_measures_with_null_analysis_uuid.rb rename to server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1267_clean_measures_with_null_analysis_uuid.rb diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1267_make_analysis_uuid_not_null_on_measures.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1268_make_analysis_uuid_not_null_on_measures.rb similarity index 100% rename from server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1267_make_analysis_uuid_not_null_on_measures.rb rename to server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1268_make_analysis_uuid_not_null_on_measures.rb diff --git a/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java b/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java index 591785e9c37..1dea1492e65 100644 --- a/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java +++ b/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java @@ -30,7 +30,7 @@ import org.sonar.db.MyBatis; public class DatabaseVersion { - public static final int LAST_VERSION = 1_267; + public static final int LAST_VERSION = 1_268; /** * The minimum supported version which can be upgraded. Lower diff --git a/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java b/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java index 833b345701a..7047aed0917 100644 --- a/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java +++ b/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java @@ -115,6 +115,7 @@ import org.sonar.db.version.v60.DropSnapshotIdColumnFromCeActivity; import org.sonar.db.version.v60.DropSnapshotIdColumnFromEvents; import org.sonar.db.version.v60.DropSnapshotIdColumnsFromDuplicationsIndex; import org.sonar.db.version.v60.DropUnusedMeasuresColumns; +import org.sonar.db.version.v60.FixProjectUuidOfDevelopers; import org.sonar.db.version.v60.MakeAnalysisUuidNotNullOnDuplicationsIndex; import org.sonar.db.version.v60.MakeAnalysisUuidNotNullOnEvents; import org.sonar.db.version.v60.MakeAnalysisUuidNotNullOnMeasures; @@ -287,6 +288,7 @@ public class MigrationStepModule extends Module { MakeAnalysisUuidNotNullOnEvents.class, DropSnapshotIdColumnFromEvents.class, + FixProjectUuidOfDevelopers.class, // PROJECTS.UUID_PATH AddUuidPathColumnToProjects.class, PopulateUuidPathColumnOnProjects.class, diff --git a/sonar-db/src/main/java/org/sonar/db/version/v60/FixProjectUuidOfDevelopers.java b/sonar-db/src/main/java/org/sonar/db/version/v60/FixProjectUuidOfDevelopers.java new file mode 100644 index 00000000000..3e042c03f3a --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v60/FixProjectUuidOfDevelopers.java @@ -0,0 +1,50 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.db.version.v60; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; +import org.sonar.db.version.SqlStatement; + +public class FixProjectUuidOfDevelopers extends BaseDataChange { + + public FixProjectUuidOfDevelopers(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("select distinct developer_uuid from projects where qualifier = 'DEV_PRJ'"); + massUpdate.update("update projects set project_uuid = developer_uuid where developer_uuid = ? and qualifier = 'DEV_PRJ'"); + massUpdate.rowPluralName("developers in project"); + massUpdate.execute((row, update) -> handleComponent(row, update)); + } + + private boolean handleComponent(Select.Row row, SqlStatement update) throws SQLException { + String developerUuid = row.getString(1); + update.setString(1, developerUuid); + + return true; + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/version/v60/PopulateUuidPathColumnOnProjects.java b/sonar-db/src/main/java/org/sonar/db/version/v60/PopulateUuidPathColumnOnProjects.java index 71e7aa77a76..a8361e0d9c2 100644 --- a/sonar-db/src/main/java/org/sonar/db/version/v60/PopulateUuidPathColumnOnProjects.java +++ b/sonar-db/src/main/java/org/sonar/db/version/v60/PopulateUuidPathColumnOnProjects.java @@ -60,7 +60,7 @@ public class PopulateUuidPathColumnOnProjects extends BaseDataChange { handleRoot(rootUuid, context); } - handleOrphans(context); + handleOrphans(context); } private void handleRoot(String rootComponentUuid, Context context) throws SQLException { @@ -91,7 +91,7 @@ public class PopulateUuidPathColumnOnProjects extends BaseDataChange { massUpdate.execute((row, update, updateIndex) -> { String uuid = row.getString(1); String rootUuid = row.getString(2); - String path = uuid.equals(rootUuid) ? ROOT_PATH : (rootUuid + PATH_SEPARATOR); + String path = uuid.equals(rootUuid) ? ROOT_PATH : (PATH_SEPARATOR + rootUuid + PATH_SEPARATOR); update.setString(1, path); update.setString(2, uuid); return true; @@ -119,7 +119,7 @@ public class PopulateUuidPathColumnOnProjects extends BaseDataChange { List componentUuidPath = Arrays.stream(snapshot.snapshotPath) .mapToObj(snapshotId -> relations.snapshotsById.get(snapshotId).componentUuid) .collect(toCollection(() -> new ArrayList<>(snapshot.snapshotPath.length))); - update.setString(1, PATH_JOINER.join(componentUuidPath) + PATH_SEPARATOR); + update.setString(1, PATH_SEPARATOR + PATH_JOINER.join(componentUuidPath) + PATH_SEPARATOR); update.setString(2, componentUuid); return true; } diff --git a/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql b/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql index 8ef6e3b5307..0c7445b65db 100644 --- a/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql +++ b/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql @@ -474,6 +474,7 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1264'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1265'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1266'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1267'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1268'); INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, EXTERNAL_IDENTITY, EXTERNAL_IDENTITY_PROVIDER, USER_LOCAL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT) VALUES (1, 'admin', 'Administrator', '', 'admin', 'sonarqube', true, 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '1418215735482', '1418215735482'); ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2; diff --git a/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java b/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java index 0502ecf2ce8..fd817bfc652 100644 --- a/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java +++ b/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java @@ -29,6 +29,6 @@ public class MigrationStepModuleTest { public void verify_count_of_added_MigrationStep_types() { ComponentContainer container = new ComponentContainer(); new MigrationStepModule().configure(container); - assertThat(container.size()).isEqualTo(123); + assertThat(container.size()).isEqualTo(124); } } diff --git a/sonar-db/src/test/java/org/sonar/db/version/v60/FixProjectUuidOfDevelopersTest.java b/sonar-db/src/test/java/org/sonar/db/version/v60/FixProjectUuidOfDevelopersTest.java new file mode 100644 index 00000000000..c1d82346580 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v60/FixProjectUuidOfDevelopersTest.java @@ -0,0 +1,108 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.db.version.v60; + +import java.sql.SQLException; +import java.util.Map; +import javax.annotation.Nullable; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; + +import static org.assertj.core.api.Assertions.assertThat; + +public class FixProjectUuidOfDevelopersTest { + + private static final String TABLE_PROJECTS = "projects"; + private static final String PROJECT_UUID = "U1"; + private static final String FILE_UUID = "U2"; + private static final String DEVELOPER_UUID = "U3"; + private static final String DEV1_IN_PROJECT_UUID = "U4"; + private static final String DEV2_IN_PROJECT_UUID = "U5"; + + @Rule + public DbTester db = DbTester.createForSchema(System2.INSTANCE, FixProjectUuidOfDevelopersTest.class, + "in_progress_projects.sql"); + + private FixProjectUuidOfDevelopers underTest = new FixProjectUuidOfDevelopers(db.database()); + + @Test + public void migration_has_no_effect_on_empty_tables() throws SQLException { + underTest.execute(); + + assertThat(db.countRowsOfTable(TABLE_PROJECTS)).isEqualTo(0); + } + + @Test + public void migration_fixes_project_uuid_of_rows_with_qualifier_DEV_PRJ() throws SQLException { + insertComponents(); + + underTest.execute(); + + verifyComponents(); + } + + @Test + public void migration_is_reentrant() throws SQLException { + insertComponents(); + + underTest.execute(); + verifyComponents(); + + underTest.execute(); + verifyComponents(); + } + + private void verifyComponents() { + verifyProjectUuid(PROJECT_UUID, PROJECT_UUID); + verifyProjectUuid(FILE_UUID, PROJECT_UUID); + verifyProjectUuid(DEVELOPER_UUID, DEVELOPER_UUID); + verifyProjectUuid(DEV1_IN_PROJECT_UUID, DEVELOPER_UUID); + verifyProjectUuid(DEV2_IN_PROJECT_UUID, DEVELOPER_UUID); + } + + private void insertComponents() { + // regular project + insert(PROJECT_UUID, "TRK", null, PROJECT_UUID); + insert(FILE_UUID, "FIL", null, PROJECT_UUID); + // developer + insert(DEVELOPER_UUID, "DEV", DEVELOPER_UUID, DEVELOPER_UUID); + insert(DEV1_IN_PROJECT_UUID, "DEV_PRJ", DEVELOPER_UUID, /* not correct */PROJECT_UUID); + insert(DEV2_IN_PROJECT_UUID, "DEV_PRJ", DEVELOPER_UUID, /* not correct */PROJECT_UUID); + db.commit(); + } + + private void verifyProjectUuid(String uuid, @Nullable String expectedProjectUuid) { + Map rows = db.selectFirst("select project_uuid as \"projectUuid\" from projects where uuid='" + uuid + "'"); + assertThat(rows.get("projectUuid")).isEqualTo(expectedProjectUuid); + } + + private String insert(String uuid, String qualifier, @Nullable String developerUuid, String projectUuid) { + db.executeInsert( + TABLE_PROJECTS, + "UUID", uuid, + "DEVELOPER_UUID", developerUuid, + "PROJECT_UUID", projectUuid, + "ROOT_UUID", "NOT_USED", + "QUALIFIER", qualifier); + return uuid; + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/version/v60/PopulateUuidPathColumnOnProjectsTest.java b/sonar-db/src/test/java/org/sonar/db/version/v60/PopulateUuidPathColumnOnProjectsTest.java index 6151dbf75bc..717c9d1f8ea 100644 --- a/sonar-db/src/test/java/org/sonar/db/version/v60/PopulateUuidPathColumnOnProjectsTest.java +++ b/sonar-db/src/test/java/org/sonar/db/version/v60/PopulateUuidPathColumnOnProjectsTest.java @@ -37,6 +37,10 @@ public class PopulateUuidPathColumnOnProjectsTest { private static final String A_MODULE_UUID = "U_MOD"; private static final String A_DIR_UUID = "U_DIR"; private static final String A_FILE_UUID = "U_FIL"; + private static final String QUALIFIER_PROJECT = "TRK"; + private static final String QUALIFIER_MODULE = "BRC"; + private static final String QUALIFIER_DIR = "DIR"; + private static final String QUALIFIER_FILE = "FIL"; @Rule public DbTester db = DbTester.createForSchema(System2.INSTANCE, PopulateUuidPathColumnOnProjectsTest.class, @@ -53,7 +57,7 @@ public class PopulateUuidPathColumnOnProjectsTest { @Test public void migrates_provisioned_projects() throws SQLException { - insert(A_PROJECT_UUID, A_PROJECT_UUID); + insert(QUALIFIER_PROJECT, A_PROJECT_UUID, A_PROJECT_UUID); underTest.execute(); @@ -62,49 +66,49 @@ public class PopulateUuidPathColumnOnProjectsTest { @Test public void migrates_projects_without_modules() throws SQLException { - insert(A_PROJECT_UUID, A_PROJECT_UUID, new Snapshot(1L, "", true)); - insert(A_DIR_UUID, A_PROJECT_UUID, new Snapshot(2L, "1.", true)); - insert(A_FILE_UUID, A_PROJECT_UUID, new Snapshot(3L, "1.2.", true)); + insert(QUALIFIER_PROJECT, A_PROJECT_UUID, A_PROJECT_UUID, new Snapshot(1L, "", true)); + insert(QUALIFIER_DIR, A_DIR_UUID, A_PROJECT_UUID, new Snapshot(2L, "1.", true)); + insert(QUALIFIER_FILE, A_FILE_UUID, A_PROJECT_UUID, new Snapshot(3L, "1.2.", true)); underTest.execute(); verifyPath(A_PROJECT_UUID, "."); - verifyPath(A_DIR_UUID, format("%s.", A_PROJECT_UUID)); - verifyPath(A_FILE_UUID, format("%s.%s.", A_PROJECT_UUID, A_DIR_UUID)); + verifyPath(A_DIR_UUID, format(".%s.", A_PROJECT_UUID)); + verifyPath(A_FILE_UUID, format(".%s.%s.", A_PROJECT_UUID, A_DIR_UUID)); } @Test public void migrates_projects_with_modules() throws SQLException { - insert(A_PROJECT_UUID, A_PROJECT_UUID, new Snapshot(1L, "", true)); - insert(A_MODULE_UUID, A_PROJECT_UUID, new Snapshot(2L, "1.", true)); - insert(A_DIR_UUID, A_PROJECT_UUID, new Snapshot(3L, "1.2.", true)); - insert(A_FILE_UUID, A_PROJECT_UUID, new Snapshot(4L, "1.2.3.", true)); + insert(QUALIFIER_PROJECT, A_PROJECT_UUID, A_PROJECT_UUID, new Snapshot(1L, "", true)); + insert(QUALIFIER_MODULE, A_MODULE_UUID, A_PROJECT_UUID, new Snapshot(2L, "1.", true)); + insert(QUALIFIER_DIR, A_DIR_UUID, A_PROJECT_UUID, new Snapshot(3L, "1.2.", true)); + insert(QUALIFIER_FILE, A_FILE_UUID, A_PROJECT_UUID, new Snapshot(4L, "1.2.3.", true)); underTest.execute(); verifyPath(A_PROJECT_UUID, "."); - verifyPath(A_MODULE_UUID, format("%s.", A_PROJECT_UUID)); - verifyPath(A_DIR_UUID, format("%s.%s.", A_PROJECT_UUID, A_MODULE_UUID)); - verifyPath(A_FILE_UUID, format("%s.%s.%s.", A_PROJECT_UUID, A_MODULE_UUID, A_DIR_UUID)); + verifyPath(A_MODULE_UUID, format(".%s.", A_PROJECT_UUID)); + verifyPath(A_DIR_UUID, format(".%s.%s.", A_PROJECT_UUID, A_MODULE_UUID)); + verifyPath(A_FILE_UUID, format(".%s.%s.%s.", A_PROJECT_UUID, A_MODULE_UUID, A_DIR_UUID)); } @Test public void migrates_components_without_snapshot_path() throws SQLException { // these components do not have snapshots - insert(A_DIR_UUID, A_PROJECT_UUID); - insert(A_FILE_UUID, A_PROJECT_UUID); + insert(QUALIFIER_DIR, A_DIR_UUID, A_PROJECT_UUID); + insert(QUALIFIER_FILE, A_FILE_UUID, A_PROJECT_UUID); underTest.execute(); - verifyPath(A_DIR_UUID, format("%s.", A_PROJECT_UUID)); - verifyPath(A_FILE_UUID, format("%s.", A_PROJECT_UUID)); + verifyPath(A_DIR_UUID, format(".%s.", A_PROJECT_UUID)); + verifyPath(A_FILE_UUID, format(".%s.", A_PROJECT_UUID)); } @Test public void migration_is_reentrant() throws SQLException { - insert(A_PROJECT_UUID, A_PROJECT_UUID, new Snapshot(1L, "", true)); - insert(A_DIR_UUID, A_PROJECT_UUID, new Snapshot(2L, "1.", true)); - insert(A_FILE_UUID, A_PROJECT_UUID, new Snapshot(3L, "1.2.", true)); + insert(QUALIFIER_PROJECT, A_PROJECT_UUID, A_PROJECT_UUID, new Snapshot(1L, "", true)); + insert(QUALIFIER_DIR, A_DIR_UUID, A_PROJECT_UUID, new Snapshot(2L, "1.", true)); + insert(QUALIFIER_FILE, A_FILE_UUID, A_PROJECT_UUID, new Snapshot(3L, "1.2.", true)); underTest.execute(); verifyNoNullPath(); @@ -113,12 +117,13 @@ public class PopulateUuidPathColumnOnProjectsTest { verifyNoNullPath(); } - private void insert(String uuid, String rootUuid, Snapshot... snapshots) { + private void insert(String qualifier, String uuid, String rootUuid, Snapshot... snapshots) { db.executeInsert( TABLE_PROJECTS, "uuid", uuid, "project_uuid", rootUuid, - "root_uuid", rootUuid); + "root_uuid", rootUuid, + "qualifier", qualifier); for (Snapshot snapshot : snapshots) { db.executeInsert( @@ -128,8 +133,8 @@ public class PopulateUuidPathColumnOnProjectsTest { "path", snapshot.idPath, "islast", String.valueOf(snapshot.isLast), "component_uuid", uuid, - "root_component_uuid", rootUuid - ); + "root_component_uuid", rootUuid, + "qualifier", qualifier); } db.commit(); } @@ -139,6 +144,11 @@ public class PopulateUuidPathColumnOnProjectsTest { assertThat(row.get("UUID_PATH")).isEqualTo(expectedUuidPath); } + private void verifyProjectUuid(String componentUuid, String expectedProjectUuid) { + Map row = db.selectFirst("select project_uuid from projects where uuid='" + componentUuid + "'"); + assertThat(row.get("PROJECT_UUID")).isEqualTo(expectedProjectUuid); + } + private void verifyNoNullPath() { assertThat(db.select("select * from projects where uuid_path is null or uuid_path = ''")).isEmpty(); } diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v60/FixProjectUuidOfDevelopersTest/in_progress_projects.sql b/sonar-db/src/test/resources/org/sonar/db/version/v60/FixProjectUuidOfDevelopersTest/in_progress_projects.sql new file mode 100644 index 00000000000..760728a8dc3 --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v60/FixProjectUuidOfDevelopersTest/in_progress_projects.sql @@ -0,0 +1,22 @@ +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(400), + "UUID" VARCHAR(50) NOT NULL, + "ROOT_UUID" VARCHAR(50) NOT NULL, + "PROJECT_UUID" VARCHAR(50), + "MODULE_UUID" VARCHAR(50), + "MODULE_UUID_PATH" VARCHAR(4000), + "NAME" VARCHAR(2000), + "DESCRIPTION" VARCHAR(2000), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "DEPRECATED_KEE" VARCHAR(400), + "PATH" VARCHAR(2000), + "LANGUAGE" VARCHAR(20), + "COPY_COMPONENT_UUID" VARCHAR(50), + "LONG_NAME" VARCHAR(2000), + "DEVELOPER_UUID" VARCHAR(50), + "CREATED_AT" TIMESTAMP, + "AUTHORIZATION_UPDATED_AT" BIGINT +); -- 2.39.5