diff options
author | Travis Collins <travistx@gmail.com> | 2025-03-13 14:49:26 -0600 |
---|---|---|
committer | Matteo Mara <matteo.mara@sonarsource.com> | 2025-03-17 22:23:20 +0100 |
commit | 9042dc991247cb82fe011994c8e0414658164e83 (patch) | |
tree | f9b244e8752e27912433d01f5ba7fa92c5605dcc | |
parent | 0cb598a8d618308002ee5c9a15f43b9d13ab2dc3 (diff) | |
download | sonarqube-9042dc991247cb82fe011994c8e0414658164e83.tar.gz sonarqube-9042dc991247cb82fe011994c8e0414658164e83.zip |
SCA-125 Perf: releases endpoint (#13178)
14 files changed, 283 insertions, 56 deletions
diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaDependenciesDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaDependenciesDaoIT.java index 67546dd215f..f122c8eefb8 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaDependenciesDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaDependenciesDaoIT.java @@ -41,7 +41,7 @@ class ScaDependenciesDaoIT { @Test void insert_shouldPersistScaDependencies() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaDependencyDto scaDependencyDto = db.getScaDependenciesDbTester().insertScaDependency(componentDto.uuid(), "scaReleaseUuid", "1", true); List<Map<String, Object>> select = db.select(db.getSession(), "select * from sca_dependencies"); @@ -63,7 +63,7 @@ class ScaDependenciesDaoIT { @Test void deleteByUuid_shouldDeleteScaDependencies() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaDependencyDto scaDependencyDto = db.getScaDependenciesDbTester().insertScaDependency(componentDto.uuid(), "scaReleaseUuid", "1", true); List<Map<String, Object>> select = db.select(db.getSession(), "select * from sca_dependencies"); @@ -77,7 +77,7 @@ class ScaDependenciesDaoIT { @Test void selectByUuid_shouldLoadScaDependency() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaDependencyDto scaDependencyDto = db.getScaDependenciesDbTester().insertScaDependency(componentDto.uuid(), "scaReleaseUuid", "1", true); var loadedOptional = scaDependenciesDao.selectByUuid(db.getSession(), scaDependencyDto.uuid()); @@ -87,7 +87,7 @@ class ScaDependenciesDaoIT { @Test void selectByReleaseUuids_shouldReturnScaDependencies() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaDependencyDto scaDependencyDto1a = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "1a", true, PackageManager.MAVEN, "foo.bar1"); // same release, different dependency ScaDependencyDto scaDependencyDto1b = db.getScaDependenciesDbTester().insertScaDependency(componentDto.uuid(), scaDependencyDto1a.scaReleaseUuid(), "1b", false); @@ -103,7 +103,7 @@ class ScaDependenciesDaoIT { @Test void selectByQuery_shouldReturnScaDependencies_whenQueryByBranchUuid() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaDependencyDto scaDependencyDto1 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "1", true, PackageManager.MAVEN, "foo.bar"); // same release, different dependency ScaDependencyDto scaDependencyDto2 = db.getScaDependenciesDbTester().insertScaDependency(componentDto.uuid(), scaDependencyDto1.scaReleaseUuid(), "2", false); @@ -116,7 +116,7 @@ class ScaDependenciesDaoIT { @Test void selectByQuery_shouldReturnPaginatedScaDependencies() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaDependencyDto scaDependencyDto1 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "1", true, PackageManager.MAVEN, "foo.bar"); ScaDependencyDto scaDependencyDto2 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "2", true, PackageManager.MAVEN, "foo.bar"); ScaDependencyDto scaDependencyDto3 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "3", true, PackageManager.MAVEN, "something"); @@ -135,7 +135,7 @@ class ScaDependenciesDaoIT { @Test void selectByQuery_shouldPartiallyMatchPackageName_whenQueriedByText() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaDependencyDto scaDependencyDto1 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "1", true, PackageManager.MAVEN, "foo.bar"); @SuppressWarnings("unused") ScaDependencyDto scaDependencyDto2 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "2", true, PackageManager.MAVEN, "bar.mee"); @@ -160,7 +160,7 @@ class ScaDependenciesDaoIT { @Test void selectByQuery_shouldReturnScaDependencies_whenQueryByDirect() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaDependencyDto scaDependencyDto1 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "1", true, PackageManager.MAVEN, "foo.bar"); ScaDependencyDto scaDependencyDto2 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "2", false, PackageManager.MAVEN, "foo.bar"); @@ -179,7 +179,7 @@ class ScaDependenciesDaoIT { @Test void selectByQuery_shouldReturnScaDependencies_whenQueryByPackageManager() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaDependencyDto scaDependencyDto1 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "1", true, PackageManager.MAVEN, "foo.bar"); ScaDependencyDto scaDependencyDto2 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "2", true, PackageManager.NPM, "foo.bar"); ScaDependencyDto scaDependencyDto3 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "3", true, PackageManager.CARGO, "foo.bar"); @@ -201,7 +201,7 @@ class ScaDependenciesDaoIT { @Test void update_shouldUpdateScaDependency() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaDependencyDto scaDependencyDto = db.getScaDependenciesDbTester().insertScaDependency(componentDto.uuid(), "scaReleaseUuid", "1", true); ScaDependencyDto updatedScaDependency = scaDependencyDto.toBuilder().setUpdatedAt(scaDependencyDto.updatedAt() + 1).setDirect(false).setLockfileDependencyFilePath("lockfile2") .build(); @@ -227,7 +227,7 @@ class ScaDependenciesDaoIT { @Test void countByQuery_shouldReturnTheTotalOfDependencies() { - ComponentDto componentDto1 = prepareComponentDto("1"); + ComponentDto componentDto1 = prepareComponentDto(); db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto1.uuid(), "1", true, PackageManager.MAVEN, "foo.bar"); db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto1.uuid(), "2", true, PackageManager.MAVEN, "foo.bar.mee"); db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto1.uuid(), "3", true, PackageManager.MAVEN, "bar.foo"); @@ -239,8 +239,8 @@ class ScaDependenciesDaoIT { assertThat(scaDependenciesDao.countByQuery(db.getSession(), new ScaDependenciesQuery("another_branch_uuid", null, null, null))).isZero(); } - private ComponentDto prepareComponentDto(String suffix) { + private ComponentDto prepareComponentDto() { ProjectData projectData = db.components().insertPublicProject(); - return db.getScaDependenciesDbTester().insertComponent(projectData.mainBranchUuid(), suffix); + return projectData.getMainBranchComponent(); } } diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaReleasesDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaReleasesDaoIT.java index 42ffcfd2c7a..e29c0f54521 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaReleasesDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaReleasesDaoIT.java @@ -45,7 +45,7 @@ class ScaReleasesDaoIT { @Test void insert_shouldPersistScaReleases() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaReleaseDto scaReleaseDto = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); List<Map<String, Object>> select = db.select(db.getSession(), "select * from sca_releases"); @@ -68,7 +68,7 @@ class ScaReleasesDaoIT { @Test void deleteByUuid_shouldDeleteScaReleases() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaReleaseDto scaReleaseDto = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); List<Map<String, Object>> select = db.select(db.getSession(), "select * from sca_releases"); @@ -82,7 +82,7 @@ class ScaReleasesDaoIT { @Test void selectByUuid_shouldLoadScaRelease() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaReleaseDto scaReleaseDto = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); var loadedOptional = scaReleasesDao.selectByUuid(db.getSession(), scaReleaseDto.uuid()); @@ -92,7 +92,7 @@ class ScaReleasesDaoIT { @Test void selectByUuid_shouldLoadScaReleases() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaReleaseDto scaReleaseDto1 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "2"); ScaReleaseDto scaReleaseDto3 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "3"); @@ -105,7 +105,7 @@ class ScaReleasesDaoIT { @Test void selectByUuid_shouldLoadEmptyScaReleases() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "2"); db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "3"); @@ -117,8 +117,9 @@ class ScaReleasesDaoIT { @Test void selectByQuery_shouldReturnScaReleases_whenQueryByBranchUuid() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaReleaseDto scaReleaseDto = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); + System.out.println("componentDto = " + componentDto); ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, null, null, null); List<ScaReleaseDto> results = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesQuery, Pagination.all()); @@ -129,7 +130,7 @@ class ScaReleasesDaoIT { @Test void selectByQuery_shouldReturnPaginatedScaReleases() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaReleaseDto scaReleaseDto1 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); ScaReleaseDto scaReleaseDto2 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "2"); ScaReleaseDto scaReleaseDto3 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "3"); @@ -148,7 +149,7 @@ class ScaReleasesDaoIT { @Test void selectByQuery_shouldPartiallyMatchPackageName_whenQueriedByText() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaReleaseDto scaReleaseDto1 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1", PackageManager.MAVEN, "foo.bar"); db.getScaDependenciesDbTester().insertScaDependency(componentDto.uuid(), scaReleaseDto1, "1", true); db.getScaDependenciesDbTester().insertScaDependency(componentDto.uuid(), scaReleaseDto1, "2", false); @@ -187,7 +188,7 @@ class ScaReleasesDaoIT { @Test void selectByQuery_shouldReturnScaReleases_whenQueryByDirect() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaReleaseDto scaReleaseDto1 = db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto.uuid(), "1", 2, true, PackageManager.MAVEN, "foo.bar"); ScaReleaseDto scaReleaseDto2 = db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto.uuid(), "2", 3, false, PackageManager.MAVEN, "foo.bar"); @@ -206,7 +207,7 @@ class ScaReleasesDaoIT { @Test void selectByQuery_shouldReturnScaReleases_whenQueryByPackageManager() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaReleaseDto scaReleaseDto1 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1", PackageManager.MAVEN, "foo.bar"); ScaReleaseDto scaReleaseDto2 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "2", PackageManager.NPM, "foo.bar"); ScaReleaseDto scaReleaseDto3 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "3", PackageManager.CARGO, "foo.bar"); @@ -228,7 +229,7 @@ class ScaReleasesDaoIT { @Test void update_shouldUpdateScaRelease() { - ComponentDto componentDto = prepareComponentDto("1"); + ComponentDto componentDto = prepareComponentDto(); ScaReleaseDto scaReleaseDto = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1", PackageManager.MAVEN, "foo.bar"); ScaReleaseDto updatedScaRelease = scaReleaseDto.toBuilder().setUpdatedAt(scaReleaseDto.updatedAt() + 1).setVersion("newVersion").build(); @@ -254,7 +255,7 @@ class ScaReleasesDaoIT { @Test void countByQuery_shouldReturnTheTotalOfReleases() { - ComponentDto componentDto1 = prepareComponentDto("1"); + ComponentDto componentDto1 = prepareComponentDto(); db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "1", 1, true, PackageManager.MAVEN, "foo.bar"); db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "2", 2, true, PackageManager.MAVEN, "foo.bar.mee"); db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "3", 3, true, PackageManager.MAVEN, "bar.fo"); @@ -266,14 +267,14 @@ class ScaReleasesDaoIT { assertThat(scaReleasesDao.countByQuery(db.getSession(), new ScaReleasesQuery("another_branch_uuid", null, null, null, null))).isZero(); } - private ComponentDto prepareComponentDto(String suffix) { + private ComponentDto prepareComponentDto() { ProjectData projectData = db.components().insertPublicProject(); - return db.getScaReleasesDbTester().insertComponent(projectData.mainBranchUuid(), suffix); + return projectData.getMainBranchComponent(); } @Test void countByPlatformQuery_shouldReturnPlatforms() { - ComponentDto componentDto1 = prepareComponentDto("1"); + ComponentDto componentDto1 = prepareComponentDto(); db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "1", 1, true, PackageManager.MAVEN, "foo.bar"); db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "2", 2, true, PackageManager.NPM, "foo.bar.mee"); db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "3", 3, true, PackageManager.MAVEN, "bar.foo"); diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaDependenciesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaDependenciesMapper.xml index 5df91bc63d7..86ffed52578 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaDependenciesMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaDependenciesMapper.xml @@ -88,8 +88,7 @@ select <include refid="scaDependenciesColumns"/> from sca_dependencies sd inner join sca_releases sr on sd.sca_release_uuid = sr.uuid - inner join components c on sr.component_uuid = c.uuid - where c.branch_uuid = #{branchUuid,jdbcType=VARCHAR} + where sr.component_uuid = #{branchUuid,jdbcType=VARCHAR} </select> <select id="selectByQuery" parameterType="map" resultMap="scaDependencyResultMap"> @@ -107,8 +106,7 @@ <sql id="sqlSelectByQuery"> from sca_dependencies sd inner join sca_releases sr on sd.sca_release_uuid = sr.uuid - inner join components c on sr.component_uuid = c.uuid - where c.branch_uuid = #{query.branchUuid,jdbcType=VARCHAR} + where sr.component_uuid = #{query.branchUuid,jdbcType=VARCHAR} <if test="query.direct != null"> AND sd.direct = #{query.direct,jdbcType=BOOLEAN} </if> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesDetailsMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesDetailsMapper.xml index b884961612b..50fc85e9db4 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesDetailsMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesDetailsMapper.xml @@ -48,7 +48,6 @@ from sca_issues_releases sir inner join sca_issues si on sir.sca_issue_uuid = si.uuid inner join sca_releases sr on sir.sca_release_uuid = sr.uuid - inner join components c on sr.component_uuid = c.uuid left join sca_vulnerability_issues svi on sir.sca_issue_uuid = svi.uuid </sql> @@ -64,7 +63,7 @@ <sql id="sqlSelectByBranchUuid"> <include refid="sqlBaseJoins"/> - where c.branch_uuid = #{branchUuid,jdbcType=VARCHAR} + where sr.component_uuid = #{branchUuid,jdbcType=VARCHAR} </sql> <select id="selectByReleaseUuid" parameterType="map" resultMap="scaIssueReleaseDetailsResultMap"> @@ -92,7 +91,7 @@ <sql id="sqlSelectByQueryWhereClause"> <where> - c.branch_uuid = #{query.branchUuid,jdbcType=VARCHAR} + sr.component_uuid = #{query.branchUuid,jdbcType=VARCHAR} <if test="query.vulnerabilityIdSubstring != null"> <!-- this screens out non-vulnerability-having issue types even if the search is for empty string --> AND si.vulnerability_id != '${@org.sonar.db.sca.ScaIssueDto@NULL_VALUE}' diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesMapper.xml index 38c7fb400e2..0ba02352a77 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesMapper.xml @@ -52,8 +52,7 @@ select <include refid="scaIssuesReleasesColumns"/> from sca_issues_releases sir inner join sca_releases sr on sir.sca_release_uuid = sr.uuid - inner join components c on sr.component_uuid = c.uuid - where c.branch_uuid = #{branchUuid,jdbcType=VARCHAR} + where sr.component_uuid = #{branchUuid,jdbcType=VARCHAR} order by sir.uuid asc </select> </mapper> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaReleasesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaReleasesMapper.xml index 192df570755..b4d9ae9c4f3 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaReleasesMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaReleasesMapper.xml @@ -75,8 +75,7 @@ <select id="selectByBranchUuid" parameterType="string" resultType="org.sonar.db.sca.ScaReleaseDto"> select <include refid="scaReleasesColumns"/> from sca_releases sr - inner join components c on sr.component_uuid = c.uuid - where c.branch_uuid = #{branchUuid,jdbcType=VARCHAR} + where sr.component_uuid = #{branchUuid,jdbcType=VARCHAR} order by <include refid="scaReleasesOrderBy"/> </select> @@ -102,8 +101,7 @@ <sql id="sqlSelectByQuery"> from sca_releases sr - inner join components c on sr.component_uuid = c.uuid - where c.branch_uuid = #{query.branchUuid,jdbcType=VARCHAR} + where sr.component_uuid = #{query.branchUuid,jdbcType=VARCHAR} <if test="query.direct != null"> <!-- we only want each sca_releases row once, so this isn't a join. --> AND exists (select 1 from sca_dependencies sd where sd.sca_release_uuid = sr.uuid and sd.direct = #{query.direct,jdbcType=BOOLEAN}) diff --git a/server/sonar-db-dao/src/schema/schema-sq.ddl b/server/sonar-db-dao/src/schema/schema-sq.ddl index c4be3c824db..8a5b9a31de0 100644 --- a/server/sonar-db-dao/src/schema/schema-sq.ddl +++ b/server/sonar-db-dao/src/schema/schema-sq.ddl @@ -1087,7 +1087,7 @@ CREATE TABLE "SCA_RELEASES"( "NEW_IN_PULL_REQUEST" BOOLEAN DEFAULT FALSE NOT NULL ); ALTER TABLE "SCA_RELEASES" ADD CONSTRAINT "PK_SCA_RELEASES" PRIMARY KEY("UUID"); -CREATE INDEX "SCA_RELEASES_COMP_UUID" ON "SCA_RELEASES"("COMPONENT_UUID" NULLS FIRST); +CREATE INDEX "SCA_RELEASES_COMP_UUID_UUID" ON "SCA_RELEASES"("COMPONENT_UUID" NULLS FIRST, "UUID" NULLS FIRST); CREATE TABLE "SCA_VULNERABILITY_ISSUES"( "UUID" CHARACTER VARYING(40) NOT NULL, diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaReleasesDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaReleasesDbTester.java index fa6137fa702..9f96277c5c6 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaReleasesDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaReleasesDbTester.java @@ -21,7 +21,6 @@ package org.sonar.db.sca; import org.sonar.db.DbClient; import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; public class ScaReleasesDbTester { private final DbTester db; @@ -46,19 +45,6 @@ public class ScaReleasesDbTester { 2L); } - public ComponentDto newComponentDto(String branchUuid, String suffix) { - return new ComponentDto().setUuid("uuid" + suffix) - .setKey("key" + suffix) - .setUuidPath("uuidPath" + suffix) - .setBranchUuid(branchUuid); - } - - public ComponentDto insertComponent(String branchUuid, String suffix) { - ComponentDto componentDto = newComponentDto(branchUuid, suffix); - db.components().insertComponent(componentDto); - return componentDto; - } - public ScaReleaseDto insertScaRelease(String componentUuid, String suffix) { return insertScaRelease(componentUuid, suffix, PackageManager.MAVEN, "packageName" + suffix); } diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202503/CreateIndexOnScaReleasesComponentUuidTest.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202503/CreateIndexOnScaReleasesComponentUuidTest.java new file mode 100644 index 00000000000..d7630686669 --- /dev/null +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202503/CreateIndexOnScaReleasesComponentUuidTest.java @@ -0,0 +1,53 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.v202503; + +import java.sql.SQLException; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.sonar.db.MigrationDbTester; +import org.sonar.server.platform.db.migration.step.DdlChange; + +import static org.sonar.db.MigrationDbTester.createForMigrationStep; +import static org.sonar.server.platform.db.migration.version.v202503.CreateIndexOnScaReleasesComponentUuid.COLUMN_NAME_COMPONENT_UUID; +import static org.sonar.server.platform.db.migration.version.v202503.CreateIndexOnScaReleasesComponentUuid.COLUMN_NAME_UUID; +import static org.sonar.server.platform.db.migration.version.v202503.CreateIndexOnScaReleasesComponentUuid.INDEX_NAME; +import static org.sonar.server.platform.db.migration.version.v202503.CreateIndexOnScaReleasesComponentUuid.TABLE_NAME; + +class CreateIndexOnScaReleasesComponentUuidTest { + @RegisterExtension + public final MigrationDbTester db = createForMigrationStep(CreateIndexOnScaReleasesComponentUuid.class); + private final DdlChange underTest = new CreateIndexOnScaReleasesComponentUuid(db.database()); + + @Test + void execute_shouldCreateIndex() throws SQLException { + db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + underTest.execute(); + db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_COMPONENT_UUID, COLUMN_NAME_UUID); + } + + @Test + void execute_shouldBeReentrant() throws SQLException { + db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + underTest.execute(); + underTest.execute(); + db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_COMPONENT_UUID, COLUMN_NAME_UUID); + } +} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202503/DropIndexOnScaReleasesComponentTest.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202503/DropIndexOnScaReleasesComponentTest.java new file mode 100644 index 00000000000..97f8a4d557d --- /dev/null +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202503/DropIndexOnScaReleasesComponentTest.java @@ -0,0 +1,58 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.v202503; + +import java.sql.SQLException; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.sonar.db.MigrationDbTester; + +import static org.sonar.db.MigrationDbTester.createForMigrationStep; + +class DropIndexOnScaReleasesComponentTest { + + private static final String TABLE_NAME = "sca_releases"; + private static final String COLUMN_NAME = "component_uuid"; + private static final String INDEX_NAME = "sca_releases_comp_uuid"; + + @RegisterExtension + public final MigrationDbTester db = createForMigrationStep(DropIndexOnScaReleasesComponent.class); + private final DropIndexOnScaReleasesComponent underTest = new DropIndexOnScaReleasesComponent(db.database()); + + @Test + void index_is_dropped() throws SQLException { + db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); + + underTest.execute(); + + db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); + } + + @Test + void migration_is_reentrant() throws SQLException { + db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); + + underTest.execute(); + underTest.execute(); + + db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java index f844369bf02..5b5af55fd0b 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java @@ -39,6 +39,7 @@ import org.sonar.server.platform.db.migration.version.v107.DbVersion107; import org.sonar.server.platform.db.migration.version.v108.DbVersion108; import org.sonar.server.platform.db.migration.version.v202501.DbVersion202501; import org.sonar.server.platform.db.migration.version.v202502.DbVersion202502; +import org.sonar.server.platform.db.migration.version.v202503.DbVersion202503; public class MigrationConfigurationModule extends Module { @Override @@ -58,6 +59,7 @@ public class MigrationConfigurationModule extends Module { DbVersion108.class, DbVersion202501.class, DbVersion202502.class, + DbVersion202503.class, // migration steps MigrationStepRegistryImpl.class, diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202503/CreateIndexOnScaReleasesComponentUuid.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202503/CreateIndexOnScaReleasesComponentUuid.java new file mode 100644 index 00000000000..85dc6395842 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202503/CreateIndexOnScaReleasesComponentUuid.java @@ -0,0 +1,58 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.v202503; + +import java.sql.Connection; +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.DatabaseUtils; +import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; +import org.sonar.server.platform.db.migration.step.DdlChange; + +public class CreateIndexOnScaReleasesComponentUuid extends DdlChange { + + static final String TABLE_NAME = "sca_releases"; + // abbreviated for 30 char limit + static final String INDEX_NAME = "sca_releases_comp_uuid_uuid"; + static final String COLUMN_NAME_COMPONENT_UUID = "component_uuid"; + static final String COLUMN_NAME_UUID = "uuid"; + + public CreateIndexOnScaReleasesComponentUuid(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + try (Connection connection = getDatabase().getDataSource().getConnection()) { + createIndex(context, connection); + } + } + + private void createIndex(Context context, Connection connection) { + if (!DatabaseUtils.indexExistsIgnoreCase(TABLE_NAME, INDEX_NAME, connection)) { + context.execute(new CreateIndexBuilder(getDialect()) + .setTable(TABLE_NAME) + .setName(INDEX_NAME) + .addColumn(COLUMN_NAME_COMPONENT_UUID, false) + .addColumn(COLUMN_NAME_UUID, false) + .build()); + } + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202503/DbVersion202503.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202503/DbVersion202503.java new file mode 100644 index 00000000000..c9898d9f923 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202503/DbVersion202503.java @@ -0,0 +1,42 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.v202503; + +import org.sonar.server.platform.db.migration.step.MigrationStepRegistry; +import org.sonar.server.platform.db.migration.version.DbVersion; + +// ignoring bad number formatting, as it's indented that we align the migration numbers to SQ versions +@SuppressWarnings("java:S3937") +public class DbVersion202503 implements DbVersion { + + /** + * We use the start of the 10.X cycle as an opportunity to align migration numbers with the SQ version number. + * Please follow this pattern: + * 2025_03_000 + * 2025_03_001 + * 2025_03_002 + */ + @Override + public void addSteps(MigrationStepRegistry registry) { + registry + .add(2025_03_000, "Drop 'sca_releases_comp_uuid' index", DropIndexOnScaReleasesComponent.class) + .add(2025_03_001, "Create 'sca_releases_comp_uuid_uuid' index", CreateIndexOnScaReleasesComponentUuid.class); + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202503/DropIndexOnScaReleasesComponent.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202503/DropIndexOnScaReleasesComponent.java new file mode 100644 index 00000000000..8001e821463 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202503/DropIndexOnScaReleasesComponent.java @@ -0,0 +1,33 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.v202503; + +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.step.DropIndexChange; + +public class DropIndexOnScaReleasesComponent extends DropIndexChange { + + private static final String TABLE_NAME = "sca_releases"; + private static final String INDEX_NAME = "sca_releases_comp_uuid"; + + public DropIndexOnScaReleasesComponent(Database db) { + super(db, INDEX_NAME, TABLE_NAME); + } +} |