]> source.dussan.org Git - sonarqube.git/commitdiff
Move some purge tasks to MyBatis
authorsimonbrandhof <simon.brandhof@gmail.com>
Tue, 24 Jan 2012 13:40:27 +0000 (14:40 +0100)
committersimonbrandhof <simon.brandhof@gmail.com>
Tue, 24 Jan 2012 13:41:22 +0000 (14:41 +0100)
SONAR-2754 add the parameter sonar.dbcleaner.cleanDirectoryHistory
SONAR-2757 remove fullscan requests on the table SNAPSHOTS

78 files changed:
plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/DbDuplicationsIndex.java
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/PeriodCleaner.java
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/Purge.java
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PurgeContext.java
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PurgeUtils.java
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteAbortedBuilds.java [new file with mode: 0644]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteDirectoryHistory.java [new file with mode: 0644]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteFileHistory.java [new file with mode: 0644]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurge.java [new file with mode: 0644]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurgeContext.java [new file with mode: 0644]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurgeTask.java [new file with mode: 0644]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDeletedResources.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDependencies.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDeprecatedLast.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDisabledResources.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeEntities.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeEventOrphans.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanResources.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanReviews.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgePropertyOrphans.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeResourceRoles.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeRuleMeasures.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeUnprocessed.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/DefaultPurgeContext.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/DeprecatedPurgePostJob.java [new file with mode: 0644]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/ProjectPurgePostJob.java [new file with mode: 0644]
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/PurgeRunner.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDeletedResourcesTest.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDependenciesTest.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDeprecatedLastTest.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDisabledResourcesTest.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeEntitiesTest.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeEventOrphansTest.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanResourcesTest.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanReviewsTest.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgePropertyOrphansTest.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeResourceRolesTest.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeRuleMeasuresTest.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeUnprocessedTest.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/runner/DeprecatedPurgePostJobTest.java [new file with mode: 0644]
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/runner/PurgeRunnerTest.java [deleted file]
plugins/sonar-dbcleaner-plugin/src/test/resources/org/sonar/plugins/dbcleaner/runner/DeprecatedPurgePostJobTest/shared.xml [new file with mode: 0644]
plugins/sonar-dbcleaner-plugin/src/test/resources/org/sonar/plugins/dbcleaner/runner/PurgeRunnerTest/shared.xml [deleted file]
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/DaoUtils.java
sonar-core/src/main/java/org/sonar/core/persistence/DatabaseMigrator.java
sonar-core/src/main/java/org/sonar/core/persistence/DatabaseUtils.java
sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
sonar-core/src/main/java/org/sonar/core/purge/PurgeDao.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/purge/PurgeSnapshotQuery.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 [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/resource/SnapshotDto.java [new file with mode: 0644]
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/resources/org/sonar/core/persistence/rows-derby.sql
sonar-core/src/main/resources/org/sonar/core/persistence/schema-derby.ddl
sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml [new file with mode: 0644]
sonar-core/src/main/resources/org/sonar/core/resource/ResourceMapper.xml [new file with mode: 0644]
sonar-core/src/test/java/org/sonar/core/purge/PurgeDaoTest.java [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteSnapshot-result.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteSnapshot.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeSnapshots-result.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeSnapshots.xml [new file with mode: 0644]
sonar-deprecated/src/main/java/org/sonar/api/batch/AbstractPurge.java [deleted file]
sonar-deprecated/src/main/java/org/sonar/api/batch/Purge.java [deleted file]
sonar-deprecated/src/main/java/org/sonar/api/batch/PurgeContext.java [deleted file]
sonar-deprecated/src/main/java/org/sonar/core/purge/AbstractPurge.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/checks/AnnotationCheckFactory.java
sonar-plugin-api/src/main/java/org/sonar/api/utils/FieldUtils.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/utils/FieldUtils2.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/utils/FieldUtils2Test.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/utils/FieldUtilsTest.java [deleted file]

index 5409e979a2402821192d09f16a9c2df496ff8399..6e9f3e43f68f9a94e5766bf585a73510b2478725 100644 (file)
  */
 package org.sonar.plugins.cpd.index;
 
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import org.sonar.api.database.model.Snapshot;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Resource;
 import org.sonar.batch.index.ResourcePersister;
-import org.sonar.duplications.block.Block;
-import org.sonar.duplications.block.ByteArray;
 import org.sonar.core.duplication.DuplicationDao;
 import org.sonar.core.duplication.DuplicationUnitDto;
+import org.sonar.duplications.block.Block;
+import org.sonar.duplications.block.ByteArray;
 
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
 
 public class DbDuplicationsIndex {
 
@@ -55,16 +54,6 @@ public class DbDuplicationsIndex {
     this.lastSnapshotId = lastSnapshot == null ? null : lastSnapshot.getId();
   }
 
-  /**
-   * For tests.
-   */
-  DbDuplicationsIndex(DuplicationDao dao, ResourcePersister resourcePersister, Integer currentProjectSnapshotId, Integer prevSnapshotId) {
-    this.dao = dao;
-    this.resourcePersister = resourcePersister;
-    this.currentProjectSnapshotId = currentProjectSnapshotId;
-    this.lastSnapshotId = prevSnapshotId;
-  }
-
   int getSnapshotIdFor(Resource resource) {
     return resourcePersister.getSnapshotOrFail(resource).getId();
   }
@@ -110,12 +99,12 @@ public class DbDuplicationsIndex {
     List<DuplicationUnitDto> units = Lists.newArrayList();
     for (Block block : blocks) {
       DuplicationUnitDto unit = new DuplicationUnitDto(
-          currentProjectSnapshotId,
-          resourceSnapshotId,
-          block.getBlockHash().toString(),
-          block.getIndexInFile(),
-          block.getFirstLineNumber(),
-          block.getLastLineNumber());
+        currentProjectSnapshotId,
+        resourceSnapshotId,
+        block.getBlockHash().toString(),
+        block.getIndexInFile(),
+        block.getFirstLineNumber(),
+        block.getLastLineNumber());
       units.add(unit);
     }
 
index 84d78def360801e86e76afe73e96bf9bd2b84947..47a872a2fd6a1fd4169a06d1fb4494de4e4fcba1 100644 (file)
@@ -25,8 +25,12 @@ 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.*;
-import org.sonar.plugins.dbcleaner.runner.PurgeRunner;
+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;
 
 import java.util.Arrays;
 import java.util.List;
@@ -42,20 +46,26 @@ import java.util.List;
       + "the DbCleaner keeps the first one and fully delete the other ones.", global = true, project = true),
   @Property(key = DbCleanerConstants.MONTHS_BEFORE_DELETING_ALL_SNAPSHOTS, defaultValue = DbCleanerConstants.FIVE_YEARS,
     name = "Number of months before starting to delete all remaining snapshots",
-    description = "After this number of months, all snapshots are fully deleted.", global = true, project = true)})
+    description = "After this number of months, all snapshots are fully deleted.", global = true, project = true),
+  @Property(key = "sonar.purge.minimumPeriodInHours", defaultValue = "12",
+    name = "Maximum duration of code inspections, in hours",
+    description = "Sonar has an embedded purge mechanism which is fairly powerful to avoid keeping useless data. This mechanism is using a minimum period during which a " +
+      "resource created should not be suppressed whatever its state. This is set by default to 12 hours and should not be changed. The only situation you could want to change " +
+      "this is in case a projects takes more than 12 hours to be analyzed by Sonar.",
+    global = true, project = false)
+}
+)
 public final class DbCleanerPlugin extends SonarPlugin {
 
   public List getExtensions() {
     return Arrays.asList(
       // shared components
-      DefaultPeriodCleaner.class,
+      DefaultPeriodCleaner.class, ProjectPurgeTask.class,
 
       // purges
-      PurgeOrphanResources.class, PurgeEntities.class, PurgeRuleMeasures.class, PurgeUnprocessed.class, PurgeDeletedResources.class,
-      PurgeDeprecatedLast.class, PurgeDisabledResources.class, PurgeResourceRoles.class, PurgeEventOrphans.class,
-      PurgePropertyOrphans.class, PeriodPurge.class, PurgeDependencies.class, PurgeOrphanReviews.class,
+      PeriodPurge.class, DeleteFileHistory.class, DeleteDirectoryHistory.class, DeleteAbortedBuilds.class, ProjectPurgePostJob.class,
 
       // post-job
-      PurgeRunner.class);
+      DeprecatedPurgePostJob.class);
   }
 }
index f9b0c412a2dab08677b47b3867537a6aeff28095..25cad3f72d54ee87a977cc3fc75c792cc391656f 100644 (file)
@@ -22,6 +22,11 @@ package org.sonar.plugins.dbcleaner.api;
 import org.sonar.api.BatchExtension;
 import org.sonar.api.resources.Project;
 
+/**
+ * @since 2.14
+ * @deprecated in 2.14
+ */
+@Deprecated
 public interface PeriodCleaner extends BatchExtension {
   void purge(Project project, int projectSnapshotId);
 }
index 20d270c5e0e8eec5aacf2aef6f312cd821991457..5a147f72028e713e5e9b3640f1720084bd63c1f7 100644 (file)
@@ -24,9 +24,11 @@ import org.sonar.api.database.DatabaseSession;
 
 /**
  * Implement this component in order to define your own rules to cleanup database.
- * 
+ *
  * @since 2.5
+ * @deprecated in 2.14
  */
+@Deprecated
 public abstract class Purge implements BatchExtension {
 
   private DatabaseSession session;
index 68a10310777b2613d1bad6340ebdd2d617d04b5c..544949a3d7ea5b942ab6ad8b2842d4c3ecb2f102 100644 (file)
@@ -22,9 +22,10 @@ package org.sonar.plugins.dbcleaner.api;
 import org.sonar.api.resources.Project;
 
 /**
- *
  * @since 2.5
+ * @deprecated in 2.14
  */
+@Deprecated
 public interface PurgeContext {
 
   Project getProject();
index dfe82050d897091c11aef58b0e637160b64f3f66..1d9a9fe4bfa597de8e066ee5fb626f2ba266086c 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.plugins.dbcleaner.api;
 
+import com.google.common.annotations.VisibleForTesting;
 import org.apache.commons.configuration.Configuration;
 import org.sonar.api.batch.Event;
 import org.sonar.api.database.DatabaseSession;
@@ -26,14 +27,14 @@ import org.sonar.api.database.model.*;
 import org.sonar.api.design.DependencyDto;
 import org.sonar.api.utils.TimeProfiler;
 
-import com.google.common.annotations.VisibleForTesting;
-
 import javax.persistence.Query;
 import java.util.List;
 
 /**
  * @since 2.5
+ * @deprecated in 2.14
  */
+@Deprecated
 public final class PurgeUtils {
 
   public static final int DEFAULT_MINIMUM_PERIOD_IN_HOURS = 12;
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
new file mode 100644 (file)
index 0000000..464fd4b
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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
new file mode 100644 (file)
index 0000000..a96389d
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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.cleanDirectoryHistory", defaultValue = "false", name = "TODO")
+})
+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
new file mode 100644 (file)
index 0000000..b0f48d9
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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
new file mode 100644 (file)
index 0000000..41ecd85
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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
new file mode 100644 (file)
index 0000000..e01330a
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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
new file mode 100644 (file)
index 0000000..de721ba
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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);
+  }
+}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDeletedResources.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDeletedResources.java
deleted file mode 100644 (file)
index 52489f9..0000000
+++ /dev/null
@@ -1,49 +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.database.DatabaseSession;
-import org.sonar.api.database.model.ResourceModel;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.plugins.dbcleaner.api.Purge;
-import org.sonar.plugins.dbcleaner.api.PurgeContext;
-import org.sonar.plugins.dbcleaner.api.PurgeUtils;
-
-import java.util.List;
-
-import javax.persistence.Query;
-
-/**
- * @since 1.11
- */
-public final class PurgeDeletedResources extends Purge {
-
-  public PurgeDeletedResources(DatabaseSession session) {
-    super(session);
-  }
-
-  public void purge(PurgeContext context) {
-    Query query = getSession().createQuery("SELECT s.id FROM " + Snapshot.class.getSimpleName() +
-        " s WHERE NOT EXISTS(FROM " + ResourceModel.class.getSimpleName() + " r WHERE r.id=s.resourceId)");
-    final List<Integer> snapshotIds = query.getResultList();
-
-    PurgeUtils.deleteSnapshotsData(getSession(), snapshotIds);
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDependencies.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDependencies.java
deleted file mode 100644 (file)
index 948df2e..0000000
+++ /dev/null
@@ -1,47 +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.database.DatabaseSession;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.design.DependencyDto;
-import org.sonar.plugins.dbcleaner.api.Purge;
-import org.sonar.plugins.dbcleaner.api.PurgeContext;
-import org.sonar.plugins.dbcleaner.api.PurgeUtils;
-
-import javax.persistence.Query;
-import java.util.List;
-
-public final class PurgeDependencies extends Purge {
-
-  public PurgeDependencies(DatabaseSession session) {
-    super(session);
-  }
-
-  public void purge(PurgeContext context) {
-    Query query = getSession().createQuery("SELECT d.projectSnapshotId FROM " + DependencyDto.class.getSimpleName() +
-        " d WHERE EXISTS(FROM " + Snapshot.class.getSimpleName() + " s WHERE s.id=d.projectSnapshotId AND s.last=:last and s.status=:status)");
-    query.setParameter("last", Boolean.FALSE);
-    query.setParameter("status", Snapshot.STATUS_PROCESSED);
-
-    final List<Integer> projectSnapshotIds = query.getResultList();
-    PurgeUtils.executeQuery(getSession(), "", projectSnapshotIds, "DELETE FROM " + DependencyDto.class.getSimpleName() + " WHERE projectSnapshotId in (:ids)");
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDeprecatedLast.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDeprecatedLast.java
deleted file mode 100644 (file)
index e62a33d..0000000
+++ /dev/null
@@ -1,49 +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.database.DatabaseSession;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.plugins.dbcleaner.api.Purge;
-import org.sonar.plugins.dbcleaner.api.PurgeContext;
-import org.sonar.plugins.dbcleaner.api.PurgeUtils;
-
-import java.util.List;
-
-import javax.persistence.Query;
-
-/**
- * @since 1.11
- */
-public final class PurgeDeprecatedLast extends Purge {
-
-  public PurgeDeprecatedLast(DatabaseSession session) {
-    super(session);
-  }
-
-  public void purge(PurgeContext context) {
-    Query query = getSession().createQuery("SELECT s.id FROM " + Snapshot.class.getSimpleName() +
-        " s WHERE s.last=:last AND s.rootId IS NOT NULL AND NOT EXISTS(FROM " + Snapshot.class.getSimpleName() + " s2 WHERE s2.id=s.rootId AND s2.last=:last)");
-    query.setParameter("last", Boolean.TRUE);
-    List<Integer> snapshotIds = query.getResultList();
-
-    PurgeUtils.deleteSnapshotsData(getSession(), snapshotIds);
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDisabledResources.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDisabledResources.java
deleted file mode 100644 (file)
index 15ddd6c..0000000
+++ /dev/null
@@ -1,58 +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.database.DatabaseSession;
-import org.sonar.api.database.model.ResourceModel;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.plugins.dbcleaner.api.Purge;
-import org.sonar.plugins.dbcleaner.api.PurgeContext;
-import org.sonar.plugins.dbcleaner.api.PurgeUtils;
-
-import javax.persistence.Query;
-import java.util.List;
-
-/**
- * @since 1.11
- */
-public final class PurgeDisabledResources extends Purge {
-
-  public PurgeDisabledResources(DatabaseSession session) {
-    super(session);
-  }
-
-  public void purge(PurgeContext context) {
-    PurgeUtils.deleteSnapshotsData(getSession(), getSnapshotIds());
-    PurgeUtils.deleteResources(getSession(), getResourceIds());
-  }
-
-  private List<Integer> getResourceIds() {
-    Query query = getSession().createQuery("SELECT r.id FROM " + ResourceModel.class.getSimpleName() + " r WHERE r.enabled=:enabled");
-    query.setParameter("enabled", Boolean.FALSE);
-    return query.getResultList();
-  }
-
-  private List<Integer> getSnapshotIds() {
-    Query query = getSession().createQuery("SELECT s.id FROM " + Snapshot.class.getSimpleName() + " s WHERE " +
-      " EXISTS (FROM " + ResourceModel.class.getSimpleName() + " r WHERE r.id=s.resourceId AND r.enabled=:enabled)");
-    query.setParameter("enabled", Boolean.FALSE);
-    return query.getResultList();
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeEntities.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeEntities.java
deleted file mode 100644 (file)
index d6b3611..0000000
+++ /dev/null
@@ -1,61 +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.apache.commons.configuration.Configuration;
-import org.apache.commons.lang.time.DateUtils;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.resources.Scopes;
-import org.sonar.api.utils.Logs;
-import org.sonar.plugins.dbcleaner.api.Purge;
-import org.sonar.plugins.dbcleaner.api.PurgeContext;
-import org.sonar.plugins.dbcleaner.api.PurgeUtils;
-
-import javax.persistence.Query;
-import java.util.Date;
-import java.util.List;
-
-/**
- * @since 1.11
- */
-public final class PurgeEntities extends Purge {
-
-  private Configuration configuration;
-
-  public PurgeEntities(DatabaseSession session, Configuration conf) {
-    super(session);
-    this.configuration = conf;
-  }
-
-  public void purge(PurgeContext context) {
-    int minimumPeriodInHours = PurgeUtils.getMinimumPeriodInHours(configuration);
-    final Date beforeDate = DateUtils.addHours(new Date(), -minimumPeriodInHours);
-    Logs.INFO.info("Deleting files data before " + beforeDate);
-
-    Query query = getSession().createQuery("SELECT s.id FROM " + Snapshot.class.getSimpleName() + " s WHERE s.last=:last AND scope=:scope AND s.createdAt<:date");
-    query.setParameter("scope", Scopes.FILE);
-    query.setParameter("date", beforeDate);
-    query.setParameter("last", Boolean.FALSE);
-    List<Integer> snapshotIds = query.getResultList();
-
-    PurgeUtils.deleteSnapshotsData(getSession(), snapshotIds);
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeEventOrphans.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeEventOrphans.java
deleted file mode 100644 (file)
index 894f15c..0000000
+++ /dev/null
@@ -1,50 +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.batch.Event;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.model.ResourceModel;
-import org.sonar.plugins.dbcleaner.api.Purge;
-import org.sonar.plugins.dbcleaner.api.PurgeContext;
-import org.sonar.plugins.dbcleaner.api.PurgeUtils;
-
-import javax.persistence.Query;
-import java.util.List;
-
-public final class PurgeEventOrphans extends Purge {
-
-  public PurgeEventOrphans(DatabaseSession session) {
-    super(session);
-  }
-
-  public void purge(PurgeContext context) {
-    String selectEventsSql = "SELECT e.id FROM " + Event.class.getSimpleName() + " e WHERE (";
-    selectEventsSql += "e.resourceId IS NOT NULL AND NOT EXISTS(FROM " + ResourceModel.class.getSimpleName()
-        + " r WHERE r.id=e.resourceId)";
-    selectEventsSql += ") OR (";
-    selectEventsSql += "e.snapshot IS NULL";
-    selectEventsSql += ")";
-
-    Query query = getSession().createQuery(selectEventsSql);
-    final List<Integer> eventIds = query.getResultList();
-    PurgeUtils.executeQuery(getSession(), "", eventIds, "DELETE FROM " + Event.class.getSimpleName() + " WHERE id in (:ids)");
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanResources.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanResources.java
deleted file mode 100644 (file)
index 11b2dda..0000000
+++ /dev/null
@@ -1,48 +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.database.DatabaseSession;
-import org.sonar.api.database.model.ResourceModel;
-import org.sonar.plugins.dbcleaner.api.Purge;
-import org.sonar.plugins.dbcleaner.api.PurgeContext;
-import org.sonar.plugins.dbcleaner.api.PurgeUtils;
-
-import javax.persistence.Query;
-import java.util.List;
-
-/**
- * @since 2.1
- */
-public final class PurgeOrphanResources extends Purge {
-
-  public PurgeOrphanResources(DatabaseSession session) {
-    super(session);
-  }
-
-  public void purge(PurgeContext context) {
-    Query query = getSession().createQuery("SELECT r1.id FROM " + ResourceModel.class.getSimpleName() +
-      " r1 WHERE r1.rootId IS NOT NULL AND NOT EXISTS(FROM " + ResourceModel.class.getSimpleName() + " r2 WHERE r1.rootId=r2.id)");
-    List<Integer> idsToDelete = query.getResultList();
-    if (!idsToDelete.isEmpty()) {
-      PurgeUtils.deleteResources(getSession(), idsToDelete);
-    }
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanReviews.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanReviews.java
deleted file mode 100644 (file)
index 6f19e20..0000000
+++ /dev/null
@@ -1,66 +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 javax.persistence.Query;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.plugins.dbcleaner.api.Purge;
-import org.sonar.plugins.dbcleaner.api.PurgeContext;
-
-/**
- * Purge Review that are attached to projects that have been deleted.
- * 
- * @since 2.8
- */
-public final class PurgeOrphanReviews extends Purge {
-
-  private static final Logger LOG = LoggerFactory.getLogger(PurgeOrphanReviews.class);
-
-  public PurgeOrphanReviews(DatabaseSession session) {
-    super(session);
-  }
-
-  public void purge(PurgeContext context) {
-    DatabaseSession session = getSession();
-    
-    // delete reviews
-    Query query = session.createNativeQuery(getDeleteReviewsSqlRequest());
-    int rowDeleted = query.executeUpdate();
-    LOG.debug("- {} reviews deleted.", rowDeleted);
-    
-    // and delete review comments
-    query = session.createNativeQuery(getDeleteReviewCommentsSqlRequest());
-    rowDeleted = query.executeUpdate();
-    LOG.debug("- {} review comments deleted.", rowDeleted);
-
-    session.commit();
-  }
-
-  protected String getDeleteReviewsSqlRequest() {
-    return "DELETE FROM reviews WHERE project_id not in (SELECT id FROM projects WHERE scope = 'PRJ' and qualifier = 'TRK')";
-  }
-
-  protected String getDeleteReviewCommentsSqlRequest() {
-    return "DELETE FROM review_comments WHERE review_id not in (SELECT id FROM reviews)";
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgePropertyOrphans.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgePropertyOrphans.java
deleted file mode 100644 (file)
index 7974391..0000000
+++ /dev/null
@@ -1,65 +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.database.DatabaseSession;
-import org.sonar.api.database.configuration.Property;
-import org.sonar.api.database.model.ResourceModel;
-import org.sonar.api.database.model.User;
-import org.sonar.plugins.dbcleaner.api.Purge;
-import org.sonar.plugins.dbcleaner.api.PurgeContext;
-import org.sonar.plugins.dbcleaner.api.PurgeUtils;
-
-import java.util.List;
-
-import javax.persistence.Query;
-
-/**
- * @since 2.2
- */
-public final class PurgePropertyOrphans extends Purge {
-
-  public PurgePropertyOrphans(DatabaseSession session) {
-    super(session);
-  }
-
-  public void purge(PurgeContext context) {
-    purgeResourceOrphans();
-    purgeUserOrphans();
-  }
-
-  void purgeResourceOrphans() {
-    Query query = getSession().createQuery("SELECT p.id FROM " + Property.class.getSimpleName() +
-        " p WHERE p.resourceId IS NOT NULL AND NOT EXISTS(FROM " + ResourceModel.class.getSimpleName() + " r WHERE r.id=p.resourceId)");
-    List<Integer> idsToDelete = query.getResultList();
-    if (!idsToDelete.isEmpty()) {
-      PurgeUtils.executeQuery(getSession(), "", idsToDelete, "DELETE FROM " + Property.class.getSimpleName() + " WHERE id in (:ids)");
-    }
-  }
-
-  void purgeUserOrphans() {
-    Query query = getSession().createQuery("SELECT p.id FROM " + Property.class.getSimpleName() +
-        " p WHERE p.userId IS NOT NULL AND NOT EXISTS(FROM " + User.class.getSimpleName() + " u WHERE u.id=p.userId)");
-    List<Integer> idsToDelete = query.getResultList();
-    if (!idsToDelete.isEmpty()) {
-      PurgeUtils.executeQuery(getSession(), "", idsToDelete, "DELETE FROM " + Property.class.getSimpleName() + " WHERE id in (:ids)");
-    }
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeResourceRoles.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeResourceRoles.java
deleted file mode 100644 (file)
index 7a22eb7..0000000
+++ /dev/null
@@ -1,54 +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.database.DatabaseSession;
-import org.sonar.api.database.model.ResourceModel;
-import org.sonar.api.security.GroupRole;
-import org.sonar.api.security.UserRole;
-import org.sonar.plugins.dbcleaner.api.Purge;
-import org.sonar.plugins.dbcleaner.api.PurgeContext;
-import org.sonar.plugins.dbcleaner.api.PurgeUtils;
-
-import java.util.List;
-
-import javax.persistence.Query;
-
-/**
- * @since 1.12
- */
-public final class PurgeResourceRoles extends Purge {
-
-  public PurgeResourceRoles(DatabaseSession session) {
-    super(session);
-  }
-
-  public void purge(PurgeContext context) {
-    deleteRoles(UserRole.class.getSimpleName());
-    deleteRoles(GroupRole.class.getSimpleName());
-  }
-
-  private void deleteRoles(String classname) {
-    Query query = getSession().createQuery("SELECT rol.id FROM " + classname + " rol "
-        + " WHERE rol.resourceId IS NOT NULL AND NOT EXISTS(FROM " + ResourceModel.class.getSimpleName() + " r WHERE r.id=rol.resourceId)");
-    List<Integer> roleIds = query.getResultList();
-    PurgeUtils.executeQuery(getSession(), "", roleIds, "delete from " + classname + " rol where rol.id in (:ids)");
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeRuleMeasures.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeRuleMeasures.java
deleted file mode 100644 (file)
index 1b6f6d7..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.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.model.MeasureModel;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.plugins.dbcleaner.api.Purge;
-import org.sonar.plugins.dbcleaner.api.PurgeContext;
-import org.sonar.plugins.dbcleaner.api.PurgeUtils;
-
-import javax.persistence.Query;
-import java.util.List;
-
-/**
- * see SONAR-522
- *
- * @since 1.11
- */
-public final class PurgeRuleMeasures extends Purge {
-
-  public PurgeRuleMeasures(DatabaseSession session) {
-    super(session);
-  }
-
-  public void purge(PurgeContext context) {
-    if (context.getPreviousSnapshotId() != null) {
-      purge(context.getPreviousSnapshotId());
-    }
-  }
-
-  private void purge(Integer sid) {
-    Query query = getSession().createQuery(
-      "SELECT m.id FROM " + MeasureModel.class.getSimpleName() + " m, " + Snapshot.class.getSimpleName() + " s " +
-        " WHERE s.id = m.snapshotId AND (s.rootId=:rootSid OR s.id=:rootSid) and m.ruleId is not null");
-    query.setParameter("rootSid", sid);
-    List<Integer> measureIds = query.getResultList();
-    PurgeUtils.deleteMeasuresById(getSession(), measureIds);
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeUnprocessed.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeUnprocessed.java
deleted file mode 100644 (file)
index e7a053b..0000000
+++ /dev/null
@@ -1,60 +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.apache.commons.configuration.Configuration;
-import org.apache.commons.lang.time.DateUtils;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.utils.Logs;
-import org.sonar.plugins.dbcleaner.api.Purge;
-import org.sonar.plugins.dbcleaner.api.PurgeContext;
-import org.sonar.plugins.dbcleaner.api.PurgeUtils;
-
-import javax.persistence.Query;
-import java.util.Date;
-import java.util.List;
-
-/**
- * @since 1.11
- */
-public final class PurgeUnprocessed extends Purge {
-
-  private Configuration configuration;
-
-  public PurgeUnprocessed(DatabaseSession session, Configuration conf) {
-    super(session);
-    this.configuration = conf;
-  }
-
-  public void purge(PurgeContext context) {
-    int minimumPeriodInHours = PurgeUtils.getMinimumPeriodInHours(configuration);
-    final Date beforeDate = DateUtils.addHours(new Date(), -minimumPeriodInHours);
-    Logs.INFO.info("Deleting unprocessed data before " + beforeDate);
-
-    Query query = getSession().createQuery("SELECT s.id FROM " + Snapshot.class.getSimpleName() + " s WHERE s.last=:last AND status=:status AND s.createdAt<:date");
-    query.setParameter("status", Snapshot.STATUS_UNPROCESSED);
-    query.setParameter("date", beforeDate);
-    query.setParameter("last", Boolean.FALSE);
-    List<Integer> snapshotIds = query.getResultList();
-
-    PurgeUtils.deleteSnapshotsData(getSession(), snapshotIds);
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/DefaultPurgeContext.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/DefaultPurgeContext.java
deleted file mode 100644 (file)
index cd3a5c4..0000000
+++ /dev/null
@@ -1,79 +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.runner;
-
-import org.apache.commons.lang.builder.ToStringBuilder;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.resources.Project;
-import org.sonar.plugins.dbcleaner.api.PurgeContext;
-
-public final class DefaultPurgeContext implements org.sonar.api.batch.PurgeContext, PurgeContext {
-
-  private Project project;
-  private Integer currentSid;
-  private Integer previousSid;
-
-  public DefaultPurgeContext(Project project, Snapshot currentSnapshot) {
-    this(project, currentSnapshot, null);
-  }
-
-  public DefaultPurgeContext(Project project, Snapshot currentSnapshot, Snapshot previousSnapshot) {
-    this.project = project;
-    if (currentSnapshot != null) {
-      currentSid = currentSnapshot.getId();
-    }
-    if (previousSnapshot != null) {
-      previousSid = previousSnapshot.getId();
-    }
-  }
-
-  public DefaultPurgeContext setLastSnapshotId(Integer previousSid) {
-    this.previousSid = previousSid;
-    return this;
-  }
-
-  public Integer getSnapshotId() {
-    return currentSid;
-  }
-
-  public Integer getPreviousSnapshotId() {
-    return previousSid;
-  }
-
-  public Project getProject() {
-    return project;
-  }
-
-  /**
-   * @deprecated 
-   */
-  @Deprecated
-  public Integer getLastSnapshotId() {
-    return currentSid;
-  }
-
-  @Override
-  public String toString() {
-    return new ToStringBuilder(this)
-        .append("currentSid", currentSid)
-        .append("previousSid", previousSid)
-        .toString();
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/DeprecatedPurgePostJob.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/DeprecatedPurgePostJob.java
new file mode 100644 (file)
index 0000000..2069b38
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * 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.runner;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.HibernateException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.batch.PostJob;
+import org.sonar.api.batch.SensorContext;
+import org.sonar.api.database.DatabaseSession;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.resources.Project;
+import org.sonar.api.utils.TimeProfiler;
+import org.sonar.core.NotDryRun;
+import org.sonar.plugins.dbcleaner.api.Purge;
+import org.sonar.plugins.dbcleaner.api.PurgeContext;
+
+import javax.persistence.Query;
+
+@NotDryRun
+public final class DeprecatedPurgePostJob implements PostJob {
+
+  private DatabaseSession session;
+  private Snapshot snapshot;
+  private Purge[] purges;
+  private Project project;
+  private static final Logger LOG = LoggerFactory.getLogger(DeprecatedPurgePostJob.class);
+
+  public DeprecatedPurgePostJob(DatabaseSession session, Project project, Snapshot snapshot, Purge[] purges) {
+    this.session = session;
+    this.project = project;
+    this.snapshot = snapshot;
+    this.purges = purges.clone();
+  }
+
+  public void executeOn(Project project, SensorContext context) {
+    if (shouldExecuteOn(project)) {
+      purge();
+    }
+  }
+
+  static boolean shouldExecuteOn(Project project) {
+    return project.isRoot();
+  }
+
+  public void purge() {
+    TimeProfiler profiler = new TimeProfiler(LOG).start("Database optimization");
+    DefaultPurgeContext context = newContext();
+    LOG.debug("Snapshots to purge: " + context);
+    executePurges(context);
+    profiler.stop();
+  }
+
+
+  private void executePurges(DefaultPurgeContext context) {
+    TimeProfiler profiler = new TimeProfiler();
+    for (Purge purge : purges) {
+      try {
+        profiler.start("Purge " + purge.getClass().getName());
+        purge.purge(context);
+        session.commit(); // force hibernate to commit, so we're sure that the potential raised exception comes from this purge
+        profiler.stop();
+      } catch (javax.persistence.PersistenceException e) {
+        // Temporary workaround for MySQL deadlocks. The exception must not fail the build
+        // See https://jira.codehaus.org/browse/SONAR-2961 and https://jira.codehaus.org/browse/SONAR-2190
+        LOG.warn("Fail to execute purge: " + purge, e);
+
+      } catch (HibernateException e) {
+        // Temporary workaround for MySQL deadlocks. The exception must not fail the build
+        // See https://jira.codehaus.org/browse/SONAR-2961 and https://jira.codehaus.org/browse/SONAR-2190
+        LOG.warn("Fail to execute purge: " + purge, e);
+      }
+    }
+  }
+
+  private DefaultPurgeContext newContext() {
+    DefaultPurgeContext context = new DefaultPurgeContext(project, snapshot);
+    Snapshot previousLastSnapshot = getPreviousLastSnapshot();
+    if (previousLastSnapshot != null && previousLastSnapshot.getCreatedAt().before(snapshot.getCreatedAt())) {
+      context.setLastSnapshotId(previousLastSnapshot.getId());
+    }
+    return context;
+  }
+
+  private Snapshot getPreviousLastSnapshot() {
+    Query query = session.createQuery(
+      "SELECT s FROM " + Snapshot.class.getSimpleName() + " s " +
+        "WHERE s.status=:status AND s.resourceId=:resourceId AND s.createdAt<:date AND s.id <> :sid ORDER BY s.createdAt DESC");
+    query.setParameter("status", Snapshot.STATUS_PROCESSED);
+    query.setParameter("resourceId", snapshot.getResourceId());
+    query.setParameter("date", snapshot.getCreatedAt());
+    query.setParameter("sid", snapshot.getId());
+    query.setMaxResults(1);
+    return session.getSingleResult(query, null);
+  }
+
+  static final class DefaultPurgeContext implements PurgeContext {
+
+    private Project project;
+    private Integer currentSid;
+    private Integer previousSid;
+
+    public DefaultPurgeContext(Project project, Snapshot currentSnapshot) {
+      this(project, currentSnapshot, null);
+    }
+
+    public DefaultPurgeContext(Project project, Snapshot currentSnapshot, Snapshot previousSnapshot) {
+      this.project = project;
+      if (currentSnapshot != null) {
+        currentSid = currentSnapshot.getId();
+      }
+      if (previousSnapshot != null) {
+        previousSid = previousSnapshot.getId();
+      }
+    }
+
+    public DefaultPurgeContext setLastSnapshotId(Integer previousSid) {
+      this.previousSid = previousSid;
+      return this;
+    }
+
+    public Integer getSnapshotId() {
+      return currentSid;
+    }
+
+    public Integer getPreviousSnapshotId() {
+      return previousSid;
+    }
+
+    public Project getProject() {
+      return project;
+    }
+
+    @Override
+    public String toString() {
+      return new ToStringBuilder(this)
+        .append("currentSid", currentSid)
+        .append("previousSid", previousSid)
+        .toString();
+    }
+  }
+
+}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/ProjectPurgePostJob.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/ProjectPurgePostJob.java
new file mode 100644 (file)
index 0000000..6dccaef
--- /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.plugins.dbcleaner.runner;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.batch.PostJob;
+import org.sonar.api.batch.SensorContext;
+import org.sonar.api.resources.Project;
+import org.sonar.core.NotDryRun;
+import org.sonar.plugins.dbcleaner.purges.ProjectPurgeContext;
+import org.sonar.plugins.dbcleaner.purges.ProjectPurgeTask;
+
+import java.util.Date;
+
+@NotDryRun
+public class ProjectPurgePostJob implements PostJob {
+
+  private ProjectPurgeTask task;
+
+  public ProjectPurgePostJob(ProjectPurgeTask task) {
+    this.task = task;
+  }
+
+  public void executeOn(final Project project, SensorContext context) {
+    final Date beforeBuildDate = new Date();
+
+    ProjectPurgeContext purgeContext = new ProjectPurgeContext() {
+      public Long getRootProjectId() {
+        return new Long(project.getId());
+      }
+
+      public Date getBeforeBuildDate() {
+        return beforeBuildDate;
+      }
+    };
+
+    Logger logger = LoggerFactory.getLogger(getClass());
+    logger.info("Optimizing project");
+    task.execute(purgeContext);
+  }
+}
diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/PurgeRunner.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/PurgeRunner.java
deleted file mode 100644 (file)
index d12beab..0000000
+++ /dev/null
@@ -1,144 +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.runner;
-
-import org.hibernate.HibernateException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.PostJob;
-import org.sonar.api.batch.SensorContext;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.resources.Project;
-import org.sonar.api.utils.TimeProfiler;
-import org.sonar.core.NotDryRun;
-import org.sonar.plugins.dbcleaner.api.Purge;
-
-import javax.persistence.Query;
-
-@NotDryRun
-public final class PurgeRunner implements PostJob {
-
-  private DatabaseSession session;
-  private Snapshot snapshot;
-  private Purge[] purges;
-  private org.sonar.api.batch.Purge[] deprecatedPurges;
-  private Project project;
-  private static final Logger LOG = LoggerFactory.getLogger(PurgeRunner.class);
-
-  public PurgeRunner(DatabaseSession session, Project project, Snapshot snapshot, Purge[] purges) {
-    this.session = session;
-    this.project = project;
-    this.snapshot = snapshot;
-    this.purges = purges.clone();
-    this.deprecatedPurges = new org.sonar.api.batch.Purge[0];
-  }
-
-  public PurgeRunner(DatabaseSession session, Project project, Snapshot snapshot, Purge[] purges, org.sonar.api.batch.Purge[] deprecatedPurges) {
-    this.session = session;
-    this.project = project;
-    this.snapshot = snapshot;
-    this.purges = purges.clone();
-    this.deprecatedPurges = deprecatedPurges.clone();
-  }
-
-  public void executeOn(Project project, SensorContext context) {
-    if (shouldExecuteOn(project)) {
-      purge();
-    }
-  }
-
-  static boolean shouldExecuteOn(Project project) {
-    return project.isRoot();
-  }
-
-  public void purge() {
-    TimeProfiler profiler = new TimeProfiler(LOG).start("Database optimization");
-    DefaultPurgeContext context = newContext();
-    LOG.debug("Snapshots to purge: " + context);
-    executeDeprecatedPurges(context);
-    executePurges(context);
-    profiler.stop();
-  }
-
-  private void executeDeprecatedPurges(DefaultPurgeContext context) {
-    TimeProfiler profiler = new TimeProfiler();
-    for (org.sonar.api.batch.Purge purge : deprecatedPurges) {
-      try {
-        profiler.start("Purge " + purge.getClass().getName());
-        purge.purge(context);
-        session.commit();// force hibernate to commit, so we're sure that the potential raised exception comes from this purge
-        profiler.stop();
-
-      } catch (javax.persistence.PersistenceException e) {
-        // Temporary workaround for MySQL deadlocks. The exception must not fail the build
-        // See https://jira.codehaus.org/browse/SONAR-2961 and https://jira.codehaus.org/browse/SONAR-2190
-        LOG.warn("Fail to execute purge: " + purge, e);
-
-      } catch (HibernateException e) {
-        // Temporary workaround for MySQL deadlocks. The exception must not fail the build
-        // See https://jira.codehaus.org/browse/SONAR-2961 and https://jira.codehaus.org/browse/SONAR-2190
-        LOG.warn("Fail to execute purge: " + purge, e);
-      }
-    }
-  }
-
-  private void executePurges(DefaultPurgeContext context) {
-    TimeProfiler profiler = new TimeProfiler();
-    for (Purge purge : purges) {
-      try {
-        profiler.start("Purge " + purge.getClass().getName());
-        purge.purge(context);
-        session.commit(); // force hibernate to commit, so we're sure that the potential raised exception comes from this purge
-        profiler.stop();
-      } catch (javax.persistence.PersistenceException e) {
-        // Temporary workaround for MySQL deadlocks. The exception must not fail the build
-        // See https://jira.codehaus.org/browse/SONAR-2961 and https://jira.codehaus.org/browse/SONAR-2190
-        LOG.warn("Fail to execute purge: " + purge, e);
-
-      } catch (HibernateException e) {
-        // Temporary workaround for MySQL deadlocks. The exception must not fail the build
-        // See https://jira.codehaus.org/browse/SONAR-2961 and https://jira.codehaus.org/browse/SONAR-2190
-        LOG.warn("Fail to execute purge: " + purge, e);
-      }
-    }
-  }
-
-  private DefaultPurgeContext newContext() {
-    DefaultPurgeContext context = new DefaultPurgeContext(project, snapshot);
-    Snapshot previousLastSnapshot = getPreviousLastSnapshot();
-    if (previousLastSnapshot != null && previousLastSnapshot.getCreatedAt().before(snapshot.getCreatedAt())) {
-      context.setLastSnapshotId(previousLastSnapshot.getId());
-    }
-    return context;
-  }
-
-  private Snapshot getPreviousLastSnapshot() {
-    Query query = session.createQuery(
-      "SELECT s FROM " + Snapshot.class.getSimpleName() + " s " +
-        "WHERE s.status=:status AND s.resourceId=:resourceId AND s.createdAt<:date AND s.id <> :sid ORDER BY s.createdAt DESC");
-    query.setParameter("status", Snapshot.STATUS_PROCESSED);
-    query.setParameter("resourceId", snapshot.getResourceId());
-    query.setParameter("date", snapshot.getCreatedAt());
-    query.setParameter("sid", snapshot.getId());
-    query.setMaxResults(1);
-    return session.getSingleResult(query, null);
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDeletedResourcesTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDeletedResourcesTest.java
deleted file mode 100644 (file)
index 32bdf86..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.junit.Test;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-
-public class PurgeDeletedResourcesTest extends AbstractDbUnitTestCase {
-
-  @Test
-  public void purgeDeletedResources() throws SQLException {
-    setupData("sharedFixture", "purgeDeletedResources");
-
-    final Connection c = getConnection().getConnection();
-    c.prepareStatement("delete from projects where id=3").executeUpdate();
-    c.commit();
-
-    final PurgeDeletedResources purge = new PurgeDeletedResources(getSession());
-    purge.purge(null);
-
-    checkTables("purgeDeletedResources", "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources");
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDependenciesTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDependenciesTest.java
deleted file mode 100644 (file)
index 3ada477..0000000
+++ /dev/null
@@ -1,49 +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.junit.Test;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.sql.SQLException;
-
-public class PurgeDependenciesTest extends AbstractDbUnitTestCase {
-
-  @Test
-  public void purgeDependencies() throws SQLException {
-    assertPurge("purgeDependencies");
-  }
-
-  /**
-   * See https://jira.codehaus.org/browse/SONAR-2707
-   * Do not remove dependencies which are computed at the same time in other parallel jobs.
-   */
-  @Test
-  public void shouldNotPurgeUnprocessedSnapshots() throws SQLException {
-    assertPurge("shouldNotPurgeUnprocessedSnapshots");
-  }
-
-  private void assertPurge(String testName) {
-    setupData(testName);
-    new PurgeDependencies(getSession()).purge(null);
-    checkTables(testName, "dependencies");
-  }
-
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDeprecatedLastTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDeprecatedLastTest.java
deleted file mode 100644 (file)
index 545b47f..0000000
+++ /dev/null
@@ -1,37 +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.junit.Test;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.sql.SQLException;
-
-public class PurgeDeprecatedLastTest extends AbstractDbUnitTestCase {
-
-  @Test
-  public void purgeDeprecatedLast() throws SQLException {
-    setupData("sharedFixture", "purgeDeprecatedLast");
-
-    new PurgeDeprecatedLast(getSession()).purge(null);
-
-    checkTables("purgeDeprecatedLast", "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources");
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDisabledResourcesTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDisabledResourcesTest.java
deleted file mode 100644 (file)
index ab9b9ff..0000000
+++ /dev/null
@@ -1,49 +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.junit.Test;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.sql.SQLException;
-
-public class PurgeDisabledResourcesTest extends AbstractDbUnitTestCase {
-
-  @Test
-  public void purgeDisabledModule() throws SQLException {
-    assertPurge("purgeDisabledModule");
-  }
-
-  @Test
-  public void purgeDisabledProject() throws SQLException {
-    assertPurge("purgeDisabledProject");
-  }
-
-  @Test
-  public void nothingToPurge() throws SQLException {
-    assertPurge("nothingToPurge");
-  }
-
-  private void assertPurge(String testName) {
-    setupData("sharedFixture", testName);
-    new PurgeDisabledResources(getSession()).purge(null);
-    checkTables(testName, "snapshots", "project_measures");
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeEntitiesTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeEntitiesTest.java
deleted file mode 100644 (file)
index b46a3c3..0000000
+++ /dev/null
@@ -1,37 +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.apache.commons.configuration.PropertiesConfiguration;
-import org.junit.Test;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-public class PurgeEntitiesTest extends AbstractDbUnitTestCase {
-
-  @Test
-  public void purgeEntities() {
-    setupData("sharedFixture", "purgeEntities");
-
-    final PurgeEntities purge = new PurgeEntities(getSession(), new PropertiesConfiguration());
-    purge.purge(null);
-
-    checkTables("purgeEntities", "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources");
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeEventOrphansTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeEventOrphansTest.java
deleted file mode 100644 (file)
index 8f53836..0000000
+++ /dev/null
@@ -1,40 +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.junit.Test;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.sql.SQLException;
-
-public class PurgeEventOrphansTest extends AbstractDbUnitTestCase {
-
-  @Test
-  public void purgeEventOrphans() throws SQLException {
-    assertPurge("purgeEventOrphans");
-  }
-
-  private void assertPurge(String testName) {
-    setupData(testName);
-    new PurgeEventOrphans(getSession()).purge(null);
-    checkTables(testName, "events");
-  }
-
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanResourcesTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanResourcesTest.java
deleted file mode 100644 (file)
index d6df515..0000000
+++ /dev/null
@@ -1,38 +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.junit.Test;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.sql.SQLException;
-
-public class PurgeOrphanResourcesTest extends AbstractDbUnitTestCase {
-  @Test
-  public void purgeOrphanResources() throws SQLException {
-    assertPurge("purgeOrphanResources");
-  }
-
-  private void assertPurge(String testName) {
-    setupData(testName);
-    new PurgeOrphanResources(getSession()).purge(null);
-    checkTables(testName, "projects");
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanReviewsTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanReviewsTest.java
deleted file mode 100644 (file)
index 2a5ef03..0000000
+++ /dev/null
@@ -1,46 +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 static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-import java.sql.Statement;
-
-import org.junit.Test;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-public class PurgeOrphanReviewsTest extends AbstractDbUnitTestCase {
-
-  @Test
-  public void shouldCloseReviewWithoutCorrespondingViolation() throws Exception {
-    setupData("purgeOrphanReviews");
-
-    Statement stmt = getConnection().getConnection().createStatement();
-    int count = stmt.executeUpdate(new PurgeOrphanReviews(null).getDeleteReviewsSqlRequest());
-    assertThat(count, is(1));
-
-    count = stmt.executeUpdate(new PurgeOrphanReviews(null).getDeleteReviewCommentsSqlRequest());
-    assertThat(count, is(1));
-
-    checkTables("purgeOrphanReviews", "reviews");
-  }
-
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgePropertyOrphansTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgePropertyOrphansTest.java
deleted file mode 100644 (file)
index 3724046..0000000
+++ /dev/null
@@ -1,42 +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.junit.Test;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.sql.SQLException;
-
-public class PurgePropertyOrphansTest extends AbstractDbUnitTestCase {
-  @Test
-  public void purgeResourceOrphans() throws SQLException {
-    setupData("purgeResourceOrphans");
-    new PurgePropertyOrphans(getSession()).purgeResourceOrphans();
-    checkTables("purgeResourceOrphans", "properties");
-  }
-
-  @Test
-  public void purgeUserOrphans() throws SQLException {
-    setupData("purgeUserOrphans");
-    new PurgePropertyOrphans(getSession()).purgeUserOrphans();
-    checkTables("purgeUserOrphans", "properties");
-  }
-
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeResourceRolesTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeResourceRolesTest.java
deleted file mode 100644 (file)
index ba7bf56..0000000
+++ /dev/null
@@ -1,38 +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.junit.Test;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.sql.SQLException;
-
-public class PurgeResourceRolesTest extends AbstractDbUnitTestCase {
-
-  @Test
-  public void purgeResourceRoles() throws SQLException {
-    setupData("purgeResourceRoles");
-
-    new PurgeResourceRoles(getSession()).purge(null);
-
-    checkTables("purgeResourceRoles", "projects", "user_roles", "group_roles");
-  }
-}
-
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeRuleMeasuresTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeRuleMeasuresTest.java
deleted file mode 100644 (file)
index c3caf3a..0000000
+++ /dev/null
@@ -1,49 +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.junit.Test;
-import org.sonar.api.resources.Project;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-import org.sonar.plugins.dbcleaner.api.PurgeContext;
-
-public class PurgeRuleMeasuresTest extends AbstractDbUnitTestCase {
-
-  @Test
-  public void purgeRuleMeasures() {
-    setupData("sharedFixture", "purgeRuleMeasures");
-
-    new PurgeRuleMeasures(getSession()).purge(new PurgeContext() {
-      public Project getProject() {
-        return null;
-      }
-
-      public Integer getSnapshotId() {
-        return 4;
-      }
-      public Integer getPreviousSnapshotId() {
-        return 1;
-      }
-
-    });
-
-    checkTables("purgeRuleMeasures", "snapshots", "project_measures", "measure_data");
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeUnprocessedTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeUnprocessedTest.java
deleted file mode 100644 (file)
index f972d17..0000000
+++ /dev/null
@@ -1,37 +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.apache.commons.configuration.PropertiesConfiguration;
-import org.junit.Test;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-public class PurgeUnprocessedTest extends AbstractDbUnitTestCase {
-
-  @Test
-  public void purgeUnprocessed() {
-    setupData("sharedFixture", "purgeUnprocessed");
-
-    new PurgeUnprocessed(getSession(), new PropertiesConfiguration()).purge(null);
-
-    checkTables("purgeUnprocessed", "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources");
-  }
-}
-
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/runner/DeprecatedPurgePostJobTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/runner/DeprecatedPurgePostJobTest.java
new file mode 100644 (file)
index 0000000..402fdff
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * 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.runner;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.junit.Test;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.resources.Project;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+import org.sonar.plugins.dbcleaner.api.Purge;
+import org.sonar.plugins.dbcleaner.api.PurgeContext;
+
+import javax.persistence.PersistenceException;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.*;
+
+public class DeprecatedPurgePostJobTest extends AbstractDbUnitTestCase {
+
+  @Test
+  public void shouldExecutePurges() {
+    setupData("shared");
+    final int currentSID = 400;
+    final int previousSID = 300;
+    Snapshot snapshot = getSession().getSingleResult(Snapshot.class, "id", currentSID);
+
+    Purge purge1 = mock(Purge.class);
+    Purge purge2 = mock(Purge.class);
+    Purge[] purges = new Purge[]{purge1, purge2};
+
+    new DeprecatedPurgePostJob(getSession(), new Project("key"), snapshot, purges).purge();
+
+    verify(purge1).purge(argThat(new BaseMatcher<PurgeContext>() {
+      public boolean matches(Object o) {
+        PurgeContext context = (PurgeContext) o;
+        return context.getSnapshotId() == currentSID && context.getPreviousSnapshotId() == previousSID;
+      }
+
+      public void describeTo(Description description) {
+      }
+    }));
+  }
+
+  @Test
+  public void shouldExecutePurgesEvenIfSingleAnalysis() {
+    setupData("shared");
+    final int currentSID = 1000;
+    Snapshot snapshot = getSession().getSingleResult(Snapshot.class, "id", currentSID);
+
+    Purge purge1 = mock(Purge.class);
+    Purge purge2 = mock(Purge.class);
+    Purge[] purges = new Purge[]{purge1, purge2};
+
+    new DeprecatedPurgePostJob(getSession(), new Project("key"), snapshot, purges).purge();
+
+    verify(purge1).purge(argThat(new BaseMatcher<PurgeContext>() {
+      public boolean matches(Object o) {
+        PurgeContext context = (PurgeContext) o;
+        return context.getSnapshotId() == currentSID && context.getPreviousSnapshotId() == null;
+      }
+
+      public void describeTo(Description description) {
+      }
+    }));
+  }
+
+  @Test
+  public void shouldExecuteOnlyOnRootProjects() {
+    Project project = mock(Project.class);
+    when(project.isRoot()).thenReturn(true);
+    assertTrue(DeprecatedPurgePostJob.shouldExecuteOn(project));
+
+    when(project.isRoot()).thenReturn(false);
+    assertFalse(DeprecatedPurgePostJob.shouldExecuteOn(project));
+  }
+
+  /**
+   * See https://jira.codehaus.org/browse/SONAR-2961
+   * Temporarily ignore MySQL deadlocks
+   */
+  @Test
+  public void shouldIgnoreDeadlocks() {
+    Purge purge = mock(Purge.class);
+    doThrow(new PersistenceException()).when(purge).purge((PurgeContext) anyObject());
+
+    DeprecatedPurgePostJob runner = new DeprecatedPurgePostJob(getSession(), new Project(""), new Snapshot(), new Purge[]{purge});
+    runner.purge();// must not raise any exceptions
+
+    verify(purge).purge((PurgeContext) anyObject());
+  }
+}
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/runner/PurgeRunnerTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/runner/PurgeRunnerTest.java
deleted file mode 100644 (file)
index 76ff59d..0000000
+++ /dev/null
@@ -1,137 +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.runner;
-
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.junit.Test;
-import org.mockito.Matchers;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.resources.Project;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-import org.sonar.plugins.dbcleaner.api.Purge;
-import org.sonar.plugins.dbcleaner.api.PurgeContext;
-
-import javax.persistence.PersistenceException;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.*;
-
-public class PurgeRunnerTest extends AbstractDbUnitTestCase {
-
-  @Test
-  public void shouldExecutePurges() {
-    setupData("shared");
-    final int currentSID = 400;
-    final int previousSID = 300;
-    Snapshot snapshot = getSession().getSingleResult(Snapshot.class, "id", currentSID);
-
-    Purge purge1 = mock(Purge.class);
-    Purge purge2 = mock(Purge.class);
-    Purge[] purges = new Purge[]{purge1, purge2};
-
-    new PurgeRunner(getSession(), new Project("key"), snapshot, purges).purge();
-
-    verify(purge1).purge(argThat(new BaseMatcher<PurgeContext>() {
-      public boolean matches(Object o) {
-        PurgeContext context = (PurgeContext) o;
-        return context.getSnapshotId() == currentSID && context.getPreviousSnapshotId() == previousSID;
-      }
-
-      public void describeTo(Description description) {
-      }
-    }));
-  }
-
-  @Test
-  public void shouldExecutePurgesEvenIfSingleAnalysis() {
-    setupData("shared");
-    final int currentSID = 1000;
-    Snapshot snapshot = getSession().getSingleResult(Snapshot.class, "id", currentSID);
-
-    Purge purge1 = mock(Purge.class);
-    Purge purge2 = mock(Purge.class);
-    Purge[] purges = new Purge[]{purge1, purge2};
-
-    new PurgeRunner(getSession(), new Project("key"), snapshot, purges).purge();
-
-    verify(purge1).purge(argThat(new BaseMatcher<PurgeContext>() {
-      public boolean matches(Object o) {
-        PurgeContext context = (PurgeContext) o;
-        return context.getSnapshotId() == currentSID && context.getPreviousSnapshotId() == null;
-      }
-
-      public void describeTo(Description description) {
-      }
-    }));
-  }
-
-
-  @Test
-  public void shouldExecuteDeprecatedPurges() {
-    setupData("shared");
-    final int currentSID = 400;
-    final int previousSID = 300;
-    Snapshot snapshot = getSession().getSingleResult(Snapshot.class, "id", currentSID);
-
-
-    org.sonar.api.batch.Purge deprecated1 = mock(org.sonar.api.batch.Purge.class), deprecated2 = mock(org.sonar.api.batch.Purge.class);
-    org.sonar.api.batch.Purge[] deprecatedPurges = new org.sonar.api.batch.Purge[]{deprecated1, deprecated2};
-
-    new PurgeRunner(getSession(), new Project("key"), snapshot, new Purge[0], deprecatedPurges).purge();
-
-    verify(deprecated1).purge(argThat(new BaseMatcher<org.sonar.api.batch.PurgeContext>() {
-      public boolean matches(Object o) {
-        org.sonar.api.batch.PurgeContext context = (org.sonar.api.batch.PurgeContext) o;
-        return context.getLastSnapshotId() == currentSID && context.getPreviousSnapshotId() == previousSID;
-      }
-
-      public void describeTo(Description description) {
-      }
-    }));
-  }
-
-  @Test
-  public void shouldExecuteOnlyOnRootProjects() {
-    Project project = mock(Project.class);
-    when(project.isRoot()).thenReturn(true);
-    assertTrue(PurgeRunner.shouldExecuteOn(project));
-
-    when(project.isRoot()).thenReturn(false);
-    assertFalse(PurgeRunner.shouldExecuteOn(project));
-  }
-
-  /**
-   * See https://jira.codehaus.org/browse/SONAR-2961
-   * Temporarily ignore MySQL deadlocks
-   */
-  @Test
-  public void shouldIgnoreDeadlocks() {
-    Purge purge = mock(Purge.class);
-    doThrow(new PersistenceException()).when(purge).purge((PurgeContext)anyObject());
-
-    PurgeRunner runner = new PurgeRunner(getSession(), new Project(""), new Snapshot(), new Purge[]{purge});
-    runner.purge();// must not raise any exceptions
-
-    verify(purge).purge((PurgeContext)anyObject());
-  }
-}
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/resources/org/sonar/plugins/dbcleaner/runner/DeprecatedPurgePostJobTest/shared.xml b/plugins/sonar-dbcleaner-plugin/src/test/resources/org/sonar/plugins/dbcleaner/runner/DeprecatedPurgePostJobTest/shared.xml
new file mode 100644 (file)
index 0000000..18860b7
--- /dev/null
@@ -0,0 +1,75 @@
+<dataset>
+
+  <!--
+
+  PROJECT WITH HISTORIC DATA
+
+  -->
+
+  <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="myproject"
+            root_id="[null]"
+            description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]"/>
+
+  <!-- first snapshot -->
+  <snapshots 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]" id="100"
+             scope="PRJ" qualifier="TRK" created_at="2009-11-02 13:58:00.00" build_date="2009-11-02 13:58:00.00"
+             version="0.1-SNAPSHOT"
+             project_id="1" depth="[null]"
+             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false"
+             path="[null]"/>
+
+  <!-- unvalid snapshot (status = UNPROCESSED) -->
+  <snapshots 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]" id="200"
+             scope="PRJ" qualifier="TRK" created_at="2009-11-03 13:58:00.00" build_date="2009-11-03 13:58:00.00"
+             version="0.1-SNAPSHOT"
+             project_id="1" depth="[null]"
+             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="U" islast="false"
+             path="[null]"/>
+
+  <!-- second snapshot -->
+  <snapshots 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]" id="300"
+             scope="PRJ" qualifier="TRK" created_at="2009-11-04 13:58:00.00" build_date="2009-11-04 13:58:00.00"
+             version="0.1-SNAPSHOT"
+             project_id="1" depth="[null]"
+             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false"
+             path="[null]"/>
+
+  <!-- last snapshot -->
+  <snapshots 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]" id="400"
+             scope="PRJ" qualifier="TRK" created_at="2009-11-05 13:58:00.00" build_date="2009-11-05 13:58:00.00"
+             version="0.1-SNAPSHOT"
+             project_id="1" depth="[null]"
+             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+             path="[null]"/>
+
+
+  <!-- PROJECT WITH ONLY A SINGLE ANALYSIS - NO TIME MACHINE -->
+  <projects long_name="[null]" id="2" scope="PRJ" qualifier="TRK" kee="mygroup2:myartifact2" name="myproject2"
+            root_id="[null]"
+            description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]"/>
+
+  <snapshots 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]" id="1000"
+             scope="PRJ" qualifier="TRK" created_at="2009-11-05 13:58:00.00" build_date="2009-11-05 13:58:00.00"
+             version="0.1-SNAPSHOT"
+             project_id="2" depth="[null]"
+             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+             path="[null]"/>
+
+</dataset>
\ No newline at end of file
diff --git a/plugins/sonar-dbcleaner-plugin/src/test/resources/org/sonar/plugins/dbcleaner/runner/PurgeRunnerTest/shared.xml b/plugins/sonar-dbcleaner-plugin/src/test/resources/org/sonar/plugins/dbcleaner/runner/PurgeRunnerTest/shared.xml
deleted file mode 100644 (file)
index 1908f9c..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<dataset>
-
-  <!--
-
-  PROJECT WITH HISTORIC DATA
-
-  -->
-
-  <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="myproject"
-            root_id="[null]"
-            description="[null]"
-            enabled="true" language="java" copy_resource_id="[null]"/>
-
-  <!-- first snapshot -->
-  <snapshots 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]" id="100" scope="PRJ" qualifier="TRK" created_at="2009-11-02 13:58:00.00" build_date="2009-11-02 13:58:00.00" version="0.1-SNAPSHOT"
-             project_id="1" depth="[null]"
-             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false"
-             path="[null]"/>
-
-  <!-- unvalid snapshot (status = UNPROCESSED) -->
-  <snapshots 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]" id="200" scope="PRJ" qualifier="TRK" created_at="2009-11-03 13:58:00.00" build_date="2009-11-03 13:58:00.00" version="0.1-SNAPSHOT"
-             project_id="1" depth="[null]"
-             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="U" islast="false"
-             path="[null]"/>
-
-  <!-- second snapshot -->
-  <snapshots 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]" id="300" scope="PRJ" qualifier="TRK" created_at="2009-11-04 13:58:00.00" build_date="2009-11-04 13:58:00.00" version="0.1-SNAPSHOT"
-             project_id="1" depth="[null]"
-             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false"
-             path="[null]"/>
-
-  <!-- last snapshot -->
-  <snapshots 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]" id="400" scope="PRJ" qualifier="TRK" created_at="2009-11-05 13:58:00.00" build_date="2009-11-05 13:58:00.00" version="0.1-SNAPSHOT"
-             project_id="1" depth="[null]"
-             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
-             path="[null]"/>
-
-
-
-
-
-  <!-- PROJECT WITH ONLY A SINGLE ANALYSIS - NO TIME MACHINE -->
-  <projects long_name="[null]" id="2" scope="PRJ" qualifier="TRK" kee="mygroup2:myartifact2" name="myproject2"
-            root_id="[null]"
-            description="[null]"
-            enabled="true" language="java" copy_resource_id="[null]"/>
-
-  <snapshots 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]" id="1000" scope="PRJ" qualifier="TRK" created_at="2009-11-05 13:58:00.00" build_date="2009-11-05 13:58:00.00" version="0.1-SNAPSHOT"
-             project_id="2" depth="[null]"
-             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
-             path="[null]"/>
-
-</dataset>
\ No newline at end of file
index 569a36b146c9b96b07bd94ebcfd063b420311979..1e283c6f5415b14df57f06888546b32679654db2 100644 (file)
@@ -39,7 +39,7 @@ public class ActiveDashboardDao implements BatchComponent, ServerComponent {
       mapper.insert(activeDashboardDto);
       session.commit();
     } finally {
-      session.close();
+      MyBatis.closeSessionQuietly(session);
     }
   }
 
index ba2d1853708aa4a46bffb13b53484e04b337c535..b70433dbf92c6ef68c585adef039234242d68fad 100644 (file)
@@ -33,12 +33,12 @@ public class DashboardDao implements BatchComponent, ServerComponent {
   }
 
   public DashboardDto selectGlobalDashboard(String name) {
-    SqlSession sqlSession = mybatis.openSession();
+    SqlSession session = mybatis.openSession();
     try {
-      DashboardMapper mapper = sqlSession.getMapper(DashboardMapper.class);
+      DashboardMapper mapper = session.getMapper(DashboardMapper.class);
       return mapper.selectGlobalDashboard(name);
     } finally {
-      sqlSession.close();
+      MyBatis.closeSessionQuietly(session);
     }
   }
 
@@ -59,7 +59,7 @@ public class DashboardDao implements BatchComponent, ServerComponent {
       }
       session.commit();
     } finally {
-      session.close();
+      MyBatis.closeSessionQuietly(session);
     }
   }
 
index eb3084ddb8d17b6d77c73f4212551c102621673a..2d98f947ca8c766ce3e00f71ae331a57fc4ef122 100644 (file)
@@ -37,12 +37,12 @@ public class DuplicationDao implements BatchComponent, ServerComponent {
   }
 
   public List<DuplicationUnitDto> selectCandidates(int resourceSnapshotId, Integer lastSnapshotId) {
-    SqlSession sqlSession = mybatis.openSession();
+    SqlSession session = mybatis.openSession();
     try {
-      DuplicationMapper mapper = sqlSession.getMapper(DuplicationMapper.class);
+      DuplicationMapper mapper = session.getMapper(DuplicationMapper.class);
       return mapper.selectCandidates(resourceSnapshotId, lastSnapshotId);
     } finally {
-      sqlSession.close();
+      MyBatis.closeSessionQuietly(session);
     }
   }
 
@@ -60,7 +60,7 @@ public class DuplicationDao implements BatchComponent, ServerComponent {
       session.commit();
 
     } finally {
-      session.close();
+      MyBatis.closeSessionQuietly(session);
     }
   }
 
index 579645ba3a9c7c1a6c29f77bddf514fcab8a36a2..5f3377821528292fa1372b981ff8a4850ebb3b6d 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.core.persistence;
 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.ResourceIndexerDao;
 import org.sonar.core.review.ReviewDao;
 import org.sonar.core.rule.RuleDao;
@@ -42,6 +43,7 @@ public final class DaoUtils {
       DashboardDao.class,
       DuplicationDao.class,
       LoadedTemplateDao.class,
+      PurgeDao.class,
       ResourceIndexerDao.class,
       ReviewDao.class,
       RuleDao.class));
index ef2950eed2a63c781883cfc5abe4450cc53ba4b4..0f7a0f0faacd27a096985939440b5ef6321d781e 100644 (file)
@@ -52,7 +52,7 @@ public class DatabaseMigrator implements ServerComponent {
         DdlUtils.createSchema(connection, database.getDialect().getId());
       } finally {
         try {
-          session.close();
+          MyBatis.closeSessionQuietly(session);
 
           // The connection is probably already closed by session.close()
           // but it's not documented in mybatis javadoc.
index be14f84242fb53a236aff819e5e9e7435b5dc07e..814c1ee26e26f39d8e76d6c139163205c3179e62 100644 (file)
@@ -43,7 +43,6 @@ public final class DatabaseUtils {
     "active_filters",
     "active_rules",
     "active_rule_changes",
-    "active_rule_notes",
     "active_rule_parameters",
     "active_rule_param_changes",
     "alerts",
@@ -73,12 +72,11 @@ public final class DatabaseUtils {
     "resource_index",
     "reviews",
     "review_comments",
-    "rule_failures",
-    "rule_notes",
     "rules",
     "rules_categories",
     "rules_parameters",
     "rules_profiles",
+    "rule_failures",
     "schema_migrations",
     "snapshots",
     "snapshot_sources",
index cd055ef0ac63c60c5d06847a41a4120c2ba20c63..59da8b5aeea39ace257e78666f2ec9cd56f98020 100644 (file)
@@ -26,14 +26,14 @@ import org.apache.ibatis.logging.LogFactory;
 import org.apache.ibatis.mapping.Environment;
 import org.apache.ibatis.session.*;
 import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
+import org.slf4j.LoggerFactory;
 import org.sonar.api.BatchComponent;
 import org.sonar.api.ServerComponent;
 import org.sonar.core.dashboard.*;
 import org.sonar.core.duplication.DuplicationMapper;
 import org.sonar.core.duplication.DuplicationUnitDto;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceIndexDto;
-import org.sonar.core.resource.ResourceIndexerMapper;
+import org.sonar.core.purge.PurgeMapper;
+import org.sonar.core.resource.*;
 import org.sonar.core.review.ReviewDto;
 import org.sonar.core.review.ReviewMapper;
 import org.sonar.core.rule.RuleDto;
@@ -70,6 +70,7 @@ public class MyBatis implements BatchComponent, ServerComponent {
     loadAlias(conf, "Resource", ResourceDto.class);
     loadAlias(conf, "ResourceIndex", ResourceIndexDto.class);
     loadAlias(conf, "Rule", RuleDto.class);
+    loadAlias(conf, "Snapshot", SnapshotDto.class);
     loadAlias(conf, "Widget", WidgetDto.class);
     loadAlias(conf, "WidgetProperty", WidgetPropertyDto.class);
 
@@ -77,6 +78,8 @@ public class MyBatis implements BatchComponent, ServerComponent {
     loadMapper(conf, DashboardMapper.class);
     loadMapper(conf, DuplicationMapper.class);
     loadMapper(conf, LoadedTemplateMapper.class);
+    loadMapper(conf, PurgeMapper.class);
+    loadMapper(conf, ResourceMapper.class);
     loadMapper(conf, ReviewMapper.class);
     loadMapper(conf, ResourceIndexerMapper.class);
     loadMapper(conf, RuleMapper.class);
@@ -99,6 +102,17 @@ public class MyBatis implements BatchComponent, ServerComponent {
     return sessionFactory.openSession(type);
   }
 
+  public static void closeSessionQuietly(SqlSession session) {
+    if (session != null) {
+      try {
+        session.close();
+      } catch (Exception e) {
+        LoggerFactory.getLogger(MyBatis.class).warn("Fail to close session", e);
+        // do not re-throw the exception
+      }
+    }
+  }
+
   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);
diff --git a/sonar-core/src/main/java/org/sonar/core/purge/PurgeDao.java b/sonar-core/src/main/java/org/sonar/core/purge/PurgeDao.java
new file mode 100644 (file)
index 0000000..510537f
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * 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.purge;
+
+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.MyBatis;
+
+public class PurgeDao {
+  private final MyBatis mybatis;
+
+  public PurgeDao(MyBatis mybatis) {
+    this.mybatis = mybatis;
+  }
+
+  public PurgeDao disableOrphanResources(Object... handlers) {
+    SqlSession session = mybatis.openSession(ExecutorType.BATCH);
+    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;
+
+    } finally {
+      MyBatis.closeSessionQuietly(session);
+    }
+  }
+
+  public PurgeDao disableResource(long resourceId, Object... handlers) {
+    SqlSession session = mybatis.openSession(ExecutorType.BATCH);
+    try {
+      final PurgeMapper mapper = session.getMapper(PurgeMapper.class);
+      disableResource(resourceId, mapper);
+      session.commit();
+      return this;
+
+    } finally {
+      MyBatis.closeSessionQuietly(session);
+    }
+  }
+
+  int disableResource(long resourceId, PurgeMapper mapper) {
+    mapper.disableResource(resourceId);
+    mapper.deleteResourceIndex(resourceId);
+    mapper.unsetSnapshotIslast(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);
+    try {
+      final PurgeMapper mapper = session.getMapper(PurgeMapper.class);
+      final BatchSession batchSession = new BatchSession(session);
+      session.select("selectSnapshotIdsToPurge", query, new ResultHandler() {
+        public void handleResult(ResultContext context) {
+          Long snapshotId = (Long) context.getResultObject();
+          batchSession.increment(purgeSnapshot(snapshotId, mapper));
+        }
+      });
+      batchSession.commit();
+      return this;
+
+    } finally {
+      MyBatis.closeSessionQuietly(session);
+    }
+  }
+
+  int purgeSnapshot(long snapshotId, PurgeMapper mapper) {
+    // note that events are not deleted.
+    mapper.deleteSnapshotDependencies(snapshotId);
+    mapper.deleteSnapshotDuplications(snapshotId);
+    mapper.deleteSnapshotSource(snapshotId);
+    mapper.deleteSnapshotViolations(snapshotId);
+    mapper.deleteSnapshotRuleMeasures(snapshotId);
+    mapper.deleteSnapshotCharacteristicMeasures(snapshotId);
+    // TODO SONAR-2061 delete wasted measures (!metric.keepHistory)
+    mapper.updatePurgeStatusToOne(snapshotId);
+    return 7; // nb of SQL requests
+  }
+
+  int deleteSnapshot(Long snapshotId, PurgeMapper mapper) {
+    mapper.deleteSnapshotDependencies(snapshotId);
+    mapper.deleteSnapshotDuplications(snapshotId);
+    mapper.deleteSnapshotEvents(snapshotId);
+    mapper.deleteSnapshotMeasureData(snapshotId);
+    mapper.deleteSnapshotMeasures(snapshotId);
+    mapper.deleteSnapshotSource(snapshotId);
+    mapper.deleteSnapshotViolations(snapshotId);
+    mapper.deleteSnapshot(snapshotId);
+    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;
+    }
+
+  }
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java b/sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java
new file mode 100644 (file)
index 0000000..2ee5c58
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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.purge;
+
+public interface PurgeMapper {
+  void deleteSnapshot(long snapshotId);
+
+  void deleteSnapshotDependencies(long snapshotId);
+
+  void deleteSnapshotDuplications(long snapshotId);
+
+  void deleteSnapshotEvents(long snapshotId);
+
+  void deleteSnapshotMeasures(long snapshotId);
+
+  void deleteSnapshotMeasureData(long snapshotId);
+
+  void deleteSnapshotSource(long snapshotId);
+
+  void deleteSnapshotViolations(long snapshotId);
+
+  void deleteSnapshotRuleMeasures(long snapshotId);
+
+  void deleteSnapshotCharacteristicMeasures(long snapshotId);
+
+  void updatePurgeStatusToOne(long snapshotId);
+
+  void disableResource(long resourceId);
+
+  void deleteResourceIndex(long resourceId);
+
+  void unsetSnapshotIslast(long resourceId);
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/purge/PurgeSnapshotQuery.java b/sonar-core/src/main/java/org/sonar/core/purge/PurgeSnapshotQuery.java
new file mode 100644 (file)
index 0000000..bb16364
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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.purge;
+
+import java.util.Date;
+
+public final class PurgeSnapshotQuery {
+  private Long rootProjectId;
+  private Date beforeBuildDate;
+  private String[] scopes;
+  private String[] qualifiers;
+  private String[] status;
+
+  private PurgeSnapshotQuery() {
+  }
+
+  public static PurgeSnapshotQuery create() {
+    return new PurgeSnapshotQuery();
+  }
+
+  public Long getRootProjectId() {
+    return rootProjectId;
+  }
+
+  public PurgeSnapshotQuery setRootProjectId(Long rootProjectId) {
+    this.rootProjectId = rootProjectId;
+    return this;
+  }
+
+  public Date getBeforeBuildDate() {
+    return beforeBuildDate;
+  }
+
+  public PurgeSnapshotQuery setBeforeBuildDate(Date beforeBuildDate) {
+    this.beforeBuildDate = beforeBuildDate;
+    return this;
+  }
+
+  public String[] getScopes() {
+    return scopes;
+  }
+
+  public PurgeSnapshotQuery setScopes(String[] scopes) {
+    this.scopes = scopes;
+    return this;
+  }
+
+  public String[] getQualifiers() {
+    return qualifiers;
+  }
+
+  public PurgeSnapshotQuery setQualifiers(String[] qualifiers) {
+    this.qualifiers = qualifiers;
+    return this;
+  }
+
+  public String[] getStatus() {
+    return status;
+  }
+
+  public PurgeSnapshotQuery setStatus(String[] status) {
+    this.status = status;
+    return this;
+  }
+}
index 7fb493e6508602ec3339f2ec2a0b3614c0893a7c..44f1d5332105a86009678e13e438f11ecd25eecd 100644 (file)
@@ -58,7 +58,7 @@ public class ResourceIndexerDao {
       return this;
 
     } finally {
-      session.close();
+      MyBatis.closeSessionQuietly(session);
     }
   }
 
@@ -79,7 +79,7 @@ public class ResourceIndexerDao {
       return this;
 
     } finally {
-      session.close();
+      MyBatis.closeSessionQuietly(session);
     }
   }
 
@@ -160,7 +160,7 @@ public class ResourceIndexerDao {
           }
         }
       } finally {
-        session.close();
+        MyBatis.closeSessionQuietly(session);
       }
     }
     return indexed;
diff --git a/sonar-core/src/main/java/org/sonar/core/resource/ResourceMapper.java b/sonar-core/src/main/java/org/sonar/core/resource/ResourceMapper.java
new file mode 100644 (file)
index 0000000..deb72ae
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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;
+
+public interface ResourceMapper {
+  SnapshotDto selectSnapshotById(Long snapshotId);
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/resource/SnapshotDto.java b/sonar-core/src/main/java/org/sonar/core/resource/SnapshotDto.java
new file mode 100644 (file)
index 0000000..f211be6
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * 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 java.util.Date;
+
+public final class SnapshotDto {
+  private Long id;
+  private Long parentId;
+  private Long rootId;
+  
+  private Date date;
+  private Date buildDate;
+  private Long resourceId;
+  private String status;
+  private Integer purgeStatus;
+  private Boolean last;
+  private String scope;
+  private String qualifier;
+  private String version;
+  private String path;
+  private Integer depth;
+  private Long rootProjectId;
+
+  public Long getId() {
+    return id;
+  }
+
+  public SnapshotDto setId(Long id) {
+    this.id = id;
+    return this;
+  }
+
+  public Long getParentId() {
+    return parentId;
+  }
+
+  public SnapshotDto setParentId(Long parentId) {
+    this.parentId = parentId;
+    return this;
+  }
+
+  public Long getRootId() {
+    return rootId;
+  }
+
+  public SnapshotDto setRootId(Long rootId) {
+    this.rootId = rootId;
+    return this;
+  }
+
+  public Date getDate() {
+    return date;
+  }
+
+  public SnapshotDto setDate(Date date) {
+    this.date = date;
+    return this;
+  }
+
+  public Date getBuildDate() {
+    return buildDate;
+  }
+
+  public SnapshotDto setBuildDate(Date buildDate) {
+    this.buildDate = buildDate;
+    return this;
+  }
+
+  public Long getResourceId() {
+    return resourceId;
+  }
+
+  public SnapshotDto setResourceId(Long resourceId) {
+    this.resourceId = resourceId;
+    return this;
+  }
+
+  public String getStatus() {
+    return status;
+  }
+
+  public SnapshotDto setStatus(String status) {
+    this.status = status;
+    return this;
+  }
+
+  public Integer getPurgeStatus() {
+    return purgeStatus;
+  }
+
+  public SnapshotDto setPurgeStatus(Integer purgeStatus) {
+    this.purgeStatus = purgeStatus;
+    return this;
+  }
+
+  public Boolean getLast() {
+    return last;
+  }
+
+  public SnapshotDto setLast(Boolean last) {
+    this.last = last;
+    return this;
+  }
+
+  public String getScope() {
+    return scope;
+  }
+
+  public SnapshotDto setScope(String scope) {
+    this.scope = scope;
+    return this;
+  }
+
+  public String getQualifier() {
+    return qualifier;
+  }
+
+  public SnapshotDto setQualifier(String qualifier) {
+    this.qualifier = qualifier;
+    return this;
+  }
+
+  public String getVersion() {
+    return version;
+  }
+
+  public SnapshotDto setVersion(String version) {
+    this.version = version;
+    return this;
+  }
+
+  public String getPath() {
+    return path;
+  }
+
+  public SnapshotDto setPath(String path) {
+    this.path = path;
+    return this;
+  }
+
+  public Integer getDepth() {
+    return depth;
+  }
+
+  public SnapshotDto setDepth(Integer depth) {
+    this.depth = depth;
+    return this;
+  }
+
+  public Long getRootProjectId() {
+    return rootProjectId;
+  }
+
+  public SnapshotDto setRootProjectId(Long rootProjectId) {
+    this.rootProjectId = rootProjectId;
+    return this;
+  }
+}
index 438bb9110213e7d08e38a4415a5b2cd912c0442c..c090251153db14f0ef0cd7b808f2a23af1a9adb5 100644 (file)
  */
 package org.sonar.core.review;
 
-import java.util.List;
-
+import com.google.common.collect.Lists;
 import org.apache.ibatis.session.SqlSession;
 import org.sonar.api.BatchComponent;
 import org.sonar.api.ServerComponent;
 import org.sonar.core.persistence.MyBatis;
 
-import com.google.common.collect.Lists;
+import java.util.List;
 
 public class ReviewDao implements BatchComponent, ServerComponent {
   private final MyBatis mybatis;
@@ -36,19 +35,19 @@ public class ReviewDao implements BatchComponent, ServerComponent {
   }
 
   public ReviewDto selectById(long id) {
-    SqlSession sqlSession = mybatis.openSession();
+    SqlSession session = mybatis.openSession();
     try {
-      ReviewMapper mapper = sqlSession.getMapper(ReviewMapper.class);
+      ReviewMapper mapper = session.getMapper(ReviewMapper.class);
       return mapper.selectById(id);
     } finally {
-      sqlSession.close();
+      MyBatis.closeSessionQuietly(session);
     }
   }
 
   public List<ReviewDto> selectByQuery(ReviewQuery query) {
-    SqlSession sqlSession = mybatis.openSession();
+    SqlSession session = mybatis.openSession();
     try {
-      ReviewMapper mapper = sqlSession.getMapper(ReviewMapper.class);
+      ReviewMapper mapper = session.getMapper(ReviewMapper.class);
       List<ReviewDto> result;
       if (query.needToPartitionQuery()) {
         result = Lists.newArrayList();
@@ -60,14 +59,14 @@ public class ReviewDao implements BatchComponent, ServerComponent {
       }
       return result;
     } finally {
-      sqlSession.close();
+      MyBatis.closeSessionQuietly(session);
     }
   }
 
   public Integer countByQuery(ReviewQuery query) {
-    SqlSession sqlSession = mybatis.openSession();
+    SqlSession session = mybatis.openSession();
     try {
-      ReviewMapper mapper = sqlSession.getMapper(ReviewMapper.class);
+      ReviewMapper mapper = session.getMapper(ReviewMapper.class);
       Integer result = 0;
       if (query.needToPartitionQuery()) {
         for (ReviewQuery partitionedQuery : query.partition()) {
@@ -78,7 +77,7 @@ public class ReviewDao implements BatchComponent, ServerComponent {
       }
       return result;
     } finally {
-      sqlSession.close();
+      MyBatis.closeSessionQuietly(session);
     }
   }
 }
index 76778d0b8655205d1e37736565bf05d9919e8a75..1b4b6545ea26d5c75c91ac71608c4e9250ba16f3 100644 (file)
@@ -35,22 +35,22 @@ public class RuleDao implements BatchComponent, ServerComponent {
   }
 
   public List<RuleDto> selectAll() {
-    SqlSession sqlSession = mybatis.openSession();
+    SqlSession session = mybatis.openSession();
     try {
-      RuleMapper mapper = sqlSession.getMapper(RuleMapper.class);
+      RuleMapper mapper = session.getMapper(RuleMapper.class);
       return mapper.selectAll();
     } finally {
-      sqlSession.close();
+      MyBatis.closeSessionQuietly(session);
     }
   }
 
   public RuleDto selectById(Long id) {
-    SqlSession sqlSession = mybatis.openSession();
+    SqlSession session = mybatis.openSession();
     try {
-      RuleMapper mapper = sqlSession.getMapper(RuleMapper.class);
+      RuleMapper mapper = session.getMapper(RuleMapper.class);
       return mapper.selectById(id);
     } finally {
-      sqlSession.close();
+      MyBatis.closeSessionQuietly(session);
     }
   }
 
index 5a183c0b567d77a1910cef9453e5fc3952bdafd0..7067d03bd7c2066c868026d9384a2c3935317e5c 100644 (file)
@@ -38,7 +38,7 @@ public class LoadedTemplateDao implements BatchComponent, ServerComponent {
     try {
       return mapper.countByTypeAndKey(type, key);
     } finally {
-      session.close();
+      MyBatis.closeSessionQuietly(session);
     }
   }
 
@@ -49,7 +49,7 @@ public class LoadedTemplateDao implements BatchComponent, ServerComponent {
       mapper.insert(loadedTemplateDto);
       session.commit();
     } finally {
-      session.close();
+      MyBatis.closeSessionQuietly(session);
     }
   }
 
index 02a2b5895b58eb5663b0a89f8011ac66bdaae13c..8144ad8cb05a3e5c585124f24363a81348a99759 100644 (file)
@@ -170,7 +170,6 @@ 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 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 6ddd00a816beb04a07afcbeeca67f2331f9b5921..81491225d86cab1e57489e071a3d7af6a9179cb7 100644 (file)
@@ -486,24 +486,6 @@ CREATE TABLE "ACTION_PLANS_REVIEWS" (
   "REVIEW_ID" INTEGER
 );
 
-CREATE TABLE "ACTIVE_RULE_NOTES" (
-  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
-  "ACTIVE_RULE_ID" INTEGER,
-  "USER_LOGIN" VARCHAR(40),
-  "DATA" BLOB(2147483647),
-  "CREATED_AT" TIMESTAMP,
-  "UPDATED_AT" TIMESTAMP
-);
-
-CREATE TABLE "RULE_NOTES" (
-  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
-  "RULE_ID" INTEGER,
-  "USER_LOGIN" VARCHAR(40),
-  "DATA" BLOB(2147483647),
-  "CREATED_AT" TIMESTAMP,
-  "UPDATED_AT" TIMESTAMP
-);
-
 
 -- ----------------------------------------------
 -- DDL Statements for indexes
@@ -597,10 +579,6 @@ CREATE INDEX "INDEX_ACTION_PLANS_REVIEWS_ON_ACTION_PLAN_ID" ON "ACTION_PLANS_REV
 
 CREATE INDEX "INDEX_ACTION_PLANS_REVIEWS_ON_REVIEW_ID" ON "ACTION_PLANS_REVIEWS" ("REVIEW_ID");
 
-CREATE INDEX "INDEX_ACTIVE_RULE_NOTES_ON_ACTIVE_RULE_ID" ON "ACTIVE_RULE_NOTES" ("ACTIVE_RULE_ID");
-
-CREATE INDEX "INDEX_RULE_NOTES_ON_ACTIVE_RULE_ID" ON "RULE_NOTES" ("RULE_ID");
-
 
 -- ----------------------------------------------
 -- DDL Statements for keys
@@ -688,7 +666,3 @@ ALTER TABLE "ACTIVE_RULE_PARAMETERS" ADD CONSTRAINT "SQL110927104437560" PRIMARY
 ALTER TABLE "LOADED_TEMPLATES" ADD CONSTRAINT "SQL110927104437650" PRIMARY KEY ("ID");
 
 ALTER TABLE "ACTION_PLANS" ADD CONSTRAINT "SQL110927104447650" PRIMARY KEY ("ID");
-
-ALTER TABLE "ACTIVE_RULE_NOTES" ADD CONSTRAINT "SQL110927104847650" PRIMARY KEY ("ID");
-
-ALTER TABLE "RULE_NOTES" ADD CONSTRAINT "SQL110927184847650" PRIMARY KEY ("ID");
diff --git a/sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml b/sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml
new file mode 100644 (file)
index 0000000..aa92585
--- /dev/null
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="org.sonar.core.purge.PurgeMapper">
+
+  <select id="selectSnapshotIds" parameterType="map" resultType="long">
+    select id from snapshots
+    <where>
+      islast=${_false}
+      <if test="rootProjectId != null">
+        and root_project_id=#{rootProjectId}
+      </if>
+      <if test="beforeBuildDate != null">
+        and build_date &lt;= #{beforeBuildDate}
+      </if>
+      <if test="status != null">
+        and status in
+        <foreach item="s" index="index" collection="status" open="(" separator="," close=")">#{s}</foreach>
+      </if>
+      <if test="scopes != null">
+        and scope in
+        <foreach item="scope" index="index" collection="scopes" open="(" separator="," close=")">#{scope}</foreach>
+      </if>
+      <if test="qualifiers != null">
+        and qualifier in
+        <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>
+
+  <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>
+
+  <delete id="deleteSnapshotMeasures" parameterType="long">
+    delete from project_measures where snapshot_id=#{id}
+  </delete>
+
+  <delete id="deleteSnapshotMeasureData" parameterType="long">
+    delete from measure_data where snapshot_id=#{id}
+  </delete>
+
+  <delete id="deleteSnapshotSource" parameterType="long">
+    delete from snapshot_sources where snapshot_id=#{id}
+  </delete>
+
+  <delete id="deleteSnapshotViolations" parameterType="long">
+    delete from rule_failures where snapshot_id=#{id}
+  </delete>
+
+  <delete id="deleteSnapshotDependencies" parameterType="long">
+    delete from dependencies where from_snapshot_id=#{id} or to_snapshot_id=#{id} or project_snapshot_id=#{id}
+  </delete>
+
+  <delete id="deleteSnapshotDuplications" parameterType="long">
+    delete from duplications_index where snapshot_id=#{id}
+  </delete>
+
+  <delete id="deleteSnapshotEvents" parameterType="long">
+    delete from events where snapshot_id=#{id}
+  </delete>
+
+  <delete id="deleteSnapshot" parameterType="long">
+    delete from snapshots where id=#{id}
+  </delete>
+
+  <delete id="deleteSnapshotRuleMeasures" parameterType="long">
+    delete from project_measures where snapshot_id=#{id} and rule_id is not null
+  </delete>
+
+  <delete id="deleteSnapshotCharacteristicMeasures" parameterType="long">
+    delete from project_measures where snapshot_id=#{id} and characteristic_id is not null
+  </delete>
+
+  <update id="updatePurgeStatusToOne" parameterType="long">
+    update snapshots set purge_status = 1 where id = #{id}
+  </update>
+
+  <update id="disableResource" parameterType="long">
+    update projects set enabled=${_false} where id=#{id}
+  </update>
+
+  <delete id="deleteResourceIndex" parameterType="long">
+    delete from resource_index where resource_id=#{id}
+  </delete>
+
+  <update id="unsetSnapshotIslast" parameterType="long">
+    update snapshots set islast=${_false} where project_id=#{id}
+  </update>
+</mapper>
+
diff --git a/sonar-core/src/main/resources/org/sonar/core/resource/ResourceMapper.xml b/sonar-core/src/main/resources/org/sonar/core/resource/ResourceMapper.xml
new file mode 100644 (file)
index 0000000..9ef0bcd
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="org.sonar.core.resource.ResourceMapper">
+
+
+  <resultMap id="snapshotResultMap" type="Snapshot">
+    <id property="id" column="id"/>
+    <result property="parentId" column="parent_snapshot_id"/>
+    <result property="rootId" column="root_snapshot_id"/>
+    <result property="date" column="created_at"/>
+    <result property="buildDate" column="build_date"/>
+    <result property="resourceId" column="project_id"/>
+    <result property="status" column="status"/>
+    <result property="purgeStatus" column="purge_status"/>
+    <result property="last" column="islast"/>
+    <result property="scope" column="scope"/>
+    <result property="qualifier" column="qualifier"/>
+    <result property="version" column="version"/>
+    <result property="path" column="path"/>
+    <result property="depth" column="depth"/>
+    <result property="rootProjectId" column="root_project_id"/>
+  </resultMap>
+
+
+  <select id="selectSnapshotById" parameterType="int" resultMap="snapshotResultMap">
+    select * from snapshots where id=#{id}
+  </select>
+
+</mapper>
+
diff --git a/sonar-core/src/test/java/org/sonar/core/purge/PurgeDaoTest.java b/sonar-core/src/test/java/org/sonar/core/purge/PurgeDaoTest.java
new file mode 100644 (file)
index 0000000..3e8f624
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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.purge;
+
+import org.apache.ibatis.session.SqlSession;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.core.persistence.DaoTestCase;
+import org.sonar.core.persistence.MyBatis;
+
+public class PurgeDaoTest extends DaoTestCase {
+
+  private PurgeDao dao;
+
+  @Before
+  public void createDao() {
+    dao = new PurgeDao(getMyBatis());
+  }
+
+  @Test
+  public void shouldDeleteSnapshot() {
+    setupData("shouldDeleteSnapshot");
+
+    SqlSession session = getMyBatis().openSession();
+    try {
+      // this method does not commit and close the session
+      dao.deleteSnapshot(5L, session.getMapper(PurgeMapper.class));
+      session.commit();
+
+    } finally {
+      MyBatis.closeSessionQuietly(session);
+    }
+    checkTables("shouldDeleteSnapshot",
+      "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources", "duplications_index", "events", "dependencies");
+  }
+
+  @Test
+  public void shouldPurgeSnapshots() {
+    setupData("shouldPurgeSnapshots");
+
+    dao.purgeSnapshots(PurgeSnapshotQuery.create());
+
+    checkTables("shouldPurgeSnapshots",
+      "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources", "duplications_index", "events", "dependencies");
+  }
+}
diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteSnapshot-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteSnapshot-result.xml
new file mode 100644 (file)
index 0000000..20f4744
--- /dev/null
@@ -0,0 +1,37 @@
+<dataset>
+
+  <!-- snapshot to keep -->
+  <snapshots id="1" 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]"/>
+
+  <SNAPSHOT_SOURCES ID="1" SNAPSHOT_ID="1" DATA="foo"/>
+  <rule_failures switched_off="[null]" permanent_id="[null]" ID="1" SNAPSHOT_ID="1" 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]"/>
+  <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="1" rules_category_id="[null]"
+                    RULE_ID="1"
+                    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="1" data="[null]"/>
+  <dependencies id="1" from_resource_id="1" from_snapshot_id="1" 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="LIB"/>
+  <events id="1" name="Version 1.0" resource_id="1" snapshot_id="1" 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"/>
+
+</dataset>
\ No newline at end of file
diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteSnapshot.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteSnapshot.xml
new file mode 100644 (file)
index 0000000..9a56459
--- /dev/null
@@ -0,0 +1,77 @@
+<dataset>
+
+  <!-- snapshot to keep -->
+  <snapshots id="1" 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]"/>
+
+  <SNAPSHOT_SOURCES ID="1" SNAPSHOT_ID="1" DATA="foo"/>
+  <rule_failures switched_off="[null]" permanent_id="[null]" ID="1" SNAPSHOT_ID="1" 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]"/>
+  <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="1" rules_category_id="[null]"
+                    RULE_ID="1"
+                    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="1" data="[null]"/>
+  <dependencies id="1" from_resource_id="1" from_snapshot_id="1" 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="LIB"/>
+  <events id="1" name="Version 1.0" resource_id="1" snapshot_id="1" 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"/>
+
+  <!-- snapshot to remove, id 5 on resource 5-->
+  <snapshots id="5" 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="5"
+             parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+             path="[null]"/>
+
+  <SNAPSHOT_SOURCES ID="2" SNAPSHOT_ID="5" DATA="foo"/>
+  <rule_failures switched_off="[null]" permanent_id="[null]" ID="3" SNAPSHOT_ID="5" RULE_ID="1" FAILURE_LEVEL="2"
+                 MESSAGE="msg3" LINE="[null]" COST="[null]"
+                 created_at="2008-12-02 13:58:00.00"
+                 checksum="[null]" committer="[null]"/>
+  <rule_failures switched_off="[null]" permanent_id="[null]" ID="4" SNAPSHOT_ID="5" RULE_ID="1" FAILURE_LEVEL="2"
+                 MESSAGE="msg4" LINE="[null]" COST="[null]"
+                 created_at="2008-12-02 13:58:00.00"
+                 checksum="[null]" committer="[null]"/>
+  <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="5" rules_category_id="[null]"
+                    RULE_ID="1"
+                    text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+                    alert_status="[null]" description="[null]"/>
+  <measure_data id="2" measure_id="2" snapshot_id="5" data="[null]"/>
+  <dependencies id="2" from_resource_id="10" from_snapshot_id="10" to_resource_id="5" to_snapshot_id="5"
+                parent_dependency_id="[null]" project_snapshot_id="5"
+                dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/>
+  <dependencies id="3" from_resource_id="5" from_snapshot_id="5" to_resource_id="300" to_snapshot_id="300"
+                parent_dependency_id="[null]" project_snapshot_id="5"
+                dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/>
+  <events id="2" name="Version 1.0" resource_id="5" snapshot_id="5" category="VERSION" description="[null]"
+          event_date="2008-12-02 13:58:00.00" created_at="[null]"/>
+  <duplications_index project_snapshot_id="5" snapshot_id="5" 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-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeSnapshots-result.xml
new file mode 100644 (file)
index 0000000..22327fa
--- /dev/null
@@ -0,0 +1,102 @@
+<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
new file mode 100644 (file)
index 0000000..cc870ca
--- /dev/null
@@ -0,0 +1,102 @@
+<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-deprecated/src/main/java/org/sonar/api/batch/AbstractPurge.java b/sonar-deprecated/src/main/java/org/sonar/api/batch/AbstractPurge.java
deleted file mode 100644 (file)
index 7482b51..0000000
+++ /dev/null
@@ -1,35 +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.api.batch;
-
-import org.sonar.api.database.DatabaseSession;
-
-/**
- * @since 1.10
- * @deprecated database components have been moved to sonar-database. Please extend org.sonar.core.purge.AbstractPurge.
- */
-@Deprecated
-public abstract class AbstractPurge extends org.sonar.core.purge.AbstractPurge {
-
-  public AbstractPurge(DatabaseSession session) {
-    super(session);
-  }
-  
-}
diff --git a/sonar-deprecated/src/main/java/org/sonar/api/batch/Purge.java b/sonar-deprecated/src/main/java/org/sonar/api/batch/Purge.java
deleted file mode 100644 (file)
index 358d23f..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.api.batch;
-
-import org.sonar.api.BatchExtension;
-
-/**
- * Extension point to purge data.
- * <p>
- * It is executed when the batch finishes.
- * </p>
- *
- * @since 1.10
- * @deprecated since 2.5. The DBCleaner plugin implements all required purge taks.
- */
-@Deprecated
-public interface Purge extends BatchExtension {
-
-  /**
-   * Snapshots include the current snapshot (flagged as last) and optionally the penultimate one.
-   *
-   * @snapshots never null.
-   */
-  void purge(PurgeContext context);
-
-}
diff --git a/sonar-deprecated/src/main/java/org/sonar/api/batch/PurgeContext.java b/sonar-deprecated/src/main/java/org/sonar/api/batch/PurgeContext.java
deleted file mode 100644 (file)
index 9062bc4..0000000
+++ /dev/null
@@ -1,33 +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.api.batch;
-
-/**
- * 
- * @since 1.10
- * @deprecated since 2.5
- */
-@Deprecated
-public interface PurgeContext {
-
-  Integer getPreviousSnapshotId();
-
-  Integer getLastSnapshotId();
-}
diff --git a/sonar-deprecated/src/main/java/org/sonar/core/purge/AbstractPurge.java b/sonar-deprecated/src/main/java/org/sonar/core/purge/AbstractPurge.java
deleted file mode 100644 (file)
index cb5500e..0000000
+++ /dev/null
@@ -1,148 +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.core.purge;
-
-import org.sonar.api.batch.Purge;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.model.*;
-import org.sonar.api.design.DependencyDto;
-import org.sonar.api.utils.TimeProfiler;
-
-import java.util.List;
-
-import javax.persistence.Query;
-
-/**
- * @deprecated since 2.5. The DBCleaner plugin implements all required purge taks, but you can extend org.sonar.plugins.dbcleaner.api.Purge
- */
-@Deprecated
-public abstract class AbstractPurge implements Purge {
-
-  private static final int MAX_IN_ELEMENTS = 950;
-
-  private int sqlInPageSize = MAX_IN_ELEMENTS;
-  private DatabaseSession session;
-  private TimeProfiler profiler = new TimeProfiler().setLevelToDebug();
-
-  public AbstractPurge(DatabaseSession session) {
-    this.session = session;
-  }
-
-  protected DatabaseSession getSession() {
-    return session;
-  }
-
-  /**
-   * Delete SNAPSHOTS and all dependent tables (MEASURES, ...)
-   */
-  protected void deleteSnapshotData(List<Integer> snapshotIds) {
-    deleteMeasuresBySnapshotId(snapshotIds);
-    deleteSources(snapshotIds);
-    deleteViolations(snapshotIds);
-    deleteDependencies(snapshotIds);
-    deleteSnapshots(snapshotIds);
-  }
-
-  protected void deleteDependencies(List<Integer> snapshotIds) {
-    executeQuery("delete dependencies", snapshotIds, "delete from " + DependencyDto.class.getSimpleName()
-        + " d where d.fromSnapshotId in (:ids)");
-    executeQuery("delete dependencies", snapshotIds, "delete from " + DependencyDto.class.getSimpleName()
-        + " d where d.toSnapshotId in (:ids)");
-  }
-
-  /**
-   * Delete all measures, including MEASURE_DATA
-   */
-  protected void deleteMeasuresBySnapshotId(List<Integer> snapshotIds) {
-    executeQuery("delete measures by snapshot id", snapshotIds, "delete from " + MeasureData.class.getSimpleName()
-        + " m where m.snapshotId in (:ids)");
-    executeQuery("delete measures by snapshot id", snapshotIds, "delete from " + MeasureModel.class.getSimpleName()
-        + " m where m.snapshotId in (:ids)");
-  }
-
-  /**
-   * Delete all measures, including MEASURE_DATA
-   */
-  protected void deleteMeasuresById(List<Integer> measureIds) {
-    executeQuery("delete measures by id", measureIds, "delete from " + MeasureData.class.getSimpleName()
-        + " m where m.measure.id in (:ids)");
-    executeQuery("delete measures by id", measureIds, "delete from " + MeasureModel.class.getSimpleName() + " m where m.id in (:ids)");
-  }
-
-  /**
-   * Delete SNAPSHOT_SOURCES table
-   */
-  protected void deleteSources(List<Integer> snapshotIds) {
-    executeQuery("delete sources", snapshotIds, "delete from " + SnapshotSource.class.getSimpleName() + " e where e.snapshotId in (:ids)");
-  }
-
-  /**
-   * Delete violations (RULE_FAILURES table)
-   */
-  protected void deleteViolations(List<Integer> snapshotIds) {
-    executeQuery("delete violations", snapshotIds, "delete from " + RuleFailureModel.class.getSimpleName()
-        + " e where e.snapshotId in (:ids)");
-  }
-
-  /**
-   * Delete SNAPSHOTS table
-   */
-  protected void deleteSnapshots(List<Integer> snapshotIds) {
-    executeQuery("delete snapshots", snapshotIds, "delete from " + Snapshot.class.getSimpleName() + " s where s.id in (:ids)");
-  }
-
-  /**
-   * Paginate execution of SQL requests to avoid exceeding size of rollback segment
-   */
-  private void executeQuery(String name, List<Integer> ids, String hql) {
-    if (ids == null || ids.isEmpty()) {
-      return;
-    }
-
-    TimeProfiler profiler = new TimeProfiler().setLevelToDebug().start("Execute " + name);
-
-    int page = 1;
-    int index = 0;
-    while (index < ids.size()) {
-      TimeProfiler pageProfiler = new TimeProfiler().setLevelToDebug().start("Execute " + name + " " + page + " page");
-      Query query = session.createQuery(hql);
-      List<Integer> paginedSids = ids.subList(index, Math.min(ids.size(), index + sqlInPageSize));
-      query.setParameter("ids", paginedSids);
-      query.executeUpdate();
-      index += sqlInPageSize;
-      page++;
-      session.commit();
-      pageProfiler.stop();
-    }
-
-    profiler.stop();
-  }
-
-  protected void executeQuery(List<Integer> ids, String hql) {
-    executeQuery("delete for " + getClass().getSimpleName(), ids, hql);
-  }
-
-  protected List<Integer> selectIds(Query query) {
-    profiler.start("Select IDs for " + getClass().getSimpleName());
-    List<Integer> result = query.getResultList();
-    profiler.stop();
-    return result;
-  }
-}
index 9088e89454c63c417442ef00b64f5a98b24bc976..a6e9147d22ceb7063f3b1758192ae1cf1402c1eb 100644 (file)
@@ -24,7 +24,7 @@ import org.apache.commons.lang.StringUtils;
 import org.sonar.api.profiles.RulesProfile;
 import org.sonar.api.rules.ActiveRule;
 import org.sonar.api.rules.ActiveRuleParam;
-import org.sonar.api.utils.FieldUtils;
+import org.sonar.api.utils.FieldUtils2;
 import org.sonar.api.utils.SonarException;
 import org.sonar.check.Check;
 import org.sonar.check.CheckProperty;
@@ -144,7 +144,7 @@ public final class AnnotationCheckFactory extends CheckFactory {
   }
 
   private Field getField(Object check, String key) {
-    List<Field> fields = FieldUtils.getFields(check.getClass(), true);
+    List<Field> fields = FieldUtils2.getFields(check.getClass(), true);
     for (Field field : fields) {
       RuleProperty propertyAnnotation = field.getAnnotation(RuleProperty.class);
       if (propertyAnnotation != null) {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/FieldUtils.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/FieldUtils.java
deleted file mode 100644 (file)
index de459c2..0000000
+++ /dev/null
@@ -1,70 +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.api.utils;
-
-import com.google.common.collect.Lists;
-import org.apache.commons.lang.ClassUtils;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.List;
-
-/**
- * Add features missing in org.apache.commons.lang3.reflect.FieldUtils
- *
- * @since 2.14
- */
-public final class FieldUtils {
-  private FieldUtils() {
-  }
-
-  /**
-   * Get accessible <code>Field</code> breaking scope if requested. Superclasses/interfaces are considered.
-   *
-   * @param clazz       the class to reflect, must not be null
-   * @param forceAccess whether to break scope restrictions using the <code>setAccessible</code> method.
-   *                    <code>False</code> only matches public fields.
-   */
-  public static List<Field> getFields(Class clazz, boolean forceAccess) {
-    List<Field> result = Lists.newArrayList();
-    Class c = clazz;
-    while (c != null) {
-      for (Field declaredField : c.getDeclaredFields()) {
-        if (!Modifier.isPublic(declaredField.getModifiers())) {
-          if (forceAccess) {
-            declaredField.setAccessible(true);//NOSONAR only works from sufficiently privileged code
-          } else {
-            continue;
-          }
-        }
-        result.add(declaredField);
-      }
-      c = c.getSuperclass();
-    }
-
-    for (Object anInterface : ClassUtils.getAllInterfaces(clazz)) {
-      for (Field declaredField : ((Class) anInterface).getDeclaredFields()) {
-        result.add(declaredField);
-      }
-    }
-
-    return result;
-  }
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/FieldUtils2.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/FieldUtils2.java
new file mode 100644 (file)
index 0000000..cc92239
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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.api.utils;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.lang.ClassUtils;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.List;
+
+/**
+ * Add features missing in org.apache.commons.lang.reflect.FieldUtils
+ *
+ * @since 2.14
+ */
+public final class FieldUtils2 {
+  private FieldUtils2() {
+  }
+
+  /**
+   * Get accessible <code>Field</code> breaking scope if requested. Superclasses/interfaces are considered.
+   *
+   * @param clazz       the class to reflect, must not be null
+   * @param forceAccess whether to break scope restrictions using the <code>setAccessible</code> method.
+   *                    <code>False</code> only matches public fields.
+   */
+  public static List<Field> getFields(Class clazz, boolean forceAccess) {
+    List<Field> result = Lists.newArrayList();
+    Class c = clazz;
+    while (c != null) {
+      for (Field declaredField : c.getDeclaredFields()) {
+        if (!Modifier.isPublic(declaredField.getModifiers())) {
+          if (forceAccess) {
+            declaredField.setAccessible(true);//NOSONAR only works from sufficiently privileged code
+          } else {
+            continue;
+          }
+        }
+        result.add(declaredField);
+      }
+      c = c.getSuperclass();
+    }
+
+    for (Object anInterface : ClassUtils.getAllInterfaces(clazz)) {
+      for (Field declaredField : ((Class) anInterface).getDeclaredFields()) {
+        result.add(declaredField);
+      }
+    }
+
+    return result;
+  }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/FieldUtils2Test.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/FieldUtils2Test.java
new file mode 100644 (file)
index 0000000..f9615c2
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * 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.api.utils;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.junit.Test;
+
+import java.lang.reflect.Field;
+import java.util.List;
+
+import static org.junit.Assert.assertThat;
+import static org.junit.matchers.JUnitMatchers.hasItem;
+
+public class FieldUtils2Test {
+
+  @Test
+  public void shouldGetFieldsOfSingleClass() {
+    List<Field> fields = FieldUtils2.getFields(FieldsWithDifferentModifiers.class, true);
+    assertThat(fields, hasItem(new FieldMatcher("publicField")));
+    assertThat(fields, hasItem(new FieldMatcher("protectedField")));
+    assertThat(fields, hasItem(new FieldMatcher("packageField")));
+    assertThat(fields, hasItem(new FieldMatcher("privateField")));
+    assertThat(fields, hasItem(new FieldMatcher("publicStaticField")));
+    assertThat(fields, hasItem(new FieldMatcher("protectedStaticField")));
+    assertThat(fields, hasItem(new FieldMatcher("packageStaticField")));
+    assertThat(fields, hasItem(new FieldMatcher("privateStaticField")));
+  }
+
+  @Test
+  public void shouldGetFieldsOfClassHierarchy() {
+    List<Field> fields = FieldUtils2.getFields(Child.class, true);
+    assertThat(fields, hasItem(new FieldMatcher("publicField")));
+    assertThat(fields, hasItem(new FieldMatcher("protectedField")));
+    assertThat(fields, hasItem(new FieldMatcher("packageField")));
+    assertThat(fields, hasItem(new FieldMatcher("privateField")));
+    assertThat(fields, hasItem(new FieldMatcher("publicStaticField")));
+    assertThat(fields, hasItem(new FieldMatcher("protectedStaticField")));
+    assertThat(fields, hasItem(new FieldMatcher("packageStaticField")));
+    assertThat(fields, hasItem(new FieldMatcher("privateStaticField")));
+    assertThat(fields, hasItem(new FieldMatcher("childPrivateField")));
+  }
+
+  @Test
+  public void shouldGetOnlyAccessibleFields() {
+    List<Field> fields = FieldUtils2.getFields(Child.class, false);
+
+    assertThat(fields, hasItem(new FieldMatcher("publicField")));
+    assertThat(fields, hasItem(new FieldMatcher("publicStaticField")));
+  }
+
+  @Test
+  public void shouldGetFieldsOfInterface() {
+    List<Field> fields = FieldUtils2.getFields(InterfaceWithFields.class, true);
+
+    assertThat(fields, hasItem(new FieldMatcher("INTERFACE_FIELD")));
+  }
+
+  @Test
+  public void shouldGetFieldsOfInterfaceImplementation() {
+    List<Field> fields = FieldUtils2.getFields(InterfaceImplementation.class, true);
+
+    assertThat(fields, hasItem(new FieldMatcher("INTERFACE_FIELD")));
+  }
+
+  static interface InterfaceWithFields {
+    String INTERFACE_FIELD = "foo";
+  }
+
+  static class InterfaceImplementation implements InterfaceWithFields {
+  }
+
+  static class FieldsWithDifferentModifiers {
+    public String publicField;
+    protected String protectedField;
+    String packageField;
+    private String privateField;
+
+    public static String publicStaticField;
+    protected static String protectedStaticField;
+    static String packageStaticField;
+    private static String privateStaticField;
+  }
+
+  static class Child extends FieldsWithDifferentModifiers {
+    private String childPrivateField;
+  }
+
+
+  static class FieldMatcher extends BaseMatcher<Field> {
+    private String name;
+
+    FieldMatcher(String name) {
+      this.name = name;
+    }
+
+    public boolean matches(Object o) {
+      Field field = (Field) o;
+      return name.equals(field.getName());
+    }
+
+    public void describeTo(Description description) {
+      description.appendText("Field with name: ").appendValue(name);
+    }
+  }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/FieldUtilsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/FieldUtilsTest.java
deleted file mode 100644 (file)
index 4694c49..0000000
+++ /dev/null
@@ -1,124 +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.api.utils;
-
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.junit.Test;
-
-import java.lang.reflect.Field;
-import java.util.List;
-
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import static org.junit.matchers.JUnitMatchers.hasItem;
-
-public class FieldUtilsTest {
-
-  @Test
-  public void shouldGetFieldsOfSingleClass() {
-    List<Field> fields = FieldUtils.getFields(FieldsWithDifferentModifiers.class, true);
-    assertThat(fields, hasItem(new FieldMatcher("publicField")));
-    assertThat(fields, hasItem(new FieldMatcher("protectedField")));
-    assertThat(fields, hasItem(new FieldMatcher("packageField")));
-    assertThat(fields, hasItem(new FieldMatcher("privateField")));
-    assertThat(fields, hasItem(new FieldMatcher("publicStaticField")));
-    assertThat(fields, hasItem(new FieldMatcher("protectedStaticField")));
-    assertThat(fields, hasItem(new FieldMatcher("packageStaticField")));
-    assertThat(fields, hasItem(new FieldMatcher("privateStaticField")));
-  }
-
-  @Test
-  public void shouldGetFieldsOfClassHierarchy() {
-    List<Field> fields = FieldUtils.getFields(Child.class, true);
-    assertThat(fields, hasItem(new FieldMatcher("publicField")));
-    assertThat(fields, hasItem(new FieldMatcher("protectedField")));
-    assertThat(fields, hasItem(new FieldMatcher("packageField")));
-    assertThat(fields, hasItem(new FieldMatcher("privateField")));
-    assertThat(fields, hasItem(new FieldMatcher("publicStaticField")));
-    assertThat(fields, hasItem(new FieldMatcher("protectedStaticField")));
-    assertThat(fields, hasItem(new FieldMatcher("packageStaticField")));
-    assertThat(fields, hasItem(new FieldMatcher("privateStaticField")));
-    assertThat(fields, hasItem(new FieldMatcher("childPrivateField")));
-  }
-
-  @Test
-  public void shouldGetOnlyAccessibleFields() {
-    List<Field> fields = FieldUtils.getFields(Child.class, false);
-
-    assertThat(fields, hasItem(new FieldMatcher("publicField")));
-    assertThat(fields, hasItem(new FieldMatcher("publicStaticField")));
-  }
-
-  @Test
-  public void shouldGetFieldsOfInterface() {
-    List<Field> fields = FieldUtils.getFields(InterfaceWithFields.class, true);
-
-    assertThat(fields, hasItem(new FieldMatcher("INTERFACE_FIELD")));
-  }
-
-  @Test
-  public void shouldGetFieldsOfInterfaceImplementation() {
-    List<Field> fields = FieldUtils.getFields(InterfaceImplementation.class, true);
-
-    assertThat(fields, hasItem(new FieldMatcher("INTERFACE_FIELD")));
-  }
-
-  static interface InterfaceWithFields {
-    String INTERFACE_FIELD = "foo";
-  }
-
-  static class InterfaceImplementation implements InterfaceWithFields {
-  }
-
-  static class FieldsWithDifferentModifiers {
-    public String publicField;
-    protected String protectedField;
-    String packageField;
-    private String privateField;
-
-    public static String publicStaticField;
-    protected static String protectedStaticField;
-    static String packageStaticField;
-    private static String privateStaticField;
-  }
-
-  static class Child extends FieldsWithDifferentModifiers {
-    private String childPrivateField;
-  }
-
-
-  static class FieldMatcher extends BaseMatcher<Field> {
-    private String name;
-
-    FieldMatcher(String name) {
-      this.name = name;
-    }
-
-    public boolean matches(Object o) {
-      Field field = (Field) o;
-      return name.equals(field.getName());
-    }
-
-    public void describeTo(Description description) {
-      description.appendText("Field with name: ").appendValue(name);
-    }
-  }
-}