]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-2757 Refactor the purge mechanisms to prevent any fullscan SQL requests on...
authorSimon Brandhof <simon.brandhof@gmail.com>
Wed, 25 Jan 2012 16:38:50 +0000 (17:38 +0100)
committerSimon Brandhof <simon.brandhof@gmail.com>
Wed, 25 Jan 2012 16:39:14 +0000 (17:39 +0100)
42 files changed:
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/DbCleanerPlugin.java
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/DbCleanerConstants.java
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteAbortedBuilds.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteDirectoryHistory.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteFileHistory.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurge.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurgeContext.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurgeTask.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/ProjectPurgePostJob.java
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/DbCleanerPluginTest.java
sonar-core/src/main/java/org/sonar/core/dashboard/ActiveDashboardDao.java
sonar-core/src/main/java/org/sonar/core/dashboard/DashboardDao.java
sonar-core/src/main/java/org/sonar/core/duplication/DuplicationDao.java
sonar-core/src/main/java/org/sonar/core/persistence/BatchSession.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java
sonar-core/src/main/java/org/sonar/core/persistence/DatabaseMigrator.java
sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
sonar-core/src/main/java/org/sonar/core/purge/PurgeDao.java
sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java
sonar-core/src/main/java/org/sonar/core/purge/PurgeSnapshotQuery.java
sonar-core/src/main/java/org/sonar/core/resource/ResourceDao.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerDao.java
sonar-core/src/main/java/org/sonar/core/resource/ResourceMapper.java
sonar-core/src/main/java/org/sonar/core/review/ReviewDao.java
sonar-core/src/main/java/org/sonar/core/rule/RuleDao.java
sonar-core/src/main/java/org/sonar/core/template/LoadedTemplateDao.java
sonar-core/src/main/java/org/sonar/jpa/entity/SchemaMigration.java
sonar-core/src/main/resources/org/sonar/core/persistence/rows-derby.sql
sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml
sonar-core/src/main/resources/org/sonar/core/resource/ResourceMapper.xml
sonar-core/src/test/java/org/sonar/core/purge/PurgeDaoTest.java
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteSnapshots-result.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteSnapshots.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDisableResourcesWithoutLastSnapshot-result.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDisableResourcesWithoutLastSnapshot.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeDirectoriesAndFiles-result.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeDirectoriesAndFiles.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeProject-result.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeProject.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeSnapshots-result.xml [deleted file]
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeSnapshots.xml [deleted file]
sonar-server/src/main/webapp/WEB-INF/db/migrate/253_update_snapshots_purge_status.rb [new file with mode: 0644]

index 47a872a2fd6a1fd4169a06d1fb4494de4e4fcba1..0eb4d380281b197fd2cbad6af9d093943e572643 100644 (file)
@@ -25,10 +25,6 @@ import org.sonar.api.SonarPlugin;
 import org.sonar.plugins.dbcleaner.api.DbCleanerConstants;
 import org.sonar.plugins.dbcleaner.period.DefaultPeriodCleaner;
 import org.sonar.plugins.dbcleaner.period.PeriodPurge;
-import org.sonar.plugins.dbcleaner.purges.DeleteAbortedBuilds;
-import org.sonar.plugins.dbcleaner.purges.DeleteDirectoryHistory;
-import org.sonar.plugins.dbcleaner.purges.DeleteFileHistory;
-import org.sonar.plugins.dbcleaner.purges.ProjectPurgeTask;
 import org.sonar.plugins.dbcleaner.runner.DeprecatedPurgePostJob;
 import org.sonar.plugins.dbcleaner.runner.ProjectPurgePostJob;
 
@@ -59,13 +55,10 @@ public final class DbCleanerPlugin extends SonarPlugin {
 
   public List getExtensions() {
     return Arrays.asList(
-      // shared components
-      DefaultPeriodCleaner.class, ProjectPurgeTask.class,
+      DefaultPeriodCleaner.class,
+      PeriodPurge.class,
 
-      // purges
-      PeriodPurge.class, DeleteFileHistory.class, DeleteDirectoryHistory.class, DeleteAbortedBuilds.class, ProjectPurgePostJob.class,
-
-      // post-job
-      DeprecatedPurgePostJob.class);
+      // post-jobs
+      ProjectPurgePostJob.class, DeprecatedPurgePostJob.class);
   }
 }
index f003ac5e16eff005e7a2b1f55590bb823495d59d..a1e4bd8aabbc4652da6401f3433c338dbcb96341 100644 (file)
@@ -23,6 +23,7 @@ public interface DbCleanerConstants {
 
   String PLUGIN_KEY = "dbcleaner";
   String PLUGIN_NAME = "DbCleaner";
+  String PROPERTY_CLEAN_DIRECTORY = "sonar.dbcleaner.cleanDirectory";
   String MONTHS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_WEEK = "sonar.dbcleaner.monthsBeforeKeepingOnlyOneSnapshotByWeek";
   String MONTHS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_MONTH = "sonar.dbcleaner.monthsBeforeKeepingOnlyOneSnapshotByMonth";
   String MONTHS_BEFORE_DELETING_ALL_SNAPSHOTS = "sonar.dbcleaner.monthsBeforeDeletingAllSnapshots";
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteAbortedBuilds.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteAbortedBuilds.java
deleted file mode 100644 (file)
index 464fd4b..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.plugins.dbcleaner.purges;
-
-import org.sonar.core.purge.PurgeDao;
-import org.sonar.core.purge.PurgeSnapshotQuery;
-
-/**
- * @since 2.14
- */
-public class DeleteAbortedBuilds extends ProjectPurge {
-  private PurgeDao purgeDao;
-
-  public DeleteAbortedBuilds(PurgeDao purgeDao) {
-    this.purgeDao = purgeDao;
-  }
-
-  @Override
-  public void execute(ProjectPurgeContext context) {
-    PurgeSnapshotQuery query = PurgeSnapshotQuery.create()
-      .setBeforeBuildDate(context.getBeforeBuildDate())
-      .setRootProjectId(context.getRootProjectId())
-      .setStatus(new String[]{"U"});
-    purgeDao.deleteSnapshots(query);
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteDirectoryHistory.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteDirectoryHistory.java
deleted file mode 100644 (file)
index dfaa68f..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.plugins.dbcleaner.purges;
-
-import org.sonar.api.Properties;
-import org.sonar.api.Property;
-import org.sonar.api.config.Settings;
-import org.sonar.api.resources.Scopes;
-import org.sonar.core.purge.PurgeDao;
-import org.sonar.core.purge.PurgeSnapshotQuery;
-
-@Properties({
-  @Property(key = "sonar.dbcleaner.cleanDirectory", defaultValue = "false", name = "Clean history data of directories/packages")
-})
-public class DeleteDirectoryHistory extends ProjectPurge {
-  private PurgeDao purgeDao;
-  private Settings settings;
-
-  public DeleteDirectoryHistory(PurgeDao purgeDao, Settings settings) {
-    this.purgeDao = purgeDao;
-    this.settings = settings;
-  }
-
-  @Override
-  public void execute(ProjectPurgeContext context) {
-    if (settings.getBoolean("sonar.dbcleaner.cleanDirectoryHistory")) {
-      PurgeSnapshotQuery query = PurgeSnapshotQuery.create()
-        .setBeforeBuildDate(context.getBeforeBuildDate())
-        .setRootProjectId(context.getRootProjectId())
-        .setScopes(new String[]{Scopes.DIRECTORY});
-      purgeDao.deleteSnapshots(query);
-    }
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteFileHistory.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteFileHistory.java
deleted file mode 100644 (file)
index b0f48d9..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.plugins.dbcleaner.purges;
-
-import org.sonar.api.resources.Scopes;
-import org.sonar.core.purge.PurgeDao;
-import org.sonar.core.purge.PurgeSnapshotQuery;
-
-public class DeleteFileHistory extends ProjectPurge {
-  private PurgeDao purgeDao;
-
-  public DeleteFileHistory(PurgeDao purgeDao) {
-    this.purgeDao = purgeDao;
-  }
-
-  @Override
-  public void execute(ProjectPurgeContext context) {
-    PurgeSnapshotQuery query = PurgeSnapshotQuery.create()
-      .setBeforeBuildDate(context.getBeforeBuildDate())
-      .setRootProjectId(context.getRootProjectId())
-      .setScopes(new String[]{Scopes.FILE});
-    purgeDao.deleteSnapshots(query);
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurge.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurge.java
deleted file mode 100644 (file)
index 41ecd85..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.plugins.dbcleaner.purges;
-
-import org.sonar.api.BatchExtension;
-
-public abstract class ProjectPurge implements BatchExtension {
-
-  public abstract void execute(ProjectPurgeContext context);
-
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurgeContext.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurgeContext.java
deleted file mode 100644 (file)
index e01330a..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.plugins.dbcleaner.purges;
-
-import java.util.Date;
-
-public interface ProjectPurgeContext {
-  Long getRootProjectId();
-
-  Date getBeforeBuildDate();
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurgeTask.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurgeTask.java
deleted file mode 100644 (file)
index de721ba..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.plugins.dbcleaner.purges;
-
-import org.slf4j.LoggerFactory;
-import org.sonar.api.BatchExtension;
-import org.sonar.core.purge.PurgeDao;
-import org.sonar.core.purge.PurgeSnapshotQuery;
-
-public class ProjectPurgeTask implements BatchExtension {
-
-  private ProjectPurge[] purges;
-  private PurgeDao purgeDao;
-
-  public ProjectPurgeTask(ProjectPurge[] purges, PurgeDao purgeDao) {
-    this.purges = purges;
-    this.purgeDao = purgeDao;
-  }
-
-  public ProjectPurgeTask execute(ProjectPurgeContext context) {
-    purgeProject(context);
-    purgeSnapshots(context);
-    return this;
-  }
-
-  private void purgeProject(ProjectPurgeContext purgeContext) {
-    for (ProjectPurge purge : purges) {
-      LoggerFactory.getLogger(getClass()).debug("Executing purge " + purge);
-      purge.execute(purgeContext);
-    }
-  }
-
-  private void purgeSnapshots(ProjectPurgeContext context) {
-    LoggerFactory.getLogger(getClass()).debug("Purging snapshots");
-    PurgeSnapshotQuery query = PurgeSnapshotQuery.create()
-      .setBeforeBuildDate(context.getBeforeBuildDate())
-      .setRootProjectId(context.getRootProjectId());
-    purgeDao.purgeSnapshots(query);
-  }
-}
index 6dccaef73beba264ffe890ff63cf300f5f1b9c99..5a5646e4187315309a7ad53a0a9b1371f94dbf2b 100644 (file)
  */
 package org.sonar.plugins.dbcleaner.runner;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.sonar.api.Properties;
+import org.sonar.api.Property;
 import org.sonar.api.batch.PostJob;
 import org.sonar.api.batch.SensorContext;
+import org.sonar.api.config.Settings;
 import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Scopes;
 import org.sonar.core.NotDryRun;
-import org.sonar.plugins.dbcleaner.purges.ProjectPurgeContext;
-import org.sonar.plugins.dbcleaner.purges.ProjectPurgeTask;
-
-import java.util.Date;
+import org.sonar.core.purge.PurgeDao;
+import org.sonar.core.purge.PurgeSnapshotQuery;
+import org.sonar.plugins.dbcleaner.api.DbCleanerConstants;
 
+@Properties({
+  @Property(
+    key = DbCleanerConstants.PROPERTY_CLEAN_DIRECTORY,
+    defaultValue = "false",
+    name = "Clean history data of directories/packages")
+})
 @NotDryRun
 public class ProjectPurgePostJob implements PostJob {
 
-  private ProjectPurgeTask task;
+  private PurgeDao purgeDao;
+  private Settings settings;
 
-  public ProjectPurgePostJob(ProjectPurgeTask task) {
-    this.task = task;
+  public ProjectPurgePostJob(PurgeDao purgeDao, Settings settings) {
+    this.purgeDao = purgeDao;
+    this.settings = settings;
   }
 
   public void executeOn(final Project project, SensorContext context) {
-    final Date beforeBuildDate = new Date();
+    long projectId = (long) project.getId();
+    deleteAbortedBuilds(projectId);
+    deleteFileHistory(projectId);
+    if (settings.getBoolean(DbCleanerConstants.PROPERTY_CLEAN_DIRECTORY)) {
+      deleteDirectoryHistory(projectId);
+    }
+    purgeProject(projectId);
+  }
+
+  private void purgeProject(long projectId) {
+    purgeDao.purgeProject(projectId);
+  }
 
-    ProjectPurgeContext purgeContext = new ProjectPurgeContext() {
-      public Long getRootProjectId() {
-        return new Long(project.getId());
-      }
+  private void deleteDirectoryHistory(long projectId) {
+    PurgeSnapshotQuery query = PurgeSnapshotQuery.create()
+      .setRootProjectId(projectId)
+      .setIslast(false)
+      .setScopes(new String[]{Scopes.DIRECTORY});
+    purgeDao.deleteSnapshots(query);
+  }
 
-      public Date getBeforeBuildDate() {
-        return beforeBuildDate;
-      }
-    };
+  private void deleteFileHistory(long projectId) {
+    PurgeSnapshotQuery query = PurgeSnapshotQuery.create()
+      .setRootProjectId(projectId)
+      .setIslast(false)
+      .setScopes(new String[]{Scopes.FILE});
+    purgeDao.deleteSnapshots(query);
+  }
 
-    Logger logger = LoggerFactory.getLogger(getClass());
-    logger.info("Optimizing project");
-    task.execute(purgeContext);
+  private void deleteAbortedBuilds(long projectId) {
+    PurgeSnapshotQuery query = PurgeSnapshotQuery.create()
+      .setRootProjectId(projectId)
+      .setIslast(false)
+      .setStatus(new String[]{"U"});
+    purgeDao.deleteSnapshots(query);
   }
 }
index 9154cce3a289d4ff4a714e2c95c0a40d2b3d9c24..f08ebf1f6900b07930d73d0a20d62b0dc40968a3 100644 (file)
@@ -28,6 +28,6 @@ public class DbCleanerPluginTest {
 
   @Test
   public void shouldGetExtensions() {
-    assertThat(new DbCleanerPlugin().getExtensions().size(), greaterThan(5));
+    assertThat(new DbCleanerPlugin().getExtensions().size(), greaterThan(2));
   }
 }
index 1e283c6f5415b14df57f06888546b32679654db2..7df166b99b97b3111f769a965a6d7f2e84fed2fb 100644 (file)
@@ -39,7 +39,7 @@ public class ActiveDashboardDao implements BatchComponent, ServerComponent {
       mapper.insert(activeDashboardDto);
       session.commit();
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 
index b70433dbf92c6ef68c585adef039234242d68fad..b6e828223d1e5021d6f417a31a4f0660b8929b3c 100644 (file)
@@ -38,7 +38,7 @@ public class DashboardDao implements BatchComponent, ServerComponent {
       DashboardMapper mapper = session.getMapper(DashboardMapper.class);
       return mapper.selectGlobalDashboard(name);
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 
@@ -59,7 +59,7 @@ public class DashboardDao implements BatchComponent, ServerComponent {
       }
       session.commit();
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 
index e557d061ca78b3683a4e09b23185c8ecc9e5d96d..fb6503ccb0a83d77817e1f7127e00ade0222e29b 100644 (file)
@@ -42,7 +42,7 @@ public class DuplicationDao implements BatchComponent, ServerComponent {
       DuplicationMapper mapper = session.getMapper(DuplicationMapper.class);
       return mapper.selectCandidates(resourceSnapshotId, lastSnapshotId, language);
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 
@@ -60,7 +60,7 @@ public class DuplicationDao implements BatchComponent, ServerComponent {
       session.commit();
 
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/BatchSession.java b/sonar-core/src/main/java/org/sonar/core/persistence/BatchSession.java
new file mode 100644 (file)
index 0000000..7a33322
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.core.persistence;
+
+import org.apache.ibatis.session.ResultHandler;
+import org.apache.ibatis.session.SqlSession;
+
+public final class BatchSession {
+
+  public static final int MAX_BATCH_SIZE = 1000;
+
+  private final SqlSession session;
+  private final int batchSize;
+  private int count = 0;
+
+  BatchSession(SqlSession session) {
+    this(session, MAX_BATCH_SIZE);
+  }
+
+  BatchSession(SqlSession session, int batchSize) {
+    this.session = session;
+    this.batchSize = batchSize;
+  }
+
+  /**
+   * This method must be called when executing SQL requests.
+   */
+  public BatchSession increment(int nbSqlRequests) {
+    count += nbSqlRequests;
+    if (count > batchSize) {
+      commit();
+    }
+    return this;
+  }
+
+  public BatchSession commit() {
+    session.commit();
+    count = 0;
+    return this;
+  }
+
+  public <T> T getMapper(Class<T> type) {
+    return session.getMapper(type);
+  }
+
+  public SqlSession getSqlSession() {
+    return session;
+  }
+
+  public void select(String statement, Object parameter, ResultHandler handler) {
+    session.select(statement, parameter, handler);
+  }
+
+  public void select(String statement, ResultHandler handler) {
+    session.select(statement, handler);
+  }
+
+}
index 5f3377821528292fa1372b981ff8a4850ebb3b6d..a6d536ca07f79a60a70cd0be015c7a5c15884ee4 100644 (file)
@@ -23,6 +23,7 @@ import org.sonar.core.dashboard.ActiveDashboardDao;
 import org.sonar.core.dashboard.DashboardDao;
 import org.sonar.core.duplication.DuplicationDao;
 import org.sonar.core.purge.PurgeDao;
+import org.sonar.core.resource.ResourceDao;
 import org.sonar.core.resource.ResourceIndexerDao;
 import org.sonar.core.review.ReviewDao;
 import org.sonar.core.rule.RuleDao;
@@ -45,6 +46,7 @@ public final class DaoUtils {
       LoadedTemplateDao.class,
       PurgeDao.class,
       ResourceIndexerDao.class,
+      ResourceDao.class,
       ReviewDao.class,
       RuleDao.class));
   }
index 0f7a0f0faacd27a096985939440b5ef6321d781e..e2688a408ef4eef835b6cf929668c3fd49dc969b 100644 (file)
@@ -52,7 +52,7 @@ public class DatabaseMigrator implements ServerComponent {
         DdlUtils.createSchema(connection, database.getDialect().getId());
       } finally {
         try {
-          MyBatis.closeSessionQuietly(session);
+          MyBatis.closeQuietly(session);
 
           // The connection is probably already closed by session.close()
           // but it's not documented in mybatis javadoc.
index 59da8b5aeea39ace257e78666f2ec9cd56f98020..8837db3c6d7145051c16c0af4954c6c55e04dc09 100644 (file)
@@ -102,7 +102,12 @@ public class MyBatis implements BatchComponent, ServerComponent {
     return sessionFactory.openSession(type);
   }
 
-  public static void closeSessionQuietly(SqlSession session) {
+  public BatchSession openBatchSession() {
+    SqlSession session = openSession(ExecutorType.BATCH);
+    return new BatchSession(session);
+  }
+
+  public static void closeQuietly(SqlSession session) {
     if (session != null) {
       try {
         session.close();
@@ -113,6 +118,12 @@ public class MyBatis implements BatchComponent, ServerComponent {
     }
   }
 
+  public static void closeQuietly(BatchSession session) {
+    if (session != null) {
+      closeQuietly(session.getSqlSession());
+    }
+  }
+
   private void loadMapper(Configuration conf, Class mapperClass) throws IOException {
     // trick to use database-specific XML files for a single Mapper Java interface
     InputStream input = getPathToMapper(mapperClass);
index 510537f9b572b0f29c8179aa69a30e40caf30472..2c2db13d8e3f61faaaf36e5b4e2fcdddf7e4215e 100644 (file)
@@ -23,91 +23,130 @@ import org.apache.ibatis.session.ExecutorType;
 import org.apache.ibatis.session.ResultContext;
 import org.apache.ibatis.session.ResultHandler;
 import org.apache.ibatis.session.SqlSession;
+import org.sonar.core.persistence.BatchSession;
 import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.resource.ResourceDao;
+
+import java.util.List;
 
 public class PurgeDao {
   private final MyBatis mybatis;
+  private final ResourceDao resourceDao;
 
-  public PurgeDao(MyBatis mybatis) {
+  public PurgeDao(MyBatis mybatis, ResourceDao resourceDao) {
     this.mybatis = mybatis;
+    this.resourceDao = resourceDao;
   }
 
-  public PurgeDao disableOrphanResources(Object... handlers) {
+  public PurgeDao purgeProject(long rootProjectId) {
     SqlSession session = mybatis.openSession(ExecutorType.BATCH);
+    PurgeMapper purgeMapper = session.getMapper(PurgeMapper.class);
     try {
-      final PurgeMapper mapper = session.getMapper(PurgeMapper.class);
-      final BatchSession batchSession = new BatchSession(session);
-      session.select("selectResourceIdsToDisable", new ResultHandler() {
-        public void handleResult(ResultContext context) {
-          Long resourceId = (Long) context.getResultObject();
-          // TODO execute handlers in order to close reviews
-          batchSession.increment(disableResource(resourceId, mapper));
-        }
-      });
-      batchSession.commit();
-      return this;
+      List<Long> projectIds = resourceDao.getDescendantProjectIdsAndSelf(rootProjectId, session);
+      for (Long projectId : projectIds) {
+        purgeProject(projectId, session, purgeMapper);
+      }
 
+      for (Long projectId : projectIds) {
+        disableOrphanResources(projectId, session, purgeMapper);
+      }
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
+    return this;
   }
 
-  public PurgeDao disableResource(long resourceId, Object... handlers) {
-    SqlSession session = mybatis.openSession(ExecutorType.BATCH);
+  private void purgeProject(final Long projectId, final SqlSession session, final PurgeMapper purgeMapper) {
+    List<Long> projectSnapshotIds = purgeMapper.selectSnapshotIds(PurgeSnapshotQuery.create().setResourceId(projectId).setIslast(false).setNotPurged(true));
+    for (final Long projectSnapshotId : projectSnapshotIds) {
+      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();
+          purgeSnapshot(snapshotId, purgeMapper);
+        }
+      });
+      // must be executed at the end for reentrance
+      purgeSnapshot(projectSnapshotId, purgeMapper);
+    }
+    session.commit();
+  }
+
+  private void disableOrphanResources(final Long projectId, final SqlSession session, final PurgeMapper purgeMapper) {
+    session.select("org.sonar.core.purge.PurgeMapper.selectResourceIdsToDisable", projectId, new ResultHandler() {
+      public void handleResult(ResultContext resultContext) {
+        Long resourceId = (Long) resultContext.getResultObject();
+        disableResource(resourceId, purgeMapper);
+      }
+    });
+    session.commit();
+  }
+
+  public PurgeDao deleteProject(long rootProjectId) {
+    final BatchSession session = mybatis.openBatchSession();
     try {
       final PurgeMapper mapper = session.getMapper(PurgeMapper.class);
-      disableResource(resourceId, mapper);
+      List<Long> projectIds = resourceDao.getDescendantProjectIdsAndSelf(rootProjectId, session.getSqlSession());
+      for (Long projectId : projectIds) {
+        session.select("org.sonar.core.purge.PurgeMapper.selectResourceIdsByRootId", projectId, new ResultHandler() {
+          public void handleResult(ResultContext context) {
+            Long resourceId = (Long) context.getResultObject();
+            deleteResource(resourceId, session, mapper);
+          }
+        });
+      }
       session.commit();
       return this;
 
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 
+  void deleteResource(final long resourceId, final BatchSession session, final PurgeMapper mapper) {
+    session.select("org.sonar.core.purge.PurgeMapper.selectSnapshotIdsByResource", new ResultHandler() {
+      public void handleResult(ResultContext context) {
+        Long snapshotId = (Long) context.getResultObject();
+        session.increment(deleteSnapshot(snapshotId, mapper));
+      }
+    });
+    // TODO optimization: filter requests according to resource scope
+    mapper.deleteResourceLinks(resourceId);
+    mapper.deleteResourceProperties(resourceId);
+    mapper.deleteResourceIndex(resourceId);
+    mapper.deleteResourceGroupRoles(resourceId);
+    mapper.deleteResourceUserRoles(resourceId);
+    mapper.deleteResourceManualMeasures(resourceId);
+    mapper.deleteResourceReviews(resourceId);
+    mapper.deleteResourceEvents(resourceId);
+    mapper.deleteResource(resourceId);
+    session.increment(9);
+  }
+
   int disableResource(long resourceId, PurgeMapper mapper) {
-    mapper.disableResource(resourceId);
     mapper.deleteResourceIndex(resourceId);
-    mapper.unsetSnapshotIslast(resourceId);
+    mapper.setSnapshotIsLastToFalse(resourceId);
+    mapper.disableResource(resourceId);
     // TODO close reviews
     return 3; // nb of SQL requests
   }
 
-  public PurgeDao deleteSnapshots(PurgeSnapshotQuery query) {
-    SqlSession session = mybatis.openSession(ExecutorType.BATCH);
-    try {
-      final PurgeMapper mapper = session.getMapper(PurgeMapper.class);
-      final BatchSession batchSession = new BatchSession(session);
-      session.select("selectSnapshotIds", query, new ResultHandler() {
-        public void handleResult(ResultContext context) {
-          Long snapshotId = (Long) context.getResultObject();
-          batchSession.increment(deleteSnapshot(snapshotId, mapper));
-        }
-      });
-      batchSession.commit();
-      return this;
-
-    } finally {
-      MyBatis.closeSessionQuietly(session);
-    }
-  }
 
-  public PurgeDao purgeSnapshots(PurgeSnapshotQuery query) {
-    SqlSession session = mybatis.openSession(ExecutorType.BATCH);
+  public PurgeDao deleteSnapshots(PurgeSnapshotQuery query) {
+    final BatchSession session = mybatis.openBatchSession();
     try {
       final PurgeMapper mapper = session.getMapper(PurgeMapper.class);
-      final BatchSession batchSession = new BatchSession(session);
-      session.select("selectSnapshotIdsToPurge", query, new ResultHandler() {
+      session.select("org.sonar.core.purge.PurgeMapper.selectSnapshotIds", query, new ResultHandler() {
         public void handleResult(ResultContext context) {
           Long snapshotId = (Long) context.getResultObject();
-          batchSession.increment(purgeSnapshot(snapshotId, mapper));
+          session.increment(deleteSnapshot(snapshotId, mapper));
         }
       });
-      batchSession.commit();
+      session.commit();
       return this;
 
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 
@@ -135,31 +174,4 @@ public class PurgeDao {
     mapper.deleteSnapshot(snapshotId);
     return 8; // nb of SQL requests
   }
-
-  // TODO could be moved to org.sonar.core.persistence
-  private static class BatchSession {
-    static final int MAX_BATCH_SIZE = 1000;
-
-    int count = 0;
-    SqlSession session;
-
-    private BatchSession(SqlSession session) {
-      this.session = session;
-    }
-
-    BatchSession increment(int i) {
-      count += i;
-      if (count > MAX_BATCH_SIZE) {
-        commit();
-      }
-      return this;
-    }
-
-    BatchSession commit() {
-      session.commit();
-      count = 0;
-      return this;
-    }
-
-  }
 }
index 2ee5c5857baf7e3242e0f4874fd66fbc79e31066..7662417ac72514638398d83c5a6d9510c1bed221 100644 (file)
  */
 package org.sonar.core.purge;
 
+import java.util.List;
+
 public interface PurgeMapper {
+
+  List<Long> selectSnapshotIds(PurgeSnapshotQuery query);
+
   void deleteSnapshot(long snapshotId);
 
   void deleteSnapshotDependencies(long snapshotId);
@@ -46,5 +51,23 @@ public interface PurgeMapper {
 
   void deleteResourceIndex(long resourceId);
 
-  void unsetSnapshotIslast(long resourceId);
+  void deleteEvent(long eventId);
+
+  void setSnapshotIsLastToFalse(long resourceId);
+
+  void deleteResourceLinks(long resourceId);
+
+  void deleteResourceProperties(long resourceId);
+
+  void deleteResource(long resourceId);
+
+  void deleteResourceGroupRoles(long resourceId);
+
+  void deleteResourceUserRoles(long resourceId);
+
+  void deleteResourceManualMeasures(long resourceId);
+
+  void deleteResourceReviews(long resourceId);
+
+  void deleteResourceEvents(long resourceId);
 }
index bb16364e559ce4384c27746c0163d45c97ebe584..95dadd2f03cbf54b260d20d0704e75a68a46dd4f 100644 (file)
@@ -23,10 +23,14 @@ import java.util.Date;
 
 public final class PurgeSnapshotQuery {
   private Long rootProjectId;
+  private Long rootSnapshotId;
+  private Long resourceId;
   private Date beforeBuildDate;
   private String[] scopes;
   private String[] qualifiers;
   private String[] status;
+  private Boolean islast;
+  private Boolean notPurged;
 
   private PurgeSnapshotQuery() {
   }
@@ -79,4 +83,40 @@ public final class PurgeSnapshotQuery {
     this.status = status;
     return this;
   }
+
+  public Boolean getIslast() {
+    return islast;
+  }
+
+  public PurgeSnapshotQuery setIslast(Boolean islast) {
+    this.islast = islast;
+    return this;
+  }
+
+  public Boolean getNotPurged() {
+    return notPurged;
+  }
+
+  public PurgeSnapshotQuery setNotPurged(Boolean notPurged) {
+    this.notPurged = notPurged;
+    return this;
+  }
+
+  public Long getRootSnapshotId() {
+    return rootSnapshotId;
+  }
+
+  public PurgeSnapshotQuery setRootSnapshotId(Long rootSnapshotId) {
+    this.rootSnapshotId = rootSnapshotId;
+    return this;
+  }
+
+  public Long getResourceId() {
+    return resourceId;
+  }
+
+  public PurgeSnapshotQuery setResourceId(Long l) {
+    this.resourceId = l;
+    return this;
+  }
 }
diff --git a/sonar-core/src/main/java/org/sonar/core/resource/ResourceDao.java b/sonar-core/src/main/java/org/sonar/core/resource/ResourceDao.java
new file mode 100644 (file)
index 0000000..3703c6b
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.core.resource;
+
+import com.google.common.collect.Lists;
+import org.apache.ibatis.session.SqlSession;
+import org.sonar.core.persistence.MyBatis;
+
+import java.util.List;
+
+public class ResourceDao {
+  private MyBatis mybatis;
+
+  public ResourceDao(MyBatis mybatis) {
+    this.mybatis = mybatis;
+  }
+
+  public List<Long> getDescendantProjectIdsAndSelf(long projectId) {
+    SqlSession session = mybatis.openSession();
+    try {
+      return getDescendantProjectIdsAndSelf(projectId, session);
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+  }
+
+  public List<Long> getDescendantProjectIdsAndSelf(long projectId, SqlSession session) {
+    ResourceMapper mapper = session.getMapper(ResourceMapper.class);
+    List<Long> ids = Lists.newArrayList();
+    appendChildProjectIds(projectId, mapper, ids);
+    return ids;
+  }
+
+  private void appendChildProjectIds(long projectId, ResourceMapper mapper, List<Long> ids) {
+    ids.add(projectId);
+    List<Long> subProjectIds = mapper.selectDescendantProjectIds(projectId);
+    for (Long subProjectId : subProjectIds) {
+      ids.add(subProjectId);
+      appendChildProjectIds(subProjectId, mapper, ids);
+    }
+  }
+}
index 44f1d5332105a86009678e13e438f11ecd25eecd..af07153a03a6f42175012b2a6af27a1c24a60b7e 100644 (file)
@@ -58,7 +58,7 @@ public class ResourceIndexerDao {
       return this;
 
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 
@@ -79,7 +79,7 @@ public class ResourceIndexerDao {
       return this;
 
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 
@@ -160,7 +160,7 @@ public class ResourceIndexerDao {
           }
         }
       } finally {
-        MyBatis.closeSessionQuietly(session);
+        MyBatis.closeQuietly(session);
       }
     }
     return indexed;
index deb72aeb3ada61545a24c6210013d680c6594f8c..24bdb00a289738f7ff1d5307293eb58de249c0f0 100644 (file)
@@ -19,6 +19,9 @@
  */
 package org.sonar.core.resource;
 
+import java.util.List;
+
 public interface ResourceMapper {
   SnapshotDto selectSnapshotById(Long snapshotId);
+  List<Long> selectDescendantProjectIds(long rootProjectId);
 }
index c090251153db14f0ef0cd7b808f2a23af1a9adb5..b9d7f7283a8de2c0ed089e690a2ae5fda205ad1d 100644 (file)
@@ -40,7 +40,7 @@ public class ReviewDao implements BatchComponent, ServerComponent {
       ReviewMapper mapper = session.getMapper(ReviewMapper.class);
       return mapper.selectById(id);
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 
@@ -59,7 +59,7 @@ public class ReviewDao implements BatchComponent, ServerComponent {
       }
       return result;
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 
@@ -77,7 +77,7 @@ public class ReviewDao implements BatchComponent, ServerComponent {
       }
       return result;
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 }
index 1b4b6545ea26d5c75c91ac71608c4e9250ba16f3..b353cbbb0b41e3ad0df23e7cbe74c0bc0f90d64b 100644 (file)
@@ -40,7 +40,7 @@ public class RuleDao implements BatchComponent, ServerComponent {
       RuleMapper mapper = session.getMapper(RuleMapper.class);
       return mapper.selectAll();
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 
@@ -50,7 +50,7 @@ public class RuleDao implements BatchComponent, ServerComponent {
       RuleMapper mapper = session.getMapper(RuleMapper.class);
       return mapper.selectById(id);
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 
index 7067d03bd7c2066c868026d9384a2c3935317e5c..83b47f075488fa77d48968ef55fa50318ac9532c 100644 (file)
@@ -38,7 +38,7 @@ public class LoadedTemplateDao implements BatchComponent, ServerComponent {
     try {
       return mapper.countByTypeAndKey(type, key);
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 
@@ -49,7 +49,7 @@ public class LoadedTemplateDao implements BatchComponent, ServerComponent {
       mapper.insert(loadedTemplateDto);
       session.commit();
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
   }
 
index 5efe3e48193ae28608cc8264173dc478e6a15473..a6e8c7653e09c021109759563fc79788ad5c5e7a 100644 (file)
@@ -34,7 +34,7 @@ public class SchemaMigration {
 
   public final static int VERSION_UNKNOWN = -1;
 
-  public static final int LAST_VERSION = 252;
+  public static final int LAST_VERSION = 253;
   public static final int VERSION_2_13 = 241;
 
   public final static String TABLE_NAME = "schema_migrations";
index 8144ad8cb05a3e5c585124f24363a81348a99759..6b842872b00e9135e25d534fa77c2a5d55f6e416 100644 (file)
@@ -170,6 +170,8 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('240');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('241');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('250');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('251');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('252');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('253');
 
 INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '2011-09-26 22:27:48.0', '2011-09-26 22:27:48.0', null, null);
 ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;
index aa92585f3d6934e236601aa1283b134f761b3bc7..9e857f38a87a06f9a93b77563e1ecd475de9f361 100644 (file)
@@ -6,10 +6,21 @@
   <select id="selectSnapshotIds" parameterType="map" resultType="long">
     select id from snapshots
     <where>
-      islast=${_false}
+      <if test="islast != null">
+        and islast=#{islast}
+      </if>
+      <if test="notPurged != null and notPurged">
+        and (purge_status is null or purge_status=0)
+      </if>
+      <if test="rootSnapshotId != null">
+        and root_snapshot_id=#{rootSnapshotId}
+      </if>
       <if test="rootProjectId != null">
         and root_project_id=#{rootProjectId}
       </if>
+      <if test="resourceId != null">
+        and project_id=#{resourceId}
+      </if>
       <if test="beforeBuildDate != null">
         and build_date &lt;= #{beforeBuildDate}
       </if>
       </if>
       <if test="qualifiers != null">
         and qualifier in
-        <foreach item="qualifier" index="index" collection="qualifiers" open="(" separator="," close=")">#{qualifier}
-        </foreach>
+        <foreach item="qualifier" index="index" collection="qualifiers" open="(" separator="," close=")">#{qualifier}</foreach>
       </if>
     </where>
   </select>
 
-  <select id="selectResourceIdsToDisable" resultType="long">
-    select s1.project_id from snapshots s1
-    where s1.islast=${_true} and s1.root_snapshot_id is not null and not exists(select s2.id from snapshots s2 where
-    s2.id=s1.root_snapshot_id and s2.islast=${_true})
+  <select id="selectResourceIdsToDisable" resultType="long" parameterType="long">
+    select p.id from projects p
+    where (p.id=#{id} or p.root_id=#{id}) and p.enabled=${_true}
+    and not exists(select s.project_id from snapshots s where s.islast=${_true} and s.project_id=p.id)
   </select>
 
-  <select id="selectSnapshotIdsToPurge" parameterType="map" resultType="long">
-    select id from snapshots
-    <where>
-      islast=${_false} and (purge_status is null or purge_status=0)
-      <if test="rootProjectId != null">
-        and root_project_id=#{rootProjectId}
-      </if>
-      <if test="beforeBuildDate!= null">
-        and build_date &lt;= #{beforeBuildDate}
-      </if>
-    </where>
+  <select id="selectResourceIdsByRootId" resultType="long" parameterType="long">
+    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 resource_index where resource_id=#{id}
   </delete>
 
-  <update id="unsetSnapshotIslast" parameterType="long">
+  <delete id="deleteEvent" parameterType="long">
+    delete from events where id=#{id}
+  </delete>
+
+  <delete id="deleteResourceLinks" parameterType="long">
+    delete from project_links where project_id=#{id}
+  </delete>
+
+  <delete id="deleteResourceProperties" parameterType="long">
+    delete from properties where resource_id=#{id}
+  </delete>
+
+  <delete id="deleteResource" parameterType="long">
+    delete from projects where id=#{id}
+  </delete>
+
+  <delete id="deleteResourceGroupRoles" parameterType="long">
+    delete from group_roles where resource_id=#{id}
+  </delete>
+
+  <delete id="deleteResourceUserRoles" parameterType="long">
+    delete from user_roles where resource_id=#{id}
+  </delete>
+
+  <delete id="deleteResourceManualMeasures" parameterType="long">
+    delete from manual_measures where resource_id=#{id}
+  </delete>
+
+  <delete id="deleteResourceReviews" parameterType="long">
+    delete from reviews where resource_id=#{id}
+  </delete>
+
+  <delete id="deleteResourceEvents" parameterType="long">
+    delete from events where resource_id=#{id}
+  </delete>
+
+  <update id="setSnapshotIsLastToFalse" parameterType="long">
     update snapshots set islast=${_false} where project_id=#{id}
   </update>
 </mapper>
index 9ef0bcd36de84bb9d6da9a22b42ba040a41fae8e..f16cc1849dd82407505b7f2daad517a906bc243b 100644 (file)
@@ -27,5 +27,8 @@
     select * from snapshots where id=#{id}
   </select>
 
+  <select id="selectDescendantProjectIds" parameterType="long" resultType="long">
+    select id from projects where scope='PRJ' and root_id=#{id}
+  </select>
 </mapper>
 
index 3e8f6249081ee279a8714f4b1bc3d4a8e89b5eaa..7db16de255d3b355b78a9c09237927b5d30bbb8a 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.sonar.core.persistence.DaoTestCase;
 import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.resource.ResourceDao;
 
 public class PurgeDaoTest extends DaoTestCase {
 
@@ -31,9 +32,12 @@ public class PurgeDaoTest extends DaoTestCase {
 
   @Before
   public void createDao() {
-    dao = new PurgeDao(getMyBatis());
+    dao = new PurgeDao(getMyBatis(), new ResourceDao(getMyBatis()));
   }
 
+  /**
+   * Test that all related data is deleted.
+   */
   @Test
   public void shouldDeleteSnapshot() {
     setupData("shouldDeleteSnapshot");
@@ -45,19 +49,37 @@ public class PurgeDaoTest extends DaoTestCase {
       session.commit();
 
     } finally {
-      MyBatis.closeSessionQuietly(session);
+      MyBatis.closeQuietly(session);
     }
     checkTables("shouldDeleteSnapshot",
       "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources", "duplications_index", "events", "dependencies");
   }
 
   @Test
-  public void shouldPurgeSnapshots() {
-    setupData("shouldPurgeSnapshots");
+  public void shouldPurgeProject() {
+    setupData("shouldPurgeProject");
+    dao.purgeProject(1);
+    checkTables("shouldPurgeProject", "projects", "snapshots");
+  }
 
-    dao.purgeSnapshots(PurgeSnapshotQuery.create());
+  @Test
+  public void shouldPurgeDirectoriesAndFiles() {
+    setupData("shouldPurgeDirectoriesAndFiles");
+    dao.purgeProject(1);
+    checkTables("shouldPurgeDirectoriesAndFiles", "projects", "snapshots");
+  }
 
-    checkTables("shouldPurgeSnapshots",
-      "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources", "duplications_index", "events", "dependencies");
+  @Test
+  public void shouldDisableResourcesWithoutLastSnapshot() {
+    setupData("shouldDisableResourcesWithoutLastSnapshot");
+    dao.purgeProject(1);
+    checkTables("shouldDisableResourcesWithoutLastSnapshot", "projects", "snapshots");
+  }
+
+  @Test
+  public void shouldDeleteSnapshots() {
+    setupData("shouldDeleteSnapshots");
+    dao.deleteSnapshots(PurgeSnapshotQuery.create().setIslast(false).setResourceId(1L));
+    checkTables("shouldDeleteSnapshots", "snapshots");
   }
 }
diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteSnapshots-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteSnapshots-result.xml
new file mode 100644 (file)
index 0000000..a995a2d
--- /dev/null
@@ -0,0 +1,35 @@
+<dataset>
+
+  <!-- do not delete if islast=true -->
+  <snapshots id="1"
+             project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="true" purge_status="[null]"
+             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]"/>
+
+  <!-- delete only resource 1 -->
+  <snapshots id="2"
+             project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+             status="P" islast="false" purge_status="[null]"
+             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]"/>
+
+  <!-- to be deleted -->
+  <!--<snapshots id="3"
+             project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="false" purge_status="[null]"
+             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/shouldDeleteSnapshots.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteSnapshots.xml
new file mode 100644 (file)
index 0000000..9d00efd
--- /dev/null
@@ -0,0 +1,35 @@
+<dataset>
+
+  <!-- do not delete if islast=true -->
+  <snapshots id="1"
+             project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="true" purge_status="[null]"
+             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]"/>
+
+  <!-- delete only resource 1 -->
+  <snapshots id="2"
+             project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+             status="P" islast="false" purge_status="[null]"
+             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]"/>
+
+  <!-- to be deleted -->
+  <snapshots id="3"
+             project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="false" purge_status="[null]"
+             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/shouldDisableResourcesWithoutLastSnapshot-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDisableResourcesWithoutLastSnapshot-result.xml
new file mode 100644 (file)
index 0000000..34d37de
--- /dev/null
@@ -0,0 +1,56 @@
+<!--
+
+What has been changed :
+* enabled=false on projects
+* purge_status=1 on snapshots
+
+-->
+<dataset>
+
+  <!-- the project -->
+  <projects id="1" enabled="false" root_id="[null]"
+            long_name="[null]" scope="PRJ" qualifier="TRK" kee="project" name="project"
+            description="[null]" language="java" copy_resource_id="[null]" profile_id="[null]"/>
+
+  <!-- the directory -->
+  <projects id="2" enabled="false" root_id="1"
+            long_name="[null]" scope="DIR" qualifier="DIR" kee="project:my/dir" name="my/dir"
+            description="[null]" language="java" copy_resource_id="[null]" profile_id="[null]"/>
+
+  <!-- the file -->
+  <projects id="3" enabled="false" root_id="1"
+            long_name="[null]" scope="FIL" qualifier="FIL" kee="project:my/dir/File.java" name="my/dir/File.java"
+            description="[null]" language="java" copy_resource_id="[null]" profile_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="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]"/>
+
+  <snapshots id="2"
+             project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+             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]"/>
+
+
+  <snapshots id="3"
+             project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
+             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]"/>
+
+</dataset>
\ No newline at end of file
diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDisableResourcesWithoutLastSnapshot.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDisableResourcesWithoutLastSnapshot.xml
new file mode 100644 (file)
index 0000000..00d35af
--- /dev/null
@@ -0,0 +1,49 @@
+<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]" profile_id="[null]"/>
+
+  <!-- the directory -->
+  <projects id="2" enabled="true" root_id="1"
+            long_name="[null]" scope="DIR" qualifier="DIR" kee="project:my/dir" name="my/dir"
+            description="[null]" language="java" copy_resource_id="[null]" profile_id="[null]"/>
+
+  <!-- the file -->
+  <projects id="3" enabled="true" root_id="1"
+            long_name="[null]" scope="FIL" qualifier="FIL" kee="project:my/dir/File.java" name="my/dir/File.java"
+            description="[null]" language="java" copy_resource_id="[null]" profile_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]"
+             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]"/>
+
+  <snapshots id="2"
+             project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+             status="P" islast="false" purge_status="[null]"
+             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]"/>
+
+
+  <snapshots id="3"
+             project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
+             status="P" islast="false" purge_status="[null]"
+             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/shouldPurgeDirectoriesAndFiles-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeDirectoriesAndFiles-result.xml
new file mode 100644 (file)
index 0000000..1a0782c
--- /dev/null
@@ -0,0 +1,88 @@
+<!--
+
+What has been changed : purge_status=1 on snapshots 4, 5 and 6
+
+-->
+
+<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]" profile_id="[null]"/>
+
+  <!-- the directory -->
+  <projects id="2" enabled="true" root_id="1"
+            long_name="[null]" scope="DIR" qualifier="DIR" kee="project:my/dir" name="my/dir"
+            description="[null]" language="java" copy_resource_id="[null]" profile_id="[null]"/>
+
+  <!-- the file -->
+  <projects id="3" enabled="true" root_id="1"
+            long_name="[null]" scope="FIL" qualifier="FIL" kee="project:my/dir/File.java" name="my/dir/File.java"
+            description="[null]" language="java" copy_resource_id="[null]" profile_id="[null]"/>
+
+  <!-- do not purge last snapshots -->
+  <snapshots id="1"
+             project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="true" purge_status="[null]"
+             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]"/>
+
+  <snapshots id="2"
+             project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+             status="P" islast="true" purge_status="[null]"
+             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]"/>
+
+
+  <snapshots id="3"
+             project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
+             status="P" islast="true" purge_status="[null]"
+             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]"/>
+
+  <!-- snapshots to be purged -->
+  <snapshots id="4"
+             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]"/>
+
+  <snapshots id="5"
+             project_id="2" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="4"
+             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]"/>
+
+
+  <snapshots id="6"
+             project_id="3" parent_snapshot_id="5" root_project_id="1" root_snapshot_id="4"
+             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]"/>
+
+</dataset>
\ No newline at end of file
diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeDirectoriesAndFiles.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeDirectoriesAndFiles.xml
new file mode 100644 (file)
index 0000000..864dc04
--- /dev/null
@@ -0,0 +1,82 @@
+<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]" profile_id="[null]"/>
+
+  <!-- the directory -->
+  <projects id="2" enabled="true" root_id="1"
+            long_name="[null]" scope="DIR" qualifier="DIR" kee="project:my/dir" name="my/dir"
+            description="[null]" language="java" copy_resource_id="[null]" profile_id="[null]"/>
+
+  <!-- the file -->
+  <projects id="3" enabled="true" root_id="1"
+            long_name="[null]" scope="FIL" qualifier="FIL" kee="project:my/dir/File.java" name="my/dir/File.java"
+            description="[null]" language="java" copy_resource_id="[null]" profile_id="[null]"/>
+
+  <!-- do not purge last snapshots -->
+  <snapshots id="1"
+             project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="true" purge_status="[null]"
+             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]"/>
+
+  <snapshots id="2"
+             project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+             status="P" islast="true" purge_status="[null]"
+             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]"/>
+
+
+  <snapshots id="3"
+             project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
+             status="P" islast="true" purge_status="[null]"
+             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]"/>
+
+  <!-- snapshots to be purged -->
+  <snapshots id="4"
+             project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="false" purge_status="[null]"
+             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]"/>
+
+  <snapshots id="5"
+             project_id="2" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="4"
+             status="P" islast="false" purge_status="[null]"
+             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]"/>
+
+
+  <snapshots id="6"
+             project_id="3" parent_snapshot_id="5" root_project_id="1" root_snapshot_id="4"
+             status="P" islast="false" purge_status="[null]"
+             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/shouldPurgeProject-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeProject-result.xml
new file mode 100644 (file)
index 0000000..1e879b7
--- /dev/null
@@ -0,0 +1,43 @@
+<dataset>
+
+  <!-- the project -->
+  <projects id="1" enabled="true"
+            long_name="[null]" scope="PRJ" qualifier="TRK" kee="project" name="project"
+            root_id="[null]" description="[null]" language="java" copy_resource_id="[null]" profile_id="[null]"/>
+
+
+  <!-- snapshot 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]"/>
+
+
+  <!-- do not purge snapshot with islast=true-->
+  <snapshots id="2"
+             project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="true" purge_status="[null]"
+             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 to be purged -->
+  <snapshots id="3"
+             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]"/>
+
+</dataset>
\ No newline at end of file
diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeProject.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeProject.xml
new file mode 100644 (file)
index 0000000..a391957
--- /dev/null
@@ -0,0 +1,43 @@
+<dataset>
+
+  <!-- the project -->
+  <projects id="1" enabled="true"
+            long_name="[null]" scope="PRJ" qualifier="TRK" kee="project" name="project"
+            root_id="[null]" description="[null]" language="java" copy_resource_id="[null]" profile_id="[null]"/>
+
+
+  <!-- snapshot 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]"/>
+
+
+  <!-- do not purge snapshot with islast=true-->
+  <snapshots id="2"
+             project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="true" purge_status="[null]"
+             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 to be purged -->
+  <snapshots id="3"
+             project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="false" purge_status="[null]"
+             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/shouldPurgeSnapshots-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeSnapshots-result.xml
deleted file mode 100644 (file)
index 22327fa..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-<dataset>
-
-  <!-- snapshot already purged -->
-  <snapshots id="1" 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]"
-             project_id="1"
-             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false"
-             path="[null]"/>
-
-
-  <!-- do not purge snapshot with islast=true-->
-  <snapshots id="2" purge_status="[null]" 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]"
-             project_id="1"
-             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
-             path="[null]"/>
-  <SNAPSHOT_SOURCES ID="2" SNAPSHOT_ID="2" DATA="foo"/>
-  <rule_failures switched_off="[null]" permanent_id="[null]" ID="2" SNAPSHOT_ID="2" RULE_ID="3" FAILURE_LEVEL="2"
-                 MESSAGE="msg1" LINE="[null]" COST="[null]"
-                 created_at="2008-12-02 13:58:00.00"
-                 checksum="[null]" committer="[null]"/>
-  <events id="2" name="Version 1.0" resource_id="1" snapshot_id="2" category="VERSION" description="[null]"
-          event_date="2008-12-02 13:58:00.00" created_at="[null]"/>
-  <duplications_index project_snapshot_id="1" snapshot_id="1" hash="bb" index_in_file="0" start_line="0" end_line="0"/>
-  <dependencies id="1" from_resource_id="1" from_snapshot_id="1" to_resource_id="2" to_snapshot_id="2"
-                parent_dependency_id="[null]" project_snapshot_id="1"
-                dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="PRJ"/>
-
-
-  <!-- snapshot to purge -> purge_status is set to 1 -->
-  <snapshots id="3" 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]"
-             project_id="1"
-             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false"
-             path="[null]"/>
-
-  <!-- source: to be deleted -->
-  <!--<SNAPSHOT_SOURCES ID="3" SNAPSHOT_ID="3" DATA="foo"/>-->
-
-  <!-- violation: to be deleted -->
-  <!--<rule_failures switched_off="[null]" permanent_id="[null]" ID="1" SNAPSHOT_ID="3" RULE_ID="1" FAILURE_LEVEL="2"-->
-  <!--MESSAGE="msg1" LINE="[null]" COST="[null]"-->
-  <!--created_at="2008-12-02 13:58:00.00"-->
-  <!--checksum="[null]" committer="[null]"/>-->
-
-  <!-- measure: do not delete -->
-  <project_measures ID="1" characteristic_id="[null]" url="[null]" variation_value_1="[null]" variation_value_2="[null]"
-                    variation_value_3="[null]" variation_value_4="[null]"
-                    variation_value_5="[null]"
-                    rule_priority="[null]"
-                    alert_text="[null]" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" rules_category_id="[null]"
-                    RULE_ID="[null]"
-                    text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
-                    alert_status="[null]" description="[null]"/>
-
-  <measure_data id="1" measure_id="1" snapshot_id="3" data="[null]"/>
-
-  <!-- rule measure: to be deleted -->
-  <!--<project_measures ID="2" characteristic_id="[null]" url="[null]" variation_value_1="[null]" variation_value_2="[null]"-->
-  <!--variation_value_3="[null]" variation_value_4="[null]"-->
-  <!--variation_value_5="[null]"-->
-  <!--rule_priority="[null]"-->
-  <!--alert_text="[null]" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" rules_category_id="[null]"-->
-  <!--RULE_ID="1"-->
-  <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"-->
-  <!--alert_status="[null]" description="[null]"/>-->
-
-  <!-- dependencies: to be deleted -->
-  <!--<dependencies id="2" from_resource_id="1" from_snapshot_id="3" to_resource_id="30" to_snapshot_id="30"-->
-  <!--parent_dependency_id="[null]" project_snapshot_id="1"-->
-  <!--dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="PRJ"/>-->
-  <!--<dependencies id="3" from_resource_id="100" from_snapshot_id="100" to_resource_id="1" to_snapshot_id="3"-->
-  <!--parent_dependency_id="[null]" project_snapshot_id="100"-->
-  <!--dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="PRJ"/>-->
-
-
-  <!--events: do not delete -->
-  <events id="3" name="Version 1.0" resource_id="1" snapshot_id="3" category="VERSION" description="[null]"
-          event_date="2008-12-02 13:58:00.00" created_at="[null]"/>
-
-  <!--duplications: to be deleted -->
-  <!--<duplications_index project_snapshot_id="100" snapshot_id="3" hash="bb" index_in_file="0" start_line="0" end_line="0"/>-->
-
-</dataset>
\ No newline at end of file
diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeSnapshots.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeSnapshots.xml
deleted file mode 100644 (file)
index cc870ca..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-<dataset>
-
-  <!-- snapshot already purged -->
-  <snapshots id="1" 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]"
-             project_id="1"
-             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false"
-             path="[null]"/>
-
-
-  <!-- do not purge snapshot with islast=true-->
-  <snapshots id="2" purge_status="[null]" 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]"
-             project_id="1"
-             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
-             path="[null]"/>
-  <SNAPSHOT_SOURCES ID="2" SNAPSHOT_ID="2" DATA="foo"/>
-  <rule_failures switched_off="[null]" permanent_id="[null]" ID="2" SNAPSHOT_ID="2" RULE_ID="3" FAILURE_LEVEL="2"
-                 MESSAGE="msg1" LINE="[null]" COST="[null]"
-                 created_at="2008-12-02 13:58:00.00"
-                 checksum="[null]" committer="[null]"/>
-  <events id="2" name="Version 1.0" resource_id="1" snapshot_id="2" category="VERSION" description="[null]"
-          event_date="2008-12-02 13:58:00.00" created_at="[null]"/>
-  <duplications_index project_snapshot_id="1" snapshot_id="1" hash="bb" index_in_file="0" start_line="0" end_line="0"/>
-  <dependencies id="1" from_resource_id="1" from_snapshot_id="1" to_resource_id="2" to_snapshot_id="2"
-                parent_dependency_id="[null]" project_snapshot_id="1"
-                dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="PRJ"/>
-
-  <!-- snapshot to purge -->
-  <snapshots id="3" purge_status="[null]" 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]"
-             project_id="1"
-             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false"
-             path="[null]"/>
-
-  <!-- source: to be deleted -->
-  <SNAPSHOT_SOURCES ID="3" SNAPSHOT_ID="3" DATA="foo"/>
-
-  <!-- violation: to be deleted -->
-  <rule_failures switched_off="[null]" permanent_id="[null]" ID="3" SNAPSHOT_ID="3" RULE_ID="1" FAILURE_LEVEL="2"
-                 MESSAGE="msg1" LINE="[null]" COST="[null]"
-                 created_at="2008-12-02 13:58:00.00"
-                 checksum="[null]" committer="[null]"/>
-
-  <!-- measure: do not delete -->
-  <project_measures ID="1" characteristic_id="[null]" url="[null]" variation_value_1="[null]" variation_value_2="[null]"
-                    variation_value_3="[null]" variation_value_4="[null]"
-                    variation_value_5="[null]"
-                    rule_priority="[null]"
-                    alert_text="[null]" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" rules_category_id="[null]"
-                    RULE_ID="[null]"
-                    text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
-                    alert_status="[null]" description="[null]"/>
-
-  <measure_data id="1" measure_id="1" snapshot_id="3" data="[null]"/>
-
-  <!-- rule measure: to be deleted -->
-  <project_measures ID="2" characteristic_id="[null]" url="[null]" variation_value_1="[null]" variation_value_2="[null]"
-                    variation_value_3="[null]" variation_value_4="[null]"
-                    variation_value_5="[null]"
-                    rule_priority="[null]"
-                    alert_text="[null]" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" rules_category_id="[null]"
-                    RULE_ID="1"
-                    text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
-                    alert_status="[null]" description="[null]"/>
-
-  <!-- dependencies: to be deleted -->
-  <dependencies id="2" from_resource_id="1" from_snapshot_id="3" to_resource_id="30" to_snapshot_id="30"
-                parent_dependency_id="[null]" project_snapshot_id="1"
-                dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="PRJ"/>
-  <dependencies id="3" from_resource_id="100" from_snapshot_id="100" to_resource_id="1" to_snapshot_id="3"
-                parent_dependency_id="[null]" project_snapshot_id="100"
-                dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="PRJ"/>
-
-
-  <!--events: do not delete -->
-  <events id="3" name="Version 1.0" resource_id="1" snapshot_id="3" category="VERSION" description="[null]"
-          event_date="2008-12-02 13:58:00.00" created_at="[null]"/>
-
-  <!-- duplications: to be deleted -->
-  <duplications_index project_snapshot_id="100" snapshot_id="3" hash="bb" index_in_file="0" start_line="0"
-                      end_line="0"/>
-
-</dataset>
\ No newline at end of file
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/253_update_snapshots_purge_status.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/253_update_snapshots_purge_status.rb
new file mode 100644 (file)
index 0000000..0138aff
--- /dev/null
@@ -0,0 +1,30 @@
+#
+# Sonar, entreprise quality control tool.
+# Copyright (C) 2008-2012 SonarSource
+# mailto:contact AT sonarsource DOT com
+#
+# Sonar is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 3 of the License, or (at your option) any later version.
+#
+# Sonar is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with Sonar; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+#
+
+#
+# Sonar 2.14
+#
+class UpdateSnapshotsPurgeStatus < ActiveRecord::Migration
+
+  def self.up
+    Snapshot.update_all('purge_status=1', ['islast=?', false])
+  end
+
+end