diff options
author | Jacek <jacek.poreda@sonarsource.com> | 2020-04-30 15:30:41 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2020-05-25 20:05:22 +0000 |
commit | 584c92dff0d1d904c770ecace709bb6e6d895ec3 (patch) | |
tree | e2147c6c235ccf7d06266ce2747bf100440ebd57 /server | |
parent | 7925b2f67b87f0d3d6086a3b006e276341f70566 (diff) | |
download | sonarqube-584c92dff0d1d904c770ecace709bb6e6d895ec3.tar.gz sonarqube-584c92dff0d1d904c770ecace709bb6e6d895ec3.zip |
SONAR-13221 change QPROFILE_EDIT_USERS user_id FK to user_uuid
Diffstat (limited to 'server')
27 files changed, 867 insertions, 99 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDao.java index df9e7c49dbf..c38a03a1f1c 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDao.java @@ -39,7 +39,7 @@ public class QProfileEditUsersDao implements Dao { } public boolean exists(DbSession dbSession, QProfileDto profile, UserDto user) { - return mapper(dbSession).selectByQProfileAndUser(profile.getKee(), user.getId()) != null; + return mapper(dbSession).selectByQProfileAndUser(profile.getKee(), user.getUuid()) != null; } public int countByQuery(DbSession dbSession, SearchUsersQuery query) { @@ -51,7 +51,7 @@ public class QProfileEditUsersDao implements Dao { } public List<String> selectQProfileUuidsByOrganizationAndUser(DbSession dbSession, OrganizationDto organization, UserDto userDto) { - return mapper(dbSession).selectQProfileUuidsByOrganizationAndUser(organization.getUuid(), userDto.getId()); + return mapper(dbSession).selectQProfileUuidsByOrganizationAndUser(organization.getUuid(), userDto.getUuid()); } public void insert(DbSession dbSession, QProfileEditUsersDto dto) { @@ -59,7 +59,7 @@ public class QProfileEditUsersDao implements Dao { } public void deleteByQProfileAndUser(DbSession dbSession, QProfileDto profile, UserDto user) { - mapper(dbSession).delete(profile.getKee(), user.getId()); + mapper(dbSession).delete(profile.getKee(), user.getUuid()); } public void deleteByQProfiles(DbSession dbSession, List<QProfileDto> qProfiles) { @@ -67,11 +67,11 @@ public class QProfileEditUsersDao implements Dao { } public void deleteByUser(DbSession dbSession, UserDto user) { - mapper(dbSession).deleteByUser(user.getId()); + mapper(dbSession).deleteByUser(user.getUuid()); } public void deleteByOrganizationAndUser(DbSession dbSession, OrganizationDto organization, UserDto user) { - mapper(dbSession).deleteByOrganizationAndUser(organization.getUuid(), user.getId()); + mapper(dbSession).deleteByOrganizationAndUser(organization.getUuid(), user.getUuid()); } private static QProfileEditUsersMapper mapper(DbSession dbSession) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDto.java index e5dfac35c00..cac845bb943 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDto.java @@ -22,7 +22,7 @@ package org.sonar.db.qualityprofile; public class QProfileEditUsersDto { private String uuid; - private int userId; + private String userUuid; private String qProfileUuid; public String getUuid() { @@ -34,12 +34,12 @@ public class QProfileEditUsersDto { return this; } - public int getUserId() { - return userId; + public String getUserUuid() { + return userUuid; } - public QProfileEditUsersDto setUserId(int userId) { - this.userId = userId; + public QProfileEditUsersDto setUserUuid(String userUuid) { + this.userUuid = userUuid; return this; } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersMapper.java index a52699481b6..5a1cb6e486a 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersMapper.java @@ -26,21 +26,21 @@ import org.sonar.db.Pagination; public interface QProfileEditUsersMapper { - QProfileEditUsersDto selectByQProfileAndUser(@Param("qProfileUuid") String qProfileUuid, @Param("userId") int userId); + QProfileEditUsersDto selectByQProfileAndUser(@Param("qProfileUuid") String qProfileUuid, @Param("userUuid") String userUuid); int countByQuery(@Param("query") SearchUsersQuery query); List<UserMembershipDto> selectByQuery(@Param("query") SearchUsersQuery query, @Param("pagination") Pagination pagination); - List<String> selectQProfileUuidsByOrganizationAndUser(@Param("organizationUuid") String organizationUuid, @Param("userId") int userId); + List<String> selectQProfileUuidsByOrganizationAndUser(@Param("organizationUuid") String organizationUuid, @Param("userUuid") String userUuid); void insert(@Param("dto") QProfileEditUsersDto dto, @Param("now") long now); - void delete(@Param("qProfileUuid") String qProfileUuid, @Param("userId") int userId); + void delete(@Param("qProfileUuid") String qProfileUuid, @Param("userUuid") String userUuid); void deleteByQProfiles(@Param("qProfileUuids") Collection<String> qProfileUuids); - void deleteByUser(@Param("userId") int userId); + void deleteByUser(@Param("userUuid") String userUuid); - void deleteByOrganizationAndUser(@Param("organizationUuid") String organizationUuid, @Param("userId") int userId); + void deleteByOrganizationAndUser(@Param("organizationUuid") String organizationUuid, @Param("userUuid") String userUuid); } diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditUsersMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditUsersMapper.xml index 5a9387d1e5f..7dd0ade9d64 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditUsersMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditUsersMapper.xml @@ -5,7 +5,7 @@ <sql id="sqlColumns"> qeu.uuid as "uuid", - qeu.user_id as "userId", + qeu.user_uuid as "userUuid", qeu.qprofile_uuid as "qProfileUuid" </sql> @@ -14,7 +14,7 @@ <include refid="sqlColumns"/> from qprofile_edit_users qeu where - qeu.user_id = #{userId, jdbcType=INTEGER} + qeu.user_uuid = #{userUuid, jdbcType=VARCHAR} and qeu.qprofile_uuid = #{qProfileUuid, jdbcType=VARCHAR} </select> @@ -56,7 +56,7 @@ <sql id="sqlSelectByQuery"> FROM users u - LEFT JOIN qprofile_edit_users qeu ON qeu.user_id=u.id AND qeu.qprofile_uuid=#{query.qProfileUuid, jdbcType=VARCHAR} + LEFT JOIN qprofile_edit_users qeu ON qeu.user_uuid=u.uuid AND qeu.qprofile_uuid=#{query.qProfileUuid, jdbcType=VARCHAR} INNER JOIN organization_members om ON u.uuid=om.user_uuid AND om.organization_uuid=#{query.organizationUuid, jdbcType=VARCHAR} <where> <choose> @@ -81,19 +81,19 @@ FROM qprofile_edit_users qeu INNER JOIN org_qprofiles oq ON qeu.qprofile_uuid=oq.uuid AND oq.organization_uuid=#{organizationUuid, jdbcType=VARCHAR} <where> - qeu.user_id=#{userId, jdbcType=INTEGER} + qeu.user_uuid=#{userUuid, jdbcType=VARCHAR} </where> </select> <insert id="insert" useGeneratedKeys="false" parameterType="map"> insert into qprofile_edit_users( uuid, - user_id, + user_uuid, qprofile_uuid, created_at ) values ( #{dto.uuid, jdbcType=VARCHAR}, - #{dto.userId, jdbcType=INTEGER}, + #{dto.userUuid, jdbcType=VARCHAR}, #{dto.qProfileUuid, jdbcType=VARCHAR}, #{now, jdbcType=BIGINT} ) @@ -102,7 +102,7 @@ <delete id="delete" parameterType="map"> delete from qprofile_edit_users where qprofile_uuid = #{qProfileUuid, jdbcType=VARCHAR} - and user_id = #{userId, jdbcType=INTEGER} + and user_uuid = #{userUuid, jdbcType=VARCHAR} </delete> <delete id="deleteByQProfiles" parameterType="map"> @@ -112,13 +112,13 @@ <delete id="deleteByUser" parameterType="map"> delete from qprofile_edit_users - where user_id = #{userId, jdbcType=INTEGER} + where user_uuid = #{userUuid, jdbcType=VARCHAR} </delete> <delete id="deleteByOrganizationAndUser" parameterType="map"> delete from qprofile_edit_users <where> - user_id=#{userId, jdbcType=INTEGER} + user_uuid=#{userUuid, jdbcType=VARCHAR} and qprofile_uuid in ( select oq.uuid from org_qprofiles oq diff --git a/server/sonar-db-dao/src/schema/schema-sq.ddl b/server/sonar-db-dao/src/schema/schema-sq.ddl index 9a09829ee26..129fc3b2f18 100644 --- a/server/sonar-db-dao/src/schema/schema-sq.ddl +++ b/server/sonar-db-dao/src/schema/schema-sq.ddl @@ -760,13 +760,13 @@ CREATE UNIQUE INDEX "QPROFILE_EDIT_GROUPS_UNIQUE" ON "QPROFILE_EDIT_GROUPS"("GRO CREATE TABLE "QPROFILE_EDIT_USERS"( "UUID" VARCHAR(40) NOT NULL, - "USER_ID" INTEGER NOT NULL, "QPROFILE_UUID" VARCHAR(255) NOT NULL, - "CREATED_AT" BIGINT NOT NULL + "CREATED_AT" BIGINT NOT NULL, + "USER_UUID" VARCHAR(40) NOT NULL ); ALTER TABLE "QPROFILE_EDIT_USERS" ADD CONSTRAINT "PK_QPROFILE_EDIT_USERS" PRIMARY KEY("UUID"); CREATE INDEX "QPROFILE_EDIT_USERS_QPROFILE" ON "QPROFILE_EDIT_USERS"("QPROFILE_UUID"); -CREATE UNIQUE INDEX "QPROFILE_EDIT_USERS_UNIQUE" ON "QPROFILE_EDIT_USERS"("USER_ID", "QPROFILE_UUID"); +CREATE UNIQUE INDEX "QPROFILE_EDIT_USERS_UNIQUE" ON "QPROFILE_EDIT_USERS"("USER_UUID", "QPROFILE_UUID"); CREATE TABLE "QUALITY_GATE_CONDITIONS"( "PERIOD" INTEGER, diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditUsersDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditUsersDaoTest.java index 99de3f627bd..5a888863bee 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditUsersDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditUsersDaoTest.java @@ -23,8 +23,8 @@ import java.sql.SQLException; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; import org.sonar.api.impl.utils.TestSystem2; +import org.sonar.api.utils.System2; import org.sonar.db.DbTester; import org.sonar.db.Pagination; import org.sonar.db.organization.OrganizationDto; @@ -85,19 +85,19 @@ public class QProfileEditUsersDaoTest { .setOrganization(organization) .setProfile(profile) .setMembership(ANY).build())) - .isEqualTo(3); + .isEqualTo(3); assertThat(underTest.countByQuery(db.getSession(), builder() .setOrganization(organization) .setProfile(profile) .setMembership(IN).build())) - .isEqualTo(2); + .isEqualTo(2); assertThat(underTest.countByQuery(db.getSession(), builder() .setOrganization(organization) .setProfile(profile) .setMembership(OUT).build())) - .isEqualTo(1); + .isEqualTo(1); } @Test @@ -117,27 +117,27 @@ public class QProfileEditUsersDaoTest { .setOrganization(organization) .setProfile(profile) .setMembership(ANY).build(), Pagination.all())) - .extracting(UserMembershipDto::getUserId, UserMembershipDto::isSelected) - .containsExactlyInAnyOrder( - tuple(user1.getId(), true), - tuple(user2.getId(), true), - tuple(user3.getId(), false)); + .extracting(UserMembershipDto::getUserId, UserMembershipDto::isSelected) + .containsExactlyInAnyOrder( + tuple(user1.getId(), true), + tuple(user2.getId(), true), + tuple(user3.getId(), false)); assertThat(underTest.selectByQuery(db.getSession(), builder() - .setOrganization(organization) - .setProfile(profile) - .setMembership(IN).build(), + .setOrganization(organization) + .setProfile(profile) + .setMembership(IN).build(), Pagination.all())) - .extracting(UserMembershipDto::getUserId, UserMembershipDto::isSelected) - .containsExactlyInAnyOrder(tuple(user1.getId(), true), tuple(user2.getId(), true)); + .extracting(UserMembershipDto::getUserId, UserMembershipDto::isSelected) + .containsExactlyInAnyOrder(tuple(user1.getId(), true), tuple(user2.getId(), true)); assertThat(underTest.selectByQuery(db.getSession(), builder() - .setOrganization(organization) - .setProfile(profile) - .setMembership(OUT).build(), + .setOrganization(organization) + .setProfile(profile) + .setMembership(OUT).build(), Pagination.all())) - .extracting(UserMembershipDto::getUserId, UserMembershipDto::isSelected) - .containsExactlyInAnyOrder(tuple(user3.getId(), false)); + .extracting(UserMembershipDto::getUserId, UserMembershipDto::isSelected) + .containsExactlyInAnyOrder(tuple(user3.getId(), false)); } @Test @@ -155,31 +155,31 @@ public class QProfileEditUsersDaoTest { db.qualityProfiles().addUserPermission(profile, user3); assertThat(underTest.selectByQuery(db.getSession(), builder() - .setOrganization(organization) - .setProfile(profile) - .setMembership(IN) - .setQuery("user2").build(), + .setOrganization(organization) + .setProfile(profile) + .setMembership(IN) + .setQuery("user2").build(), Pagination.all())) - .extracting(UserMembershipDto::getUserId) - .containsExactlyInAnyOrder(user2.getId()); + .extracting(UserMembershipDto::getUserId) + .containsExactlyInAnyOrder(user2.getId()); assertThat(underTest.selectByQuery(db.getSession(), builder() - .setOrganization(organization) - .setProfile(profile) - .setMembership(IN) - .setQuery("joh").build(), + .setOrganization(organization) + .setProfile(profile) + .setMembership(IN) + .setQuery("joh").build(), Pagination.all())) - .extracting(UserMembershipDto::getUserId) - .containsExactlyInAnyOrder(user1.getId(), user2.getId()); + .extracting(UserMembershipDto::getUserId) + .containsExactlyInAnyOrder(user1.getId(), user2.getId()); assertThat(underTest.selectByQuery(db.getSession(), builder() - .setOrganization(organization) - .setProfile(profile) - .setMembership(IN) - .setQuery("Doe").build(), + .setOrganization(organization) + .setProfile(profile) + .setMembership(IN) + .setQuery("Doe").build(), Pagination.all())) - .extracting(UserMembershipDto::getUserId) - .containsExactlyInAnyOrder(user1.getId(), user3.getId()); + .extracting(UserMembershipDto::getUserId) + .containsExactlyInAnyOrder(user1.getId(), user3.getId()); } @Test @@ -196,31 +196,31 @@ public class QProfileEditUsersDaoTest { db.qualityProfiles().addUserPermission(profile, user2); assertThat(underTest.selectByQuery(db.getSession(), builder() - .setOrganization(organization) - .setProfile(profile) - .setMembership(ANY) - .build(), + .setOrganization(organization) + .setProfile(profile) + .setMembership(ANY) + .build(), Pagination.forPage(1).andSize(1))) - .extracting(UserMembershipDto::getUserId) - .containsExactly(user1.getId()); + .extracting(UserMembershipDto::getUserId) + .containsExactly(user1.getId()); assertThat(underTest.selectByQuery(db.getSession(), builder() - .setOrganization(organization) - .setProfile(profile) - .setMembership(ANY) - .build(), + .setOrganization(organization) + .setProfile(profile) + .setMembership(ANY) + .build(), Pagination.forPage(3).andSize(1))) - .extracting(UserMembershipDto::getUserId) - .containsExactly(user3.getId()); + .extracting(UserMembershipDto::getUserId) + .containsExactly(user3.getId()); assertThat(underTest.selectByQuery(db.getSession(), builder() - .setOrganization(organization) - .setProfile(profile) - .setMembership(ANY) - .build(), + .setOrganization(organization) + .setProfile(profile) + .setMembership(ANY) + .build(), Pagination.forPage(1).andSize(10))) - .extracting(UserMembershipDto::getUserId) - .containsExactly(user1.getId(), user2.getId(), user3.getId()); + .extracting(UserMembershipDto::getUserId) + .containsExactly(user1.getId(), user2.getId(), user3.getId()); } @Test @@ -246,32 +246,30 @@ public class QProfileEditUsersDaoTest { public void insert() { underTest.insert(db.getSession(), new QProfileEditUsersDto() .setUuid("ABCD") - .setUserId(100) - .setQProfileUuid("QPROFILE") - ); - - assertThat(db.selectFirst(db.getSession(), "select uuid as \"uuid\", user_id as \"userId\", qprofile_uuid as \"qProfileUuid\", created_at as \"createdAt\" from qprofile_edit_users")).contains( - entry("uuid", "ABCD"), - entry("userId", 100L), - entry("qProfileUuid", "QPROFILE"), - entry("createdAt", NOW)); + .setUserUuid("100") + .setQProfileUuid("QPROFILE")); + + assertThat(db.selectFirst(db.getSession(), + "select uuid as \"uuid\", user_uuid as \"userUuid\", qprofile_uuid as \"qProfileUuid\", created_at as \"createdAt\" from qprofile_edit_users")).contains( + entry("uuid", "ABCD"), + entry("userUuid", "100"), + entry("qProfileUuid", "QPROFILE"), + entry("createdAt", NOW)); } @Test public void fail_to_insert_same_row_twice() { underTest.insert(db.getSession(), new QProfileEditUsersDto() .setUuid("UUID-1") - .setUserId(100) - .setQProfileUuid("QPROFILE") - ); + .setUserUuid("100") + .setQProfileUuid("QPROFILE")); expectedException.expectCause(hasType(SQLException.class)); underTest.insert(db.getSession(), new QProfileEditUsersDto() .setUuid("UUID-2") - .setUserId(100) - .setQProfileUuid("QPROFILE") - ); + .setUserUuid("100") + .setQProfileUuid("QPROFILE")); } @Test diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/qualityprofile/QualityProfileDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/qualityprofile/QualityProfileDbTester.java index 349b319e7da..63be5801b23 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/qualityprofile/QualityProfileDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/qualityprofile/QualityProfileDbTester.java @@ -117,7 +117,7 @@ public class QualityProfileDbTester { checkArgument(!profile.isBuiltIn(), "Built-In profile cannot be used"); dbClient.qProfileEditUsersDao().insert(dbSession, new QProfileEditUsersDto() .setUuid(Uuids.createFast()) - .setUserId(user.getId()) + .setUserUuid(user.getUuid()) .setQProfileUuid(profile.getKee()) ); dbSession.commit(); diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/DbVersion83.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/DbVersion83.java index f567447bfba..c7fc42b7ff1 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/DbVersion83.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/DbVersion83.java @@ -282,6 +282,12 @@ import org.sonar.server.platform.db.migration.version.v83.users.fk.permtemplates import org.sonar.server.platform.db.migration.version.v83.users.fk.properties.AddUserUuidColumnToPropertiesUsers; import org.sonar.server.platform.db.migration.version.v83.users.fk.properties.DropUserIdColumnOfPropertiesTable; import org.sonar.server.platform.db.migration.version.v83.users.fk.properties.PopulatePropertiesUserUuid; +import org.sonar.server.platform.db.migration.version.v83.users.fk.qprofileeditusers.AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTable; +import org.sonar.server.platform.db.migration.version.v83.users.fk.qprofileeditusers.AddUserUuidColumnToQProfileEditUsers; +import org.sonar.server.platform.db.migration.version.v83.users.fk.qprofileeditusers.DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTable; +import org.sonar.server.platform.db.migration.version.v83.users.fk.qprofileeditusers.DropUserIdColumnOfQProfileEditUsersTable; +import org.sonar.server.platform.db.migration.version.v83.users.fk.qprofileeditusers.MakeQProfileEditUsersUserUuidColumnNotNullable; +import org.sonar.server.platform.db.migration.version.v83.users.fk.qprofileeditusers.PopulateQProfileEditUsersUserUuid; import org.sonar.server.platform.db.migration.version.v83.usertokens.AddPrimaryKeyOnUuidColumnOfUserTokensTable; import org.sonar.server.platform.db.migration.version.v83.usertokens.AddUuidColumnToUserTokens; import org.sonar.server.platform.db.migration.version.v83.usertokens.DropIdColumnOfUserTokensTable; @@ -682,6 +688,14 @@ public class DbVersion83 implements DbVersion { .add(3617, "Populate 'user_uuid' for 'PROPERTIES'", PopulatePropertiesUserUuid.class) .add(3618, "Drop column on 'user_id' column of 'PROPERTIES' table", DropUserIdColumnOfPropertiesTable.class) + // Migration of FK in QPROFILE_EDIT_USERS to USERS + .add(3619, "Add 'user_uuid' column on 'QPROFILE_EDIT_USERS' table", AddUserUuidColumnToQProfileEditUsers.class) + .add(3620, "Populate 'user_uuid' for 'QPROFILE_EDIT_USERS'", PopulateQProfileEditUsersUserUuid.class) + .add(3621, "Make 'user_uuid' not-null for 'QPROFILE_EDIT_USERS'", MakeQProfileEditUsersUserUuidColumnNotNullable.class) + .add(3622, "Drop unique index on 'user_id','qprofile_uuid' columns of 'QPROFILE_EDIT_USERS' table", DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTable.class) + .add(3623, "Add unique index on 'user_uuid','qprofile_uuid' columns of 'QPROFILE_EDIT_USERS' table", AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTable.class) + .add(3624, "Drop column on 'user_id' column of 'QPROFILE_EDIT_USERS' table", DropUserIdColumnOfQProfileEditUsersTable.class) + ; } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTable.java new file mode 100644 index 00000000000..46bbc23f541 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTable.java @@ -0,0 +1,64 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 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.v83.users.fk.qprofileeditusers; + +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; + +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; + +public class AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTable extends DdlChange { + private static final String TABLE_NAME = "qprofile_edit_users"; + private static final String INDEX_NAME = "qprofile_edit_users_unique"; + + public AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTable(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + if (!indexExists()) { + context.execute(new CreateIndexBuilder() + .setUnique(true) + .setTable(TABLE_NAME) + .setName(INDEX_NAME) + .addColumn(newVarcharColumnDefBuilder() + .setColumnName("user_uuid") + .setLimit(UUID_SIZE) + .build()) + .addColumn(newVarcharColumnDefBuilder() + .setColumnName("qprofile_uuid") + .setLimit(UUID_SIZE) + .build()) + .build()); + } + } + + private boolean indexExists() throws SQLException { + try (Connection connection = getDatabase().getDataSource().getConnection()) { + return DatabaseUtils.indexExists(TABLE_NAME, INDEX_NAME, connection); + } + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUserUuidColumnToQProfileEditUsers.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUserUuidColumnToQProfileEditUsers.java new file mode 100644 index 00000000000..3018ecaef87 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUserUuidColumnToQProfileEditUsers.java @@ -0,0 +1,30 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 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.v83.users.fk.qprofileeditusers; + +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.version.v83.users.fk.util.AddUserUuidColumnToTable; + +public class AddUserUuidColumnToQProfileEditUsers extends AddUserUuidColumnToTable { + + public AddUserUuidColumnToQProfileEditUsers(Database db) { + super(db, "qprofile_edit_users"); + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTable.java new file mode 100644 index 00000000000..b3d3e6ce23b --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTable.java @@ -0,0 +1,52 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 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.v83.users.fk.qprofileeditusers; + +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.DropIndexBuilder; +import org.sonar.server.platform.db.migration.step.DdlChange; + +public class DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTable extends DdlChange { + private static final String TABLE_NAME = "qprofile_edit_users"; + private static final String INDEX_NAME = "qprofile_edit_users_unique"; + + public DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTable(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + if (indexExists()) { + context.execute(new DropIndexBuilder(getDialect()) + .setTable(TABLE_NAME) + .setName(INDEX_NAME) + .build()); + } + } + + private boolean indexExists() throws SQLException { + try (Connection connection = getDatabase().getDataSource().getConnection()) { + return DatabaseUtils.indexExists(TABLE_NAME, INDEX_NAME, connection); + } + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUserIdColumnOfQProfileEditUsersTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUserIdColumnOfQProfileEditUsersTable.java new file mode 100644 index 00000000000..f0638133a90 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUserIdColumnOfQProfileEditUsersTable.java @@ -0,0 +1,36 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 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.v83.users.fk.qprofileeditusers; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder; +import org.sonar.server.platform.db.migration.step.DdlChange; + +public class DropUserIdColumnOfQProfileEditUsersTable extends DdlChange { + public DropUserIdColumnOfQProfileEditUsersTable(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + context.execute(new DropColumnsBuilder(getDialect(), "qprofile_edit_users", "user_id").build()); + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/MakeQProfileEditUsersUserUuidColumnNotNullable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/MakeQProfileEditUsersUserUuidColumnNotNullable.java new file mode 100644 index 00000000000..cb7b5144fa7 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/MakeQProfileEditUsersUserUuidColumnNotNullable.java @@ -0,0 +1,31 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 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.v83.users.fk.qprofileeditusers; + +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.version.v83.users.fk.util.MakeUserUuidColumnNotNullable; + +public class MakeQProfileEditUsersUserUuidColumnNotNullable extends MakeUserUuidColumnNotNullable { + private static final String TABLE_NAME = "qprofile_edit_users"; + + public MakeQProfileEditUsersUserUuidColumnNotNullable(Database db) { + super(db, TABLE_NAME); + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/PopulateQProfileEditUsersUserUuid.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/PopulateQProfileEditUsersUserUuid.java new file mode 100644 index 00000000000..0a10dc06008 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/PopulateQProfileEditUsersUserUuid.java @@ -0,0 +1,52 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 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.v83.users.fk.qprofileeditusers; + +import java.sql.SQLException; +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 PopulateQProfileEditUsersUserUuid extends DataChange { + + public PopulateQProfileEditUsersUserUuid(Database db) { + super(db); + } + + @Override + protected void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + + massUpdate.select("select qeu.uuid, u.uuid " + + "from qprofile_edit_users qeu " + + "join users u on qeu.user_id = u.id where qeu.user_uuid is null"); + + massUpdate.update("update qprofile_edit_users set user_uuid = ? where uuid = ?"); + + massUpdate.execute((row, update, index) -> { + String permTemplatesUuid = row.getString(1); + String userUuid = row.getString(2); + + update.setString(1, userUuid); + update.setString(2, permTemplatesUuid); + return true; + }); + } +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTableTest.java new file mode 100644 index 00000000000..f7aafed1ad5 --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTableTest.java @@ -0,0 +1,49 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 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.v83.users.fk.qprofileeditusers; + +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.DdlChange; + +public class AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTableTest { + + private static final String TABLE_NAME = "qprofile_edit_users"; + private static final String INDEX_NAME = "qprofile_edit_users_unique"; + + @Rule + public CoreDbTester dbTester = CoreDbTester.createForSchema(AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTableTest.class, "schema.sql"); + + DdlChange underTest = new AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTable(dbTester.database()); + + @Test + public void add_index() throws SQLException { + underTest.execute(); + dbTester.assertUniqueIndex(TABLE_NAME, INDEX_NAME, "user_uuid", "qprofile_uuid"); + } + + @Test + public void migration_is_reentrant() throws SQLException { + underTest.execute(); + dbTester.assertUniqueIndex(TABLE_NAME, INDEX_NAME, "user_uuid", "qprofile_uuid"); + } +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUserUuidColumnToQProfileEditUsersTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUserUuidColumnToQProfileEditUsersTest.java new file mode 100644 index 00000000000..4beb6c96eef --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUserUuidColumnToQProfileEditUsersTest.java @@ -0,0 +1,64 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 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.v83.users.fk.qprofileeditusers; + +import java.sql.SQLException; +import java.sql.Types; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.core.util.Uuids; +import org.sonar.db.CoreDbTester; +import org.sonar.server.platform.db.migration.step.DdlChange; + +import static org.assertj.core.api.Assertions.assertThat; + +public class AddUserUuidColumnToQProfileEditUsersTest { + + @Rule + public CoreDbTester db = CoreDbTester.createForSchema(AddUserUuidColumnToQProfileEditUsersTest.class, "schema.sql"); + + private DdlChange underTest = new AddUserUuidColumnToQProfileEditUsers(db.database()); + + @Before + public void setup() { + insertQProfileEditUser(Uuids.createFast(), 1L); + insertQProfileEditUser(Uuids.createFast(), 2L); + insertQProfileEditUser(Uuids.createFast(), 3L); + } + + @Test + public void add_uuid_column() throws SQLException { + underTest.execute(); + + db.assertColumnDefinition("qprofile_edit_users", "user_uuid", Types.VARCHAR, 40, true); + + assertThat(db.countSql("select count(*) from qprofile_edit_users")) + .isEqualTo(3); + } + + private void insertQProfileEditUser(String uuid, long userId) { + db.executeInsert("qprofile_edit_users", + "uuid", uuid, + "user_id", userId, + "qprofile_uuid", Uuids.createFast(), + "created_at", System.currentTimeMillis()); + } +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTableTest.java new file mode 100644 index 00000000000..e7669043943 --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTableTest.java @@ -0,0 +1,50 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 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.v83.users.fk.qprofileeditusers; + +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.DdlChange; + +public class DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTableTest { + + private static final String TABLE_NAME = "qprofile_edit_users"; + private static final String INDEX_NAME = "qprofile_edit_users_unique"; + + @Rule + public CoreDbTester dbTester = CoreDbTester.createForSchema(DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTableTest.class, "schema.sql"); + + DdlChange underTest = new DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTable(dbTester.database()); + + @Test + public void add_index() throws SQLException { + underTest.execute(); + dbTester.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + } + + @Test + public void migration_is_reentrant() throws SQLException { + underTest.execute(); + dbTester.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + } + +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUserIdColumnOfQProfileEditUsersTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUserIdColumnOfQProfileEditUsersTableTest.java new file mode 100644 index 00000000000..f5b8acdd528 --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUserIdColumnOfQProfileEditUsersTableTest.java @@ -0,0 +1,51 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 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.v83.users.fk.qprofileeditusers; + +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.DdlChange; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class DropUserIdColumnOfQProfileEditUsersTableTest { + + @Rule + public CoreDbTester db = CoreDbTester.createForSchema(DropUserIdColumnOfQProfileEditUsersTableTest.class, "schema.sql"); + + private DdlChange underTest = new DropUserIdColumnOfQProfileEditUsersTable(db.database()); + + @Test + public void execute() throws SQLException { + underTest.execute(); + + db.assertColumnDoesNotExist("qprofile_edit_users", "user_id"); + } + + @Test + public void migration_is_not_re_entrant() throws SQLException { + underTest.execute(); + + assertThatThrownBy(() -> underTest.execute()).isInstanceOf(IllegalStateException.class); + } + +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/MakeQProfileEditUsersUserUuidColumnNotNullableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/MakeQProfileEditUsersUserUuidColumnNotNullableTest.java new file mode 100644 index 00000000000..1d6b6f54e36 --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/MakeQProfileEditUsersUserUuidColumnNotNullableTest.java @@ -0,0 +1,43 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 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.v83.users.fk.qprofileeditusers; + +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.MigrationStep; + +import static java.sql.Types.VARCHAR; +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; + +public class MakeQProfileEditUsersUserUuidColumnNotNullableTest { + @Rule + public CoreDbTester db = CoreDbTester.createForSchema(MakeQProfileEditUsersUserUuidColumnNotNullableTest.class, "schema.sql"); + + private MigrationStep underTest = new MakeQProfileEditUsersUserUuidColumnNotNullable(db.database()); + + @Test + public void uuid_column_is_not_null() throws SQLException { + underTest.execute(); + + db.assertColumnDefinition("qprofile_edit_users", "user_uuid", VARCHAR, UUID_SIZE, false); + } +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/PopulateQProfileEditUsersUserUuidTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/PopulateQProfileEditUsersUserUuidTest.java new file mode 100644 index 00000000000..28e18bf816d --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/PopulateQProfileEditUsersUserUuidTest.java @@ -0,0 +1,145 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 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.v83.users.fk.qprofileeditusers; + +import java.sql.SQLException; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.core.util.Uuids; +import org.sonar.db.CoreDbTester; +import org.sonar.server.platform.db.migration.step.DataChange; + +import static org.assertj.core.api.Assertions.assertThat; + +public class PopulateQProfileEditUsersUserUuidTest { + + @Rule + public CoreDbTester db = CoreDbTester.createForSchema(PopulateQProfileEditUsersUserUuidTest.class, "schema.sql"); + + private DataChange underTest = new PopulateQProfileEditUsersUserUuid(db.database()); + + @Test + public void populate_uuids() throws SQLException { + long userId_1 = 1L; + String userUuid_1 = "uuid-1"; + insertUser(userId_1, userUuid_1); + + long userId_2 = 2L; + String userUuid_2 = "uuid-2"; + insertUser(userId_2, userUuid_2); + + long userId_3 = 3L; + String userUuid_3 = "uuid-3"; + insertUser(userId_3, userUuid_3); + + long userId_4 = 4L; + String userUuid_4 = "uuid-4"; + insertUser(userId_4, userUuid_4); + + String qprofileEditUserUuid_1 = Uuids.createFast(); + insertQProfileEditUser(qprofileEditUserUuid_1, userId_1); + String qprofileEditUserUuid_2 = Uuids.createFast(); + insertQProfileEditUser(qprofileEditUserUuid_2, userId_2); + String qprofileEditUserUuid_3 = Uuids.createFast(); + insertQProfileEditUser(qprofileEditUserUuid_3, userId_3); + String qprofileEditUserUuid_4 = Uuids.createFast(); + insertQProfileEditUser(qprofileEditUserUuid_4, userId_4); + String qprofileEditUserUuid_5 = Uuids.createFast(); + insertQProfileEditUser(qprofileEditUserUuid_5, userId_1); + + underTest.execute(); + + assertThatQProfileEditUserUserUuidIsEqualTo(qprofileEditUserUuid_1, userUuid_1); + assertThatQProfileEditUserUserUuidIsEqualTo(qprofileEditUserUuid_2, userUuid_2); + assertThatQProfileEditUserUserUuidIsEqualTo(qprofileEditUserUuid_3, userUuid_3); + assertThatQProfileEditUserUserUuidIsEqualTo(qprofileEditUserUuid_4, userUuid_4); + assertThatQProfileEditUserUserUuidIsEqualTo(qprofileEditUserUuid_5, userUuid_1); + } + + @Test + public void migration_is_reentrant() throws SQLException { + long userId_1 = 1L; + String userUuid_1 = "uuid-1"; + insertUser(userId_1, userUuid_1); + + long userId_2 = 2L; + String userUuid_2 = "uuid-2"; + insertUser(userId_2, userUuid_2); + + long userId_3 = 3L; + String userUuid_3 = "uuid-3"; + insertUser(userId_3, userUuid_3); + + long userId_4 = 4L; + String userUuid_4 = "uuid-4"; + insertUser(userId_4, userUuid_4); + + String qprofileEditUserUuid_1 = Uuids.createFast(); + insertQProfileEditUser(qprofileEditUserUuid_1, userId_1); + String qprofileEditUserUuid_2 = Uuids.createFast(); + insertQProfileEditUser(qprofileEditUserUuid_2, userId_2); + String qprofileEditUserUuid_3 = Uuids.createFast(); + insertQProfileEditUser(qprofileEditUserUuid_3, userId_3); + + underTest.execute(); + + String qprofileEditUserUuid_4 = Uuids.createFast(); + insertQProfileEditUser(qprofileEditUserUuid_4, userId_4); + String qprofileEditUserUuid_5 = Uuids.createFast(); + insertQProfileEditUser(qprofileEditUserUuid_5, userId_1); + + // re-entrant + underTest.execute(); + + assertThatQProfileEditUserUserUuidIsEqualTo(qprofileEditUserUuid_1, userUuid_1); + assertThatQProfileEditUserUserUuidIsEqualTo(qprofileEditUserUuid_2, userUuid_2); + assertThatQProfileEditUserUserUuidIsEqualTo(qprofileEditUserUuid_3, userUuid_3); + assertThatQProfileEditUserUserUuidIsEqualTo(qprofileEditUserUuid_4, userUuid_4); + assertThatQProfileEditUserUserUuidIsEqualTo(qprofileEditUserUuid_5, userUuid_1); + } + + private void assertThatQProfileEditUserUserUuidIsEqualTo(String qprofileEditUserUuid, String expectedUuid) { + assertThat(db.select(String.format("select user_uuid from qprofile_edit_users where uuid = '%s'", qprofileEditUserUuid)) + .stream() + .map(row -> row.get("USER_UUID")) + .findFirst()) + .hasValue(expectedUuid); + } + + private void insertQProfileEditUser(String uuid, long userId) { + db.executeInsert("qprofile_edit_users", + "uuid", uuid, + "user_id", userId, + "qprofile_uuid", Uuids.createFast(), + "created_at", System.currentTimeMillis()); + } + + private void insertUser(Long id, String uuid) { + db.executeInsert("users", + "id", id, + "uuid", uuid, + "login", "login" + id, + "external_login", "ex-login" + id, + "external_identity_provider", "ex-provider" + id, + "external_id", id + 1, + "is_root", false, + "onboarded", false); + } +} diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTableTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTableTest/schema.sql new file mode 100644 index 00000000000..6111eb1f8e1 --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTableTest/schema.sql @@ -0,0 +1,9 @@ +CREATE TABLE "QPROFILE_EDIT_USERS"( + "UUID" VARCHAR(40) NOT NULL, + "USER_ID" INTEGER NOT NULL, + "QPROFILE_UUID" VARCHAR(255) NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "USER_UUID" VARCHAR(40) NOT NULL +); +ALTER TABLE "QPROFILE_EDIT_USERS" ADD CONSTRAINT "PK_QPROFILE_EDIT_USERS" PRIMARY KEY("UUID"); +CREATE INDEX "QPROFILE_EDIT_USERS_QPROFILE" ON "QPROFILE_EDIT_USERS"("QPROFILE_UUID"); diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUserUuidColumnToQProfileEditUsersTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUserUuidColumnToQProfileEditUsersTest/schema.sql new file mode 100644 index 00000000000..1149cf96ee7 --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUserUuidColumnToQProfileEditUsersTest/schema.sql @@ -0,0 +1,9 @@ +CREATE TABLE "QPROFILE_EDIT_USERS"( + "UUID" VARCHAR(40) NOT NULL, + "USER_ID" INTEGER NOT NULL, + "QPROFILE_UUID" VARCHAR(255) NOT NULL, + "CREATED_AT" BIGINT NOT NULL +); +ALTER TABLE "QPROFILE_EDIT_USERS" ADD CONSTRAINT "PK_QPROFILE_EDIT_USERS" PRIMARY KEY("UUID"); +CREATE INDEX "QPROFILE_EDIT_USERS_QPROFILE" ON "QPROFILE_EDIT_USERS"("QPROFILE_UUID"); +CREATE UNIQUE INDEX "QPROFILE_EDIT_USERS_UNIQUE" ON "QPROFILE_EDIT_USERS"("USER_ID", "QPROFILE_UUID"); diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTableTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTableTest/schema.sql new file mode 100644 index 00000000000..94fa29f1c1a --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTableTest/schema.sql @@ -0,0 +1,10 @@ +CREATE TABLE "QPROFILE_EDIT_USERS"( + "UUID" VARCHAR(40) NOT NULL, + "USER_ID" INTEGER NOT NULL, + "QPROFILE_UUID" VARCHAR(255) NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "USER_UUID" VARCHAR(40) NOT NULL +); +ALTER TABLE "QPROFILE_EDIT_USERS" ADD CONSTRAINT "PK_QPROFILE_EDIT_USERS" PRIMARY KEY("UUID"); +CREATE INDEX "QPROFILE_EDIT_USERS_QPROFILE" ON "QPROFILE_EDIT_USERS"("QPROFILE_UUID"); +CREATE UNIQUE INDEX "QPROFILE_EDIT_USERS_UNIQUE" ON "QPROFILE_EDIT_USERS"("USER_ID", "QPROFILE_UUID"); diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUserIdColumnOfQProfileEditUsersTableTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUserIdColumnOfQProfileEditUsersTableTest/schema.sql new file mode 100644 index 00000000000..e1a14b02b7b --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUserIdColumnOfQProfileEditUsersTableTest/schema.sql @@ -0,0 +1,10 @@ +CREATE TABLE "QPROFILE_EDIT_USERS"( + "UUID" VARCHAR(40) NOT NULL, + "USER_ID" INTEGER NOT NULL, + "QPROFILE_UUID" VARCHAR(255) NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "USER_UUID" VARCHAR(40) NOT NULL +); +ALTER TABLE "QPROFILE_EDIT_USERS" ADD CONSTRAINT "PK_QPROFILE_EDIT_USERS" PRIMARY KEY("UUID"); +CREATE INDEX "QPROFILE_EDIT_USERS_QPROFILE" ON "QPROFILE_EDIT_USERS"("QPROFILE_UUID"); +CREATE UNIQUE INDEX "QPROFILE_EDIT_USERS_UNIQUE" ON "QPROFILE_EDIT_USERS"("USER_UUID", "QPROFILE_UUID"); diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/MakeQProfileEditUsersUserUuidColumnNotNullableTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/MakeQProfileEditUsersUserUuidColumnNotNullableTest/schema.sql new file mode 100644 index 00000000000..d1a00b9e64b --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/MakeQProfileEditUsersUserUuidColumnNotNullableTest/schema.sql @@ -0,0 +1,10 @@ +CREATE TABLE "QPROFILE_EDIT_USERS"( + "UUID" VARCHAR(40) NOT NULL, + "USER_ID" INTEGER NOT NULL, + "QPROFILE_UUID" VARCHAR(255) NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "USER_UUID" VARCHAR(40) +); +ALTER TABLE "QPROFILE_EDIT_USERS" ADD CONSTRAINT "PK_QPROFILE_EDIT_USERS" PRIMARY KEY("UUID"); +CREATE INDEX "QPROFILE_EDIT_USERS_QPROFILE" ON "QPROFILE_EDIT_USERS"("QPROFILE_UUID"); +CREATE UNIQUE INDEX "QPROFILE_EDIT_USERS_UNIQUE" ON "QPROFILE_EDIT_USERS"("USER_ID", "QPROFILE_UUID"); diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/PopulateQProfileEditUsersUserUuidTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/PopulateQProfileEditUsersUserUuidTest/schema.sql new file mode 100644 index 00000000000..d10b8b5184c --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/PopulateQProfileEditUsersUserUuidTest/schema.sql @@ -0,0 +1,41 @@ +CREATE TABLE "USERS"( + "ID" INTEGER NOT NULL AUTO_INCREMENT (1,1), + "UUID" VARCHAR(255) NOT NULL, + "LOGIN" VARCHAR(255) NOT NULL, + "ORGANIZATION_UUID" VARCHAR(40), + "NAME" VARCHAR(200), + "EMAIL" VARCHAR(100), + "CRYPTED_PASSWORD" VARCHAR(100), + "SALT" VARCHAR(40), + "HASH_METHOD" VARCHAR(10), + "ACTIVE" BOOLEAN DEFAULT TRUE, + "SCM_ACCOUNTS" VARCHAR(4000), + "EXTERNAL_LOGIN" VARCHAR(255) NOT NULL, + "EXTERNAL_IDENTITY_PROVIDER" VARCHAR(100) NOT NULL, + "EXTERNAL_ID" VARCHAR(255) NOT NULL, + "IS_ROOT" BOOLEAN NOT NULL, + "USER_LOCAL" BOOLEAN, + "ONBOARDED" BOOLEAN NOT NULL, + "HOMEPAGE_TYPE" VARCHAR(40), + "HOMEPAGE_PARAMETER" VARCHAR(40), + "LAST_CONNECTION_DATE" BIGINT, + "CREATED_AT" BIGINT, + "UPDATED_AT" BIGINT +); +ALTER TABLE "USERS" ADD CONSTRAINT "PK_USERS" PRIMARY KEY("ID"); +CREATE UNIQUE INDEX "USERS_LOGIN" ON "USERS"("LOGIN"); +CREATE INDEX "USERS_UPDATED_AT" ON "USERS"("UPDATED_AT"); +CREATE UNIQUE INDEX "USERS_UUID" ON "USERS"("UUID"); +CREATE UNIQUE INDEX "UNIQ_EXTERNAL_ID" ON "USERS"("EXTERNAL_IDENTITY_PROVIDER", "EXTERNAL_ID"); +CREATE UNIQUE INDEX "UNIQ_EXTERNAL_LOGIN" ON "USERS"("EXTERNAL_IDENTITY_PROVIDER", "EXTERNAL_LOGIN"); + +CREATE TABLE "QPROFILE_EDIT_USERS"( + "UUID" VARCHAR(40) NOT NULL, + "USER_ID" INTEGER NOT NULL, + "QPROFILE_UUID" VARCHAR(255) NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "USER_UUID" VARCHAR(40) +); +ALTER TABLE "QPROFILE_EDIT_USERS" ADD CONSTRAINT "PK_QPROFILE_EDIT_USERS" PRIMARY KEY("UUID"); +CREATE INDEX "QPROFILE_EDIT_USERS_QPROFILE" ON "QPROFILE_EDIT_USERS"("QPROFILE_UUID"); +CREATE UNIQUE INDEX "QPROFILE_EDIT_USERS_UNIQUE" ON "QPROFILE_EDIT_USERS"("USER_ID", "QPROFILE_UUID"); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/AddUserAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/AddUserAction.java index 9c2517b268d..1c8c2fec8fc 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/AddUserAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/AddUserAction.java @@ -108,7 +108,7 @@ public class AddUserAction implements QProfileWsAction { dbClient.qProfileEditUsersDao().insert(dbSession, new QProfileEditUsersDto() .setUuid(uuidFactory.create()) - .setUserId(user.getId()) + .setUserUuid(user.getUuid()) .setQProfileUuid(profile.getKee())); dbSession.commit(); } |