diff options
68 files changed, 1418 insertions, 1596 deletions
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/DbDuplicationsIndex.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/DbDuplicationsIndex.java index 5409e979a24..6e9f3e43f68 100644 --- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/DbDuplicationsIndex.java +++ b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/DbDuplicationsIndex.java @@ -19,22 +19,21 @@ */ 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); } diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/DbCleanerPlugin.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/DbCleanerPlugin.java index 84d78def360..47a872a2fd6 100644 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/DbCleanerPlugin.java +++ b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/DbCleanerPlugin.java @@ -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); } } diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PeriodCleaner.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PeriodCleaner.java index f9b0c412a2d..25cad3f72d5 100644 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PeriodCleaner.java +++ b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PeriodCleaner.java @@ -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); } diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/Purge.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/Purge.java index 20d270c5e0e..5a147f72028 100644 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/Purge.java +++ b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/Purge.java @@ -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; diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PurgeContext.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PurgeContext.java index 68a10310777..544949a3d7e 100644 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PurgeContext.java +++ b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PurgeContext.java @@ -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(); diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PurgeUtils.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PurgeUtils.java index dfe82050d89..1d9a9fe4bfa 100644 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PurgeUtils.java +++ b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/PurgeUtils.java @@ -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/test/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanResourcesTest.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteAbortedBuilds.java index d6df515c6b2..464fd4b2714 100644 --- a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanResourcesTest.java +++ b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteAbortedBuilds.java @@ -19,20 +19,25 @@ */ package org.sonar.plugins.dbcleaner.purges; -import org.junit.Test; -import org.sonar.jpa.test.AbstractDbUnitTestCase; +import org.sonar.core.purge.PurgeDao; +import org.sonar.core.purge.PurgeSnapshotQuery; -import java.sql.SQLException; +/** + * @since 2.14 + */ +public class DeleteAbortedBuilds extends ProjectPurge { + private PurgeDao purgeDao; -public class PurgeOrphanResourcesTest extends AbstractDbUnitTestCase { - @Test - public void purgeOrphanResources() throws SQLException { - assertPurge("purgeOrphanResources"); + public DeleteAbortedBuilds(PurgeDao purgeDao) { + this.purgeDao = purgeDao; } - private void assertPurge(String testName) { - setupData(testName); - new PurgeOrphanResources(getSession()).purge(null); - checkTables(testName, "projects"); + @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 index 00000000000..a96389dc685 --- /dev/null +++ b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteDirectoryHistory.java @@ -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/test/java/org/sonar/plugins/dbcleaner/purges/PurgeEventOrphansTest.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteFileHistory.java index 8f53836fff6..b0f48d93239 100644 --- a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeEventOrphansTest.java +++ b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/DeleteFileHistory.java @@ -19,22 +19,23 @@ */ package org.sonar.plugins.dbcleaner.purges; -import org.junit.Test; -import org.sonar.jpa.test.AbstractDbUnitTestCase; +import org.sonar.api.resources.Scopes; +import org.sonar.core.purge.PurgeDao; +import org.sonar.core.purge.PurgeSnapshotQuery; -import java.sql.SQLException; +public class DeleteFileHistory extends ProjectPurge { + private PurgeDao purgeDao; -public class PurgeEventOrphansTest extends AbstractDbUnitTestCase { - - @Test - public void purgeEventOrphans() throws SQLException { - assertPurge("purgeEventOrphans"); + public DeleteFileHistory(PurgeDao purgeDao) { + this.purgeDao = purgeDao; } - private void assertPurge(String testName) { - setupData(testName); - new PurgeEventOrphans(getSession()).purge(null); - checkTables(testName, "events"); + @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/sonar-deprecated/src/main/java/org/sonar/api/batch/AbstractPurge.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurge.java index 7482b514627..41ecd85098f 100644 --- a/sonar-deprecated/src/main/java/org/sonar/api/batch/AbstractPurge.java +++ b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurge.java @@ -17,19 +17,12 @@ * 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; +package org.sonar.plugins.dbcleaner.purges; -import org.sonar.api.database.DatabaseSession; +import org.sonar.api.BatchExtension; -/** - * @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 abstract class ProjectPurge implements BatchExtension { + + public abstract void execute(ProjectPurgeContext context); - public AbstractPurge(DatabaseSession session) { - super(session); - } - } diff --git a/sonar-deprecated/src/main/java/org/sonar/api/batch/PurgeContext.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurgeContext.java index 9062bc46f4c..e01330a0598 100644 --- a/sonar-deprecated/src/main/java/org/sonar/api/batch/PurgeContext.java +++ b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurgeContext.java @@ -17,17 +17,12 @@ * 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; +package org.sonar.plugins.dbcleaner.purges; -/** - * - * @since 1.10 - * @deprecated since 2.5 - */ -@Deprecated -public interface PurgeContext { +import java.util.Date; - Integer getPreviousSnapshotId(); +public interface ProjectPurgeContext { + Long getRootProjectId(); - Integer getLastSnapshotId(); + 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 index 00000000000..de721ba1891 --- /dev/null +++ b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/ProjectPurgeTask.java @@ -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 index 52489f93e98..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDeletedResources.java +++ /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 index 948df2ecba4..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDependencies.java +++ /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 index e62a33daf4d..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDeprecatedLast.java +++ /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 index 15ddd6c1f25..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeDisabledResources.java +++ /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 index d6b3611b46a..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeEntities.java +++ /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 index 894f15c8559..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeEventOrphans.java +++ /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 index 11b2ddada56..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanResources.java +++ /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 index 6f19e20871f..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanReviews.java +++ /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 index 79743915054..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgePropertyOrphans.java +++ /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 index 7a22eb718c9..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeResourceRoles.java +++ /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 index 1b6f6d75444..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeRuleMeasures.java +++ /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 index e7a053bfd41..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/purges/PurgeUnprocessed.java +++ /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 index cd3a5c4fbca..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/DefaultPurgeContext.java +++ /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/PurgeRunner.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/DeprecatedPurgePostJob.java index d12beab914c..2069b3873cd 100644 --- 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/DeprecatedPurgePostJob.java @@ -19,6 +19,7 @@ */ 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; @@ -30,33 +31,24 @@ 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 PurgeRunner implements PostJob { +public final class DeprecatedPurgePostJob 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); + private static final Logger LOG = LoggerFactory.getLogger(DeprecatedPurgePostJob.class); - public PurgeRunner(DatabaseSession session, Project project, Snapshot snapshot, Purge[] purges) { + public DeprecatedPurgePostJob(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) { @@ -73,32 +65,10 @@ public final class PurgeRunner implements PostJob { 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(); @@ -141,4 +111,51 @@ public final class PurgeRunner implements PostJob { 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 index 00000000000..6dccaef73be --- /dev/null +++ b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/ProjectPurgePostJob.java @@ -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/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 index 32bdf869c75..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDeletedResourcesTest.java +++ /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 index 3ada47736c6..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDependenciesTest.java +++ /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 index 545b47f924c..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDeprecatedLastTest.java +++ /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 index ab9b9ff2b28..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeDisabledResourcesTest.java +++ /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 index b46a3c3919b..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeEntitiesTest.java +++ /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/PurgeOrphanReviewsTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanReviewsTest.java deleted file mode 100644 index 2a5ef03385c..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeOrphanReviewsTest.java +++ /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 index 3724046de94..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgePropertyOrphansTest.java +++ /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/PurgeUnprocessedTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeUnprocessedTest.java deleted file mode 100644 index f972d17184c..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeUnprocessedTest.java +++ /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/PurgeRunnerTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/runner/DeprecatedPurgePostJobTest.java index 76ff59d0424..402fdff856a 100644 --- 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/DeprecatedPurgePostJobTest.java @@ -22,7 +22,6 @@ 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; @@ -36,7 +35,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.*; -public class PurgeRunnerTest extends AbstractDbUnitTestCase { +public class DeprecatedPurgePostJobTest extends AbstractDbUnitTestCase { @Test public void shouldExecutePurges() { @@ -49,7 +48,7 @@ public class PurgeRunnerTest extends AbstractDbUnitTestCase { Purge purge2 = mock(Purge.class); Purge[] purges = new Purge[]{purge1, purge2}; - new PurgeRunner(getSession(), new Project("key"), snapshot, purges).purge(); + new DeprecatedPurgePostJob(getSession(), new Project("key"), snapshot, purges).purge(); verify(purge1).purge(argThat(new BaseMatcher<PurgeContext>() { public boolean matches(Object o) { @@ -72,7 +71,7 @@ public class PurgeRunnerTest extends AbstractDbUnitTestCase { Purge purge2 = mock(Purge.class); Purge[] purges = new Purge[]{purge1, purge2}; - new PurgeRunner(getSession(), new Project("key"), snapshot, purges).purge(); + new DeprecatedPurgePostJob(getSession(), new Project("key"), snapshot, purges).purge(); verify(purge1).purge(argThat(new BaseMatcher<PurgeContext>() { public boolean matches(Object o) { @@ -85,39 +84,14 @@ public class PurgeRunnerTest extends AbstractDbUnitTestCase { })); } - - @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)); + assertTrue(DeprecatedPurgePostJob.shouldExecuteOn(project)); when(project.isRoot()).thenReturn(false); - assertFalse(PurgeRunner.shouldExecuteOn(project)); + assertFalse(DeprecatedPurgePostJob.shouldExecuteOn(project)); } /** @@ -127,11 +101,11 @@ public class PurgeRunnerTest extends AbstractDbUnitTestCase { @Test public void shouldIgnoreDeadlocks() { Purge purge = mock(Purge.class); - doThrow(new PersistenceException()).when(purge).purge((PurgeContext)anyObject()); + doThrow(new PersistenceException()).when(purge).purge((PurgeContext) anyObject()); - PurgeRunner runner = new PurgeRunner(getSession(), new Project(""), new Snapshot(), new Purge[]{purge}); + DeprecatedPurgePostJob runner = new DeprecatedPurgePostJob(getSession(), new Project(""), new Snapshot(), new Purge[]{purge}); runner.purge();// must not raise any exceptions - verify(purge).purge((PurgeContext)anyObject()); + 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 index 00000000000..18860b7ab95 --- /dev/null +++ b/plugins/sonar-dbcleaner-plugin/src/test/resources/org/sonar/plugins/dbcleaner/runner/DeprecatedPurgePostJobTest/shared.xml @@ -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 index 1908f9ccf0a..00000000000 --- a/plugins/sonar-dbcleaner-plugin/src/test/resources/org/sonar/plugins/dbcleaner/runner/PurgeRunnerTest/shared.xml +++ /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 diff --git a/sonar-core/src/main/java/org/sonar/core/dashboard/ActiveDashboardDao.java b/sonar-core/src/main/java/org/sonar/core/dashboard/ActiveDashboardDao.java index 569a36b146c..1e283c6f541 100644 --- a/sonar-core/src/main/java/org/sonar/core/dashboard/ActiveDashboardDao.java +++ b/sonar-core/src/main/java/org/sonar/core/dashboard/ActiveDashboardDao.java @@ -39,7 +39,7 @@ public class ActiveDashboardDao implements BatchComponent, ServerComponent { mapper.insert(activeDashboardDto); session.commit(); } finally { - session.close(); + MyBatis.closeSessionQuietly(session); } } diff --git a/sonar-core/src/main/java/org/sonar/core/dashboard/DashboardDao.java b/sonar-core/src/main/java/org/sonar/core/dashboard/DashboardDao.java index ba2d1853708..b70433dbf92 100644 --- a/sonar-core/src/main/java/org/sonar/core/dashboard/DashboardDao.java +++ b/sonar-core/src/main/java/org/sonar/core/dashboard/DashboardDao.java @@ -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); } } diff --git a/sonar-core/src/main/java/org/sonar/core/duplication/DuplicationDao.java b/sonar-core/src/main/java/org/sonar/core/duplication/DuplicationDao.java index eb3084ddb8d..2d98f947ca8 100644 --- a/sonar-core/src/main/java/org/sonar/core/duplication/DuplicationDao.java +++ b/sonar-core/src/main/java/org/sonar/core/duplication/DuplicationDao.java @@ -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); } } diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java b/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java index 579645ba3a9..5f337782152 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java @@ -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)); diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseMigrator.java b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseMigrator.java index ef2950eed2a..0f7a0f0faac 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseMigrator.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseMigrator.java @@ -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. diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseUtils.java b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseUtils.java index be14f84242f..814c1ee26e2 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseUtils.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseUtils.java @@ -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", diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java index cd055ef0ac6..59da8b5aeea 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java @@ -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 index 00000000000..510537f9b57 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/purge/PurgeDao.java @@ -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/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeRuleMeasuresTest.java b/sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java index c3caf3ac3ff..2ee5c5857ba 100644 --- a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeRuleMeasuresTest.java +++ b/sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java @@ -17,33 +17,34 @@ * 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; +package org.sonar.core.purge; -import org.junit.Test; -import org.sonar.api.resources.Project; -import org.sonar.jpa.test.AbstractDbUnitTestCase; -import org.sonar.plugins.dbcleaner.api.PurgeContext; +public interface PurgeMapper { + void deleteSnapshot(long snapshotId); -public class PurgeRuleMeasuresTest extends AbstractDbUnitTestCase { + void deleteSnapshotDependencies(long snapshotId); - @Test - public void purgeRuleMeasures() { - setupData("sharedFixture", "purgeRuleMeasures"); + void deleteSnapshotDuplications(long snapshotId); - new PurgeRuleMeasures(getSession()).purge(new PurgeContext() { - public Project getProject() { - return null; - } + void deleteSnapshotEvents(long snapshotId); - public Integer getSnapshotId() { - return 4; - } - public Integer getPreviousSnapshotId() { - return 1; - } + void deleteSnapshotMeasures(long snapshotId); - }); + void deleteSnapshotMeasureData(long snapshotId); - checkTables("purgeRuleMeasures", "snapshots", "project_measures", "measure_data"); - } + 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 index 00000000000..bb16364e559 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/purge/PurgeSnapshotQuery.java @@ -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; + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerDao.java b/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerDao.java index 7fb493e6508..44f1d533210 100644 --- a/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerDao.java +++ b/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerDao.java @@ -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/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeResourceRolesTest.java b/sonar-core/src/main/java/org/sonar/core/resource/ResourceMapper.java index ba7bf56aec3..deb72aeb3ad 100644 --- a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/purges/PurgeResourceRolesTest.java +++ b/sonar-core/src/main/java/org/sonar/core/resource/ResourceMapper.java @@ -17,22 +17,8 @@ * 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; +package org.sonar.core.resource; -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"); - } +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 index 00000000000..f211be6aac3 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/resource/SnapshotDto.java @@ -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; + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/review/ReviewDao.java b/sonar-core/src/main/java/org/sonar/core/review/ReviewDao.java index 438bb911021..c090251153d 100644 --- a/sonar-core/src/main/java/org/sonar/core/review/ReviewDao.java +++ b/sonar-core/src/main/java/org/sonar/core/review/ReviewDao.java @@ -19,14 +19,13 @@ */ 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); } } } diff --git a/sonar-core/src/main/java/org/sonar/core/rule/RuleDao.java b/sonar-core/src/main/java/org/sonar/core/rule/RuleDao.java index 76778d0b865..1b4b6545ea2 100644 --- a/sonar-core/src/main/java/org/sonar/core/rule/RuleDao.java +++ b/sonar-core/src/main/java/org/sonar/core/rule/RuleDao.java @@ -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); } } diff --git a/sonar-core/src/main/java/org/sonar/core/template/LoadedTemplateDao.java b/sonar-core/src/main/java/org/sonar/core/template/LoadedTemplateDao.java index 5a183c0b567..7067d03bd7c 100644 --- a/sonar-core/src/main/java/org/sonar/core/template/LoadedTemplateDao.java +++ b/sonar-core/src/main/java/org/sonar/core/template/LoadedTemplateDao.java @@ -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); } } diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-derby.sql b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-derby.sql index 02a2b5895b5..8144ad8cb05 100644 --- a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-derby.sql +++ b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-derby.sql @@ -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; diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/schema-derby.ddl b/sonar-core/src/main/resources/org/sonar/core/persistence/schema-derby.ddl index 6ddd00a816b..81491225d86 100644 --- a/sonar-core/src/main/resources/org/sonar/core/persistence/schema-derby.ddl +++ b/sonar-core/src/main/resources/org/sonar/core/persistence/schema-derby.ddl @@ -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 index 00000000000..aa92585f3d6 --- /dev/null +++ b/sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml @@ -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 <= #{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 <= #{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 index 00000000000..9ef0bcd36de --- /dev/null +++ b/sonar-core/src/main/resources/org/sonar/core/resource/ResourceMapper.xml @@ -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 index 00000000000..3e8f6249081 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/purge/PurgeDaoTest.java @@ -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 index 00000000000..20f47449b5b --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteSnapshot-result.xml @@ -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 index 00000000000..9a564593166 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteSnapshot.xml @@ -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 index 00000000000..22327faf348 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeSnapshots-result.xml @@ -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 index 00000000000..cc870ca1a5b --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeSnapshots.xml @@ -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/Purge.java b/sonar-deprecated/src/main/java/org/sonar/api/batch/Purge.java deleted file mode 100644 index 358d23f5f4a..00000000000 --- a/sonar-deprecated/src/main/java/org/sonar/api/batch/Purge.java +++ /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/core/purge/AbstractPurge.java b/sonar-deprecated/src/main/java/org/sonar/core/purge/AbstractPurge.java deleted file mode 100644 index cb5500e26e9..00000000000 --- a/sonar-deprecated/src/main/java/org/sonar/core/purge/AbstractPurge.java +++ /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; - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/checks/AnnotationCheckFactory.java b/sonar-plugin-api/src/main/java/org/sonar/api/checks/AnnotationCheckFactory.java index 9088e89454c..a6e9147d22c 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/checks/AnnotationCheckFactory.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/checks/AnnotationCheckFactory.java @@ -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/FieldUtils2.java index de459c25af1..cc922397148 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/FieldUtils.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/FieldUtils2.java @@ -27,12 +27,12 @@ import java.lang.reflect.Modifier; import java.util.List; /** - * Add features missing in org.apache.commons.lang3.reflect.FieldUtils + * Add features missing in org.apache.commons.lang.reflect.FieldUtils * * @since 2.14 */ -public final class FieldUtils { - private FieldUtils() { +public final class FieldUtils2 { + private FieldUtils2() { } /** 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/FieldUtils2Test.java index 4694c498e8c..f9615c2d394 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/FieldUtilsTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/FieldUtils2Test.java @@ -26,15 +26,14 @@ 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 { +public class FieldUtils2Test { @Test public void shouldGetFieldsOfSingleClass() { - List<Field> fields = FieldUtils.getFields(FieldsWithDifferentModifiers.class, true); + 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"))); @@ -47,7 +46,7 @@ public class FieldUtilsTest { @Test public void shouldGetFieldsOfClassHierarchy() { - List<Field> fields = FieldUtils.getFields(Child.class, true); + 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"))); @@ -61,7 +60,7 @@ public class FieldUtilsTest { @Test public void shouldGetOnlyAccessibleFields() { - List<Field> fields = FieldUtils.getFields(Child.class, false); + List<Field> fields = FieldUtils2.getFields(Child.class, false); assertThat(fields, hasItem(new FieldMatcher("publicField"))); assertThat(fields, hasItem(new FieldMatcher("publicStaticField"))); @@ -69,14 +68,14 @@ public class FieldUtilsTest { @Test public void shouldGetFieldsOfInterface() { - List<Field> fields = FieldUtils.getFields(InterfaceWithFields.class, true); + List<Field> fields = FieldUtils2.getFields(InterfaceWithFields.class, true); assertThat(fields, hasItem(new FieldMatcher("INTERFACE_FIELD"))); } @Test public void shouldGetFieldsOfInterfaceImplementation() { - List<Field> fields = FieldUtils.getFields(InterfaceImplementation.class, true); + List<Field> fields = FieldUtils2.getFields(InterfaceImplementation.class, true); assertThat(fields, hasItem(new FieldMatcher("INTERFACE_FIELD"))); } |