]> source.dussan.org Git - sonarqube.git/commitdiff
Improve batch execution of DELETE statements in PurgeDao
authorSimon Brandhof <simon.brandhof@gmail.com>
Mon, 5 Mar 2012 15:04:44 +0000 (16:04 +0100)
committerSimon Brandhof <simon.brandhof@gmail.com>
Mon, 5 Mar 2012 15:04:44 +0000 (16:04 +0100)
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/DefaultPurgeTask.java
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/period/DefaultPeriodCleaner.java
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/period/DefaultPeriodCleanerTest.java
sonar-core/src/main/java/org/sonar/core/purge/PurgeDao.java
sonar-core/src/main/java/org/sonar/core/purge/PurgeSnapshotQuery.java
sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml
sonar-core/src/test/java/org/sonar/core/purge/PurgeDaoTest.java
sonar-core/src/test/java/org/sonar/core/resource/ResourceDaoTest.java
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteAbortedBuilds-result.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteAbortedBuilds.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/fixture.xml

index cdb55dd86ad2fa0fc1e63cc2d5aa849cc8b38ade..10f75cc1ef71602a6b4dc3c4b3eddb2887df1f34 100644 (file)
@@ -58,7 +58,6 @@ public class DefaultPurgeTask implements PurgeTask {
   }
 
   public PurgeTask purge(long resourceId) {
-    LOG.info("Clean historical data [id=" + resourceId + "]");
     cleanHistoricalData(resourceId);
     doPurge(resourceId);
     return this;
index 9b9bc9e1dc67141f84ddce30d442316af0c6cd9d..e81e3cd30ea8b3d7cfc92c3b18816e6f0df187d8 100644 (file)
@@ -64,6 +64,7 @@ public class DefaultPeriodCleaner implements PeriodCleaner {
     for (PurgeableSnapshotDto snapshot : snapshots) {
       LOG.info("<- Delete snapshot: " + DateUtils.formatDateTime(snapshot.getDate()) + " [" + snapshot.getSnapshotId() + "]");
       purgeDao.deleteSnapshots(PurgeSnapshotQuery.create().setRootSnapshotId(snapshot.getSnapshotId()));
+      purgeDao.deleteSnapshots(PurgeSnapshotQuery.create().setId(snapshot.getSnapshotId()));
     }
   }
 
index 0d4ba72ebd93b9d156583d1d0407ed7eaaabce52..c9f27bc979e5529cea1e02e2cc6dd8b04e2a18d9 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.plugins.dbcleaner.period;
 
+import org.apache.commons.lang.ObjectUtils;
 import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
 import org.junit.Test;
@@ -42,7 +43,7 @@ public class DefaultPeriodCleanerTest {
   public void doClean() {
     PurgeDao dao = mock(PurgeDao.class);
     when(dao.selectPurgeableSnapshots(123L)).thenReturn(Arrays.asList(
-      new PurgeableSnapshotDto().setSnapshotId(999L).setDate(new Date())));
+        new PurgeableSnapshotDto().setSnapshotId(999L).setDate(new Date())));
     Filter filter1 = newLazyFilter();
     Filter filter2 = newLazyFilter();
 
@@ -52,12 +53,26 @@ public class DefaultPeriodCleanerTest {
     verify(filter1).log();
     verify(filter2).log();
     verify(dao, times(2)).deleteSnapshots(argThat(newRootSnapshotQuery()));
+    verify(dao, times(2)).deleteSnapshots(argThat(newSnapshotIdQuery()));
   }
 
   private BaseMatcher<PurgeSnapshotQuery> newRootSnapshotQuery() {
     return new BaseMatcher<PurgeSnapshotQuery>() {
       public boolean matches(Object o) {
-        return ((PurgeSnapshotQuery) o).getRootSnapshotId() == 999L;
+        PurgeSnapshotQuery query = (PurgeSnapshotQuery) o;
+        return ObjectUtils.equals(query.getRootSnapshotId(), 999L);
+      }
+
+      public void describeTo(Description description) {
+      }
+    };
+  }
+
+  private BaseMatcher<PurgeSnapshotQuery> newSnapshotIdQuery() {
+    return new BaseMatcher<PurgeSnapshotQuery>() {
+      public boolean matches(Object o) {
+        PurgeSnapshotQuery query = (PurgeSnapshotQuery) o;
+        return ObjectUtils.equals(query.getId(), 999L);
       }
 
       public void describeTo(Description description) {
index 72322a2e180834e5bd4a384027ed1329aae74d1b..3a262e92f191111dcb6f750df42032c9613cf6fc 100644 (file)
@@ -34,6 +34,9 @@ import org.sonar.core.resource.ResourceDto;
 import java.util.Collections;
 import java.util.List;
 
+/**
+ * @since 2.14
+ */
 public class PurgeDao {
   private final MyBatis mybatis;
   private final ResourceDao resourceDao;
@@ -50,10 +53,10 @@ public class PurgeDao {
     try {
       List<ResourceDto> projects = getProjects(rootResourceId, session);
       for (ResourceDto project : projects) {
+        LOG.info("-> Clean " + project.getLongName() + " [id=" + project.getId() + "]");
         deleteAbortedBuilds(project, session, purgeMapper);
         purge(project, scopesWithoutHistoricalData, session, purgeMapper);
       }
-
       for (ResourceDto project : projects) {
         disableOrphanResources(project, session, purgeMapper);
       }
@@ -65,12 +68,13 @@ public class PurgeDao {
 
   private void deleteAbortedBuilds(ResourceDto project, SqlSession session, PurgeMapper purgeMapper) {
     if (hasAbortedBuilds(project.getId(), purgeMapper)) {
-      LOG.info("<- Deleting aborted builds of " + project.getLongName());
+      LOG.info("<- Delete aborted builds");
       PurgeSnapshotQuery query = PurgeSnapshotQuery.create()
           .setIslast(false)
           .setStatus(new String[]{"U"})
           .setRootProjectId(project.getId());
-      deleteSnapshots(query, session, purgeMapper);
+      deleteSnapshots(query, purgeMapper);
+      session.commit();
     }
   }
 
@@ -87,29 +91,24 @@ public class PurgeDao {
         PurgeSnapshotQuery.create().setResourceId(project.getId()).setIslast(false).setNotPurged(true)
     );
     for (final Long projectSnapshotId : projectSnapshotIds) {
-      // TODO log date
+      LOG.info("<- Clean snapshot " + projectSnapshotId);
       if (!ArrayUtils.isEmpty(scopesWithoutHistoricalData)) {
         PurgeSnapshotQuery query = PurgeSnapshotQuery.create()
             .setIslast(false)
             .setScopes(scopesWithoutHistoricalData)
             .setRootSnapshotId(projectSnapshotId);
-        deleteSnapshots(query, session, purgeMapper);
+        deleteSnapshots(query, purgeMapper);
+        session.commit();
       }
 
       PurgeSnapshotQuery query = PurgeSnapshotQuery.create().setRootSnapshotId(projectSnapshotId).setNotPurged(true);
-      session.select("org.sonar.core.purge.PurgeMapper.selectSnapshotIds", query, new ResultHandler() {
-        public void handleResult(ResultContext resultContext) {
-          Long snapshotId = (Long) resultContext.getResultObject();
-          if (snapshotId != null) {
-            purgeSnapshot(snapshotId, purgeMapper);
-          }
-        }
-      });
+      purgeSnapshots(query, purgeMapper);
+      session.commit();
 
       // must be executed at the end for reentrance
-      purgeSnapshot(projectSnapshotId, purgeMapper);
+      purgeSnapshots(PurgeSnapshotQuery.create().setId(projectSnapshotId).setNotPurged(true), purgeMapper);
+      session.commit();
     }
-    session.commit();
   }
 
   private void disableOrphanResources(final ResourceDto project, final SqlSession session, final PurgeMapper purgeMapper) {
@@ -144,6 +143,7 @@ public class PurgeDao {
     final PurgeVendorMapper vendorMapper = session.getMapper(PurgeVendorMapper.class);
     try {
       deleteProject(rootProjectId, session, mapper, vendorMapper);
+      session.commit();
       return this;
     } finally {
       MyBatis.closeQuietly(session);
@@ -160,22 +160,15 @@ public class PurgeDao {
       public void handleResult(ResultContext context) {
         Long resourceId = (Long) context.getResultObject();
         if (resourceId != null) {
-          deleteResource(resourceId, session, mapper, vendorMapper);
+          deleteResource(resourceId, mapper, vendorMapper);
         }
       }
     });
-    session.commit();
   }
 
-  void deleteResource(final long resourceId, final SqlSession session, final PurgeMapper mapper, final PurgeVendorMapper vendorMapper) {
-    session.select("org.sonar.core.purge.PurgeMapper.selectSnapshotIdsByResource", resourceId, new ResultHandler() {
-      public void handleResult(ResultContext context) {
-        Long snapshotId = (Long) context.getResultObject();
-        if (snapshotId != null) {
-          deleteSnapshot(snapshotId, mapper);
-        }
-      }
-    });
+  void deleteResource(final long resourceId, final PurgeMapper mapper, final PurgeVendorMapper vendorMapper) {
+    deleteSnapshots(PurgeSnapshotQuery.create().setResourceId(resourceId), mapper);
+
     // possible optimization: filter requests according to resource scope
     mapper.deleteResourceLinks(resourceId);
     mapper.deleteResourceProperties(resourceId);
@@ -203,7 +196,7 @@ public class PurgeDao {
     final SqlSession session = mybatis.openBatchSession();
     try {
       final PurgeMapper mapper = session.getMapper(PurgeMapper.class);
-      deleteSnapshots(query, session, mapper);
+      deleteSnapshots(mapper.selectSnapshotIds(query), mapper);
       session.commit();
       return this;
 
@@ -212,15 +205,66 @@ public class PurgeDao {
     }
   }
 
-  private void deleteSnapshots(PurgeSnapshotQuery query, SqlSession session, final PurgeMapper mapper) {
-    session.select("org.sonar.core.purge.PurgeMapper.selectSnapshotIds", query, new ResultHandler() {
-      public void handleResult(ResultContext context) {
-        Long snapshotId = (Long) context.getResultObject();
-        if (snapshotId != null) {
-          deleteSnapshot(snapshotId, mapper);
-        }
-      }
-    });
+  @VisibleForTesting
+  void deleteSnapshots(final PurgeSnapshotQuery query, final PurgeMapper mapper) {
+    deleteSnapshots(mapper.selectSnapshotIds(query), mapper);
+  }
+
+  private void deleteSnapshots(final List<Long> snapshotIds, final PurgeMapper mapper) {
+    for (Long snapshotId : snapshotIds) {
+      mapper.deleteSnapshotDependencies(snapshotId);
+    }
+    for (Long snapshotId : snapshotIds) {
+      mapper.deleteSnapshotDuplications(snapshotId);
+    }
+    for (Long snapshotId : snapshotIds) {
+      mapper.deleteSnapshotEvents(snapshotId);
+    }
+    for (Long snapshotId : snapshotIds) {
+      mapper.deleteSnapshotMeasureData(snapshotId);
+    }
+    for (Long snapshotId : snapshotIds) {
+      mapper.deleteSnapshotMeasures(snapshotId);
+    }
+    for (Long snapshotId : snapshotIds) {
+      mapper.deleteSnapshotSource(snapshotId);
+    }
+    for (Long snapshotId : snapshotIds) {
+      mapper.deleteSnapshotViolations(snapshotId);
+    }
+    for (Long snapshotId : snapshotIds) {
+      mapper.deleteSnapshot(snapshotId);
+    }
+  }
+
+  @VisibleForTesting
+  void purgeSnapshots(final PurgeSnapshotQuery query, final PurgeMapper mapper) {
+    purgeSnapshots(mapper.selectSnapshotIds(query), mapper);
+  }
+
+  private void purgeSnapshots(final List<Long> snapshotIds, final PurgeMapper mapper) {
+    // note that events are not deleted
+    for (Long snapshotId : snapshotIds) {
+      mapper.deleteSnapshotDependencies(snapshotId);
+    }
+    for (Long snapshotId : snapshotIds) {
+      mapper.deleteSnapshotDuplications(snapshotId);
+    }
+    for (Long snapshotId : snapshotIds) {
+      mapper.deleteSnapshotSource(snapshotId);
+    }
+    for (Long snapshotId : snapshotIds) {
+      mapper.deleteSnapshotViolations(snapshotId);
+    }
+    for (Long snapshotId : snapshotIds) {
+      mapper.deleteSnapshotWastedMeasures(snapshotId);
+    }
+    for (Long snapshotId : snapshotIds) {
+      mapper.deleteSnapshotMeasuresOnQualityModelRequirements(snapshotId);
+    }
+    for (Long snapshotId : snapshotIds) {
+      mapper.updatePurgeStatusToOne(snapshotId);
+    }
   }
 
   /**
@@ -233,27 +277,4 @@ public class PurgeDao {
     return projects;
   }
 
-  @VisibleForTesting
-  void purgeSnapshot(long snapshotId, PurgeMapper mapper) {
-    // note that events are not deleted
-    mapper.deleteSnapshotDependencies(snapshotId);
-    mapper.deleteSnapshotDuplications(snapshotId);
-    mapper.deleteSnapshotSource(snapshotId);
-    mapper.deleteSnapshotViolations(snapshotId);
-    mapper.deleteSnapshotWastedMeasures(snapshotId);
-    mapper.deleteSnapshotMeasuresOnQualityModelRequirements(snapshotId);
-    mapper.updatePurgeStatusToOne(snapshotId);
-  }
-
-  @VisibleForTesting
-  void deleteSnapshot(long snapshotId, PurgeMapper mapper) {
-    mapper.deleteSnapshotDependencies(snapshotId);
-    mapper.deleteSnapshotDuplications(snapshotId);
-    mapper.deleteSnapshotEvents(snapshotId);
-    mapper.deleteSnapshotMeasureData(snapshotId);
-    mapper.deleteSnapshotMeasures(snapshotId);
-    mapper.deleteSnapshotSource(snapshotId);
-    mapper.deleteSnapshotViolations(snapshotId);
-    mapper.deleteSnapshot(snapshotId);
-  }
 }
index 7fca0f6773a3ff22dbd8298a521244c90bc93cc2..c3905abcd67982d4108a7ffdc876c9cc6ec0f8cc 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.core.purge;
 
 public final class PurgeSnapshotQuery {
+  private Long id;
   private Long rootProjectId;
   private Long rootSnapshotId;
   private Long resourceId;
@@ -37,6 +38,15 @@ public final class PurgeSnapshotQuery {
     return new PurgeSnapshotQuery();
   }
 
+  public Long getId() {
+    return id;
+  }
+
+  public PurgeSnapshotQuery setId(Long l) {
+    this.id = l;
+    return this;
+  }
+
   public Long getRootProjectId() {
     return rootProjectId;
   }
index aad082e351616c46884fc6a41f21f8fb10df4186..931b6e953f09f42ff02f9ac4bfae29d9e8113fc5 100644 (file)
         and (s.purge_status is null or s.purge_status=0)
       </if>
       <if test="rootSnapshotId != null">
-        and (s.root_snapshot_id=#{rootSnapshotId} or s.id=#{rootSnapshotId})
+        and s.root_snapshot_id=#{rootSnapshotId}
+      </if>
+      <if test="id != null">
+        and s.id=#{id}
       </if>
       <if test="rootProjectId != null">
         and s.root_project_id=#{rootProjectId}
     select id from projects where root_id=#{id} or id=#{id}
   </select>
 
-  <select id="selectSnapshotIdsByResource" parameterType="long" resultType="long">
-    select id from snapshots where project_id=#{id}
-  </select>
-
   <delete id="deleteSnapshotMeasures" parameterType="long">
     delete from project_measures where snapshot_id=#{id}
   </delete>
index 0c6ea4e6d9ab14d9259fe49440b57dd4729a444b..7cd74d9f51115c6c31f2cae77d3d918139a3ac02 100644 (file)
@@ -54,14 +54,21 @@ public class PurgeDaoTest extends DaoTestCase {
     SqlSession session = getMyBatis().openSession();
     try {
       // this method does not commit and close the session
-      dao.deleteSnapshot(5L, session.getMapper(PurgeMapper.class));
+      dao.deleteSnapshots(PurgeSnapshotQuery.create().setId(5L), session.getMapper(PurgeMapper.class));
       session.commit();
 
     } finally {
       MyBatis.closeQuietly(session);
     }
     checkTables("shouldDeleteSnapshot",
-      "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources", "duplications_index", "events", "dependencies");
+        "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources", "duplications_index", "events", "dependencies");
+  }
+
+  @Test
+  public void shouldDeleteAbortedBuilds() {
+    setupData("shouldDeleteAbortedBuilds");
+    dao.purge(1L, new String[0]);
+    checkTables("shouldDeleteAbortedBuilds", "snapshots");
   }
 
   /**
@@ -73,15 +80,16 @@ public class PurgeDaoTest extends DaoTestCase {
 
     SqlSession session = getMyBatis().openSession();
     try {
-      // this method does not commit and close the session
-      dao.purgeSnapshot(1L, session.getMapper(PurgeMapper.class));
+      dao.purgeSnapshots(PurgeSnapshotQuery.create().setId(1L), session.getMapper(PurgeMapper.class));
+
+      // the above method does not commit and close the session
       session.commit();
 
     } finally {
       MyBatis.closeQuietly(session);
     }
     checkTables("shouldPurgeSnapshot",
-      "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources", "duplications_index", "events", "dependencies", "reviews");
+        "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources", "duplications_index", "events", "dependencies", "reviews");
   }
 
   @Test
@@ -90,8 +98,9 @@ public class PurgeDaoTest extends DaoTestCase {
 
     SqlSession session = getMyBatis().openSession();
     try {
-      // this method does not commit and close the session
-      dao.purgeSnapshot(1L, session.getMapper(PurgeMapper.class));
+      dao.purgeSnapshots(PurgeSnapshotQuery.create().setId(1L), session.getMapper(PurgeMapper.class));
+
+// the above method does not commit and close the session
       session.commit();
 
     } finally {
@@ -106,8 +115,9 @@ public class PurgeDaoTest extends DaoTestCase {
 
     SqlSession session = getMyBatis().openSession();
     try {
-      // this method does not commit and close the session
       dao.disableResource(1L, session.getMapper(PurgeMapper.class));
+
+      // the above method does not commit and close the session
       session.commit();
 
     } finally {
@@ -161,8 +171,9 @@ public class PurgeDaoTest extends DaoTestCase {
     setupData("shouldDeleteResource");
     SqlSession session = getMyBatis().openSession();
     try {
-      // this method does not commit and close the session
-      dao.deleteResource(1L, session, session.getMapper(PurgeMapper.class), session.getMapper(PurgeVendorMapper.class));
+      dao.deleteResource(1L, session.getMapper(PurgeMapper.class), session.getMapper(PurgeVendorMapper.class));
+
+      // the above method does not commit and close the session
       session.commit();
 
     } finally {
@@ -196,9 +207,9 @@ public class PurgeDaoTest extends DaoTestCase {
 
     public void describeTo(Description description) {
       description
-        .appendText("snapshotId").appendValue(snapshotId)
-        .appendText("isLast").appendValue(isLast)
-        .appendText("hasEvents").appendValue(hasEvents);
+          .appendText("snapshotId").appendValue(snapshotId)
+          .appendText("isLast").appendValue(isLast)
+          .appendText("hasEvents").appendValue(hasEvents);
     }
   }
 }
index bdda1f21aebfea73bba97c218c1f438626ed00b4..cb9d765a95b92ebbe4186ac5b6479bc48e112cbe 100644 (file)
@@ -27,10 +27,8 @@ import org.sonar.core.persistence.DaoTestCase;
 import java.util.List;
 
 import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.core.IsNot.not;
-import static org.hamcrest.core.IsNull.nullValue;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
-import static org.junit.matchers.JUnitMatchers.hasItems;
 
 public class ResourceDaoTest extends DaoTestCase {
 
@@ -57,5 +55,22 @@ public class ResourceDaoTest extends DaoTestCase {
 
     assertThat(dao.getDescendantProjects(33333L).size(), Is.is(0));
   }
+
+  @Test
+  public void getResource() {
+    setupData("fixture");
+
+    ResourceDto resource = dao.getResource(1L);
+    assertThat(resource.getName(), Is.is("Struts"));
+    assertThat(resource.getLongName(), Is.is("Apache Struts"));
+    assertThat(resource.getScope(), Is.is("PRJ"));
+  }
+
+  @Test
+  public void getResource_not_found() {
+    setupData("fixture");
+
+    assertNull(dao.getResource(987654321L));
+  }
 }
 
diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteAbortedBuilds-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteAbortedBuilds-result.xml
new file mode 100644 (file)
index 0000000..7f21ab0
--- /dev/null
@@ -0,0 +1,46 @@
+<!--
+
+Snapshot 2 has been deleted
+
+-->
+<dataset>
+
+  <!-- the project -->
+  <projects id="1" enabled="[true]" root_id="[null]"
+            long_name="[null]" scope="PRJ" qualifier="TRK" kee="project" name="project"
+            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" profile_id="[null]"/>
+
+  <!-- past snapshot with status "processed" and already purged -->
+  <snapshots id="1"
+             project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="[false]" purge_status="1"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" version="[null]" path="[null]"/>
+
+  <!-- snapshot with status "unprocessed" -> to be deleted -->
+  <!--<snapshots id="2"-->
+             <!--project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"-->
+             <!--status="U" islast="[false]" purge_status="0"-->
+             <!--period1_mode="[null]" period1_param="[null]" period1_date="[null]"-->
+             <!--period2_mode="[null]" period2_param="[null]" period2_date="[null]"-->
+             <!--period3_mode="[null]" period3_param="[null]" period3_date="[null]"-->
+             <!--period4_mode="[null]" period4_param="[null]" period4_date="[null]"-->
+             <!--period5_mode="[null]" period5_param="[null]" period5_date="[null]"-->
+             <!--depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" version="[null]" path="[null]"/>-->
+
+  <!-- snapshot with status "processed" and flagged as "last" -> do not purge and do not delete -->
+  <snapshots id="3"
+             project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="[true]" purge_status="0"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" version="[null]" path="[null]"/>
+
+</dataset>
\ No newline at end of file
diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteAbortedBuilds.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteAbortedBuilds.xml
new file mode 100644 (file)
index 0000000..da6f528
--- /dev/null
@@ -0,0 +1,41 @@
+<dataset>
+
+  <!-- the project -->
+  <projects id="1" enabled="[true]" root_id="[null]"
+            long_name="[null]" scope="PRJ" qualifier="TRK" kee="project" name="project"
+            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" profile_id="[null]"/>
+
+  <!-- past snapshot with status "processed" and already purged -->
+  <snapshots id="1"
+             project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="[false]" purge_status="1"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" version="[null]" path="[null]"/>
+
+  <!-- snapshot with status "unprocessed" -> to be deleted -->
+  <snapshots id="2"
+             project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="U" islast="[false]" purge_status="0"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" version="[null]" path="[null]"/>
+
+  <!-- snapshot with status "processed" and flagged as "last" -> do not purge and do not delete -->
+  <snapshots id="3"
+             project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="[true]" purge_status="0"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" version="[null]" path="[null]"/>
+
+</dataset>
\ No newline at end of file
index a993fe82a6f974cec8e60bb40d281b01b4bda4e2..e92a256f5537110e0b91f1f827004dbf54c4f573 100644 (file)
@@ -2,7 +2,7 @@
 
   <!-- root project -->
   <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
-            description="[null]" long_name="Struts"
+            description="[null]" long_name="Apache Struts"
             enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"/>
   <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
                status="P" islast="[false]" purge_status="[null]"