aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorJacek <jacek.poreda@sonarsource.com>2020-04-30 15:30:41 +0200
committersonartech <sonartech@sonarsource.com>2020-05-25 20:05:22 +0000
commit584c92dff0d1d904c770ecace709bb6e6d895ec3 (patch)
treee2147c6c235ccf7d06266ce2747bf100440ebd57 /server
parent7925b2f67b87f0d3d6086a3b006e276341f70566 (diff)
downloadsonarqube-584c92dff0d1d904c770ecace709bb6e6d895ec3.tar.gz
sonarqube-584c92dff0d1d904c770ecace709bb6e6d895ec3.zip
SONAR-13221 change QPROFILE_EDIT_USERS user_id FK to user_uuid
Diffstat (limited to 'server')
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDao.java10
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDto.java10
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersMapper.java10
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditUsersMapper.xml18
-rw-r--r--server/sonar-db-dao/src/schema/schema-sq.ddl6
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditUsersDaoTest.java138
-rw-r--r--server/sonar-db-dao/src/testFixtures/java/org/sonar/db/qualityprofile/QualityProfileDbTester.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/DbVersion83.java14
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTable.java64
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUserUuidColumnToQProfileEditUsers.java30
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTable.java52
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUserIdColumnOfQProfileEditUsersTable.java36
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/MakeQProfileEditUsersUserUuidColumnNotNullable.java31
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/PopulateQProfileEditUsersUserUuid.java52
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTableTest.java49
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUserUuidColumnToQProfileEditUsersTest.java64
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTableTest.java50
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUserIdColumnOfQProfileEditUsersTableTest.java51
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/MakeQProfileEditUsersUserUuidColumnNotNullableTest.java43
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/PopulateQProfileEditUsersUserUuidTest.java145
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUniqueIndexOnUserUuidAndQProfileUuidOfQProfileEditUsersTableTest/schema.sql9
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/AddUserUuidColumnToQProfileEditUsersTest/schema.sql9
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUniqueIndexOnUserIdAndQProfileUuidOfQProfileEditUsersTableTest/schema.sql10
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/DropUserIdColumnOfQProfileEditUsersTableTest/schema.sql10
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/MakeQProfileEditUsersUserUuidColumnNotNullableTest/schema.sql10
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/users/fk/qprofileeditusers/PopulateQProfileEditUsersUserUuidTest/schema.sql41
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/AddUserAction.java2
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();
}