deleteSnapshots(purgeMapper.selectSnapshotIds(query));
}
- private void deleteSnapshots(final List<Long> snapshotIds) {
+ @VisibleForTesting
+ protected void deleteSnapshots(final List<Long> snapshotIds) {
List<List<Long>> snapshotIdsPartition = Lists.partition(snapshotIds, MAX_SNAPSHOTS_PER_QUERY);
purgeSnapshots(purgeMapper.selectSnapshotIds(query));
}
- private void purgeSnapshots(final List<Long> snapshotIds) {
+ @VisibleForTesting
+ protected void purgeSnapshots(final List<Long> snapshotIds) {
// note that events are not deleted
List<List<Long>> snapshotIdsPartition = Lists.partition(snapshotIds, MAX_SNAPSHOTS_PER_QUERY);
private void deleteSnapshotDependencies(final List<List<Long>> snapshotIdsPartition) {
profiler.start("deleteSnapshotDependencies (dependencies)");
for (List<Long> partSnapshotIds : snapshotIdsPartition) {
- purgeMapper.deleteSnapshotDependencies(partSnapshotIds);
+ // SONAR-4586
+ // On MsSQL, the maximum number of parameters allowed in a query is 2000, so we have to execute 3 queries instead of one with 3 or inside
+ purgeMapper.deleteSnapshotDependenciesFromSnapshotId(partSnapshotIds);
+ purgeMapper.deleteSnapshotDependenciesToSnapshotId(partSnapshotIds);
+ purgeMapper.deleteSnapshotDependenciesProjectSnapshotId(partSnapshotIds);
}
session.commit();
profiler.stop();
</foreach>
</delete>
- <delete id="deleteSnapshotDependencies" parameterType="map">
+ <delete id="deleteSnapshotDependenciesFromSnapshotId" parameterType="map">
delete from dependencies where from_snapshot_id in
<foreach collection="snapshotIds" open="(" close=")" item="snapshotId" separator=",">
#{snapshotId}
</foreach>
- or to_snapshot_id in
+ </delete>
+
+ <delete id="deleteSnapshotDependenciesToSnapshotId" parameterType="map">
+ delete from dependencies where to_snapshot_id in
<foreach collection="snapshotIds" open="(" close=")" item="snapshotId" separator=",">
- #{snapshotId}
+ #{snapshotId}
</foreach>
- or project_snapshot_id in
+ </delete>
+
+ <delete id="deleteSnapshotDependenciesProjectSnapshotId" parameterType="map">
+ delete from dependencies where project_snapshot_id in
<foreach collection="snapshotIds" open="(" close=")" item="snapshotId" separator=",">
- #{snapshotId}
+ #{snapshotId}
</foreach>
</delete>
import org.sonar.core.persistence.MyBatis;
import java.util.Arrays;
+import java.util.List;
+
+import static com.google.common.collect.Lists.newArrayList;
public class PurgeCommandsTest extends AbstractDaoTestCase {
"snapshots", "project_measures", "measure_data", "snapshot_sources", "duplications_index", "events", "dependencies", "snapshot_data");
}
+ /**
+ * Test that SQL queries execution do not fail with a huge number of parameter
+ */
+ @Test
+ public void should_not_fail_when_deleting_huge_number_of_snapshots() {
+ SqlSession session = getMyBatis().openSession();
+ try {
+ new PurgeCommands(session, profiler).deleteSnapshots(getHugeNumberOfIds());
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ // The goal of this test is only to check that the query do no fail, not to check result
+ }
+
/**
* Test that all related data is purged.
*/
checkTables("shouldDeleteWastedMeasuresWhenPurgingSnapshot", "project_measures");
}
+ /**
+ * Test that SQL queries execution do not fail with a huge number of parameter
+ */
+ @Test
+ public void should_not_fail_when_purging_huge_number_of_snapshots() {
+ SqlSession session = getMyBatis().openSession();
+ try {
+ new PurgeCommands(session, profiler).purgeSnapshots(getHugeNumberOfIds());
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ // The goal of this test is only to check that the query do no fail, not to check result
+ }
+
@Test
public void shouldDeleteResource() {
setupData("shouldDeleteResource");
assertEmptyTables("projects", "snapshots", "events", "issues", "issue_changes", "authors");
}
+ /**
+ * Test that SQL queries execution do not fail with a huge number of parameter
+ */
+ @Test
+ public void should_not_fail_when_deleting_huge_number_of_resources() {
+ SqlSession session = getMyBatis().openSession();
+ try {
+ new PurgeCommands(session, profiler).deleteResources(getHugeNumberOfIds());
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ // The goal of this test is only to check that the query do no fail, not to check result
+ }
+
+ private List<Long> getHugeNumberOfIds(){
+ List<Long> hugeNbOfSnapshotIds = newArrayList();
+ for (long i=0; i<4500; i++) {
+ hugeNbOfSnapshotIds.add(i);
+ }
+ return hugeNbOfSnapshotIds;
+ }
+
}