aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorBelen Pruvost <belen.pruvost@sonarsource.com>2022-01-13 11:08:07 +0100
committersonartech <sonartech@sonarsource.com>2022-01-21 20:03:22 +0000
commitc27e6f711185a6b6b64e381f9c8b152b4ac999e8 (patch)
tree69dbd7d6176cd6411ce057f3d21b55175bf14370 /server
parent573f47d57bc4cc52235a22066d81b6be7dee4f3c (diff)
downloadsonarqube-c27e6f711185a6b6b64e381f9c8b152b4ac999e8.tar.gz
sonarqube-c27e6f711185a6b6b64e381f9c8b152b4ac999e8.zip
SONAR-14929 - Purge new_code_reference_issues when issues are deleted
Diffstat (limited to 'server')
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDao.java5
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueTesting.java7
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java5
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java6
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java6
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml47
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDaoTest.java25
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java20
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java10
-rw-r--r--server/sonar-db-dao/src/testFixtures/java/org/sonar/db/issue/IssueDbTester.java8
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();
+ }
+
}