diff options
2 files changed, 55 insertions, 9 deletions
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PurgeUtils.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PurgeUtils.java index 390f4f0736f..37747560318 100644 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PurgeUtils.java +++ b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PurgeUtils.java @@ -26,6 +26,8 @@ import org.sonar.api.database.model.*; import org.sonar.api.design.DependencyDto; import org.sonar.api.utils.TimeProfiler; +import com.google.common.annotations.VisibleForTesting; + import javax.persistence.Query; import java.util.List; @@ -141,27 +143,32 @@ public final class PurgeUtils { if (ids == null || ids.isEmpty()) { return; } - executeQuery(session, description, ids, session.createQuery(hql)); + TimeProfiler profiler = new TimeProfiler().setLevelToDebug().start("Execute " + description); + int index = 0; + while (index < ids.size()) { + List<Integer> paginedSids = ids.subList(index, Math.min(ids.size(), index + MAX_IN_ELEMENTS)); + Query query = session.createQuery(hql); + query.setParameter("ids", paginedSids); + query.executeUpdate(); + index += MAX_IN_ELEMENTS; + session.commit(); + } + profiler.stop(); } /** * @since 2.13 */ - private static void executeNativeQuery(DatabaseSession session, String description, List<Integer> ids, String sql) { + @VisibleForTesting + static void executeNativeQuery(DatabaseSession session, String description, List<Integer> ids, String sql) { if (ids == null || ids.isEmpty()) { return; } - executeQuery(session, description, ids, session.createNativeQuery(sql)); - } - - /** - * @since 2.13 - */ - private static void executeQuery(DatabaseSession session, String description, List<Integer> ids, Query query) { TimeProfiler profiler = new TimeProfiler().setLevelToDebug().start("Execute " + description); int index = 0; while (index < ids.size()) { List<Integer> paginedSids = ids.subList(index, Math.min(ids.size(), index + MAX_IN_ELEMENTS)); + Query query = session.createNativeQuery(sql); query.setParameter("ids", paginedSids); query.executeUpdate(); index += MAX_IN_ELEMENTS; diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/api/PurgeUtilsTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/api/PurgeUtilsTest.java index 2b34186a8a5..d57d181b5d1 100644 --- a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/api/PurgeUtilsTest.java +++ b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/api/PurgeUtilsTest.java @@ -21,13 +21,28 @@ package org.sonar.plugins.dbcleaner.api; import org.apache.commons.configuration.PropertiesConfiguration; import org.junit.Test; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.ResourceModel; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.Scopes; import org.sonar.jpa.test.AbstractDbUnitTestCase; +import com.google.common.collect.Lists; + import java.sql.SQLException; import java.util.Arrays; +import java.util.List; + +import javax.persistence.Query; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; public class PurgeUtilsTest extends AbstractDbUnitTestCase { @@ -51,4 +66,28 @@ public class PurgeUtilsTest extends AbstractDbUnitTestCase { checkTables("purgeSnapshots", "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources", "dependencies", "events", "duplications_index"); } + + @Test + public void shouldPaginate() throws Exception { + DatabaseSession session = mock(DatabaseSession.class); + Query query = mock(Query.class); + when(session.createQuery(anyString())).thenReturn(query); + when(session.createNativeQuery(anyString())).thenReturn(query); + + List<Integer> ids = Lists.newArrayList(); + for (int i = 0; i < PurgeUtils.MAX_IN_ELEMENTS + 1; i++) { + ids.add(i); + } + + // createQuery() and createNativeQuery() should be invoked as many times as commit(), because it starts new transaction + + PurgeUtils.executeQuery(session, "description", ids, "hql"); + verify(session, times(2)).createQuery(anyString()); + verify(session, times(2)).commit(); + + PurgeUtils.executeNativeQuery(session, "description", ids, "sql"); + verify(session, times(2)).createNativeQuery(anyString()); + verify(session, times(4)).commit(); + } + } |