Skip to content

Commit ce64fe3

Browse files
bogdanakushnirsonartech
authored andcommitted
SONAR-26264 Allow Slack app multiple workspace installation and assign correct userType
1 parent a7d353d commit ce64fe3

File tree

6 files changed

+208
-1
lines changed

6 files changed

+208
-1
lines changed

server/sonar-db-dao/src/schema/schema-sq.ddl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1415,8 +1415,8 @@ CREATE TABLE "USER_BINDINGS"(
14151415
"UPDATED_AT" BIGINT NOT NULL
14161416
);
14171417
ALTER TABLE "USER_BINDINGS" ADD CONSTRAINT "PK_USER_BINDINGS" PRIMARY KEY("UUID");
1418-
CREATE UNIQUE NULLS NOT DISTINCT INDEX "UB_USER_INTEGRATION_CONFIG" ON "USER_BINDINGS"("USER_UUID" NULLS FIRST, "INTEGRATION_CONFIG_UUID" NULLS FIRST);
14191418
CREATE INDEX "UB_INTEGRATION_CONFIG_UUID" ON "USER_BINDINGS"("INTEGRATION_CONFIG_UUID" NULLS FIRST);
1419+
CREATE INDEX "USER_BINDINGS_USER_UUID" ON "USER_BINDINGS"("USER_UUID" NULLS FIRST);
14201420

14211421
CREATE TABLE "USER_BINDINGS_SLACK"(
14221422
"UUID" CHARACTER VARYING(40) NOT NULL,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* SonarQube
3+
* Copyright (C) 2009-2025 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
package org.sonar.server.platform.db.migration.version.v202506;
21+
22+
import java.sql.SQLException;
23+
import org.junit.jupiter.api.Test;
24+
import org.junit.jupiter.api.extension.RegisterExtension;
25+
import org.sonar.db.MigrationDbTester;
26+
import org.sonar.server.platform.db.migration.step.DdlChange;
27+
28+
import static org.sonar.server.platform.db.migration.version.v202506.CreateIndexOnUserBindingsUserUuid.COLUMN_NAME_USER_UUID;
29+
import static org.sonar.server.platform.db.migration.version.v202506.CreateIndexOnUserBindingsUserUuid.INDEX_NAME;
30+
import static org.sonar.server.platform.db.migration.version.v202506.CreateIndexOnUserBindingsUserUuid.TABLE_NAME;
31+
32+
class CreateIndexOnUserBindingsUserUuidIT {
33+
34+
@RegisterExtension
35+
public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexOnUserBindingsUserUuid.class);
36+
private final DdlChange underTest = new CreateIndexOnUserBindingsUserUuid(db.database());
37+
38+
@Test
39+
void execute_shouldCreateIndex() throws SQLException {
40+
db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME);
41+
42+
underTest.execute();
43+
44+
db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_USER_UUID);
45+
}
46+
47+
@Test
48+
void execute_shouldBeReentrant() throws SQLException {
49+
db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME);
50+
51+
underTest.execute();
52+
// should not fail when executed twice
53+
underTest.execute();
54+
55+
db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_USER_UUID);
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* SonarQube
3+
* Copyright (C) 2009-2025 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
package org.sonar.server.platform.db.migration.version.v202506;
21+
22+
import java.sql.Connection;
23+
import java.sql.SQLException;
24+
import org.sonar.db.Database;
25+
import org.sonar.db.DatabaseUtils;
26+
import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
27+
import org.sonar.server.platform.db.migration.step.DdlChange;
28+
29+
public class CreateIndexOnUserBindingsUserUuid extends DdlChange {
30+
31+
static final String TABLE_NAME = "user_bindings";
32+
static final String INDEX_NAME = "user_bindings_user_uuid";
33+
static final String COLUMN_NAME_USER_UUID = "user_uuid";
34+
35+
public CreateIndexOnUserBindingsUserUuid(Database db) {
36+
super(db);
37+
}
38+
39+
@Override
40+
public void execute(Context context) throws SQLException {
41+
try (Connection connection = getDatabase().getDataSource().getConnection()) {
42+
createIndex(context, connection);
43+
}
44+
}
45+
46+
private void createIndex(Context context, Connection connection) {
47+
if (!DatabaseUtils.indexExistsIgnoreCase(TABLE_NAME, INDEX_NAME, connection)) {
48+
context.execute(new CreateIndexBuilder(getDialect())
49+
.setTable(TABLE_NAME)
50+
.setName(INDEX_NAME)
51+
.addColumn(COLUMN_NAME_USER_UUID, false)
52+
.build());
53+
}
54+
}
55+
}

server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202506/DbVersion202506.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public void addSteps(MigrationStepRegistry registry) {
4444
.add(2025_06_014, "Populate 'issue_stats_by_rule_key'", PopulateIssueStatsByRuleKey.class)
4545
.add(2025_06_015, "Add 'created_by' column to 'jira_work_items' table", AddCreatedByColumnToJiraWorkItemsTable.class)
4646
.add(2025_06_016, "Add index based on 'resource_id' and 'resource_type' to 'jira_work_items_resources' table", AddResourceIndexForJiraWorkItemsResourcesTable.class)
47+
.add(2025_06_017, "Remove unique index from 'user_bindings' table", RemoveUniqueIndexFromUserBindingsTable.class)
48+
.add(2025_06_018, "Create index on 'user_uuid' column in 'user_bindings' table", CreateIndexOnUserBindingsUserUuid.class)
4749
;
4850
}
4951

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* SonarQube
3+
* Copyright (C) 2009-2025 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
package org.sonar.server.platform.db.migration.version.v202506;
21+
22+
import org.sonar.db.Database;
23+
import org.sonar.server.platform.db.migration.step.DropIndexChange;
24+
25+
public class RemoveUniqueIndexFromUserBindingsTable extends DropIndexChange {
26+
27+
private static final String TABLE_NAME = "user_bindings";
28+
private static final String INDEX_NAME = "ub_user_integration_config";
29+
30+
public RemoveUniqueIndexFromUserBindingsTable(Database db) {
31+
super(db, INDEX_NAME, TABLE_NAME);
32+
}
33+
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* SonarQube
3+
* Copyright (C) 2009-2025 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
package org.sonar.server.platform.db.migration.version.v202506;
21+
22+
import java.sql.SQLException;
23+
import org.junit.jupiter.api.Test;
24+
import org.junit.jupiter.api.extension.RegisterExtension;
25+
import org.sonar.db.MigrationDbTester;
26+
27+
import static org.sonar.server.platform.db.migration.version.v202506.CreateUserBindingsTable.COLUMN_INTEGRATION_CONFIG_UUID;
28+
import static org.sonar.server.platform.db.migration.version.v202506.CreateUserBindingsTable.COLUMN_USER_UUID;
29+
import static org.sonar.server.platform.db.migration.version.v202506.CreateUserBindingsTable.USER_BINDINGS_TABLE_NAME;
30+
31+
class RemoveUniqueIndexFromUserBindingsTableTest {
32+
33+
@RegisterExtension
34+
public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RemoveUniqueIndexFromUserBindingsTable.class);
35+
36+
private final CreateUserBindingsTable createTableMigration = new CreateUserBindingsTable(db.database());
37+
private final RemoveUniqueIndexFromUserBindingsTable underTest = new RemoveUniqueIndexFromUserBindingsTable(db.database());
38+
39+
@Test
40+
void migration_should_remove_unique_index() throws SQLException {
41+
createTableMigration.execute();
42+
db.assertUniqueIndex(USER_BINDINGS_TABLE_NAME, "ub_user_integration_config", COLUMN_USER_UUID, COLUMN_INTEGRATION_CONFIG_UUID);
43+
44+
underTest.execute();
45+
46+
db.assertIndexDoesNotExist(USER_BINDINGS_TABLE_NAME, "ub_user_integration_config");
47+
}
48+
49+
@Test
50+
void migration_should_be_reentrant() throws SQLException {
51+
createTableMigration.execute();
52+
53+
underTest.execute();
54+
underTest.execute();
55+
56+
db.assertIndexDoesNotExist(USER_BINDINGS_TABLE_NAME, "ub_user_integration_config");
57+
}
58+
59+
}

0 commit comments

Comments
 (0)