diff options
author | Belen Pruvost <belen.pruvost@sonarsource.com> | 2022-01-13 11:08:07 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-01-21 20:03:22 +0000 |
commit | c27e6f711185a6b6b64e381f9c8b152b4ac999e8 (patch) | |
tree | 69dbd7d6176cd6411ce057f3d21b55175bf14370 /server | |
parent | 573f47d57bc4cc52235a22066d81b6be7dee4f3c (diff) | |
download | sonarqube-c27e6f711185a6b6b64e381f9c8b152b4ac999e8.tar.gz sonarqube-c27e6f711185a6b6b64e381f9c8b152b4ac999e8.zip |
SONAR-14929 - Purge new_code_reference_issues when issues are deleted
Diffstat (limited to 'server')
10 files changed, 125 insertions, 14 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDao.java index bb9a136b987..0e0de4ed55a 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDao.java @@ -111,6 +111,11 @@ public class IssueDao implements Dao { mapper(session).update(dto); } + public void insertAsNewOnReferenceBranch(DbSession session, NewCodeReferenceIssueDto dto) { + IssueMapper mapper = mapper(session); + mapper.insertAsNewOnReferenceBranch(dto); + } + private static IssueMapper mapper(DbSession session) { return session.getMapper(IssueMapper.class); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueTesting.java b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueTesting.java index a0b81a20edc..bdc71fea083 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueTesting.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueTesting.java @@ -117,4 +117,11 @@ public class IssueTesting { .setUpdatedAt(1_400_000_000_000L); } + public static NewCodeReferenceIssueDto newCodeReferenceIssue(IssueDto issue) { + return new NewCodeReferenceIssueDto() + .setUuid(Uuids.createFast()) + .setIssueKey(issue.getKey()) + .setCreatedAt(1_400_000_000_000L); + } + } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java index 64139dbb480..2b95bb4bd3a 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java @@ -206,6 +206,11 @@ class PurgeCommands { session.commit(); profiler.stop(); + profiler.start("deleteIssues (new_code_reference_issues)"); + purgeMapper.deleteNewCodeReferenceIssuesByProjectUuid(rootUuid); + session.commit(); + profiler.stop(); + profiler.start("deleteIssues (issues)"); purgeMapper.deleteIssuesByProjectUuid(rootUuid); session.commit(); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java index 21211047e58..a5898f10a28 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java @@ -116,6 +116,12 @@ public class PurgeDao implements Dao { mapper.deleteIssueChangesFromIssueKeys(input); return emptyList(); }); + + executeLargeInputs(issueKeys, input -> { + mapper.deleteNewCodeReferenceIssuesFromKeys(input); + return emptyList(); + }); + executeLargeInputs(issueKeys, input -> { mapper.deleteIssuesFromKeys(input); return emptyList(); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java index eb9ba4d01d6..32ab5319e4d 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java @@ -84,9 +84,11 @@ public interface PurgeMapper { List<PurgeableAnalysisDto> selectPurgeableAnalyses(@Param("componentUuid") String componentUuid); + void deleteIssuesByProjectUuid(@Param("projectUuid") String projectUuid); + void deleteIssueChangesByProjectUuid(@Param("projectUuid") String projectUuid); - void deleteIssuesByProjectUuid(@Param("projectUuid") String projectUuid); + void deleteNewCodeReferenceIssuesByProjectUuid(@Param("projectUuid") String projectUuid); List<String> selectOldClosedIssueKeys(@Param("projectUuid") String projectUuid, @Nullable @Param("toDate") Long toDate); @@ -101,6 +103,8 @@ public interface PurgeMapper { void deleteIssueChangesFromIssueKeys(@Param("issueKeys") List<String> issueKeys); + void deleteNewCodeReferenceIssuesFromKeys(@Param("issueKeys") List<String> keys); + void deleteFileSourcesByProjectUuid(String rootProjectUuid); void deleteFileSourcesByFileUuid(@Param("fileUuids") List<String> fileUuids); diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml index 28b145031fc..8b21a47bfe7 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml @@ -268,13 +268,25 @@ event_component_uuid = #{componentUuid,jdbcType=VARCHAR} </delete> + <delete id="deleteIssuesByProjectUuid" parameterType="map"> + delete from issues + where project_uuid = #{projectUuid,jdbcType=VARCHAR} + </delete> + <delete id="deleteIssueChangesByProjectUuid" parameterType="map"> delete from issue_changes where project_uuid = #{projectUuid,jdbcType=VARCHAR} </delete> - <delete id="deleteIssuesByProjectUuid" parameterType="map"> - delete from issues - where project_uuid = #{projectUuid,jdbcType=VARCHAR} + <delete id="deleteNewCodeReferenceIssuesByProjectUuid" parameterType="map"> + delete from new_code_reference_issues + where + issue_key in ( + select + kee + from issues + where + project_uuid = #{projectUuid,jdbcType=VARCHAR} + ) </delete> <delete id="deleteFileSourcesByProjectUuid"> @@ -369,10 +381,10 @@ FROM portfolio_projects WHERE uuid in ( SELECT ppb.portfolio_project_uuid FROM portfolio_proj_branches ppb - <!-- branch was selected --> - WHERE ppb.branch_uuid = #{branchUuid,jdbcType=VARCHAR} - <!-- and was the only one selected in the project --> - AND (SELECT count(*) FROM portfolio_proj_branches ppb2 WHERE ppb2.portfolio_project_uuid = ppb.portfolio_project_uuid) = 1 + <!-- branch was selected --> + WHERE ppb.branch_uuid = #{branchUuid,jdbcType=VARCHAR} + <!-- and was the only one selected in the project --> + AND (SELECT count(*) FROM portfolio_proj_branches ppb2 WHERE ppb2.portfolio_project_uuid = ppb.portfolio_project_uuid) = 1 ) </delete> @@ -396,6 +408,14 @@ </foreach> </delete> + <delete id="deleteNewCodeReferenceIssuesFromKeys" parameterType="map"> + DELETE FROM new_code_reference_issues + WHERE issue_key IN + <foreach collection="issueKeys" open="(" close=")" item="issueKey" separator=","> + #{issueKey,jdbcType=VARCHAR} + </foreach> + </delete> + <delete id="deleteCeScannerContextOfCeActivityByRootUuidOrBefore"> delete from ce_scanner_context where @@ -403,7 +423,7 @@ select uuid from ce_activity - <include refid="whereClauseCeActivityByRootUuidOrBefore" /> + <include refid="whereClauseCeActivityByRootUuidOrBefore"/> ) </delete> @@ -414,7 +434,7 @@ select uuid from ce_activity - <include refid="whereClauseCeActivityByRootUuidOrBefore" /> + <include refid="whereClauseCeActivityByRootUuidOrBefore"/> ) </delete> @@ -425,7 +445,7 @@ select uuid from ce_activity - <include refid="whereClauseCeActivityByRootUuidOrBefore" /> + <include refid="whereClauseCeActivityByRootUuidOrBefore"/> ) </delete> @@ -436,13 +456,13 @@ select uuid from ce_activity - <include refid="whereClauseCeActivityByRootUuidOrBefore" /> + <include refid="whereClauseCeActivityByRootUuidOrBefore"/> ) </delete> <delete id="deleteCeActivityByRootUuidOrBefore"> delete from ce_activity - <include refid="whereClauseCeActivityByRootUuidOrBefore" /> + <include refid="whereClauseCeActivityByRootUuidOrBefore"/> </delete> <sql id="whereClauseCeActivityByRootUuidOrBefore"> @@ -565,7 +585,8 @@ </delete> <delete id="deleteLiveMeasuresByComponentUuids"> - delete from live_measures where component_uuid in <foreach item="componentUuid" index="index" collection="componentUuids" open="(" separator="," close=")">#{componentUuid, jdbcType=VARCHAR}</foreach> + delete from live_measures where component_uuid in <foreach item="componentUuid" index="index" collection="componentUuids" open="(" + separator="," close=")">#{componentUuid, jdbcType=VARCHAR}</foreach> </delete> <delete id="deleteUserDismissedMessagesByProjectUuid"> diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDaoTest.java index 13772704f58..afa5e7b28de 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDaoTest.java @@ -50,6 +50,7 @@ import static org.junit.Assert.assertFalse; import static org.sonar.db.component.ComponentTesting.newDirectory; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newModuleDto; +import static org.sonar.db.issue.IssueTesting.newCodeReferenceIssue; public class IssueDaoTest { @@ -442,6 +443,30 @@ public class IssueDaoTest { }); } + @Test + public void selectByKey_givenOneIssueWithQuickFix_selectOneIssueWithQuickFix2() { + prepareIssuesComponent(); + underTest.insert(db.getSession(), newIssueDto(ISSUE_KEY1) + .setMessage("the message") + .setRuleUuid(RULE.getUuid()) + .setComponentUuid(FILE_UUID) + .setProjectUuid(PROJECT_UUID) + .setQuickFixAvailable(true)); + underTest.insert(db.getSession(), newIssueDto(ISSUE_KEY2) + .setMessage("the message") + .setRuleUuid(RULE.getUuid()) + .setComponentUuid(FILE_UUID) + .setProjectUuid(PROJECT_UUID) + .setQuickFixAvailable(true)); + IssueDto issue1 = underTest.selectOrFailByKey(db.getSession(), ISSUE_KEY1); + + underTest.insertAsNewOnReferenceBranch(db.getSession(), + newCodeReferenceIssue(issue1)); + + assertThat(underTest.isNewCodeOnReferencedBranch(db.getSession(), ISSUE_KEY1)).isTrue(); + assertThat(underTest.isNewCodeOnReferencedBranch(db.getSession(), ISSUE_KEY2)).isFalse(); + } + private static IssueDto newIssueDto(String key) { IssueDto dto = new IssueDto(); dto.setComponent(new ComponentDto().setDbKey("struts:Action").setUuid("component-uuid")); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java index a5c5ddf86bd..ef8e6d0d357 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java @@ -66,6 +66,7 @@ import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newProjectCopy; import static org.sonar.db.component.SnapshotDto.STATUS_PROCESSED; import static org.sonar.db.component.SnapshotDto.STATUS_UNPROCESSED; +import static org.sonar.db.issue.IssueTesting.newCodeReferenceIssue; @RunWith(DataProviderRunner.class) public class PurgeCommandsTest { @@ -535,6 +536,25 @@ public class PurgeCommandsTest { } @Test + @UseDataProvider("projectsAndViews") + public void deleteIssues_deletes_new_code_reference_issues(ComponentDto projectOrView) { + RuleDefinitionDto rule = dbTester.rules().insert(); + dbTester.components().insertComponent(projectOrView); + ComponentDto file = dbTester.components().insertComponent(newFileDto(projectOrView)); + int count = 5; + IntStream.range(0, count).forEach(i -> { + IssueDto issue = dbTester.issues().insertIssue(t -> t.setRule(rule).setProject(projectOrView).setComponent(projectOrView)); + dbTester.issues().insertNewCodeReferenceIssue(newCodeReferenceIssue(issue)); + issue = dbTester.issues().insertIssue(t -> t.setRule(rule).setProject(projectOrView).setComponent(file)); + dbTester.issues().insertNewCodeReferenceIssue(newCodeReferenceIssue(issue)); + }); + + underTest.deleteIssues(projectOrView.uuid()); + + assertThat(dbTester.countRowsOfTable("NEW_CODE_REFERENCE_ISSUES")).isZero(); + } + + @Test public void deletePermissions_deletes_permissions_of_public_project() { ComponentDto project = dbTester.components().insertPublicProject(); addPermissions(project); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java index 80238ce0ae5..19b84c9db2c 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java @@ -105,6 +105,7 @@ import static org.sonar.db.component.SnapshotDto.STATUS_PROCESSED; import static org.sonar.db.component.SnapshotDto.STATUS_UNPROCESSED; import static org.sonar.db.component.SnapshotTesting.newSnapshot; import static org.sonar.db.event.EventDto.CATEGORY_VERSION; +import static org.sonar.db.issue.IssueTesting.newCodeReferenceIssue; import static org.sonar.db.webhook.WebhookDeliveryTesting.newDto; import static org.sonar.db.webhook.WebhookDeliveryTesting.selectAllDeliveryUuids; @@ -527,6 +528,7 @@ public class PurgeDaoTest { IssueChangeDto issueChange1 = db.issues().insertChange(issue1); IssueDto issue2 = db.issues().insert(rule, project, file); FileSourceDto fileSource = db.fileSources().insertFileSource(file); + db.issues().insertNewCodeReferenceIssue(newCodeReferenceIssue(issue1)); ComponentDto otherProject = db.components().insertPrivateProject(); ComponentDto otherModule = db.components().insertComponent(newModuleDto(otherProject)); @@ -537,6 +539,7 @@ public class PurgeDaoTest { IssueChangeDto otherIssueChange1 = db.issues().insertChange(otherIssue1); IssueDto otherIssue2 = db.issues().insert(rule, otherProject, otherFile); FileSourceDto otherFileSource = db.fileSources().insertFileSource(otherFile); + db.issues().insertNewCodeReferenceIssue(newCodeReferenceIssue(otherIssue1)); underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey()); dbSession.commit(); @@ -546,6 +549,7 @@ public class PurgeDaoTest { assertThat(uuidsIn("snapshots")).containsOnly(otherAnalysis.getUuid()); assertThat(uuidsIn("issues", "kee")).containsOnly(otherIssue1.getKey(), otherIssue2.getKey()); assertThat(uuidsIn("issue_changes", "kee")).containsOnly(otherIssueChange1.getKey()); + assertThat(uuidsIn("new_code_reference_issues", "issue_key")).containsOnly(otherIssue1.getKey()); assertThat(uuidsIn("file_sources", "file_uuid")).containsOnly(otherFileSource.getFileUuid()); } @@ -1103,12 +1107,15 @@ public class PurgeDaoTest { issue.setStatus("CLOSED"); issue.setIssueCloseDate(DateUtils.addDays(new Date(), -31)); }); + db.issues().insertNewCodeReferenceIssue(newCodeReferenceIssue(oldClosed)); IssueDto notOldEnoughClosed = db.issues().insert(rule, project, file, issue -> { issue.setStatus("CLOSED"); issue.setIssueCloseDate(new Date()); }); + db.issues().insertNewCodeReferenceIssue(newCodeReferenceIssue(notOldEnoughClosed)); IssueDto notClosed = db.issues().insert(rule, project, file); + db.issues().insertNewCodeReferenceIssue(newCodeReferenceIssue(notClosed)); when(system2.now()).thenReturn(new Date().getTime()); underTest.purge(dbSession, newConfigurationWith30Days(system2, project.uuid(), project.uuid()), PurgeListener.EMPTY, new PurgeProfiler()); @@ -1120,7 +1127,10 @@ public class PurgeDaoTest { // others remain assertThat(db.countRowsOfTable("issues")).isEqualTo(2); assertThat(db.getDbClient().issueDao().selectByKey(dbSession, notOldEnoughClosed.getKey())).isNotEmpty(); + assertThat(db.getDbClient().issueDao().isNewCodeOnReferencedBranch(dbSession, notOldEnoughClosed.getKey())).isTrue(); assertThat(db.getDbClient().issueDao().selectByKey(dbSession, notClosed.getKey())).isNotEmpty(); + assertThat(db.getDbClient().issueDao().isNewCodeOnReferencedBranch(dbSession, notClosed.getKey())).isTrue(); + assertThat(db.getDbClient().issueDao().isNewCodeOnReferencedBranch(dbSession, oldClosed.getKey())).isFalse(); } @Test diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/issue/IssueDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/issue/IssueDbTester.java index 31dcfe133e0..10ce0985873 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/issue/IssueDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/issue/IssueDbTester.java @@ -218,4 +218,12 @@ public class IssueDbTester { db.commit(); } + /** + * Inserts an issue as new code in a branch using reference branch for new code + */ + public void insertNewCodeReferenceIssue(NewCodeReferenceIssueDto dto) { + db.getDbClient().issueDao().insertAsNewOnReferenceBranch(db.getSession(), dto); + db.commit(); + } + } |